From bcbbef82f2fc25f1c58cae2dc5dba3e0a768c78e Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 8 Dec 2023 15:54:48 -0800 Subject: [PATCH 01/46] feat(GWE): Introduce Groundwater Energy Transport --- autotest/test_gwe_dsp.py | 500 ++++++ doc/Common/gwe-cntobs.tex | 1 + doc/Common/gwe-esrobs.tex | 1 + doc/Common/gwe-gweobs.tex | 1 + doc/Common/gwe-lkeobs.tex | 25 + doc/Common/gwe-mweobs.tex | 13 + doc/Common/gwe-obs.tex | 2 + doc/Common/gwe-obstypetable.tex | 94 ++ doc/Common/gwe-sfeobs.tex | 16 + doc/Common/gwe-uzeobs.tex | 14 + doc/MODFLOW6References.bib | 22 + doc/mf6io/body.tex | 5 + doc/mf6io/gwe/adv.tex | 16 + doc/mf6io/gwe/cnt.tex | 47 + doc/mf6io/gwe/dsp.tex | 17 + doc/mf6io/gwe/fmi.tex | 54 + doc/mf6io/gwe/gwe-gwe.tex | 45 + doc/mf6io/gwe/gwe-obs.tex | 39 + doc/mf6io/gwe/gwe.tex | 131 ++ doc/mf6io/gwe/ic.tex | 17 + doc/mf6io/gwe/mst.tex | 17 + doc/mf6io/gwe/namefile.tex | 47 + doc/mf6io/gwe/oc.tex | 25 + doc/mf6io/gwe/ssm.tex | 114 ++ doc/mf6io/mf6io.bbl | 12 + doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn | 275 ++++ doc/mf6io/mf6ivar/dfn/exg-gwfgwe.dfn | 3 + doc/mf6io/mf6ivar/dfn/gwe-adv.dfn | 11 + doc/mf6io/mf6ivar/dfn/gwe-cnt.dfn | 213 +++ doc/mf6io/mf6ivar/dfn/gwe-dis.dfn | 122 ++ doc/mf6io/mf6ivar/dfn/gwe-disu.dfn | 277 ++++ doc/mf6io/mf6ivar/dfn/gwe-disv.dfn | 204 +++ doc/mf6io/mf6ivar/dfn/gwe-dsp.dfn | 92 ++ doc/mf6io/mf6ivar/dfn/gwe-fmi.dfn | 58 + doc/mf6io/mf6ivar/dfn/gwe-ic.dfn | 11 + doc/mf6io/mf6ivar/dfn/gwe-mst.dfn | 106 ++ doc/mf6io/mf6ivar/dfn/gwe-nam.dfn | 74 + doc/mf6io/mf6ivar/dfn/gwe-oc.dfn | 313 ++++ doc/mf6io/mf6ivar/dfn/gwe-ssm.dfn | 122 ++ doc/mf6io/mf6ivar/dfn/utl-spt.dfn | 118 ++ doc/mf6io/mf6ivar/dfn/utl-spta.dfn | 89 ++ .../examples/exg-gwegwe-example-obs.dat | 12 + .../mf6ivar/examples/exg-gwegwe-example.dat | 57 + .../mf6ivar/examples/gwe-adv-example.dat | 3 + .../mf6ivar/examples/gwe-cnt-example-obs.dat | 16 + .../mf6ivar/examples/gwe-cnt-example.dat | 15 + .../mf6ivar/examples/gwe-dsp-example.dat | 19 + .../mf6ivar/examples/gwe-fmi-example.dat | 14 + doc/mf6io/mf6ivar/examples/gwe-ic-example.dat | 10 + .../mf6ivar/examples/gwe-mst-example.dat | 15 + .../mf6ivar/examples/gwe-nam-example.dat | 16 + doc/mf6io/mf6ivar/examples/gwe-oc-example.dat | 10 + .../mf6ivar/examples/gwe-ssm-example.dat | 16 + .../mf6ivar/examples/utl-obs-gwe-example.dat | 18 + .../mf6ivar/examples/utl-spt-example.dat | 28 + .../mf6ivar/examples/utl-spta-example.dat | 20 + doc/mf6io/mf6ivar/md/mf6ivar.md | 182 +++ doc/mf6io/mf6ivar/mf6ivar.py | 667 ++++---- doc/mf6io/mf6ivar/tex/appendixA.tex | 56 + doc/mf6io/mf6ivar/tex/exg-gwegwe-desc.tex | 63 + .../mf6ivar/tex/exg-gwegwe-dimensions.dat | 3 + .../mf6ivar/tex/exg-gwegwe-exchangedata.dat | 5 + doc/mf6io/mf6ivar/tex/exg-gwegwe-options.dat | 14 + doc/mf6io/mf6ivar/tex/exg-gwfgwe-desc.tex | 3 + doc/mf6io/mf6ivar/tex/gwe-adv-desc.tex | 9 + doc/mf6io/mf6ivar/tex/gwe-adv-options.dat | 3 + doc/mf6io/mf6ivar/tex/gwe-cnt-desc.tex | 49 + doc/mf6io/mf6ivar/tex/gwe-cnt-dimensions.dat | 3 + doc/mf6io/mf6ivar/tex/gwe-cnt-options.dat | 10 + doc/mf6io/mf6ivar/tex/gwe-cnt-period.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-dis-desc.tex | 41 + doc/mf6io/mf6ivar/tex/gwe-dis-dimensions.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-dis-griddata.dat | 12 + doc/mf6io/mf6ivar/tex/gwe-dis-options.dat | 7 + doc/mf6io/mf6ivar/tex/gwe-disu-cell2d.dat | 5 + .../mf6ivar/tex/gwe-disu-connectiondata.dat | 14 + doc/mf6io/mf6ivar/tex/gwe-disu-desc.tex | 81 + doc/mf6io/mf6ivar/tex/gwe-disu-dimensions.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-disu-griddata.dat | 10 + doc/mf6io/mf6ivar/tex/gwe-disu-options.dat | 8 + doc/mf6io/mf6ivar/tex/gwe-disu-vertices.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-disv-cell2d.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-disv-desc.tex | 61 + doc/mf6io/mf6ivar/tex/gwe-disv-dimensions.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-disv-griddata.dat | 8 + doc/mf6io/mf6ivar/tex/gwe-disv-options.dat | 7 + doc/mf6io/mf6ivar/tex/gwe-disv-vertices.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-dsp-desc.tex | 29 + doc/mf6io/mf6ivar/tex/gwe-dsp-griddata.dat | 16 + doc/mf6io/mf6ivar/tex/gwe-dsp-options.dat | 4 + doc/mf6io/mf6ivar/tex/gwe-fmi-desc.tex | 21 + doc/mf6io/mf6ivar/tex/gwe-fmi-options.dat | 4 + doc/mf6io/mf6ivar/tex/gwe-fmi-packagedata.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-ic-desc.tex | 9 + doc/mf6io/mf6ivar/tex/gwe-ic-griddata.dat | 4 + doc/mf6io/mf6ivar/tex/gwe-mst-desc.tex | 35 + doc/mf6io/mf6ivar/tex/gwe-mst-griddata.dat | 10 + doc/mf6io/mf6ivar/tex/gwe-mst-options.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-mst-packagedata.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex | 25 + doc/mf6io/mf6ivar/tex/gwe-nam-options.dat | 6 + doc/mf6io/mf6ivar/tex/gwe-nam-packages.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-oc-desc.tex | 63 + doc/mf6io/mf6ivar/tex/gwe-oc-options.dat | 6 + doc/mf6io/mf6ivar/tex/gwe-oc-period.dat | 4 + doc/mf6io/mf6ivar/tex/gwe-ssm-desc.tex | 35 + doc/mf6io/mf6ivar/tex/gwe-ssm-fileinput.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-ssm-options.dat | 4 + doc/mf6io/mf6ivar/tex/gwe-ssm-sources.dat | 5 + doc/mf6io/mf6ivar/tex/utl-spt-desc.tex | 37 + doc/mf6io/mf6ivar/tex/utl-spt-dimensions.dat | 3 + doc/mf6io/mf6ivar/tex/utl-spt-options.dat | 4 + doc/mf6io/mf6ivar/tex/utl-spt-period.dat | 5 + doc/mf6io/mf6ivar/tex/utl-spta-desc.tex | 25 + doc/mf6io/mf6ivar/tex/utl-spta-options.dat | 5 + doc/mf6io/mf6ivar/tex/utl-spta-period.dat | 4 + doc/mf6io/obs/obs-gwe.tex | 7 + doc/mf6io/obs/obs.tex | 2 + make/makefile | 80 +- msvs/mf6core.vfproj | 22 + src/Distributed/VirtualDataContainer.f90 | 14 +- src/Distributed/VirtualGweExchange.f90 | 109 ++ src/Distributed/VirtualGweModel.f90 | 202 +++ src/Exchange/GweGweExchange.f90 | 1367 +++++++++++++++++ src/Exchange/GwfGweExchange.f90 | 546 +++++++ src/Exchange/GwfGwtExchange.f90 | 2 +- src/Model/Connection/GweGweConnection.f90 | 505 ++++++ src/Model/Connection/GweInterfaceModel.f90 | 267 ++++ src/Model/Connection/GwtGwtConnection.f90 | 6 +- src/Model/Connection/GwtInterfaceModel.f90 | 90 +- src/Model/GroundWaterEnergy/gwe1.f90 | 993 ++++++++++++ src/Model/GroundWaterEnergy/gwe1cnt1.f90 | 533 +++++++ src/Model/GroundWaterEnergy/gwe1cnt1idm.f90 | 411 +++++ src/Model/GroundWaterEnergy/gwe1dis1idm.f90 | 313 ++++ src/Model/GroundWaterEnergy/gwe1disu1idm.f90 | 618 ++++++++ src/Model/GroundWaterEnergy/gwe1disv1idm.f90 | 460 ++++++ src/Model/GroundWaterEnergy/gwe1dsp1.f90 | 942 ++++++++++++ src/Model/GroundWaterEnergy/gwe1dsp1idm.f90 | 231 +++ src/Model/GroundWaterEnergy/gwe1ic1idm.f90 | 79 + src/Model/GroundWaterEnergy/gwe1idm.f90 | 196 +++ src/Model/GroundWaterEnergy/gwe1mst1.f90 | 912 +++++++++++ src/Model/GroundWaterTransport/gwt1.f90 | 3 +- src/Model/GroundWaterTransport/gwt1cnc1.f90 | 3 + src/Model/GroundWaterTransport/gwt1dsp1.f90 | 2 +- .../ModelUtilities/FlowModelInterface.f90 | 14 +- src/Model/ModelUtilities/GweDspOptions.f90 | 12 + src/Model/ModelUtilities/GweInputData.f90 | 211 +++ .../ModelUtilities/ModelPackageInput.f90 | 16 + src/Model/ModelUtilities/Xt3dInterface.f90 | 2 +- src/Model/TransportModel/tsp1.f90 | 15 +- src/Model/TransportModel/tsp1fmi1.f90 | 97 ++ src/Model/TransportModel/tsp1ic1.f90 | 3 + src/Model/TransportModel/tsp1ssm1.f90 | 15 +- src/SimulationCreate.f90 | 25 + src/Utilities/Idm/selector/IdmDfnSelector.f90 | 13 + .../Idm/selector/IdmGweDfnSelector.f90 | 160 ++ src/meson.build | 20 + utils/idmloader/scripts/dfn2f90.py | 135 +- 158 files changed, 14620 insertions(+), 409 deletions(-) create mode 100644 autotest/test_gwe_dsp.py create mode 100644 doc/Common/gwe-cntobs.tex create mode 100644 doc/Common/gwe-esrobs.tex create mode 100644 doc/Common/gwe-gweobs.tex create mode 100644 doc/Common/gwe-lkeobs.tex create mode 100644 doc/Common/gwe-mweobs.tex create mode 100644 doc/Common/gwe-obs.tex create mode 100644 doc/Common/gwe-obstypetable.tex create mode 100644 doc/Common/gwe-sfeobs.tex create mode 100644 doc/Common/gwe-uzeobs.tex create mode 100644 doc/mf6io/gwe/adv.tex create mode 100644 doc/mf6io/gwe/cnt.tex create mode 100644 doc/mf6io/gwe/dsp.tex create mode 100644 doc/mf6io/gwe/fmi.tex create mode 100644 doc/mf6io/gwe/gwe-gwe.tex create mode 100644 doc/mf6io/gwe/gwe-obs.tex create mode 100644 doc/mf6io/gwe/gwe.tex create mode 100644 doc/mf6io/gwe/ic.tex create mode 100644 doc/mf6io/gwe/mst.tex create mode 100644 doc/mf6io/gwe/namefile.tex create mode 100644 doc/mf6io/gwe/oc.tex create mode 100644 doc/mf6io/gwe/ssm.tex create mode 100644 doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/exg-gwfgwe.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-adv.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-cnt.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-dis.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-disu.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-disv.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-dsp.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-fmi.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-ic.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-mst.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-nam.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-oc.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-ssm.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/utl-spt.dfn create mode 100644 doc/mf6io/mf6ivar/dfn/utl-spta.dfn create mode 100644 doc/mf6io/mf6ivar/examples/exg-gwegwe-example-obs.dat create mode 100644 doc/mf6io/mf6ivar/examples/exg-gwegwe-example.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-adv-example.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-cnt-example-obs.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-cnt-example.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-dsp-example.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-fmi-example.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-ic-example.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-mst-example.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-nam-example.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-oc-example.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-ssm-example.dat create mode 100644 doc/mf6io/mf6ivar/examples/utl-obs-gwe-example.dat create mode 100644 doc/mf6io/mf6ivar/examples/utl-spt-example.dat create mode 100644 doc/mf6io/mf6ivar/examples/utl-spta-example.dat create mode 100644 doc/mf6io/mf6ivar/tex/exg-gwegwe-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/exg-gwegwe-dimensions.dat create mode 100644 doc/mf6io/mf6ivar/tex/exg-gwegwe-exchangedata.dat create mode 100644 doc/mf6io/mf6ivar/tex/exg-gwegwe-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/exg-gwfgwe-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-adv-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-adv-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-cnt-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-cnt-dimensions.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-cnt-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-cnt-period.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-dis-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-dis-dimensions.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-dis-griddata.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-dis-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-disu-cell2d.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-disu-connectiondata.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-disu-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-disu-dimensions.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-disu-griddata.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-disu-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-disu-vertices.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-disv-cell2d.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-disv-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-disv-dimensions.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-disv-griddata.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-disv-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-disv-vertices.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-dsp-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-dsp-griddata.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-dsp-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-fmi-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-fmi-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-fmi-packagedata.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-ic-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-ic-griddata.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-mst-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-mst-griddata.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-mst-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-mst-packagedata.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-nam-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-nam-packages.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-oc-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-oc-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-oc-period.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-ssm-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-ssm-fileinput.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-ssm-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-ssm-sources.dat create mode 100644 doc/mf6io/mf6ivar/tex/utl-spt-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/utl-spt-dimensions.dat create mode 100644 doc/mf6io/mf6ivar/tex/utl-spt-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/utl-spt-period.dat create mode 100644 doc/mf6io/mf6ivar/tex/utl-spta-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/utl-spta-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/utl-spta-period.dat create mode 100644 doc/mf6io/obs/obs-gwe.tex create mode 100644 src/Distributed/VirtualGweExchange.f90 create mode 100644 src/Distributed/VirtualGweModel.f90 create mode 100644 src/Exchange/GweGweExchange.f90 create mode 100644 src/Exchange/GwfGweExchange.f90 create mode 100644 src/Model/Connection/GweGweConnection.f90 create mode 100644 src/Model/Connection/GweInterfaceModel.f90 create mode 100644 src/Model/GroundWaterEnergy/gwe1.f90 create mode 100644 src/Model/GroundWaterEnergy/gwe1cnt1.f90 create mode 100644 src/Model/GroundWaterEnergy/gwe1cnt1idm.f90 create mode 100644 src/Model/GroundWaterEnergy/gwe1dis1idm.f90 create mode 100644 src/Model/GroundWaterEnergy/gwe1disu1idm.f90 create mode 100644 src/Model/GroundWaterEnergy/gwe1disv1idm.f90 create mode 100644 src/Model/GroundWaterEnergy/gwe1dsp1.f90 create mode 100644 src/Model/GroundWaterEnergy/gwe1dsp1idm.f90 create mode 100644 src/Model/GroundWaterEnergy/gwe1ic1idm.f90 create mode 100644 src/Model/GroundWaterEnergy/gwe1idm.f90 create mode 100644 src/Model/GroundWaterEnergy/gwe1mst1.f90 create mode 100644 src/Model/ModelUtilities/GweDspOptions.f90 create mode 100644 src/Model/ModelUtilities/GweInputData.f90 create mode 100644 src/Utilities/Idm/selector/IdmGweDfnSelector.f90 diff --git a/autotest/test_gwe_dsp.py b/autotest/test_gwe_dsp.py new file mode 100644 index 00000000000..36a6f91b420 --- /dev/null +++ b/autotest/test_gwe_dsp.py @@ -0,0 +1,500 @@ +# ## Test problem for GWE +# +# One-Dimensional Transport in a Uniform Flow Field. +# The purpose of this script is to test the new heat transport model developed +# for MODFLOW 6. To that end, this problem uses the setup of the first MT3DMS +# test problem but adapts it for heat. MODFLOW 6 is setup using the new GWE +# model with input parameters entered in their native units. +# +# It may be possible to find a 1D heat transport analytical solution in the +# future. + +# Imports + +import os +import sys + +import numpy as np +import pytest + +try: + import pymake +except: + msg = "Error. Pymake package is not available.\n" + msg += "Try installing using the following command:\n" + msg += " pip install https://github.com/modflowpy/pymake/zipball/master" + raise Exception(msg) + +try: + import flopy +except: + msg = "Error. FloPy package is not available.\n" + msg += "Try installing using the following command:\n" + msg += " pip install flopy" + raise Exception(msg) + + +from framework import TestFramework +from simulation import TestSimulation + +# Base simulation and model name and workspace + +viscosity_on = [False] +ex = ["dsp01"] +exdirs = [] +for s in ex: + exdirs.append(os.path.join("temp", s)) + +# Model units + +length_units = "meters" +time_units = "days" + +# Table MODFLOW 6 GWE comparison to MT3DMS + +nper = 1 # Number of periods +nlay = 1 # Number of layers +ncol = 101 # Number of columns +nrow = 1 # Number of rows +delr = 10.0 # Column width ($m$) +delc = 1.0 # Row width ($m$) +top = 0.0 # Top of the model ($m$) +botm = -1.0 # Layer bottom elevations ($m$) +prsity = 0.25 # Porosity +perlen = 2000 # Simulation time ($days$) +k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$) + +# Set some static model parameter values + +k33 = k11 # Vertical hydraulic conductivity ($m/d$) +laytyp = 1 +nstp = 100.0 +dt0 = perlen / nstp +Lx = (ncol - 1) * delr +v = 0.24 +q = v * prsity +h1 = q * Lx +strt = np.zeros((nlay, nrow, ncol), dtype=float) +strt[0, 0, 0] = h1 # Starting head ($m$) +l = 1000.0 # Needed for plots +icelltype = 1 # Cell conversion type +ibound = np.ones((nlay, nrow, ncol), dtype=int) +ibound[0, 0, 0] = -1 +ibound[0, 0, -1] = -1 + +# Set some static transport related model parameter values + +mixelm = 0 # FD +rhob = 1110.0 +sp2 = 0.0 # read, but not used in this problem +kd = 1.8168e-4 +strt_temp = np.zeros((nlay, nrow, ncol), dtype=float) +dispersivity = 1.0 +dmcoef = 3.2519e-7 # Molecular diffusion coefficient + +# Set some static heat transport related model parameter values +cpw = 4183.0 +rhow = 1000.0 +lhv = 2454.0 + +# Set solver parameter values (and related) +nouter, ninner = 100, 300 +hclose, rclose, relax = 1e-6, 1e-6, 1.0 +ttsmult = 1.0 +dceps = 1.0e-5 # HMOC parameters in case they are invoked +nplane = 1 # HMOC +npl = 0 # HMOC +nph = 4 # HMOC +npmin = 0 # HMOC +npmax = 8 # HMOC +nlsink = nplane # HMOC +npsink = nph # HMOC + +# Static temporal data used by TDIS file + +tdis_rc = [] +tdis_rc.append((perlen, nstp, 1.0)) + +# ### Create MODFLOW 6 GWE MT3DMS Example 1 Boundary Conditions +# +# Constant head cells are specified on both ends of the model + +chdspd = [[(0, 0, 0), h1], [(0, 0, ncol - 1), 0.0]] +c0 = 40.0 +ctpspd = [[(0, 0, 0), c0]] + + +def build_model(idx, dir): + # Base MF6 GWE model type + ws = dir + name = ex[idx] + + print("Building MF6 model...()".format(name)) + + # generate names for each model + gwfname = "gwf-" + name + gwename = "gwe-" + name + + sim_ws = os.path.join(ws, name) + sim = flopy.mf6.MFSimulation( + sim_name=name, sim_ws=ws, exe_name="mf6", version="mf6" + ) + + # Instantiating MODFLOW 6 time discretization + flopy.mf6.ModflowTdis( + sim, nper=nper, perioddata=tdis_rc, time_units=time_units + ) + + # Instantiating MODFLOW 6 groundwater flow model + gwf = flopy.mf6.ModflowGwf( + sim, + modelname=gwfname, + save_flows=True, + model_nam_file="{}.nam".format(gwfname), + ) + + # Instantiating MODFLOW 6 solver for flow model + imsgwf = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="CG", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwfname), + ) + sim.register_ims_package(imsgwf, [gwfname]) + + # Instantiating MODFLOW 6 discretization package + flopy.mf6.ModflowGwfdis( + gwf, + length_units=length_units, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=np.ones((nlay, nrow, ncol), dtype=int), + filename="{}.dis".format(gwfname), + ) + + # Instantiating MODFLOW 6 node-property flow package + flopy.mf6.ModflowGwfnpf( + gwf, + save_flows=False, + icelltype=icelltype, + k=k11, + k33=k33, + save_specific_discharge=True, + filename="{}.npf".format(gwfname), + ) + + # Instantiating MODFLOW 6 initial conditions package for flow model + flopy.mf6.ModflowGwfic(gwf, strt=strt, filename="{}.ic".format(gwfname)) + + # Instantiating VSC + if viscosity_on[idx]: + # Instantiate viscosity (VSC) package + vsc_filerecord = "{}.vsc.bin".format(gwfname) + vsc_pd = [(0, 0.0, 20.0, gwename, "temperature")] + flopy.mf6.ModflowGwfvsc( + gwf, + viscref=8.904e-4, + viscosity_filerecord=vsc_filerecord, + thermal_formulation="nonlinear", + thermal_a2=10.0, + thermal_a3=248.37, + thermal_a4=133.16, + nviscspecies=len(vsc_pd), + packagedata=vsc_pd, + pname="vsc", + filename="{}.vsc".format(gwfname), + ) + + # Instantiating MODFLOW 6 constant head package + flopy.mf6.ModflowGwfchd( + gwf, + maxbound=len(chdspd), + stress_period_data=chdspd, + save_flows=False, + pname="CHD-1", + filename="{}.chd".format(gwfname), + ) + + # Instantiating MODFLOW 6 output control package for flow model + flopy.mf6.ModflowGwfoc( + gwf, + head_filerecord="{}.hds".format(gwfname), + budget_filerecord="{}.cbc".format(gwfname), + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + printrecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + ) + + # Instantiating MODFLOW 6 groundwater transport package + gwe = flopy.mf6.MFModel( + sim, + model_type="gwe6", + modelname=gwename, + model_nam_file="{}.nam".format(gwename), + ) + gwe.name_file.save_flows = True + imsgwe = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwename), + ) + sim.register_ims_package(imsgwe, [gwe.name]) + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwedis( + gwe, + nogrb=True, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=1, + filename="{}.dis".format(gwename), + ) + + # Instantiating MODFLOW 6 transport initial concentrations + flopy.mf6.ModflowGweic( + gwe, strt=strt_temp, filename="{}.ic".format(gwename) + ) + + # Instantiating MODFLOW 6 transport advection package + if mixelm == 0: + scheme = "UPSTREAM" + elif mixelm == -1: + scheme = "TVD" + else: + raise Exception() + flopy.mf6.ModflowGweadv( + gwe, scheme=scheme, filename="{}.adv".format(gwename) + ) + + # Instantiating MODFLOW 6 transport dispersion package + if dispersivity != 0: + flopy.mf6.ModflowGwedsp( + gwe, + xt3d_off=True, + alh=dispersivity, + ath1=dispersivity, + ktw=0.5918, + kts=0.2700, + filename="{}.dsp".format(gwename), + ) + + # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) + flopy.mf6.ModflowGwemst( + gwe, + save_flows=True, + porosity=prsity, + cps=760.0, + rhos=1500.0, + packagedata=[cpw, rhow, lhv], + filename="{}.mst".format(gwename), + ) + + # Instantiating MODFLOW 6 transport constant concentration package + flopy.mf6.ModflowGwecnt( + gwe, + maxbound=len(ctpspd), + stress_period_data=ctpspd, + save_flows=False, + pname="CNT-1", + filename="{}.cnt".format(gwename), + ) + + # Instantiating MODFLOW 6 transport source-sink mixing package + flopy.mf6.ModflowGwessm( + gwe, sources=[[]], filename="{}.ssm".format(gwename) + ) + + # Instantiate MODFLOW 6 heat transport output control package + flopy.mf6.ModflowGweoc( + gwe, + budget_filerecord="{}.cbc".format(gwename), + temperature_filerecord="{}.ucn".format(gwename), + temperatureprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + printrecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + ) + + # Instantiating MODFLOW 6 flow-transport exchange mechanism + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename, + filename="{}.gwfgwe".format(name), + ) + + return sim, None + + +def eval_transport(sim): + print("evaluating results...") + + # read transport results from GWE model + name = ex[sim.idxsim] + gwename = "gwe-" + name + + fpth = os.path.join(sim.simpath, f"{gwename}.ucn") + try: + # load temperatures + cobj = flopy.utils.HeadFile( + fpth, precision="double", text="TEMPERATURE" + ) + conc1 = cobj.get_alldata() + except: + assert False, f'could not load concentration data from "{fpth}"' + + # This is the answer + c_ans = [ + 4.00000000e01, + 3.99999983e01, + 3.99999898e01, + 3.99999566e01, + 3.99998462e01, + 3.99995197e01, + 3.99986427e01, + 3.99964775e01, + 3.99915230e01, + 3.99809477e01, + 3.99597839e01, + 3.99198995e01, + 3.98488519e01, + 3.97288247e01, + 3.95359427e01, + 3.92403042e01, + 3.88070317e01, + 3.81985089e01, + 3.73777505e01, + 3.63125911e01, + 3.49801399e01, + 3.33708033e01, + 3.14911723e01, + 2.93652158e01, + 2.70334931e01, + 2.45504338e01, + 2.19800532e01, + 1.93907148e01, + 1.68496655e01, + 1.44180473e01, + 1.21469471e01, + 1.00748333e01, + 8.22648357e00, + 6.61329449e00, + 5.23470060e00, + 4.08034410e00, + 3.13261741e00, + 2.36924164e00, + 1.76562010e00, + 1.29679741e00, + 9.38944408e-01, + 6.70362685e-01, + 4.72056032e-01, + 3.27947150e-01, + 2.24829892e-01, + 1.52144844e-01, + 1.01654320e-01, + 6.70766201e-02, + 4.37223104e-02, + 2.81598160e-02, + 1.79249349e-02, + 1.12795213e-02, + 7.01828727e-03, + 4.31895689e-03, + 2.62924728e-03, + 1.58374083e-03, + 9.44125798e-04, + 5.57133590e-04, + 3.25507431e-04, + 1.88330495e-04, + 1.07925092e-04, + 6.12700035e-05, + 3.44648666e-05, + 1.92125906e-05, + 1.06157638e-05, + 5.81494908e-06, + 3.15821246e-06, + 1.70101068e-06, + 9.08679391e-07, + 4.81524218e-07, + 2.53159103e-07, + 1.32068539e-07, + 6.83748562e-08, + 3.51353218e-08, + 1.79225415e-08, + 9.07652498e-09, + 4.56413759e-09, + 2.27913640e-09, + 1.13033292e-09, + 5.56823550e-10, + 2.72491770e-10, + 1.32483548e-10, + 6.40015158e-11, + 3.07244529e-11, + 1.46584603e-11, + 6.95098705e-12, + 3.27643160e-12, + 1.53530190e-12, + 7.15261898e-13, + 3.31325318e-13, + 1.52616350e-13, + 6.99104644e-14, + 3.18504005e-14, + 1.44329547e-14, + 6.50576657e-15, + 2.91728603e-15, + 1.30145909e-15, + 5.77678170e-16, + 2.55141072e-16, + 1.12178999e-16, + 5.01900830e-17, + ] + + msg = f"gwe temperatures do not match stored concentrations" + assert np.allclose(conc1[-1, 0, 0, :], c_ans, atol=1e-5), msg + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(ex)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + ws = str(function_tmpdir) + test = TestFramework() + test.build(build_model, idx, ws) + test.run( + TestSimulation( + name=name, exe_dict=targets, exfunc=eval_transport, idxsim=idx + ), + ws, + ) diff --git a/doc/Common/gwe-cntobs.tex b/doc/Common/gwe-cntobs.tex new file mode 100644 index 00000000000..c8e2e87ec4c --- /dev/null +++ b/doc/Common/gwe-cntobs.tex @@ -0,0 +1 @@ +CNT & cnt & cellid or boundname & -- & Energy flow between the groundwater system and a constant-temperature boundary or a group of cells with constant-temperature boundaries. diff --git a/doc/Common/gwe-esrobs.tex b/doc/Common/gwe-esrobs.tex new file mode 100644 index 00000000000..1bb6fbb305a --- /dev/null +++ b/doc/Common/gwe-esrobs.tex @@ -0,0 +1 @@ +ESR & esr & cellid or boundname & -- & Energy source loading rate between the groundwater system and a energy source loading boundary or a group of boundaries. \ No newline at end of file diff --git a/doc/Common/gwe-gweobs.tex b/doc/Common/gwe-gweobs.tex new file mode 100644 index 00000000000..cc8058514c5 --- /dev/null +++ b/doc/Common/gwe-gweobs.tex @@ -0,0 +1 @@ +GWE-GWE & flow-ja-face & exchange number or boundname & -- & Energy flow between model 1 and model 2 for a specified exchange (which is the consecutive exchange number listed in the EXCHANGEDATA block), or the sum of these exchange flows by boundname if boundname is specified. \ No newline at end of file diff --git a/doc/Common/gwe-lkeobs.tex b/doc/Common/gwe-lkeobs.tex new file mode 100644 index 00000000000..ac32aee4ffe --- /dev/null +++ b/doc/Common/gwe-lkeobs.tex @@ -0,0 +1,25 @@ +% general APT observations +LKE & temperature & ifno or boundname & -- & Lake temperature. If boundname is specified, boundname must be unique for each lake. \\ +LKE & flow-ja-face & ifno or boundname & ifno or -- & Energy flow between two lakes connected by an outlet. If more than one outlet is used to connect the same two lakes, then the energy flow for only the first outlet can be observed. If a boundname is specified for ID1, then the result is the total energy flow for all outlets for a lake. If a boundname is specified for ID1 then ID2 is not used.\\ +LKE & storage & ifno or boundname & -- & Simulated energy storage flow rate for a lake or group of lakes. \\ +LKE & constant & ifno or boundname & -- & Simulated energy constant-flow rate for a lake or group of lakes. \\ +LKE & from-mvr & ifno or boundname & -- & Simulated energy inflow into a lake or group of lakes from the MVE package. Energy inflow is calculated as the product of provider temperature and the mover flow rate. \\ +LKE & to-mvr & outletno or boundname & -- & Energy outflow from a lake outlet, a lake, or a group of lakes that is available for the MVR package. If boundname is not specified for ID, then the outflow available for the MVR package from a specific lake outlet is observed. In this case, ID is the outlet number, which must be between 1 and NOUTLETS. \\ +LKE & lkt & ifno or boundname & \texttt{iconn} or -- & Energy flow rate for a lake or group of lakes and its aquifer connection(s). If boundname is not specified for ID, then the simulated lake-aquifer flow rate at a specific lake connection is observed. In this case, ID2 must be specified and is the connection number \texttt{iconn} for lake \texttt{ifno}. \\ + +%observations specific to the lake package +% rainfall evaporation runoff ext-inflow withdrawal outflow +LKE & rainfall & ifno or boundname & -- & Rainfall rate applied to a lake or group of lakes multiplied by the rainfall temperature. \\ +LKE & evaporation & ifno or boundname & -- & Simulated evaporation rate from a lake or group of lakes multiplied by latent heat of vaporization, heat capcity of the simulated fluid, and the density of the simulated fluid. \\ +LKE & runoff & ifno or boundname & -- & Runoff rate applied to a lake or group of lakes multiplied by the runoff temperature. \\ +LKE & ext-inflow & ifno or boundname & -- & Energy inflow into a lake or group of lakes calculated as the external inflow rate multiplied by the inflow temperature. \\ +LKE & withdrawal & ifno or boundname & -- & Specified withdrawal rate from a lake or group of lakes multiplied by the simulated lake temperature. \\ +LKE & ext-outflow & ifno or boundname & -- & External outflow from a lake or a group of lakes, through their outlets, to an external boundary. If the water mover is active, the reported ext-outflow value plus the rate to mover is equal to the total outlet outflow. + +%LKE & outlet-inflow & ifno or boundname & -- & Simulated inflow from upstream lake outlets into a lake or group of lakes. \\ +%LKE & inflow & ifno or boundname & -- & Sum of specified inflow and simulated inflow from upstream lake outlets into a lake or group of lakes. \\ +%LKE & outlet & outletno or boundname & -- & Simulate outlet flow rate from a lake outlet, a lake, or a group of lakes. If boundname is not specified for ID, then the flow from a specific lake outlet is observed. In this case, ID is the outlet number outletno. \\ +%LKE & volume & ifno or boundname & -- & Simulated lake volume or group of lakes. \\ +%LKE & surface-area & ifno or boundname & -- & Simulated surface area for a lake or group of lakes. \\ +%LKE & wetted-area & ifno or boundname & \texttt{iconn} or -- & Simulated wetted-area for a lake or group of lakes and its aquifer connection(s). If boundname is not specified for ID, then the wetted area of a specific lake connection is observed. In this case, ID2 must be specified and is the connection number \texttt{iconn}. \\ +%LKE & conductance & ifno or boundname & \texttt{iconn} or -- & Calculated conductance for a lake or group of lakes and its aquifer connection(s). If boundname is not specified for ID, then the calculated conductance of a specific lake connection is observed. In this case, ID2 must be specified and is the connection number \texttt{iconn}. diff --git a/doc/Common/gwe-mweobs.tex b/doc/Common/gwe-mweobs.tex new file mode 100644 index 00000000000..3594db046cf --- /dev/null +++ b/doc/Common/gwe-mweobs.tex @@ -0,0 +1,13 @@ +% general APT observations +MWE & temperature & ifno or boundname & -- & Well temperature. If boundname is specified, boundname must be unique for each well. \\ +%flowjaface not included +MWE & storage & ifno or boundname & -- & Simulated energy storage flow rate for a well or group of wells. \\ +MWE & constant & ifno or boundname & -- & Simulated energy constant-flow rate for a well or group of wells. \\ +MWE & from-mvr & ifno or boundname & -- & Simulated energy inflow into a well or group of wells from the MVE package. Energy inflow is calculated as the product of provider temperature and the mover flow rate. \\ +MWE & mwt & ifno or boundname & \texttt{iconn} or -- & Energy flow rate for a well or group of wells and its aquifer connection(s). If boundname is not specified for ID, then the simulated well-aquifer flow rate at a specific well connection is observed. In this case, ID2 must be specified and is the connection number \texttt{iconn} for well \texttt{ifno}. \\ + +% observations specific to the mwt package +MWE & rate & ifno or boundname & -- & Simulated energy flow rate for a well or group of wells. \\ +MWE & fw-rate & ifno or boundname & -- & Simulated energy flow rate for a flowing well or group of flowing wells. \\ +MWE & rate-to-mvr & well or boundname & -- & Simulated energy flow rate that is sent to the MVE Package for a well or group of wells.\\ +MWE & fw-rate-to-mvr & well or boundname & -- & Simulated energy flow rate that is sent to the MVE Package from a flowing well or group of flowing wells. \\ diff --git a/doc/Common/gwe-obs.tex b/doc/Common/gwe-obs.tex new file mode 100644 index 00000000000..9113ede12f3 --- /dev/null +++ b/doc/Common/gwe-obs.tex @@ -0,0 +1,2 @@ +GWE & temperature & cellid & -- & Temperature at a specified cell. \\ +GWE & flow-ja-face & cellid & cellid & Energy flow in dimensions of watts between two adjacent cells. The energy flow rate includes the contributions from both advection (convection) and dispersion (conduction) if those packages are active \ No newline at end of file diff --git a/doc/Common/gwe-obstypetable.tex b/doc/Common/gwe-obstypetable.tex new file mode 100644 index 00000000000..a91fa294b8c --- /dev/null +++ b/doc/Common/gwe-obstypetable.tex @@ -0,0 +1,94 @@ + +\begingroup +\makeatletter +\ifx\LT@ii\@undefined\else +\def\LT@entry#1#2{\noexpand\LT@entry{-#1}{#2}} +\xdef\LT@i{\LT@ii} +\fi +\endgroup + +% model observations +\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}} +\caption{Available observation types for the GWE Model} \tabularnewline + +\hline +\hline +\textbf{Model} & \textbf{Observation types} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endfirsthead + +\captionsetup{textformat=simple} +\caption*{\textbf{Table \arabic{table}.}{\quad}List of symbols used in this report.---Continued} \\ + +\hline +\hline +\textbf{Model} & \textbf{Observation types} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endhead + +\hline +\endfoot + +\input{../Common/gwe-obs.tex} +\end{longtable} +\addtocounter{table}{-1} + +% stress packages +\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}} +\hline +\hline +\textbf{Stress Package} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endfirsthead + +\captionsetup{textformat=simple} +\caption*{\textbf{Table \arabic{table}.}{\quad}Available GWE observation types.---Continued} \\ + +\hline +\hline +\textbf{Stress Package} & \textbf{Observation types} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endhead + +\hline +\endfoot + +\input{../Common/gwe-cntobs.tex} \\ +\hline +% \input{../Common/gwe-esrobs.tex} \\ +% \hline +% \input{../Common/gwe-sfeobs.tex} \\ +% \hline +% \input{../Common/gwe-lkeobs.tex} \\ +% \hline +% \input{../Common/gwe-mweobs.tex} \\ +\hline +\input{../Common/gwe-uzeobs.tex} +\label{table:gwe-obstypetable} +\end{longtable} +\addtocounter{table}{-1} + +% exchange +\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}} +\hline +\hline +\textbf{Exchange} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endfirsthead + +\captionsetup{textformat=simple} +\caption*{\textbf{Table \arabic{table}.}{\quad}Available GWE observation types.---Continued} \\ + +\hline +\hline +\textbf{Exchange} & \textbf{Observation types} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endhead + +\hline +\endfoot + +\input{../Common/gwe-gweobs.tex} +\end{longtable} + +\normalsize diff --git a/doc/Common/gwe-sfeobs.tex b/doc/Common/gwe-sfeobs.tex new file mode 100644 index 00000000000..cf35588bad0 --- /dev/null +++ b/doc/Common/gwe-sfeobs.tex @@ -0,0 +1,16 @@ +% general APT observations +SFE & temperature & ifno or boundname & -- & Reach temperature. If boundname is specified, boundname must be unique for each reach. \\ +SFE & flow-ja-face & ifno or boundname & ifno or -- & Energy flow between two reaches. If a boundname is specified for ID1, then the result is the total energy flow for all reaches. If a boundname is specified for ID1 then ID2 is not used.\\ +SFE & storage & ifno or boundname & -- & Simulated energy storage flow rate for a reach or group of reaches. \\ +SFE & constant & ifno or boundname & -- & Simulated energy constant-flow rate for a reach or group of reaches. \\ +SFE & from-mvr & ifno or boundname & -- & Simulated energy inflow into a reach or group of reaches from the MVE package. Energy inflow is calculated as the product of provider temperature and the mover flow rate. \\ +SFE & to-mvr & ifno or boundname & -- & Energy outflow from a reach, or a group of reaches that is available for the MVR package. If boundname is not specified for ID, then the outflow available for the MVR package from a specific reach is observed. \\ +SFE & sfe & ifno or boundname & -- & Energy flow rate for a reach or group of reaches and its aquifer connection(s). \\ + +%observations specific to the stream transport package +% rainfall evaporation runoff ext-inflow withdrawal outflow +SFE & rainfall & ifno or boundname & -- & Rainfall rate applied to a reach or group of reaches multiplied by the rainfall temperature. \\ +SFE & evaporation & ifno or boundname & -- & Simulated evaporation rate from a reach or group of reaches multiplied by the latent heat of vaporization, heat capacity of the simulated fluid, and the density of the simulated fluid. \\ +SFE & runoff & ifno or boundname & -- & Runoff rate applied to a reach or group of reaches multiplied by the runoff temperature. \\ +SFE & ext-inflow & ifno or boundname & -- & Energy inflow into a reach or group of reaches calculated as the external inflow rate multiplied by the inflow temperature. \\ +SFE & ext-outflow & ifno or boundname & -- & External outflow from a reach or group of reaches to an external boundary. If boundname is not specified for ID, then the external outflow from a specific reach is observed. In this case, ID is the reach ifno. diff --git a/doc/Common/gwe-uzeobs.tex b/doc/Common/gwe-uzeobs.tex new file mode 100644 index 00000000000..f9a6aa1f2ba --- /dev/null +++ b/doc/Common/gwe-uzeobs.tex @@ -0,0 +1,14 @@ +% general APT observations +UZE & temperature & ifno or boundname & -- & uze cell temperature. If boundname is specified, boundname must be unique for each uze cell. \\ +UZE & flow-ja-face & ifno or boundname & ifno or -- & Energy flow between two uze cells. If a boundname is specified for ID1, then the result is the total energy flow for all uze cells. If a boundname is specified for ID1 then ID2 is not used.\\ +UZE & storage & ifno or boundname & -- & Simulated energy storage flow rate for a uze cell or group of uze cells. \\ +UZE & constant & ifno or boundname & -- & Simulated energy constant-flow rate for a uze cell or a group of uze cells. \\ +UZE & from-mvr & ifno or boundname & -- & Simulated energy inflow into a uze cell or group of uze cells from the MVE package. Energy inflow is calculated as the product of provider temperature and the mover flow rate. \\ +UZE & uze & ifno or boundname & -- & Energy flow rate for a uze cell or group of uze cells and its aquifer connection(s). \\ + +%observations specific to the uze package +% infiltration rej-inf uzet rej-inf-to-mvr +UZE & infiltration & ifno or boundname & -- & Infiltration rate applied to a uze cell or group of uze cells multiplied by the infiltration temperature. \\ +UZE & rej-inf & ifno or boundname & -- & Rejected infiltration rate applied to a uze cell or group of uze cells multiplied by the infiltration temperature. \\ +UZE & uzet & ifno or boundname & -- & Unsaturated zone evapotranspiration rate applied to a uze cell or group of uze cells multiplied by the latent heat of vaporization, heat capacity of the simulated fluid, and density of the simulated flued. \\ +UZE & rej-inf-to-mvr & ifno or boundname & -- & Rejected infiltration rate applied to a uze cell or group of uze cells multiplied by the infiltration temperature that is sent to the mover package. \\ diff --git a/doc/MODFLOW6References.bib b/doc/MODFLOW6References.bib index 0623f871f57..e1b6525749d 100644 --- a/doc/MODFLOW6References.bib +++ b/doc/MODFLOW6References.bib @@ -8,6 +8,28 @@ +@article{mazheng2010, + author = {Ma, Rui and Zheng, Chunmiao}, + title = {Effects of Density and Viscosity in Modeling Heat as a Groundwater Tracer}, + journal = {Groundwater}, + year = {2010}, + volume = {48}, + number = {3}, + pages = {380--389}, + doi = {10.1111/j.1745-6584.2009.00660.x}, + } + +@article{hechtmendez, + author = {Hecht-Mendez, J. and Molina-Giraldo, N. and Blum, P. and Bayer, P.}, + title = {Evaluating MT3DMS for Heat Transport Simulation of Closed Geothermal Systems}, + journal = {Groundwater}, + year = {2010}, + volume = {48}, + number = {5}, + pages = {741--756}, + doi = {10.1111/j.1745-6584.2010.00678.x}, + } + @article{morway2021, author = {Morway, Eric D. and Langevin, Christian D. and Hughes, Joseph D.}, title = {Use of the {MODFLOW 6} Water Mover Package to Represent Natural and Managed Hydrologic Connections}, diff --git a/doc/mf6io/body.tex b/doc/mf6io/body.tex index 32f0150cf94..b3da3ed0042 100644 --- a/doc/mf6io/body.tex +++ b/doc/mf6io/body.tex @@ -45,6 +45,11 @@ \SECTION{Groundwater Transport (GWT) Model Input} \input{gwt/gwt.tex} +%GWE Model Input Instructions +\newpage +\SECTION{Groundwater Energy Transport (GWE) Model Input} +\input{gwe/gwe.tex} + %Sparse Matrix Solution (IMS) \newpage \SECTION{Iterative Model Solution} diff --git a/doc/mf6io/gwe/adv.tex b/doc/mf6io/gwe/adv.tex new file mode 100644 index 00000000000..3c10f398dec --- /dev/null +++ b/doc/mf6io/gwe/adv.tex @@ -0,0 +1,16 @@ +Advection (ADV) Package information is read from the file that is specified by ``ADV6'' as the file type. Only one ADV Package can be specified for a GWE model. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-adv-options.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-adv-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-adv-example.dat} + diff --git a/doc/mf6io/gwe/cnt.tex b/doc/mf6io/gwe/cnt.tex new file mode 100644 index 00000000000..acdfd152f97 --- /dev/null +++ b/doc/mf6io/gwe/cnt.tex @@ -0,0 +1,47 @@ +Constant Temperature (CNT) Package information is read from the file that is specified by ``CNT6'' as the file type. Any number of CNT Packages can be specified for a single GWE model, but the same cell cannot be designated as a constant temperature by more than one CNT entry. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\vspace{5mm} + +\noindent \textit{FOR EACH SIMULATION} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-cnt-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-cnt-dimensions.dat} +\vspace{5mm} +\noindent \textit{FOR ANY STRESS PERIOD} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-cnt-period.dat} +\packageperioddescription + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-cnt-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-cnt-example.dat} + +\vspace{5mm} +\subsubsection{Available observation types} +CNT Package observations are limited to the simulated constant temperature energy flow rate (\texttt{cnt}). The data required for the CNT Package observation type is defined in table~\ref{table:gwe-cntobstype}. Negative and positive values for an observation represent a loss from and gain to the GWE model, respectively. + +\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}} +\caption{Available CNT Package observation types} \tabularnewline + +\hline +\hline +\textbf{Model} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endhead + +\hline +\endfoot + +\input{../Common/gwe-cntobs.tex} +\label{table:gwe-cntobstype} +\end{longtable} + +\vspace{5mm} +\subsubsection{Example Observation Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-cnt-example-obs.dat} diff --git a/doc/mf6io/gwe/dsp.tex b/doc/mf6io/gwe/dsp.tex new file mode 100644 index 00000000000..a12f1f3cd0c --- /dev/null +++ b/doc/mf6io/gwe/dsp.tex @@ -0,0 +1,17 @@ +Dispersion (DSP) Package information is read from the file that is specified by ``DSP6'' as the file type. Only one DSP Package can be specified for a GWE model. The DSP Package is based on the mathematical formulation presented for the XT3D option of the NPF Package available to represent full three-dimensional anisotropy in groundwater flow. XT3D can be computationally expensive and can be turned off to use a simplified and approximate form of the dispersion equations. For most problems, however, XT3D will be required to accurately represent dispersion. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-dsp-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-dsp-griddata.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-dsp-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-dsp-example.dat} + diff --git a/doc/mf6io/gwe/fmi.tex b/doc/mf6io/gwe/fmi.tex new file mode 100644 index 00000000000..5eab129cbed --- /dev/null +++ b/doc/mf6io/gwe/fmi.tex @@ -0,0 +1,54 @@ +Flow Model Interface (FMI) Package information is read from the file that is specified by ``FMI6'' as the file type. The FMI Package is optional, but if provided, only one FMI Package can be specified for a GWE model. + +For most simulations, the GWE Model needs groundwater flows for every cell in the model grid, for all boundary conditions, and for other terms, such as the flow of water in or out of storage. The FMI Package is the interface between the GWE Model and simulated groundwater flows provided by a corresponding GWF Model that is running concurrently within the simulation or from binary budget files that were created from a previous GWF model run. The following are several different FMI simulation cases: + +\begin{itemize} + +\item Flows are provided by a corresponding GWF Model running in the same simulation---in this case, all groundwater flows are calculated by the corresponding GWF Model and provided through FMI to the energy transport model. This is a common use case in which the user wants to run the flow and energy transport models as part of a single simulation. The GWF and GWE models must be part of a GWF-GWE Exchange that is listed in mfsim.nam. If a GWF-GWE Exchange is specified by the user, then the user does not need to specify an FMI Package input file for the simulation, unless an FMI option is needed. If a GWF-GWE Exchange is specified and the FMI Package is specified, then the PACKAGEDATA block below is not read or used. + +\item There is no groundwater flow and the user is interested only in the effects of diffusion, sorption, and decay or production---in this case, FMI should not be provided in the GWE name file and the GWE model should not be listed in any GWF-GWE Exchanges in mfsim.nam. In this case, all groundwater flows are assumed to be zero and cells are assumed to be fully saturated. The SSM Package should not be activated in this case, because there can be no sources or sinks of water. Likewise, none of the advanced transport packages (LKE, SFE, MWE, and UZE) should be specified in the GWE name file. This type of model simulation without an FMI Package is included as an option to represent diffusion, sorption, and decay or growth in the absence of any groundwater flow. + +\item Flows are provided from a previous GWF model simulation---in this case the FMI Package should be listed in the GWE name file and the head and budget files should be listed in the FMI PACKAGEDATA block. In this case, FMI reads the simulated head and flows from these files and makes them available to the energy transport model. There are some additional considerations when the heads and flows are provided from binary files. + +\begin{itemize} +\item The binary budget file must contain the simulated flows for all of the packages that were included in the GWF model run. Saving of flows can be activated for all packages by specifying ``SAVE\_FLOWS'' as an option in the GWF name file. The GWF Output Control Package must also have ``SAVE BUGET ALL'' specified. The easiest way to ensure that all flows and heads are saved is to use the following simple form of a GWF Output Control file: + +\begin{verbatim} +BEGIN OPTIONS + HEAD FILEOUT mymodel.hds + BUDGET FILEOUT mymodel.bud +END OPTIONS + +BEGIN PERIOD 1 + SAVE HEAD ALL + SAVE BUDGET ALL +END PERIOD +\end{verbatim} + +\item The binary budget file must have the same number of budget terms listed for each time step. This will always be the case when the binary budget file is created by \mf. +\item The advanced flow packages (LAK, SFR, MAW, and UZF) all have options for saving a detailed budget file the describes all of the flows for each lake, reach, well, or UZF cell. These budget files can also be used as input to FMI if a corresponding advanced transport package is needed, such as LKE, SFE, MWE, and UZE. If the Water Mover Package is also specified for the GWF Model, then the the budget file for the Water Mover Package will also need to be specified as input to this FMI Package. +\item The binary heads file must have heads saved for all layers in the model. This will always be the case when the binary head file is created by \mf. This was not always the case as previous MODFLOW versions allowed different save options for each layer. +\item If the binary budget and head files have more than one time step for a single stress period, then the budget and head information must be contained within the binary file for every time step in the simulation stress period. +\item The binary budget and head files must correspond in terms of information stored for each time step and stress period. +\item If the binary budget and head files have information provided for only the first time step of a given stress period, this information will be used for all time steps in that stress period in the GWE simulation. If the final stress period (which may be the only stress period) in the binary budget and head files has information provided for only one time step, this information will be used for any subsequent time steps and stress periods in the GWE simulation. This makes it possible to provide flows, for example, from a steady-state GWF stress period and have those flows used for all GWE time steps in that stress period, for all remaining time steps in the GWE simulation, or for all time steps throughout the entire GWE simulation. With this option, it is possible to have smaller time steps in the GWE simulation than the time steps used in the GWF simulation. Note that this cannot be done when the GWF and GWE models are run in the same simulation, because in that case, both models are solved for each time step in the stress period, as listed in the TDIS Package. This option for reading flows from a previous GWF simulation may offer an efficient alternative to running both models in the same simulation, but it comes at the cost of having potentially very large budget files. +\end{itemize} + +\end{itemize} + +\noindent Determination of which FMI use case to invoke requires careful consideration of the different advantages and disadvantages of each case. For example, running GWE and GWF in the same simulation can often be faster because GWF flows are passed through memory to the GWE model instead of being written to files. The disadvantage of this approach is that the same time step lengths must be used for both GWF and GWE. Ultimately, it should be relatively straightforward to test different ways in which GWF and GWE interact and select the use case most appropriate for the particular problem. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-fmi-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-fmi-packagedata.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-fmi-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-fmi-example.dat} + diff --git a/doc/mf6io/gwe/gwe-gwe.tex b/doc/mf6io/gwe/gwe-gwe.tex new file mode 100644 index 00000000000..7428d6d4af7 --- /dev/null +++ b/doc/mf6io/gwe/gwe-gwe.tex @@ -0,0 +1,45 @@ +Input to the Groundwater Energy Transport (GWE-GWE) Exchange is read from the file that has type ``GWE6-GWE6'' in the Simulation Name File. + +The list of exchanges entered into the EXCHANGEDATA block must be identical to the list of exchanges entered for the GWF-GWF input file. One way to ensure that this information is identical is to put this list into an external file and refer to this same list using the OPEN/CLOSE functionality in both this EXCHANGEDATA input block and the EXCHANGEDATA input block in the GWF-GWF input file. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/exg-gwegwe-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/exg-gwegwe-dimensions.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/exg-gwegwe-exchangedata.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/exg-gwegwe-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/exg-gwegwe-example.dat} + +\vspace{5mm} +\subsubsection{Available observation types} +GWE-GWE Exchange observations include the simulated flow for any exchange (\texttt{flow-ja-face}). The data required for each GWE-GWE Exchange observation type is defined in table~\ref{table:gwe-gweobstype}. For \texttt{flow-ja-face} observation types, negative and positive values represent a loss from and gain to the first model specified for this exchange. + +\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}} +\caption{Available GWE-GWE Exchange observation types} \tabularnewline + +\hline +\hline +\textbf{Exchange} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endhead + +\hline +\endfoot + +\input{../Common/gwe-gweobs.tex} +\label{table:gwe-gweobstype} +\end{longtable} + + +\vspace{5mm} +\subsubsection{Example Observation Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/exg-gwegwe-example-obs.dat} + diff --git a/doc/mf6io/gwe/gwe-obs.tex b/doc/mf6io/gwe/gwe-obs.tex new file mode 100644 index 00000000000..a46ca5de597 --- /dev/null +++ b/doc/mf6io/gwe/gwe-obs.tex @@ -0,0 +1,39 @@ + +GWE Model observations include the simulated groundwater temperature (\texttt{temperature}), and the energy flow, with units of energy per time, between two connected cells (\texttt{flow-ja-face}). The data required for each GWE Model observation type is defined in table~\ref{table:gweobstype}. For \texttt{flow-ja-face} observation types, negative and positive values represent a loss from and gain to the \texttt{cellid} specified for ID, respectively. + +\subsubsection{Structure of Blocks} +\vspace{5mm} + +\noindent \textit{FOR EACH SIMULATION} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/utl-obs-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/utl-obs-continuous.dat} + +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/utl-obs-desc.tex} +\end{description} + + +\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}} +\caption{Available GWE model observation types} \tabularnewline + +\hline +\hline +\textbf{Model} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endhead + +\hline +\endfoot + +\input{../Common/gwe-obs.tex} +\label{table:gweobstype} +\end{longtable} + +\vspace{5mm} +\subsubsection{Example Observation Input File} + +An example GWE Model observation file is shown below. + +\lstinputlisting[style=inputfile]{./mf6ivar/examples/utl-obs-gwe-example.dat} + diff --git a/doc/mf6io/gwe/gwe.tex b/doc/mf6io/gwe/gwe.tex new file mode 100644 index 00000000000..0da6f6208fd --- /dev/null +++ b/doc/mf6io/gwe/gwe.tex @@ -0,0 +1,131 @@ +Like GWT \citep{modflow6gwt}, the GWE Model simulates three-dimensional transport in flowing groundwater. The primary difference between GWT and GWE is that heat (i.e., temperature), instead of concentration, is the simulated ``species.'' As such, the GWE Model solves the heat transport equation using numerical methods and a generalized control-volume finite-difference approach, which can be used with regular MODFLOW grids (DIS Package) or with unstructured grids (DISV and DISU Packages). The GWE Model is designed to work with most of the new capabilities released with the GWF Model, including the Newton flow formulation, XT3D \citep{modflow6xt3d}, unstructured grids, advanced packages, the movement of water between packages. The GWF and GWE (and, if active, GWT) models operate simultaneously during a \mf simulation to represent coupled groundwater flow and heat transport. The GWE Model can also run separately from a GWF Model by reading the heads and flows saved by a previously run GWF Model. The GWE model is also capable of working with the flows from another groundwater flow model as long as the cell-by-cell and boundary flows and groundwater heads are written to ``linker'' files in the correct format. + +The purpose of the GWE Model is to calculate changes in groundwater temperature in both space and time. Groundwater temperature within an aquifer can change in response to different energy transport processes. These processes include (1) convective (advective) transport of heat with flowing groundwater, (2) the combined hydrodynamic dispersion processes of velocity-dependent mechanical dispersion and conduction (analogous to chemical diffusion), (3) thermal equilibrium with the aquifer matrix, (4) mixing with fluids from groundwater sources and sinks, and (5) direct addition of thermal energy. + +For GWE, the energy present in the aquifer is assumed to instantaneously equilibrate between the aqueous and solid phase domains. For example, a pulse of heat convecting through an aquifer will be retarded through thermal equilibration with the aquifer material. Conversely, the introduction of cold groundwater into a previously warm region of the aquifer will warmup, at least in part, as energy within the aquifer matrix transfers to the aqueous phase. Unlike GWT, the GWE Model type does not support an immobile domain. The energy that is transferred between the aqeous and solid phases of the groundwater system are tracked in the GWE Model budget. + +This section describes the data files for a \mf Groundwater Energy Transport (GWE) Model. A GWE Model is added to the simulation by including a GWE entry in the MODELS block of the simulation name file. There are three types of spatial discretization approaches that can be used with the GWE Model: DIS, DISV, and DISU. The input instructions for these three packages are not described here in this section on GWE Model input; input instructions for these three packages are described in the section on GWF Model input. + +The GWE Model is designed to permit input to be gathered, as it is needed, from many different files. Likewise, results from the model calculations can be written to a number of output files. The GWE Model Listing File is a key file to which the GWE model output is written. As \mf runs, information about the GWE Model is written to the GWE Model Listing File, including much of the input data (as a record of the simulation) and calculated results. Details about the files used by each package are provided in this section. + +The GWE Model reads a file called the Name File, which specifies most of the files that will be used in a groundwater energy transport simulation. Several files are always required whereas other files are optional depending on the question(s) being addressed by the model. The Output Control Package receives instructions from the user to control the amount and frequency of output. Details about the Name File and the Output Control Package are described in this section. + +For the GWE Model, ``flows'' (unless stated otherwise) represent the ``flow'' of energy, often expressed in units of energy (e.g., joules) per time, rather than groundwater flow. + +\subsection{Information for Existing Heat Transport Modelers} +An important goal of the \mf GWE Model is to alleviate the need for ``parameter equivalents'' when simulating heat transport in groundwater systems. In the past, codes like HST3D \citep{kipp1987} or VS2DH \citep{healy1996} simulated energy transport directly by supporting the use of native heat transport units. For example, users could directly specify thermal conductivity of the fluid and solid phases, as well as the heat capacity of both phases. Alternatively, codes like MT3DMS \citep{zheng1999mt3dms}, MT3D-USGS \citep{mt3dusgs}, and MODFLOW-USG \citep{modflowusg} could be used to simulate the movement of heat in groundwater, but required users to leverage existing variables as surrogates for heat transport. For example, the molecular diffusion parameter may be used as a surrogate for simulating thermal conduction in an aquifer \citep{mazheng2010, hechtmendez}. + +The following list summarizes important aspects of GWE for simulating heat transport with \mf: + +\begin{enumerate} + +\item The GWE Model uses parameters that are native to heat transport, including thermal conductivity of water, heat capacity of water, thermal conductivity of the aquifer material, heat capacity of of the aquifer material, and latent heat of vaporization. Therefore, users do not need to pre-calculate ``parameter equivalents'' when generating GWE model input; users can instead enter native parameter values that are readily available. + +\item Thermal energy transport budgets written to the \mf list file are reported in units of energy (e.g., joules). Previously, using a program like MT3D-USGS \citep{mt3dusgs} to simulate heat transport, units in the list file budget did not correspond to thermal energy, but were reported in units of $\frac{m^{3 \;\circ}C}{d}$. To convert to thermal energy units, values in the list file had to be post-processed by multiplying each line item by the density of water ($\rho_w$) and the heat capacity of water ($C_p$) \citep{langevin2008seawat}. + +\item Thermal equilibrium between the aqueous and solid phases is assumed. Thus, simulated temperatures are representive of both phases. As a result, thermal conduction between adjacent cells may still occur even in the absense of convection. + +\item In GWE, dry cells (devoid of groundwater) remain active for simulating thermal conduction. For example, energy (heat) transfer will be simulated between a partially saturated cell (i.e., ``water-table'' cell) and an overlying dry cell. In this way, a more full accounting of various heat transport processes is represented in the subsurface. Moreover, this approach readily supports heat transport in the unsaturated-zone when the UZE (unsaturated-zone energy transport) Package is active. + +\item Heat transport is supported for all five of the advanced GWF packages using the following packages in GWE: (1) streamflow energy transport, SFE Package; (2) lake energy transport, LKE Package; (3) multi-aquifer well energy transport, MWE Package; (4) unsaturated zone energy transport, UZE Package; and the (5) Water Mover Package, MVE. Similar to GWT, GWE will simulate heat transfer between an advanced package and the groundwater system via groundwater surface-water exchange; however, GWE also simulates a conductive transfer of heat between an advanced package feature and the aquifer. To take advantage of this functionality, users must specify the thermal conductivity of the material separating a stream from the aquifer, for example, the thermal conductivity of the streambed (or lakebed), as well as the thickness of the streambed (or lakebed). As with the advanced GWT packages, GWE simulates thermal convection between package features, such as between two stream reaches for example. Also, dispersive heat transport among among advanced package features is not represented, similar to GWT. + +\item Where the GWF model simulates evaporation from an open body of water, for example from the surface of a stream or lake, the latent heat of vaporization may be used to simulate evaporative cooling. As water is converted from liquid to gas, the energy required by the phase change is drawn from the remaining body of water and the resulting cool down is calculated. + +\end{enumerate} + +Many of the same considerations listed for the GWT model should be kept in mind when developing a GWE model. For convenience, many of those considerations are adapted for GWE and repeated here. + +\begin{enumerate} + +\item A GWE Model can access flows calculated by a GWF Model that is running in the same simulation as the GWE Model. Alternatively, a GWE Model can read binary head and budget files created from a previous GWF Model simulation (provided these files contain all of the required information for all time steps); there is no specialized flow and transport link file \citep{zheng2001modflow} as there is for MT3D. Details on these two different use cases are provided in the chapter on the FMI Package. + +\item The GWE Model is based on a generalized control-volume finite-difference method, which means that heat transport can be simulated using regular MODFLOW grids consisting of layers, rows, and columns, or heat transport can be simulated using unstructured grids. + +\item GWE and GWT use the same advection package source code. As a result, advection can be simulated using central-in-space weighting, upstream weighting, or an implicit second-order TVD scheme. Currently, neither the GWE or GWT models can use a Method of Characteristics (particle-based approaches) or an explicit TVD scheme to simulate convective (or advective) transport. Consequently, the GWE Model may require a higher level of spatial discretization than other transport models that use higher order terms for advection dominated systems. This can be an important limitation in problems involving sharp heat fronts. + +\item The Viscosity Package may reference a GWE model directly for adjusting the viscosity-affected groundwater flow. + +\item GWE and GWT use the same Source and Sink Mixing (SSM) Package for representing the effects of GWF stress package inflows and outflows on simulated temperatures and concentrations. In a GWE simulation, there are two ways in which users can assign concentrations to the individual features in these stress package. The first way is to activate a temperature auxiliary variable in the corresponding GWF stress package. In the SSM input file, the user provides the name of the auxiliary variable to be used for temperature. The second way is to create a special SPC file, which contains user-assigned time-varying temperatures for stress package features. + +\item The GWE model includes an MST Package, but does not include an IST Package. Heat transport-related parameters such as thermal conductivities and heat capacities are specified in the MST Package. + +\item A GWE-GWE Exchange (introduced in version 6.5.0) can be used to tightly couple multiple heat transport models, as might be done in a nested grid configuration. + +\item There is no option to automatically run the GWE Model to steady state using a single time step. This is an option available in MT3DMS \citep{zheng2010supplemental}. Steady state conditions must be determined by running the transport model under transient conditions until temperatures stabilize. + +\item As is the case with GWT, the GWE Model has not yet been programmed to work with the Skeletal Storage, Compaction, and Subsidence (CSUB) Package for the GWF Model. + +\item There are many other differences between the \mf GWE Model and other solute transport models that work with MODFLOW, especially with regards to program design and input and output. Descriptions for the GWE input and output are described here. + +\end{enumerate} + +\subsection{Units of Length and Time} +The GWF Model formulates the groundwater flow equation without using prescribed length and time units. Any consistent units of length and time can be used when specifying the input data for a simulation. This capability gives a certain amount of freedom to the user, but care must be exercised to avoid mixing units. The program cannot detect the use of inconsistent units. + +\subsection{Thermal Energy Budget} +A summary of all inflow (sources) and outflow (sinks) of thermal energy is referred to as an energy budget. \mf calculates an energy budget for the overall model as a check on the acceptability of the solution, and to provide a summary of the sources and sinks of energy to the flow system. The energy budget is printed to the GWE Model Listing File for specified time steps. + +\subsection{Time Stepping} + +For the present implementation of the GWE Model, all terms in the heat transport equation are solved implicitly. With the implicit approach applied to the transport equation, it is possible to take relatively large time steps and efficiently obtain a stable solution. If the time steps are too large, however, accuracy of the model results will suffer, so there is usually some compromise required between the desired level of accuracy and length of the time step. An assessment of accuracy can be performed by simply running simulations with shorter time steps and comparing results. + +In \mf time step lengths are controlled by the user and specified in the Temporal Discretization (TDIS) input file. When the flow model and heat transport model are included in the same simulation, then the length of the time step specified in TDIS is used for both models. If the GWE Model runs in a separate simulation from the GWE Model, then the time steps used for the heat transport model can be different, and likely shorter, than the time steps used for the flow solution. Instructions for specifying time steps are described in the TDIS section of this user guide; additional information on GWF and GWE configurations are in the Flow Model Interface section. + + + +\newpage +\subsection{GWE Model Name File} +\input{gwe/namefile.tex} + +%\newpage +%\subsection{Structured Discretization (DIS) Input File} +%\input{gwf/dis} + +%\newpage +%\subsection{Discretization with Vertices (DISV) Input File} +%\input{gwf/disv} + +%\newpage +%\subsection{Unstructured Discretization (DISU) Input File} +%\input{gwf/disu} + +\newpage +\subsection{Initial Conditions (IC) Package} +\input{gwe/ic} + +\newpage +\subsection{Output Control (OC) Option} +\input{gwe/oc} + +\newpage +\subsection{Observation (OBS) Utility for a GWE Model} +\input{gwe/gwe-obs} + +\newpage +\subsection{Advection (ADV) Package} +\input{gwe/adv} + +\newpage +\subsection{Dispersion (DSP) Package} +\input{gwe/dsp} + +\newpage +\subsection{Source and Sink Mixing (SSM) Package} +\input{gwe/ssm} + +\newpage +\subsection{Mobile Storage and Transfer (MST) Package} +\input{gwe/mst} + +\newpage +\subsection{Constant Temperature (CNT) Package} +\input{gwe/cnt} + +\newpage +\subsection{Flow Model Interface (FMI) Package} +\input{gwe/fmi} + +\newpage +\subsection{Groundwater Energy Transport (GWE) Exchange} +\input{gwe/gwe-gwe} + diff --git a/doc/mf6io/gwe/ic.tex b/doc/mf6io/gwe/ic.tex new file mode 100644 index 00000000000..aa9c1accaad --- /dev/null +++ b/doc/mf6io/gwe/ic.tex @@ -0,0 +1,17 @@ +Initial Conditions (IC) Package information is read from the file that is specified by ``IC6'' as the file type. Only one IC Package can be specified for a GWE model. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +%\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-ic-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-ic-griddata.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-ic-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-ic-example.dat} + diff --git a/doc/mf6io/gwe/mst.tex b/doc/mf6io/gwe/mst.tex new file mode 100644 index 00000000000..283e3febead --- /dev/null +++ b/doc/mf6io/gwe/mst.tex @@ -0,0 +1,17 @@ +Mobile Storage and Transfer (MST) Package information is read from the file that is specified by ``MST6'' as the file type. Only one MST Package can be specified for a GWE model. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-mst-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-mst-griddata.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-mst-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-mst-example.dat} + diff --git a/doc/mf6io/gwe/namefile.tex b/doc/mf6io/gwe/namefile.tex new file mode 100644 index 00000000000..5d27d8b70fc --- /dev/null +++ b/doc/mf6io/gwe/namefile.tex @@ -0,0 +1,47 @@ +The GWE Model Name File specifies the options and packages that are active for a GWE model. The Name File contains two blocks: OPTIONS and PACKAGES. The length of each line must be 299 characters or less. The lines in each block can be in any order. Files listed in the PACKAGES block must exist when the program starts. + +Comment lines are indicated when the first character in a line is one of the valid comment characters. Commented lines can be located anywhere in the file. Any text characters can follow the comment character. Comment lines have no effect on the simulation; their purpose is to allow users to provide documentation about a particular simulation. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-nam-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-nam-packages.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-nam-desc.tex} +\end{description} + +\begin{table}[H] +\caption{Ftype values described in this report. The \texttt{Pname} column indicates whether or not a package name can be provided in the name file. The capability to provide a package name also indicates that the GWE Model can have more than one package of that Ftype} +\small +\begin{center} +\begin{tabular*}{\columnwidth}{l l l} +\hline +\hline +Ftype & Input File Description & \texttt{Pname}\\ +\hline +DIS6 & Rectilinear Discretization Input File \\ +DISV6 & Discretization by Vertices Input File \\ +DISU6 & Unstructured Discretization Input File \\ +FMI6 & Flow Model Interface Package & \\ +IC6 & Initial Conditions Package \\ +OC6 & Output Control Option \\ +ADV6 & Advection Package \\ +DSP6 & Dispersion Package \\ +SSM6 & Source and Sink Mixing Package \\ +MST6 & Mobile Storage and Transfer Package \\ +CNT6 & Constant Temperature Package & * \\ +OBS6 & Observations Option \\ +\hline +\end{tabular*} +\label{table:ftype} +\end{center} +\normalsize +\end{table} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-nam-example.dat} + diff --git a/doc/mf6io/gwe/oc.tex b/doc/mf6io/gwe/oc.tex new file mode 100644 index 00000000000..d534a14eb08 --- /dev/null +++ b/doc/mf6io/gwe/oc.tex @@ -0,0 +1,25 @@ +Input to the Output Control Option of the Groundwater Energy Transport Model is read from the file that is specified as type ``OC6'' in the Name File. If no ``OC6'' file is specified, default output control is used. The Output Control Option determines how and when temperatures are printed to the listing file and/or written to a separate binary output file. Under the default, temperature and the overall energy transport budget are written to the Listing File at the end of every stress period. The default printout format for temperatures is 10G11.4. The temperatures and overall energy transport budget are also written to the list file if the simulation terminates prematurely due to failed convergence. + +Output Control data must be specified using words. The numeric codes supported in earlier MODFLOW versions can no longer be used. + +For the PRINT and SAVE options of temperature, there is no option to specify individual layers. Whenever the temperature array is printed or saved, all layers are printed or saved. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\vspace{5mm} + +\noindent \textit{FOR EACH SIMULATION} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-oc-options.dat} +\vspace{5mm} +\noindent \textit{FOR ANY STRESS PERIOD} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-oc-period.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-oc-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-oc-example.dat} diff --git a/doc/mf6io/gwe/ssm.tex b/doc/mf6io/gwe/ssm.tex new file mode 100644 index 00000000000..ab8de50a564 --- /dev/null +++ b/doc/mf6io/gwe/ssm.tex @@ -0,0 +1,114 @@ +Source and Sink Mixing (SSM) Package information is read from the file that is specified by ``SSM6'' as the file type. Only one SSM Package can be specified for a GWE model. The SSM Package is required if the flow model has any stress packages. + +The SSM Package is used to add or remove thermal energy from GWE model cells based on inflows and outflows from GWF stress packages. If a GWF stress package provides flow into a model cell, that flow can be assigned a user-specified temperature. If a GWF stress package removes water from a model cell, the temperature of that water is the temperature of the cell from which the water is removed. For flow boundary conditions that include evapotranspiration, the latent heat of vaporization may be used to represent evaporative cooling. There are several different ways for the user to specify the temperatures. + +\begin{itemize} +\item The default condition is that sources have a temperature of zero and sinks withdraw water at the calculated temperature of the cell. This default condition is assigned to any GWF stress package that is not included in a SOURCES block or FILEINPUT block. +\item A second option is to assign auxiliary variables in the GWF model and include a temperature for each stress boundary. In this case, the user provides the name of the package and the name of the auxiliary variable containing temperature values for each boundary. As described below for srctype, there are multiple options for defining this behavior. +\item A third option is to prepare an SPT6 file for any desired GWF stress package. This SPT6 file allows users to change temperatures by stress period, or to use the time-series option to interpolate temperatures by time step. This third option was introduced in MODFLOW version 6.3.0. Information for this approach is entered in an optional FILEINPUT block below. The SPT6 input file supports list-based temperature input for most corresponding GWF stress packages, but also supports a READASARRAYS array-based input format if a corresponding GWF recharge or evapotranspiration package uses the READASARRAYS option. +\end{itemize} + +\noindent The auxiliary method and the SPT6 file input method can both be used for a GWE model, but only one approach can be assigned per GWF stress package. If a flow package specified in the SOURCES or FILEINPUT blocks is also represented using an advanced transport package (SFE, LKE, MWE, or UZE), then the advanced transport package will override SSM calculations for that package. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-ssm-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-ssm-sources.dat} +\vspace{5mm} +\noindent \textit{FILEINPUT BLOCK IS OPTIONAL} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-ssm-fileinput.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-ssm-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-ssm-example.dat} + +% when obs are ready, they should go here + +\newpage +\subsection{Stress Package Temperatures (SPT) -- List-Based Input} +As mentioned in the previous section on the SSM Package, temperatures can be specified for GWF stress packages using auxiliary variables, or they can be specified using input files dedicated to this purpose. The Stress Package Temperatures (SPT) input file can be used to provide temperatures that are assigned for GWF sources and sinks. An SPT input file can be list based or array based. List-based input files can be used for list-based GWF stress packages, such as wells, drains, and rivers. Array-based input files can be used for array-based GWF stress packages, such as recharge and evapotranspiration (provided the READASARRAYS options is used; these packages can also be provided in a list-based format). Array-based SPT input files are discussed in the next section. This section describes the list-based input format for the SPT input file. + +An SPT6 file can be prepared to provide user-specified temperatures for a GWF stress package, such a Well or General-Head Boundary Package, for example. One SPT6 file applies to one GWF stress package. Names for the SPT6 input files are provided in the FILEINPUT block of the SSM Package. SPT6 entries cannot be specified in the GWE name file. Use of the SPT6 input file is an alternative to specifying stress package temperatures as auxiliary variables in the flow model stress package. + +The boundary number in the PERIOD block corresponds to the boundary number in the GWF stress period package. Assignment of the boundary number is straightforward for the advanced packages (SFR, LAK, MAW, and UZF) because the features in these advanced packages are defined once at the beginning of the simulation and they do not change. For the other stress packages, however, the order of boundaries may change between stress periods. Consider the following Well Package input file, for example: + +\begin{verbatim} +# This is an example of a GWF Well Package +# in which the order of the wells changes from +# stress period 1 to 2. This must be explicitly +# handled by the user if using the SPT6 input +# for a GWE model. +BEGIN options + BOUNDNAMES +END options + +BEGIN dimensions + MAXBOUND 3 +END dimensions + +BEGIN period 1 + 1 77 65 -2200 SHALLOW_WELL + 2 77 65 -24.0 INTERMEDIATE_WELL + 3 77 65 -6.20 DEEP_WELL +END period + +BEGIN period 2 + 1 77 65 -1100 SHALLOW_WELL + 3 77 65 -3.10 DEEP_WELL + 2 77 65 -12.0 INTERMEDIATE_WELL +END period +\end{verbatim} + +\noindent In this Well input file, the order of the wells changed between periods 1 and 2. This reordering must be explicitly taken into account by the user when creating an SSMI6 file, because the boundary number in the SSMI file corresponds to the boundary number in the Well input file. In stress period 1, boundary number 2 is the INTERMEDIATE\_WELL, whereas in stress period 2, boundary number 2 is the DEEP\_WELL. When using this SSMI capability to specify boundary temperatures, it is recommended that users write the corresponding GWF stress packages using the same number, cell locations, and order of boundary conditions for each stress period. In addition, users can activate the PRINT\_FLOWS option in the SSM input file. When the SSM Package prints the individual solute flows to the transport list file, it includes a column containing the boundary temperature. Users can check the boundary temperatures in this output to verify that they are assigned as intended. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\vspace{5mm} + +\noindent \textit{FOR EACH SIMULATION} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/utl-spt-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/utl-spt-dimensions.dat} +\vspace{5mm} +\noindent \textit{FOR ANY STRESS PERIOD} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/utl-spt-period.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/utl-spt-desc.tex} +\end{description} + +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/utl-spt-example.dat} + +% SPT array based +\newpage +\subsection{Stress Package Temperatures (SPT) -- Array-Based Input} + +This section describes array-based input for the SPT input file. If the READASARRAYS options is specified for either the GWF Recharge (RCH) or Evapotranspiration (EVT) Packages, then temperatures for these packages can be specified using array-based temperature input. This SPT array-based input is distinguished from the list-based input in the previous section through specification of the READASARRAYS option. When the READASARRAYS option is specified, then there is no DIMENSIONS block in the SPT input file. Instead, the shape of the array for temperatures is the number of rows by number of columns (NROW, NCOL), for a regular MODFLOW grid (DIS), and the number of cells in a layer (NCPL) for a discretization by vertices (DISV) grid. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\vspace{5mm} + +\noindent \textit{FOR EACH SIMULATION} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/utl-spta-options.dat} +\vspace{5mm} +\noindent \textit{FOR ANY STRESS PERIOD} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/utl-spta-period.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/utl-spta-desc.tex} +\end{description} + +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/utl-spta-example.dat} + diff --git a/doc/mf6io/mf6io.bbl b/doc/mf6io/mf6io.bbl index 240c6f51337..9fb5b05f2a4 100644 --- a/doc/mf6io/mf6io.bbl +++ b/doc/mf6io/mf6io.bbl @@ -64,6 +64,13 @@ Harbaugh, A.W., 2005, MODFLOW-2005, the U.S. Geological Survey modular Techniques and Methods, book 6, chap. A16, variously paged}, accessed June 27, 2017, at \url{https://pubs.usgs.gov/tm/2005/tm6A16/}. +\bibitem[{Hecht-Mendez and others(2010)Hecht-Mendez, Molina-Giraldo, Blum, and + Bayer}]{hechtmendez} +Hecht-Mendez, J., Molina-Giraldo, N., Blum, P., and Bayer, P., 2010, Evaluating + mt3dms for heat transport simulation of closed geothermal systems: + Groundwater, v.~48, no.~5, p.~741--756, + \url{https://doi.org/10.1111/j.1745-6584.2010.00678.x}. + \bibitem[{Hill(1990)}]{hill1990preconditioned} Hill, M.C., 1990, Preconditioned Conjugate-Gradient 2 (PCG2), a computer program for solving ground-water flow equations: {U.S. Geological Survey @@ -172,6 +179,11 @@ Leake, S.A., and Lilly, M.R., 1997, Documentation of computer program (FHB1) (MODFLOW): {U.S. Geological Survey Open-File Report 97--571, 50 p.}, accessed June 27, 2017, at \url{https://pubs.er.usgs.gov/publication/ofr97571}. +\bibitem[{Ma and Zheng(2010)}]{mazheng2010} +Ma, Rui, and Zheng, Chunmiao, 2010, Effects of density and viscosity in + modeling heat as a groundwater tracer: Groundwater, v.~48, no.~3, + p.~380--389, \url{https://doi.org/10.1111/j.1745-6584.2009.00660.x}. + \bibitem[{Maddock and others(2012)Maddock, Baird, Hanson, Schmid, and Ajami}]{modflowripetpack} Maddock, Thomas, I., Baird, K.J., Hanson, R.T., Schmid, W., and Ajami, H., diff --git a/doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn b/doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn new file mode 100644 index 00000000000..f65627640ac --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn @@ -0,0 +1,275 @@ +# --------------------- exg gwegwe options --------------------- +# flopy multi-package + +block options +name gwfmodelname1 +type string +reader urword +optional false +longname keyword to specify name of first corresponding GWF Model +description keyword to specify name of first corresponding GWF Model. In the simulation name file, the GWE6-GWE6 entry contains names for GWE Models (exgmnamea and exgmnameb). The GWE Model with the name exgmnamea must correspond to the GWF Model with the name gwfmodelname1. + +block options +name gwfmodelname2 +type string +reader urword +optional false +longname keyword to specify name of second corresponding GWF Model +description keyword to specify name of second corresponding GWF Model. In the simulation name file, the GWE6-GWE6 entry contains names for GWE Models (exgmnamea and exgmnameb). The GWE Model with the name exgmnameb must correspond to the GWF Model with the name gwfmodelname2. + +block options +name auxiliary +type string +shape (naux) +reader urword +optional true +longname keyword to specify aux variables +description an array of auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided. Most auxiliary variables will not be used by the GWF-GWF Exchange, but they will be available for use by other parts of the program. If an auxiliary variable with the name ``ANGLDEGX'' is found, then this information will be used as the angle (provided in degrees) between the connection face normal and the x axis, where a value of zero indicates that a normal vector points directly along the positive x axis. The connection face normal is a normal vector on the cell face shared between the cell in model 1 and the cell in model 2 pointing away from the model 1 cell. Additional information on ``ANGLDEGX'' is provided in the description of the DISU Package. If an auxiliary variable with the name ``CDIST'' is found, then this information will be used as the straight-line connection distance, including the vertical component, between the two cell centers. Both ANGLDEGX and CDIST are required if specific discharge is calculated for either of the groundwater models. + +block options +name boundnames +type keyword +shape +reader urword +optional true +longname +description REPLACE boundnames {'{#1}': 'GWE Exchange'} + +block options +name print_input +type keyword +reader urword +optional true +longname keyword to print input to list file +description keyword to indicate that the list of exchange entries will be echoed to the listing file immediately after it is read. + +block options +name print_flows +type keyword +reader urword +optional true +longname keyword to print gwfgwf flows to list file +description keyword to indicate that the list of exchange flow rates will be printed to the listing file for every stress period in which ``SAVE BUDGET'' is specified in Output Control. + +block options +name save_flows +type keyword +reader urword +optional true +longname keyword to save GWFGWF flows +description keyword to indicate that cell-by-cell flow terms will be written to the budget file for each model provided that the Output Control for the models are set up with the ``BUDGET SAVE FILE'' option. + +block options +name adv_scheme +type string +valid upstream central tvd +reader urword +optional true +longname advective scheme +description scheme used to solve the advection term. Can be upstream, central, or TVD. If not specified, upstream weighting is the default weighting scheme. + +block options +name dsp_xt3d_off +type keyword +shape +reader urword +optional true +longname deactivate xt3d +description deactivate the xt3d method for the dispersive flux and use the faster and less accurate approximation for this exchange. + +block options +name dsp_xt3d_rhs +type keyword +shape +reader urword +optional true +longname xt3d on right-hand side +description add xt3d dispersion terms to right-hand side, when possible, for this exchange. + +block options +name filein +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname file keyword +description keyword to specify that an input filename is expected next. + +block options +name mve_filerecord +type record mve6 filein mve6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name mve6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname obs keyword +description keyword to specify that record corresponds to an energy transport mover file. + +block options +name mve6_filename +type string +preserve_case true +in_record true +tagged false +reader urword +optional false +longname mve6 input filename +description is the file name of the transport mover input file to apply to this exchange. Information for the transport mover are provided in the file provided with these keywords. + +block options +name obs_filerecord +type record obs6 filein obs6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name obs6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname obs keyword +description keyword to specify that record corresponds to an observations file. + +block options +name obs6_filename +type string +preserve_case true +in_record true +tagged false +reader urword +optional false +longname obs6 input filename +description is the file name of the observations input file for this exchange. See the ``Observation utility'' section for instructions for preparing observation input files. Table \ref{table:gwe-obstypetable} lists observation type(s) supported by the GWE-GWE package. + +block options +name dev_interfacemodel_on +type keyword +reader urword +optional true +longname activate interface model on exchange +description activates the interface model mechanism for calculating the coefficients at (and possibly near) the exchange. This keyword should only be used for development purposes. + +# --------------------- exg gwegwe dimensions --------------------- + +block dimensions +name nexg +type integer +reader urword +optional false +longname number of exchanges +description keyword and integer value specifying the number of GWE-GWE exchanges. + + +# --------------------- exg gwegwe exchangedata --------------------- + +block exchangedata +name exchangedata +type recarray cellidm1 cellidm2 ihc cl1 cl2 hwva aux boundname +reader urword +optional false +longname exchange data +description + +block exchangedata +name cellidm1 +type integer +in_record true +tagged false +reader urword +optional false +longname cellid of first cell +description is the cellid of the cell in model 1 as specified in the simulation name file. For a structured grid that uses the DIS input file, CELLIDM1 is the layer, row, and column numbers of the cell. For a grid that uses the DISV input file, CELLIDM1 is the layer number and CELL2D number for the two cells. If the model uses the unstructured discretization (DISU) input file, then CELLIDM1 is the node number for the cell. +numeric_index true + +block exchangedata +name cellidm2 +type integer +in_record true +tagged false +reader urword +optional false +longname cellid of second cell +description is the cellid of the cell in model 2 as specified in the simulation name file. For a structured grid that uses the DIS input file, CELLIDM2 is the layer, row, and column numbers of the cell. For a grid that uses the DISV input file, CELLIDM2 is the layer number and CELL2D number for the two cells. If the model uses the unstructured discretization (DISU) input file, then CELLIDM2 is the node number for the cell. +numeric_index true + +block exchangedata +name ihc +type integer +in_record true +tagged false +reader urword +optional false +longname integer flag for connection type +description is an integer flag indicating the direction between node n and all of its m connections. If IHC = 0 then the connection is vertical. If IHC = 1 then the connection is horizontal. If IHC = 2 then the connection is horizontal for a vertically staggered grid. + +block exchangedata +name cl1 +type double precision +in_record true +tagged false +reader urword +optional false +longname connection distance +description is the distance between the center of cell 1 and the its shared face with cell 2. + +block exchangedata +name cl2 +type double precision +in_record true +tagged false +reader urword +optional false +longname connection distance +description is the distance between the center of cell 2 and the its shared face with cell 1. + +block exchangedata +name hwva +type double precision +in_record true +tagged false +reader urword +optional false +longname horizontal cell width or area for vertical flow +description is the horizontal width of the flow connection between cell 1 and cell 2 if IHC $>$ 0, or it is the area perpendicular to flow of the vertical connection between cell 1 and cell 2 if IHC = 0. + +block exchangedata +name aux +type double precision +in_record true +tagged false +shape (naux) +reader urword +optional true +longname auxiliary variables +description represents the values of the auxiliary variables for each GWEGWE Exchange. The values of auxiliary variables must be present for each exchange. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. + +block exchangedata +name boundname +type string +shape +tagged false +in_record true +reader urword +optional true +longname exchange boundname +description REPLACE boundname {'{#1}': 'GWE Exchange'} diff --git a/doc/mf6io/mf6ivar/dfn/exg-gwfgwe.dfn b/doc/mf6io/mf6ivar/dfn/exg-gwfgwe.dfn new file mode 100644 index 00000000000..fe5410261fc --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/exg-gwfgwe.dfn @@ -0,0 +1,3 @@ +# --------------------- exg gwfgwe options --------------------- + + diff --git a/doc/mf6io/mf6ivar/dfn/gwe-adv.dfn b/doc/mf6io/mf6ivar/dfn/gwe-adv.dfn new file mode 100644 index 00000000000..682ed4a756a --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-adv.dfn @@ -0,0 +1,11 @@ +# --------------------- gwe adv options --------------------- + +block options +name scheme +type string +valid central upstream tvd +reader urword +optional true +longname advective scheme +description scheme used to solve the advection term. Can be upstream, central, or TVD. If not specified, upstream weighting is the default weighting scheme. + diff --git a/doc/mf6io/mf6ivar/dfn/gwe-cnt.dfn b/doc/mf6io/mf6ivar/dfn/gwe-cnt.dfn new file mode 100644 index 00000000000..b636ac1cd00 --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-cnt.dfn @@ -0,0 +1,213 @@ +# --------------------- gwe cnt options --------------------- +# flopy multi-package + +block options +name auxiliary +type string +shape (naux) +reader urword +optional true +longname keyword to specify aux variables +description REPLACE auxnames {'{#1}': 'Groundwater Energy Transport'} + +block options +name auxmultname +type string +shape +reader urword +optional true +longname name of auxiliary variable for multiplier +description REPLACE auxmultname {'{#1}': 'temperature value'} + +block options +name boundnames +type keyword +shape +reader urword +optional true +longname +description REPLACE boundnames {'{#1}': 'constant temperature'} + +block options +name print_input +type keyword +reader urword +optional true +longname print input to listing file +description REPLACE print_input {'{#1}': 'constant temperature'} +mf6internal iprflow + +block options +name print_flows +type keyword +reader urword +optional true +longname print calculated flows to listing file +description REPLACE print_flows {'{#1}': 'constant temperature'} +mf6internal ipakcb + +block options +name save_flows +type keyword +reader urword +optional true +longname save constant temperature flows to budget file +description REPLACE save_flows {'{#1}': 'constant temperature'} +mf6internal iprpak + +block options +name ts_filerecord +type record ts6 filein ts6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name ts6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname time series keyword +description keyword to specify that record corresponds to a time-series file. + +block options +name filein +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname file keyword +description keyword to specify that an input filename is expected next. + +block options +name ts6_filename +type string +preserve_case true +in_record true +reader urword +optional false +tagged false +longname file name of time series information +description REPLACE timeseriesfile {} + +block options +name obs_filerecord +type record obs6 filein obs6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name obs6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname obs keyword +description keyword to specify that record corresponds to an observations file. + +block options +name obs6_filename +type string +preserve_case true +in_record true +tagged false +reader urword +optional false +longname obs6 input filename +description REPLACE obs6_filename {'{#1}': 'Constant Temperature'} + + +# --------------------- gwe cnt dimensions --------------------- + +block dimensions +name maxbound +type integer +reader urword +optional false +longname maximum number of constant temperatures +description REPLACE maxbound {'{#1}': 'constant temperatures'} + + +# --------------------- gwe cnt period --------------------- + +block period +name iper +type integer +block_variable True +in_record true +tagged false +shape +valid +reader urword +optional false +longname stress period number +description REPLACE iper {} + +block period +name stress_period_data +type recarray cellid temp aux boundname +shape (maxbound) +reader urword +longname +description +mf6internal spd + +block period +name cellid +type integer +shape (ncelldim) +tagged false +in_record true +reader urword +longname cell identifier +description REPLACE cellid {} + +block period +name temp +type double precision +shape +tagged false +in_record true +reader urword +time_series true +longname constant temperature value +description is the constant temperature value. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. +mf6internal tspvar + +block period +name aux +type double precision +in_record true +tagged false +shape (naux) +reader urword +optional true +time_series true +longname auxiliary variables +description REPLACE aux {'{#1}': 'constant temperature'} +mf6internal auxvar + +block period +name boundname +type string +shape +tagged false +in_record true +reader urword +optional true +longname constant temperature name +description REPLACE boundname {'{#1}': 'constant temperature'} diff --git a/doc/mf6io/mf6ivar/dfn/gwe-dis.dfn b/doc/mf6io/mf6ivar/dfn/gwe-dis.dfn new file mode 100644 index 00000000000..bb77bac782e --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-dis.dfn @@ -0,0 +1,122 @@ +# --------------------- gwe dis options --------------------- + +block options +name length_units +type string +reader urword +optional true +longname model length units +description is the length units used for this model. Values can be ``FEET'', ``METERS'', or ``CENTIMETERS''. If not specified, the default is ``UNKNOWN''. + +block options +name nogrb +type keyword +reader urword +optional true +longname do not write binary grid file +description keyword to deactivate writing of the binary grid file. + +block options +name xorigin +type double precision +reader urword +optional true +longname x-position of the model grid origin +description x-position of the lower-left corner of the model grid. A default value of zero is assigned if not specified. The value for XORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +block options +name yorigin +type double precision +reader urword +optional true +longname y-position of the model grid origin +description y-position of the lower-left corner of the model grid. If not specified, then a default value equal to zero is used. The value for YORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +block options +name angrot +type double precision +reader urword +optional true +longname rotation angle +description counter-clockwise rotation angle (in degrees) of the lower-left corner of the model grid. If not specified, then a default value of 0.0 is assigned. The value for ANGROT does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + + +# --------------------- gwe dis dimensions --------------------- + +block dimensions +name nlay +type integer +reader urword +optional false +longname number of layers +description is the number of layers in the model grid. +default_value 1 + +block dimensions +name nrow +type integer +reader urword +optional false +longname number of rows +description is the number of rows in the model grid. +default_value 2 + +block dimensions +name ncol +type integer +reader urword +optional false +longname number of columns +description is the number of columns in the model grid. +default_value 2 + +# --------------------- gwe dis griddata --------------------- + +block griddata +name delr +type double precision +shape (ncol) +reader readarray +longname spacing along a row +description is the column spacing in the row direction. +default_value 1.0 + +block griddata +name delc +type double precision +shape (nrow) +reader readarray +longname spacing along a column +description is the row spacing in the column direction. +default_value 1.0 + +block griddata +name top +type double precision +shape (ncol, nrow) +reader readarray +longname cell top elevation +description is the top elevation for each cell in the top model layer. +default_value 1.0 + +block griddata +name botm +type double precision +shape (ncol, nrow, nlay) +reader readarray +layered true +longname cell bottom elevation +description is the bottom elevation for each cell. +default_value 0. + +block griddata +name idomain +type integer +shape (ncol, nrow, nlay) +reader readarray +layered true +optional true +longname idomain existence array +description is an optional array that characterizes the existence status of a cell. If the IDOMAIN array is not specified, then all model cells exist within the solution. If the IDOMAIN value for a cell is 0, the cell does not exist in the simulation. Input and output values will be read and written for the cell, but internal to the program, the cell is excluded from the solution. If the IDOMAIN value for a cell is 1, the cell exists in the simulation. If the IDOMAIN value for a cell is -1, the cell does not exist in the simulation. Furthermore, the first existing cell above will be connected to the first existing cell below. This type of cell is referred to as a ``vertical pass through'' cell. + + diff --git a/doc/mf6io/mf6ivar/dfn/gwe-disu.dfn b/doc/mf6io/mf6ivar/dfn/gwe-disu.dfn new file mode 100644 index 00000000000..ec86d0852c7 --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-disu.dfn @@ -0,0 +1,277 @@ +# --------------------- gwe disu options --------------------- + +block options +name length_units +type string +reader urword +optional true +longname model length units +description is the length units used for this model. Values can be ``FEET'', ``METERS'', or ``CENTIMETERS''. If not specified, the default is ``UNKNOWN''. + +block options +name nogrb +type keyword +reader urword +optional true +longname do not write binary grid file +description keyword to deactivate writing of the binary grid file. + +block options +name xorigin +type double precision +reader urword +optional true +longname x-position origin of the model grid coordinate system +description x-position of the origin used for model grid vertices. This value should be provided in a real-world coordinate system. A default value of zero is assigned if not specified. The value for XORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +block options +name yorigin +type double precision +reader urword +optional true +longname y-position origin of the model grid coordinate system +description y-position of the origin used for model grid vertices. This value should be provided in a real-world coordinate system. If not specified, then a default value equal to zero is used. The value for YORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +block options +name angrot +type double precision +reader urword +optional true +longname rotation angle +description counter-clockwise rotation angle (in degrees) of the model grid coordinate system relative to a real-world coordinate system. If not specified, then a default value of 0.0 is assigned. The value for ANGROT does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +block options +name vertical_offset_tolerance +type double precision +reader urword +optional true +default_value 0.0 +longname vertical length dimension for top and bottom checking +description checks are performed to ensure that the top of a cell is not higher than the bottom of an overlying cell. This option can be used to specify the tolerance that is used for checking. If top of a cell is above the bottom of an overlying cell by a value less than this tolerance, then the program will not terminate with an error. The default value is zero. This option should generally not be used. +mf6internal voffsettol + +# --------------------- gwe disu dimensions --------------------- + +block dimensions +name nodes +type integer +reader urword +optional false +longname number of layers +description is the number of cells in the model grid. + +block dimensions +name nja +type integer +reader urword +optional false +longname number of columns +description is the sum of the number of connections and NODES. When calculating the total number of connections, the connection between cell n and cell m is considered to be different from the connection between cell m and cell n. Thus, NJA is equal to the total number of connections, including n to m and m to n, and the total number of cells. + +block dimensions +name nvert +type integer +reader urword +optional true +longname number of vertices +description is the total number of (x, y) vertex pairs used to define the plan-view shape of each cell in the model grid. If NVERT is not specified or is specified as zero, then the VERTICES and CELL2D blocks below are not read. NVERT and the accompanying VERTICES and CELL2D blocks should be specified for most simulations. If the XT3D or SAVE\_SPECIFIC\_DISCHARGE options are specified in the NPF Package, then this information is required. + +# --------------------- gwe disu griddata --------------------- + +block griddata +name top +type double precision +shape (nodes) +reader readarray +longname cell top elevation +description is the top elevation for each cell in the model grid. + +block griddata +name bot +type double precision +shape (nodes) +reader readarray +longname cell bottom elevation +description is the bottom elevation for each cell. + +block griddata +name area +type double precision +shape (nodes) +reader readarray +longname cell surface area +description is the cell surface area (in plan view). + +block griddata +name idomain +type integer +shape (nodes) +reader readarray +layered false +optional true +longname idomain existence array +description is an optional array that characterizes the existence status of a cell. If the IDOMAIN array is not specified, then all model cells exist within the solution. If the IDOMAIN value for a cell is 0, the cell does not exist in the simulation. Input and output values will be read and written for the cell, but internal to the program, the cell is excluded from the solution. If the IDOMAIN value for a cell is 1 or greater, the cell exists in the simulation. IDOMAIN values of -1 cannot be specified for the DISU Package. + +# --------------------- gwe disu connectiondata --------------------- + +block connectiondata +name iac +type integer +shape (nodes) +reader readarray +longname number of cell connections +description is the number of connections (plus 1) for each cell. The sum of all the entries in IAC must be equal to NJA. + +block connectiondata +name ja +type integer +shape (nja) +reader readarray +longname grid connectivity +description is a list of cell number (n) followed by its connecting cell numbers (m) for each of the m cells connected to cell n. The number of values to provide for cell n is IAC(n). This list is sequentially provided for the first to the last cell. The first value in the list must be cell n itself, and the remaining cells must be listed in an increasing order (sorted from lowest number to highest). Note that the cell and its connections are only supplied for the GWE cells and their connections to the other GWE cells. Also note that the JA list input may be divided such that every node and its connectivity list can be on a separate line for ease in readability of the file. To further ease readability of the file, the node number of the cell whose connectivity is subsequently listed, may be expressed as a negative number, the sign of which is subsequently converted to positive by the code. +numeric_index true +jagged_array iac + +block connectiondata +name ihc +type integer +shape (nja) +reader readarray +longname connection type +description is an index array indicating the direction between node n and all of its m connections. If IHC = 0 then cell n and cell m are connected in the vertical direction. Cell n overlies cell m if the cell number for n is less than m; cell m overlies cell n if the cell number for m is less than n. If IHC = 1 then cell n and cell m are connected in the horizontal direction. If IHC = 2 then cell n and cell m are connected in the horizontal direction, and the connection is vertically staggered. A vertically staggered connection is one in which a cell is horizontally connected to more than one cell in a horizontal connection. +jagged_array iac + +block connectiondata +name cl12 +type double precision +shape (nja) +reader readarray +longname connection lengths +description is the array containing connection lengths between the center of cell n and the shared face with each adjacent m cell. +jagged_array iac + +block connectiondata +name hwva +type double precision +shape (nja) +reader readarray +longname connection lengths +description is a symmetric array of size NJA. For horizontal connections, entries in HWVA are the horizontal width perpendicular to flow. For vertical connections, entries in HWVA are the vertical area for flow. Thus, values in the HWVA array contain dimensions of both length and area. Entries in the HWVA array have a one-to-one correspondence with the connections specified in the JA array. Likewise, there is a one-to-one correspondence between entries in the HWVA array and entries in the IHC array, which specifies the connection type (horizontal or vertical). Entries in the HWVA array must be symmetric; the program will terminate with an error if the value for HWVA for an n to m connection does not equal the value for HWVA for the corresponding n to m connection. +jagged_array iac + +block connectiondata +name angldegx +type double precision +optional true +shape (nja) +reader readarray +longname angle of face normal to connection +description is the angle (in degrees) between the horizontal x-axis and the outward normal to the face between a cell and its connecting cells. The angle varies between zero and 360.0 degrees, where zero degrees points in the positive x-axis direction, and 90 degrees points in the positive y-axis direction. ANGLDEGX is only needed if horizontal anisotropy is specified in the NPF Package, if the XT3D option is used in the NPF Package, or if the SAVE\_SPECIFIC\_DISCHARGE option is specifed in the NPF Package. ANGLDEGX does not need to be specified if these conditions are not met. ANGLDEGX is of size NJA; values specified for vertical connections and for the diagonal position are not used. Note that ANGLDEGX is read in degrees, which is different from MODFLOW-USG, which reads a similar variable (ANGLEX) in radians. +jagged_array iac + +# --------------------- gwe disu vertices --------------------- + +block vertices +name vertices +type recarray iv xv yv +shape (nvert) +reader urword +optional false +longname vertices data +description + +block vertices +name iv +type integer +in_record true +tagged false +reader urword +optional false +longname vertex number +description is the vertex number. Records in the VERTICES block must be listed in consecutive order from 1 to NVERT. +numeric_index true + +block vertices +name xv +type double precision +in_record true +tagged false +reader urword +optional false +longname x-coordinate for vertex +description is the x-coordinate for the vertex. + +block vertices +name yv +type double precision +in_record true +tagged false +reader urword +optional false +longname y-coordinate for vertex +description is the y-coordinate for the vertex. + + +# --------------------- gwe disu cell2d --------------------- + +block cell2d +name cell2d +type recarray icell2d xc yc ncvert icvert +shape (nodes) +reader urword +optional false +longname cell2d data +description + +block cell2d +name icell2d +type integer +in_record true +tagged false +reader urword +optional false +longname cell2d number +description is the cell2d number. Records in the CELL2D block must be listed in consecutive order from 1 to NODES. +numeric_index true + +block cell2d +name xc +type double precision +in_record true +tagged false +reader urword +optional false +longname x-coordinate for cell center +description is the x-coordinate for the cell center. + +block cell2d +name yc +type double precision +in_record true +tagged false +reader urword +optional false +longname y-coordinate for cell center +description is the y-coordinate for the cell center. + +block cell2d +name ncvert +type integer +in_record true +tagged false +reader urword +optional false +longname number of cell vertices +description is the number of vertices required to define the cell. There may be a different number of vertices for each cell. + +block cell2d +name icvert +type integer +shape (ncvert) +in_record true +tagged false +reader urword +optional false +longname array of vertex numbers +description is an array of integer values containing vertex numbers (in the VERTICES block) used to define the cell. Vertices must be listed in clockwise order. +numeric_index true diff --git a/doc/mf6io/mf6ivar/dfn/gwe-disv.dfn b/doc/mf6io/mf6ivar/dfn/gwe-disv.dfn new file mode 100644 index 00000000000..b752a40b03c --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-disv.dfn @@ -0,0 +1,204 @@ +# --------------------- gwe disv options --------------------- + +block options +name length_units +type string +reader urword +optional true +longname model length units +description is the length units used for this model. Values can be ``FEET'', ``METERS'', or ``CENTIMETERS''. If not specified, the default is ``UNKNOWN''. + +block options +name nogrb +type keyword +reader urword +optional true +longname do not write binary grid file +description keyword to deactivate writing of the binary grid file. + +block options +name xorigin +type double precision +reader urword +optional true +longname x-position origin of the model grid coordinate system +description x-position of the origin used for model grid vertices. This value should be provided in a real-world coordinate system. A default value of zero is assigned if not specified. The value for XORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +block options +name yorigin +type double precision +reader urword +optional true +longname y-position origin of the model grid coordinate system +description y-position of the origin used for model grid vertices. This value should be provided in a real-world coordinate system. If not specified, then a default value equal to zero is used. The value for YORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +block options +name angrot +type double precision +reader urword +optional true +longname rotation angle +description counter-clockwise rotation angle (in degrees) of the model grid coordinate system relative to a real-world coordinate system. If not specified, then a default value of 0.0 is assigned. The value for ANGROT does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +# --------------------- gwe disv dimensions --------------------- + +block dimensions +name nlay +type integer +reader urword +optional false +longname number of layers +description is the number of layers in the model grid. + +block dimensions +name ncpl +type integer +reader urword +optional false +longname number of cells per layer +description is the number of cells per layer. This is a constant value for the grid and it applies to all layers. + +block dimensions +name nvert +type integer +reader urword +optional false +longname number of columns +description is the total number of (x, y) vertex pairs used to characterize the horizontal configuration of the model grid. + +# --------------------- gwe disv griddata --------------------- + +block griddata +name top +type double precision +shape (ncpl) +reader readarray +longname model top elevation +description is the top elevation for each cell in the top model layer. + +block griddata +name botm +type double precision +shape (ncpl, nlay) +reader readarray +layered true +longname model bottom elevation +description is the bottom elevation for each cell. + +block griddata +name idomain +type integer +shape (ncpl, nlay) +reader readarray +layered true +optional true +longname idomain existence array +description is an optional array that characterizes the existence status of a cell. If the IDOMAIN array is not specified, then all model cells exist within the solution. If the IDOMAIN value for a cell is 0, the cell does not exist in the simulation. Input and output values will be read and written for the cell, but internal to the program, the cell is excluded from the solution. If the IDOMAIN value for a cell is 1, the cell exists in the simulation. If the IDOMAIN value for a cell is -1, the cell does not exist in the simulation. Furthermore, the first existing cell above will be connected to the first existing cell below. This type of cell is referred to as a ``vertical pass through'' cell. + + +# --------------------- gwe disv vertices --------------------- + +block vertices +name vertices +type recarray iv xv yv +shape (nvert) +reader urword +optional false +longname vertices data +description + +block vertices +name iv +type integer +in_record true +tagged false +reader urword +optional false +longname vertex number +description is the vertex number. Records in the VERTICES block must be listed in consecutive order from 1 to NVERT. +numeric_index true + +block vertices +name xv +type double precision +in_record true +tagged false +reader urword +optional false +longname x-coordinate for vertex +description is the x-coordinate for the vertex. + +block vertices +name yv +type double precision +in_record true +tagged false +reader urword +optional false +longname y-coordinate for vertex +description is the y-coordinate for the vertex. + + +# --------------------- gwe disv cell2d --------------------- + +block cell2d +name cell2d +type recarray icell2d xc yc ncvert icvert +shape (ncpl) +reader urword +optional false +longname cell2d data +description + +block cell2d +name icell2d +type integer +in_record true +tagged false +reader urword +optional false +longname cell2d number +description is the CELL2D number. Records in the CELL2D block must be listed in consecutive order from the first to the last. +numeric_index true + +block cell2d +name xc +type double precision +in_record true +tagged false +reader urword +optional false +longname x-coordinate for cell center +description is the x-coordinate for the cell center. + +block cell2d +name yc +type double precision +in_record true +tagged false +reader urword +optional false +longname y-coordinate for cell center +description is the y-coordinate for the cell center. + +block cell2d +name ncvert +type integer +in_record true +tagged false +reader urword +optional false +longname number of cell vertices +description is the number of vertices required to define the cell. There may be a different number of vertices for each cell. + +block cell2d +name icvert +type integer +shape (ncvert) +in_record true +tagged false +reader urword +optional false +longname array of vertex numbers +description is an array of integer values containing vertex numbers (in the VERTICES block) used to define the cell. Vertices must be listed in clockwise order. Cells that are connected must share vertices. +numeric_index true diff --git a/doc/mf6io/mf6ivar/dfn/gwe-dsp.dfn b/doc/mf6io/mf6ivar/dfn/gwe-dsp.dfn new file mode 100644 index 00000000000..5faa7f1c26b --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-dsp.dfn @@ -0,0 +1,92 @@ +# --------------------- gwe dsp options --------------------- + +block options +name xt3d_off +type keyword +shape +reader urword +optional true +longname deactivate xt3d +description deactivate the xt3d method and use the faster and less accurate approximation. This option may provide a fast and accurate solution under some circumstances, such as when flow aligns with the model grid, there is no mechanical dispersion, or when the longitudinal and transverse dispersivities are equal. This option may also be used to assess the computational demand of the XT3D approach by noting the run time differences with and without this option on. + +block options +name xt3d_rhs +type keyword +shape +reader urword +optional true +longname xt3d on right-hand side +description add xt3d terms to right-hand side, when possible. This option uses less memory, but may require more iterations. + +# --------------------- gwe dsp griddata --------------------- + +block griddata +name alh +type double precision +shape (nodes) +reader readarray +layered true +optional true +longname longitudinal dispersivity in horizontal direction +description longitudinal dispersivity in horizontal direction. If flow is strictly horizontal, then this is the longitudinal dispersivity that will be used. If flow is not strictly horizontal or strictly vertical, then the longitudinal dispersivity is a function of both ALH and ALV. If mechanical dispersion is represented (by specifying any dispersivity values) then this array is required. + +block griddata +name alv +type double precision +shape (nodes) +reader readarray +layered true +optional true +longname longitudinal dispersivity in vertical direction +description longitudinal dispersivity in vertical direction. If flow is strictly vertical, then this is the longitudinal dispsersivity value that will be used. If flow is not strictly horizontal or strictly vertical, then the longitudinal dispersivity is a function of both ALH and ALV. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ALH. + +block griddata +name ath1 +type double precision +shape (nodes) +reader readarray +layered true +optional true +longname transverse dispersivity in horizontal direction +description transverse dispersivity in horizontal direction. This is the transverse dispersivity value for the second ellipsoid axis. If flow is strictly horizontal and directed in the x direction (along a row for a regular grid), then this value controls spreading in the y direction. If mechanical dispersion is represented (by specifying any dispersivity values) then this array is required. + +block griddata +name ath2 +type double precision +shape (nodes) +reader readarray +layered true +optional true +longname transverse dispersivity in horizontal direction +description transverse dispersivity in horizontal direction. This is the transverse dispersivity value for the third ellipsoid axis. If flow is strictly horizontal and directed in the x direction (along a row for a regular grid), then this value controls spreading in the z direction. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ATH1. + +block griddata +name atv +type double precision +shape (nodes) +reader readarray +layered true +optional true +longname transverse dispersivity when flow is in vertical direction +description transverse dispersivity when flow is in vertical direction. If flow is strictly vertical and directed in the z direction, then this value controls spreading in the x and y directions. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ATH2. + +block griddata +name ktw +type double precision +shape (nodes) +reader readarray +layered true +optional true +longname thermal conductivity of the simulated fluid +description thermal conductivity of the simulated fluid + +block griddata +name kts +type double precision +shape (nodes) +reader readarray +layered true +optional true +longname thermal conductivity of the aquifer material +description thermal conductivity of the aquifer material + diff --git a/doc/mf6io/mf6ivar/dfn/gwe-fmi.dfn b/doc/mf6io/mf6ivar/dfn/gwe-fmi.dfn new file mode 100644 index 00000000000..fb71131e605 --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-fmi.dfn @@ -0,0 +1,58 @@ +# --------------------- gwe fmi options --------------------- + +block options +name save_flows +type keyword +reader urword +optional true +longname save calculated flow imbalance correction to budget file +description REPLACE save_flows {'{#1}': 'FMI'} + +block options +name flow_imbalance_correction +type keyword +reader urword +optional true +longname correct for flow imbalance +description correct for an imbalance in flows by assuming that any residual flow error comes in or leaves at the temperature of the cell. When this option is activated, the GWE Model budget written to the listing file will contain two additional entries: FLOW-ERROR and FLOW-CORRECTION. These two entries will be equal but opposite in sign. The FLOW-CORRECTION term is a mass flow that is added to offset the error caused by an imprecise flow balance. If these terms are not relatively small, the flow model should be rerun with stricter convergence tolerances. + +# --------------------- gwe fmi packagedata --------------------- + +block packagedata +name packagedata +type recarray flowtype filein fname +reader urword +optional false +longname flowtype list +description + +block packagedata +name flowtype +in_record true +type string +tagged false +reader urword +longname flow type +description is the word GWFBUDGET, GWFHEAD, GWFMOVER or the name of an advanced GWF stress package. If GWFBUDGET is specified, then the corresponding file must be a budget file from a previous GWF Model run. If an advanced GWF stress package name appears then the corresponding file must be the budget file saved by a LAK, SFR, MAW or UZF Package. + +block packagedata +name filein +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname file keyword +description keyword to specify that an input filename is expected next. + +block packagedata +name fname +in_record true +type string +preserve_case true +tagged false +reader urword +longname file name +description is the name of the file containing flows. The path to the file should be included if the file is not located in the folder where the program was run. + diff --git a/doc/mf6io/mf6ivar/dfn/gwe-ic.dfn b/doc/mf6io/mf6ivar/dfn/gwe-ic.dfn new file mode 100644 index 00000000000..0cda10416ba --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-ic.dfn @@ -0,0 +1,11 @@ +# --------------------- gwe ic griddata --------------------- + +block griddata +name strt +type double precision +shape (nodes) +reader readarray +layered true +longname starting temperature +description is the initial (starting) temperature---that is, the temperature at the beginning of the GWE Model simulation. STRT must be specified for all GWE Model simulations. One value is read for every model cell. +default_value 0.0 diff --git a/doc/mf6io/mf6ivar/dfn/gwe-mst.dfn b/doc/mf6io/mf6ivar/dfn/gwe-mst.dfn new file mode 100644 index 00000000000..75f780ba5df --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-mst.dfn @@ -0,0 +1,106 @@ +# --------------------- gwe mst options --------------------- + +block options +name save_flows +type keyword +reader urword +optional true +longname save calculated flows to budget file +description REPLACE save_flows {'{#1}': 'MST'} + +block options +name zero_order_decay +type keyword +reader urword +optional true +longname activate zero-order decay +description is a text keyword to indicate that zero-order decay will occur. Use of this keyword requires that DECAY and DECAY\_SORBED (if sorption is active) are specified in the GRIDDATA block. + +block options +name latent_heat_vaporization +type keyword +reader urword +optional true +longname activate cooling associated with evaporation +description is a text keyword to indicate that cooling associated with evaporation will occur. Use of this keyword requires that LATHEATVAP are specified in the GRIDDATA block. While the MST package does not simulate evaporation, multiple other packages in a GWE simulation may. For example, evaporation may occur from the surface of streams or lakes. Owing to the energy consumed by the change in phase, the latent heat of vaporization is required. + +# --------------------- gwe mst griddata --------------------- + +block griddata +name porosity +type double precision +shape (nodes) +reader readarray +layered true +longname porosity +description is the mobile domain porosity, defined as the mobile domain pore volume per mobile domain volume. The GWE model does not support the concept of an immobile domain in the context of heat transport. + +block griddata +name decay +type double precision +shape (nodes) +reader readarray +layered true +optional true +longname aqueous phase decay rate coefficient +description is the rate coefficient for zero-order decay for the aqueous phase of the mobile domain. A negative value indicates heat (energy) production. The dimensions of decay for zero-order decay is energy per length cubed per time. Zero-order decay will have no effect on simulation results unless zero-order decay is specified in the options block. + +block griddata +name cps +type double precision +shape (nodes) +reader readarray +layered true +longname heat capacity of the aquifer material +description is the mass-based heat capacity of dry solids (aquifer material). For example, units of J/kg/C may be used (or equivalent). + +block griddata +name rhos +type double precision +shape (nodes) +reader readarray +layered true +longname density of aquifer material +description is a user-specified value of the density of aquifer material not considering the voids. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. + +# --------------------- gwe mst packagedata --------------------- + +block packagedata +name packagedata +type recarray cpw rhow latheatvap +shape +reader urword +longname +description + +block packagedata +name cpw +type double precision +shape +tagged false +in_record true +reader urword +longname heat capacity of water +description is the mass-based heat capacity of the simulated fluid. For example, units of J/kg/C may be used (or equivalent). + +block packagedata +name rhow +type double precision +shape +tagged false +in_record true +reader urword +longname density of water +description is a user-specified value of the density of water. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. + + +block packagedata +name latheatvap +type double precision +shape +tagged false +in_record true +reader urword +longname latent heat of vaporization +description is the user-specified value for the latent heat of vaporization. For example, if working in SI units, values may be entered as kJ/kg. + diff --git a/doc/mf6io/mf6ivar/dfn/gwe-nam.dfn b/doc/mf6io/mf6ivar/dfn/gwe-nam.dfn new file mode 100644 index 00000000000..9bb5fef92ef --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-nam.dfn @@ -0,0 +1,74 @@ +# --------------------- gwe nam options --------------------- + +block options +name list +type string +reader urword +optional true +preserve_case true +longname name of listing file +description is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the '.lst' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. + +block options +name print_input +type keyword +reader urword +optional true +longname print input to listing file +description REPLACE print_input {'{#1}': 'all model stress package'} + +block options +name print_flows +type keyword +reader urword +optional true +longname print calculated flows to listing file +description REPLACE print_flows {'{#1}': 'all model package'} + +block options +name save_flows +type keyword +reader urword +optional true +longname save flows for all packages to budget file +description REPLACE save_flows {'{#1}': 'all model package'} + +# --------------------- gwe nam packages --------------------- + +block packages +name packages +type recarray ftype fname pname +reader urword +optional false +longname package list +description + +block packages +name ftype +in_record true +type string +tagged false +reader urword +longname package type +description is the file type, which must be one of the following character values shown in table~\ref{table:ftype}. Ftype may be entered in any combination of uppercase and lowercase. + +block packages +name fname +in_record true +type string +preserve_case true +tagged false +reader urword +longname file name +description is the name of the file containing the package input. The path to the file should be included if the file is not located in the folder where the program was run. + +block packages +name pname +in_record true +type string +tagged false +reader urword +optional true +longname user name for package +description is the user-defined name for the package. PNAME is restricted to 16 characters. No spaces are allowed in PNAME. PNAME character values are read and stored by the program for stress packages only. These names may be useful for labeling purposes when multiple stress packages of the same type are located within a single GWE Model. If PNAME is specified for a stress package, then PNAME will be used in the flow budget table in the listing file; it will also be used for the text entry in the cell-by-cell budget file. PNAME is case insensitive and is stored in all upper case letters. + diff --git a/doc/mf6io/mf6ivar/dfn/gwe-oc.dfn b/doc/mf6io/mf6ivar/dfn/gwe-oc.dfn new file mode 100644 index 00000000000..296113c7ba6 --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-oc.dfn @@ -0,0 +1,313 @@ +# --------------------- gwt oc options --------------------- + +block options +name budget_filerecord +type record budget fileout budgetfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name budget +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname budget keyword +description keyword to specify that record corresponds to the budget. + +block options +name fileout +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname file keyword +description keyword to specify that an output filename is expected next. + +block options +name budgetfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the output file to write budget information. + +block options +name budgetcsv_filerecord +type record budgetcsv fileout budgetcsvfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name budgetcsv +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname budget keyword +description keyword to specify that record corresponds to the budget CSV. + +block options +name budgetcsvfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. + +block options +name temperature_filerecord +type record temperature fileout temperaturefile +shape +reader urword +tagged true +optional true +longname +description + +block options +name temperature +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname temperature keyword +description keyword to specify that record corresponds to temperature. + +block options +name temperaturefile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the output file to write conc information. + +block options +name temperatureprintrecord +type record temperature print_format formatrecord +shape +reader urword +optional true +longname +description + +block options +name print_format +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname keyword to indicate that a print format follows +description keyword to specify format for printing to the listing file. + +block options +name formatrecord +type record columns width digits format +shape +in_record true +reader urword +tagged +optional false +longname +description + +block options +name columns +type integer +shape +in_record true +reader urword +tagged true +optional +longname number of columns +description number of columns for writing data. + +block options +name width +type integer +shape +in_record true +reader urword +tagged true +optional +longname width for each number +description width for writing each number. + +block options +name digits +type integer +shape +in_record true +reader urword +tagged true +optional +longname number of digits +description number of digits to use for writing a number. + +block options +name format +type string +shape +in_record true +reader urword +tagged false +optional false +longname write format +description write format can be EXPONENTIAL, FIXED, GENERAL, or SCIENTIFIC. + + +# --------------------- gwt oc period --------------------- + +block period +name iper +type integer +block_variable True +in_record true +tagged false +shape +valid +reader urword +optional false +longname stress period number +description REPLACE iper {} + +block period +name saverecord +type record save rtype ocsetting +shape +reader urword +tagged false +optional true +longname +description + +block period +name save +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname keyword to save +description keyword to indicate that information will be saved this stress period. + +block period +name printrecord +type record print rtype ocsetting +shape +reader urword +tagged false +optional true +longname +description + +block period +name print +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname keyword to save +description keyword to indicate that information will be printed this stress period. + +block period +name rtype +type string +shape +in_record true +reader urword +tagged false +optional false +longname record type +description type of information to save or print. Can be BUDGET or TEMPERATURE. + +block period +name ocsetting +type keystring all first last frequency steps +shape +tagged false +in_record true +reader urword +longname +description specifies the steps for which the data will be saved. + +block period +name all +type keyword +shape +in_record true +reader urword +longname +description keyword to indicate save for all time steps in period. + +block period +name first +type keyword +shape +in_record true +reader urword +longname +description keyword to indicate save for first step in period. This keyword may be used in conjunction with other keywords to print or save results for multiple time steps. + +block period +name last +type keyword +shape +in_record true +reader urword +longname +description keyword to indicate save for last step in period. This keyword may be used in conjunction with other keywords to print or save results for multiple time steps. + +block period +name frequency +type integer +shape +tagged true +in_record true +reader urword +longname +description save at the specified time step frequency. This keyword may be used in conjunction with other keywords to print or save results for multiple time steps. + +block period +name steps +type integer +shape ($ 0, or it is the area perpendicular to flow of the vertical connection between cell 1 and cell 2 if IHC = 0. | | EXG | GWTGWT | EXCHANGEDATA | AUX | DOUBLE PRECISION (NAUX) | represents the values of the auxiliary variables for each GWTGWT Exchange. The values of auxiliary variables must be present for each exchange. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. | | EXG | GWTGWT | EXCHANGEDATA | BOUNDNAME | STRING | name of the GWT Exchange cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. | +| EXG | GWEGWE | OPTIONS | GWFMODELNAME1 | STRING | keyword to specify name of first corresponding GWF Model. In the simulation name file, the GWE6-GWE6 entry contains names for GWE Models (exgmnamea and exgmnameb). The GWE Model with the name exgmnamea must correspond to the GWF Model with the name gwfmodelname1. | +| EXG | GWEGWE | OPTIONS | GWFMODELNAME2 | STRING | keyword to specify name of second corresponding GWF Model. In the simulation name file, the GWE6-GWE6 entry contains names for GWE Models (exgmnamea and exgmnameb). The GWE Model with the name exgmnameb must correspond to the GWF Model with the name gwfmodelname2. | +| EXG | GWEGWE | OPTIONS | AUXILIARY | STRING (NAUX) | an array of auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided. Most auxiliary variables will not be used by the GWF-GWF Exchange, but they will be available for use by other parts of the program. If an auxiliary variable with the name ``ANGLDEGX'' is found, then this information will be used as the angle (provided in degrees) between the connection face normal and the x axis, where a value of zero indicates that a normal vector points directly along the positive x axis. The connection face normal is a normal vector on the cell face shared between the cell in model 1 and the cell in model 2 pointing away from the model 1 cell. Additional information on ``ANGLDEGX'' is provided in the description of the DISU Package. If an auxiliary variable with the name ``CDIST'' is found, then this information will be used as the straight-line connection distance, including the vertical component, between the two cell centers. Both ANGLDEGX and CDIST are required if specific discharge is calculated for either of the groundwater models. | +| EXG | GWEGWE | OPTIONS | BOUNDNAMES | KEYWORD | keyword to indicate that boundary names may be provided with the list of GWE Exchange cells. | +| EXG | GWEGWE | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of exchange entries will be echoed to the listing file immediately after it is read. | +| EXG | GWEGWE | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of exchange flow rates will be printed to the listing file for every stress period in which ``SAVE BUDGET'' is specified in Output Control. | +| EXG | GWEGWE | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that cell-by-cell flow terms will be written to the budget file for each model provided that the Output Control for the models are set up with the ``BUDGET SAVE FILE'' option. | +| EXG | GWEGWE | OPTIONS | ADV_SCHEME | STRING | scheme used to solve the advection term. Can be upstream, central, or TVD. If not specified, upstream weighting is the default weighting scheme. | +| EXG | GWEGWE | OPTIONS | DSP_XT3D_OFF | KEYWORD | deactivate the xt3d method for the dispersive flux and use the faster and less accurate approximation for this exchange. | +| EXG | GWEGWE | OPTIONS | DSP_XT3D_RHS | KEYWORD | add xt3d dispersion terms to right-hand side, when possible, for this exchange. | +| EXG | GWEGWE | OPTIONS | FILEIN | KEYWORD | keyword to specify that an input filename is expected next. | +| EXG | GWEGWE | OPTIONS | MVE6 | KEYWORD | keyword to specify that record corresponds to an energy transport mover file. | +| EXG | GWEGWE | OPTIONS | MVE6_FILENAME | STRING | is the file name of the transport mover input file to apply to this exchange. Information for the transport mover are provided in the file provided with these keywords. | +| EXG | GWEGWE | OPTIONS | OBS6 | KEYWORD | keyword to specify that record corresponds to an observations file. | +| EXG | GWEGWE | OPTIONS | OBS6_FILENAME | STRING | is the file name of the observations input file for this exchange. See the ``Observation utility'' section for instructions for preparing observation input files. Table \ref{table:gwe-obstypetable} lists observation type(s) supported by the GWE-GWE package. | +| EXG | GWEGWE | OPTIONS | DEV_INTERFACEMODEL_ON | KEYWORD | activates the interface model mechanism for calculating the coefficients at (and possibly near) the exchange. This keyword should only be used for development purposes. | +| EXG | GWEGWE | DIMENSIONS | NEXG | INTEGER | keyword and integer value specifying the number of GWE-GWE exchanges. | +| EXG | GWEGWE | EXCHANGEDATA | CELLIDM1 | INTEGER | is the cellid of the cell in model 1 as specified in the simulation name file. For a structured grid that uses the DIS input file, CELLIDM1 is the layer, row, and column numbers of the cell. For a grid that uses the DISV input file, CELLIDM1 is the layer number and CELL2D number for the two cells. If the model uses the unstructured discretization (DISU) input file, then CELLIDM1 is the node number for the cell. | +| EXG | GWEGWE | EXCHANGEDATA | CELLIDM2 | INTEGER | is the cellid of the cell in model 2 as specified in the simulation name file. For a structured grid that uses the DIS input file, CELLIDM2 is the layer, row, and column numbers of the cell. For a grid that uses the DISV input file, CELLIDM2 is the layer number and CELL2D number for the two cells. If the model uses the unstructured discretization (DISU) input file, then CELLIDM2 is the node number for the cell. | +| EXG | GWEGWE | EXCHANGEDATA | IHC | INTEGER | is an integer flag indicating the direction between node n and all of its m connections. If IHC = 0 then the connection is vertical. If IHC = 1 then the connection is horizontal. If IHC = 2 then the connection is horizontal for a vertically staggered grid. | +| EXG | GWEGWE | EXCHANGEDATA | CL1 | DOUBLE PRECISION | is the distance between the center of cell 1 and the its shared face with cell 2. | +| EXG | GWEGWE | EXCHANGEDATA | CL2 | DOUBLE PRECISION | is the distance between the center of cell 2 and the its shared face with cell 1. | +| EXG | GWEGWE | EXCHANGEDATA | HWVA | DOUBLE PRECISION | is the horizontal width of the flow connection between cell 1 and cell 2 if IHC $>$ 0, or it is the area perpendicular to flow of the vertical connection between cell 1 and cell 2 if IHC = 0. | +| EXG | GWEGWE | EXCHANGEDATA | AUX | DOUBLE PRECISION (NAUX) | represents the values of the auxiliary variables for each GWEGWE Exchange. The values of auxiliary variables must be present for each exchange. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. | +| EXG | GWEGWE | EXCHANGEDATA | BOUNDNAME | STRING | name of the GWE Exchange cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. | | SLN | IMS | OPTIONS | PRINT_OPTION | STRING | is a flag that controls printing of convergence information from the solver. NONE means print nothing. SUMMARY means print only the total number of iterations and nonlinear residual reduction summaries. ALL means print linear matrix solver convergence information to the solution listing file and model specific linear matrix solver convergence information to each model listing file in addition to SUMMARY information. NONE is default if PRINT\_OPTION is not specified. | | SLN | IMS | OPTIONS | COMPLEXITY | STRING | is an optional keyword that defines default non-linear and linear solver parameters. SIMPLE - indicates that default solver input values will be defined that work well for nearly linear models. This would be used for models that do not include nonlinear stress packages and models that are either confined or consist of a single unconfined layer that is thick enough to contain the water table within a single layer. MODERATE - indicates that default solver input values will be defined that work well for moderately nonlinear models. This would be used for models that include nonlinear stress packages and models that consist of one or more unconfined layers. The MODERATE option should be used when the SIMPLE option does not result in successful convergence. COMPLEX - indicates that default solver input values will be defined that work well for highly nonlinear models. This would be used for models that include nonlinear stress packages and models that consist of one or more unconfined layers representing complex geology and surface-water/groundwater interaction. The COMPLEX option should be used when the MODERATE option does not result in successful convergence. Non-linear and linear solver parameters assigned using a specified complexity can be modified in the NONLINEAR and LINEAR blocks. If the COMPLEXITY option is not specified, NONLINEAR and LINEAR variables will be assigned the simple complexity values. | | SLN | IMS | OPTIONS | CSV_OUTPUT | KEYWORD | keyword to specify that the record corresponds to the comma separated values solver convergence output. The CSV\_OUTPUT option has been deprecated and split into the CSV_OUTER_OUTPUT and CSV_INNER_OUTPUT options. Starting with MODFLOW 6 version 6.1.1 if the CSV_OUTPUT option is specified, then it is treated as the CSV_OUTER_OUTPUT option. | @@ -1159,6 +1184,147 @@ | GWT | API | OPTIONS | OBS6_FILENAME | STRING | name of input file to define observations for the api boundary package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the api boundary package. | | GWT | API | OPTIONS | MOVER | KEYWORD | keyword to indicate that this instance of the api boundary Package can be used with the Water Mover (MVR) Package. When the MOVER option is specified, additional memory is allocated within the package to store the available, provided, and received water. | | GWT | API | DIMENSIONS | MAXBOUND | INTEGER | integer value specifying the maximum number of api boundary cells that will be specified for use during any stress period. | +| GWE | ADV | OPTIONS | SCHEME | STRING | scheme used to solve the advection term. Can be upstream, central, or TVD. If not specified, upstream weighting is the default weighting scheme. | +| GWE | CNT | OPTIONS | AUXILIARY | STRING (NAUX) | defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. | +| GWE | CNT | OPTIONS | AUXMULTNAME | STRING | name of auxiliary variable to be used as multiplier of temperature value. | +| GWE | CNT | OPTIONS | BOUNDNAMES | KEYWORD | keyword to indicate that boundary names may be provided with the list of constant temperature cells. | +| GWE | CNT | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of constant temperature information will be written to the listing file immediately after it is read. | +| GWE | CNT | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of constant temperature flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | +| GWE | CNT | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that constant temperature flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | +| GWE | CNT | OPTIONS | TS6 | KEYWORD | keyword to specify that record corresponds to a time-series file. | +| GWE | CNT | OPTIONS | FILEIN | KEYWORD | keyword to specify that an input filename is expected next. | +| GWE | CNT | OPTIONS | TS6_FILENAME | STRING | defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. | +| GWE | CNT | OPTIONS | OBS6 | KEYWORD | keyword to specify that record corresponds to an observations file. | +| GWE | CNT | OPTIONS | OBS6_FILENAME | STRING | name of input file to define observations for the Constant Temperature package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the Constant Temperature package. | +| GWE | CNT | DIMENSIONS | MAXBOUND | INTEGER | integer value specifying the maximum number of constant temperatures cells that will be specified for use during any stress period. | +| GWE | CNT | PERIOD | IPER | INTEGER | integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. | +| GWE | CNT | PERIOD | CELLID | INTEGER (NCELLDIM) | is the cell identifier, and depends on the type of grid that is used for the simulation. For a structured grid that uses the DIS input file, CELLID is the layer, row, and column. For a grid that uses the DISV input file, CELLID is the layer and CELL2D number. If the model uses the unstructured discretization (DISU) input file, CELLID is the node number for the cell. | +| GWE | CNT | PERIOD | TEMP | DOUBLE PRECISION | is the constant temperature value. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | CNT | PERIOD | AUX | DOUBLE PRECISION (NAUX) | represents the values of the auxiliary variables for each constant temperature. The values of auxiliary variables must be present for each constant temperature. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | CNT | PERIOD | BOUNDNAME | STRING | name of the constant temperature cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. | +| GWE | DIS | OPTIONS | LENGTH_UNITS | STRING | is the length units used for this model. Values can be ``FEET'', ``METERS'', or ``CENTIMETERS''. If not specified, the default is ``UNKNOWN''. | +| GWE | DIS | OPTIONS | NOGRB | KEYWORD | keyword to deactivate writing of the binary grid file. | +| GWE | DIS | OPTIONS | XORIGIN | DOUBLE PRECISION | x-position of the lower-left corner of the model grid. A default value of zero is assigned if not specified. The value for XORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. | +| GWE | DIS | OPTIONS | YORIGIN | DOUBLE PRECISION | y-position of the lower-left corner of the model grid. If not specified, then a default value equal to zero is used. The value for YORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. | +| GWE | DIS | OPTIONS | ANGROT | DOUBLE PRECISION | counter-clockwise rotation angle (in degrees) of the lower-left corner of the model grid. If not specified, then a default value of 0.0 is assigned. The value for ANGROT does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. | +| GWE | DIS | DIMENSIONS | NLAY | INTEGER | is the number of layers in the model grid. | +| GWE | DIS | DIMENSIONS | NROW | INTEGER | is the number of rows in the model grid. | +| GWE | DIS | DIMENSIONS | NCOL | INTEGER | is the number of columns in the model grid. | +| GWE | DIS | GRIDDATA | DELR | DOUBLE PRECISION (NCOL) | is the column spacing in the row direction. | +| GWE | DIS | GRIDDATA | DELC | DOUBLE PRECISION (NROW) | is the row spacing in the column direction. | +| GWE | DIS | GRIDDATA | TOP | DOUBLE PRECISION (NCOL, NROW) | is the top elevation for each cell in the top model layer. | +| GWE | DIS | GRIDDATA | BOTM | DOUBLE PRECISION (NCOL, NROW, NLAY) | is the bottom elevation for each cell. | +| GWE | DIS | GRIDDATA | IDOMAIN | INTEGER (NCOL, NROW, NLAY) | is an optional array that characterizes the existence status of a cell. If the IDOMAIN array is not specified, then all model cells exist within the solution. If the IDOMAIN value for a cell is 0, the cell does not exist in the simulation. Input and output values will be read and written for the cell, but internal to the program, the cell is excluded from the solution. If the IDOMAIN value for a cell is 1, the cell exists in the simulation. If the IDOMAIN value for a cell is -1, the cell does not exist in the simulation. Furthermore, the first existing cell above will be connected to the first existing cell below. This type of cell is referred to as a ``vertical pass through'' cell. | +| GWE | DISV | OPTIONS | LENGTH_UNITS | STRING | is the length units used for this model. Values can be ``FEET'', ``METERS'', or ``CENTIMETERS''. If not specified, the default is ``UNKNOWN''. | +| GWE | DISV | OPTIONS | NOGRB | KEYWORD | keyword to deactivate writing of the binary grid file. | +| GWE | DISV | OPTIONS | XORIGIN | DOUBLE PRECISION | x-position of the origin used for model grid vertices. This value should be provided in a real-world coordinate system. A default value of zero is assigned if not specified. The value for XORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. | +| GWE | DISV | OPTIONS | YORIGIN | DOUBLE PRECISION | y-position of the origin used for model grid vertices. This value should be provided in a real-world coordinate system. If not specified, then a default value equal to zero is used. The value for YORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. | +| GWE | DISV | OPTIONS | ANGROT | DOUBLE PRECISION | counter-clockwise rotation angle (in degrees) of the model grid coordinate system relative to a real-world coordinate system. If not specified, then a default value of 0.0 is assigned. The value for ANGROT does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. | +| GWE | DISV | DIMENSIONS | NLAY | INTEGER | is the number of layers in the model grid. | +| GWE | DISV | DIMENSIONS | NCPL | INTEGER | is the number of cells per layer. This is a constant value for the grid and it applies to all layers. | +| GWE | DISV | DIMENSIONS | NVERT | INTEGER | is the total number of (x, y) vertex pairs used to characterize the horizontal configuration of the model grid. | +| GWE | DISV | GRIDDATA | TOP | DOUBLE PRECISION (NCPL) | is the top elevation for each cell in the top model layer. | +| GWE | DISV | GRIDDATA | BOTM | DOUBLE PRECISION (NCPL, NLAY) | is the bottom elevation for each cell. | +| GWE | DISV | GRIDDATA | IDOMAIN | INTEGER (NCPL, NLAY) | is an optional array that characterizes the existence status of a cell. If the IDOMAIN array is not specified, then all model cells exist within the solution. If the IDOMAIN value for a cell is 0, the cell does not exist in the simulation. Input and output values will be read and written for the cell, but internal to the program, the cell is excluded from the solution. If the IDOMAIN value for a cell is 1, the cell exists in the simulation. If the IDOMAIN value for a cell is -1, the cell does not exist in the simulation. Furthermore, the first existing cell above will be connected to the first existing cell below. This type of cell is referred to as a ``vertical pass through'' cell. | +| GWE | DISV | VERTICES | IV | INTEGER | is the vertex number. Records in the VERTICES block must be listed in consecutive order from 1 to NVERT. | +| GWE | DISV | VERTICES | XV | DOUBLE PRECISION | is the x-coordinate for the vertex. | +| GWE | DISV | VERTICES | YV | DOUBLE PRECISION | is the y-coordinate for the vertex. | +| GWE | DISV | CELL2D | ICELL2D | INTEGER | is the CELL2D number. Records in the CELL2D block must be listed in consecutive order from the first to the last. | +| GWE | DISV | CELL2D | XC | DOUBLE PRECISION | is the x-coordinate for the cell center. | +| GWE | DISV | CELL2D | YC | DOUBLE PRECISION | is the y-coordinate for the cell center. | +| GWE | DISV | CELL2D | NCVERT | INTEGER | is the number of vertices required to define the cell. There may be a different number of vertices for each cell. | +| GWE | DISV | CELL2D | ICVERT | INTEGER (NCVERT) | is an array of integer values containing vertex numbers (in the VERTICES block) used to define the cell. Vertices must be listed in clockwise order. Cells that are connected must share vertices. | +| GWE | DISU | OPTIONS | LENGTH_UNITS | STRING | is the length units used for this model. Values can be ``FEET'', ``METERS'', or ``CENTIMETERS''. If not specified, the default is ``UNKNOWN''. | +| GWE | DISU | OPTIONS | NOGRB | KEYWORD | keyword to deactivate writing of the binary grid file. | +| GWE | DISU | OPTIONS | XORIGIN | DOUBLE PRECISION | x-position of the origin used for model grid vertices. This value should be provided in a real-world coordinate system. A default value of zero is assigned if not specified. The value for XORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. | +| GWE | DISU | OPTIONS | YORIGIN | DOUBLE PRECISION | y-position of the origin used for model grid vertices. This value should be provided in a real-world coordinate system. If not specified, then a default value equal to zero is used. The value for YORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. | +| GWE | DISU | OPTIONS | ANGROT | DOUBLE PRECISION | counter-clockwise rotation angle (in degrees) of the model grid coordinate system relative to a real-world coordinate system. If not specified, then a default value of 0.0 is assigned. The value for ANGROT does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. | +| GWE | DISU | OPTIONS | VERTICAL_OFFSET_TOLERANCE | DOUBLE PRECISION | checks are performed to ensure that the top of a cell is not higher than the bottom of an overlying cell. This option can be used to specify the tolerance that is used for checking. If top of a cell is above the bottom of an overlying cell by a value less than this tolerance, then the program will not terminate with an error. The default value is zero. This option should generally not be used. | +| GWE | DISU | DIMENSIONS | NODES | INTEGER | is the number of cells in the model grid. | +| GWE | DISU | DIMENSIONS | NJA | INTEGER | is the sum of the number of connections and NODES. When calculating the total number of connections, the connection between cell n and cell m is considered to be different from the connection between cell m and cell n. Thus, NJA is equal to the total number of connections, including n to m and m to n, and the total number of cells. | +| GWE | DISU | DIMENSIONS | NVERT | INTEGER | is the total number of (x, y) vertex pairs used to define the plan-view shape of each cell in the model grid. If NVERT is not specified or is specified as zero, then the VERTICES and CELL2D blocks below are not read. NVERT and the accompanying VERTICES and CELL2D blocks should be specified for most simulations. If the XT3D or SAVE\_SPECIFIC\_DISCHARGE options are specified in the NPF Package, then this information is required. | +| GWE | DISU | GRIDDATA | TOP | DOUBLE PRECISION (NODES) | is the top elevation for each cell in the model grid. | +| GWE | DISU | GRIDDATA | BOT | DOUBLE PRECISION (NODES) | is the bottom elevation for each cell. | +| GWE | DISU | GRIDDATA | AREA | DOUBLE PRECISION (NODES) | is the cell surface area (in plan view). | +| GWE | DISU | GRIDDATA | IDOMAIN | INTEGER (NODES) | is an optional array that characterizes the existence status of a cell. If the IDOMAIN array is not specified, then all model cells exist within the solution. If the IDOMAIN value for a cell is 0, the cell does not exist in the simulation. Input and output values will be read and written for the cell, but internal to the program, the cell is excluded from the solution. If the IDOMAIN value for a cell is 1 or greater, the cell exists in the simulation. IDOMAIN values of -1 cannot be specified for the DISU Package. | +| GWE | DISU | CONNECTIONDATA | IAC | INTEGER (NODES) | is the number of connections (plus 1) for each cell. The sum of all the entries in IAC must be equal to NJA. | +| GWE | DISU | CONNECTIONDATA | JA | INTEGER (NJA) | is a list of cell number (n) followed by its connecting cell numbers (m) for each of the m cells connected to cell n. The number of values to provide for cell n is IAC(n). This list is sequentially provided for the first to the last cell. The first value in the list must be cell n itself, and the remaining cells must be listed in an increasing order (sorted from lowest number to highest). Note that the cell and its connections are only supplied for the GWE cells and their connections to the other GWE cells. Also note that the JA list input may be divided such that every node and its connectivity list can be on a separate line for ease in readability of the file. To further ease readability of the file, the node number of the cell whose connectivity is subsequently listed, may be expressed as a negative number, the sign of which is subsequently converted to positive by the code. | +| GWE | DISU | CONNECTIONDATA | IHC | INTEGER (NJA) | is an index array indicating the direction between node n and all of its m connections. If IHC = 0 then cell n and cell m are connected in the vertical direction. Cell n overlies cell m if the cell number for n is less than m; cell m overlies cell n if the cell number for m is less than n. If IHC = 1 then cell n and cell m are connected in the horizontal direction. If IHC = 2 then cell n and cell m are connected in the horizontal direction, and the connection is vertically staggered. A vertically staggered connection is one in which a cell is horizontally connected to more than one cell in a horizontal connection. | +| GWE | DISU | CONNECTIONDATA | CL12 | DOUBLE PRECISION (NJA) | is the array containing connection lengths between the center of cell n and the shared face with each adjacent m cell. | +| GWE | DISU | CONNECTIONDATA | HWVA | DOUBLE PRECISION (NJA) | is a symmetric array of size NJA. For horizontal connections, entries in HWVA are the horizontal width perpendicular to flow. For vertical connections, entries in HWVA are the vertical area for flow. Thus, values in the HWVA array contain dimensions of both length and area. Entries in the HWVA array have a one-to-one correspondence with the connections specified in the JA array. Likewise, there is a one-to-one correspondence between entries in the HWVA array and entries in the IHC array, which specifies the connection type (horizontal or vertical). Entries in the HWVA array must be symmetric; the program will terminate with an error if the value for HWVA for an n to m connection does not equal the value for HWVA for the corresponding n to m connection. | +| GWE | DISU | CONNECTIONDATA | ANGLDEGX | DOUBLE PRECISION (NJA) | is the angle (in degrees) between the horizontal x-axis and the outward normal to the face between a cell and its connecting cells. The angle varies between zero and 360.0 degrees, where zero degrees points in the positive x-axis direction, and 90 degrees points in the positive y-axis direction. ANGLDEGX is only needed if horizontal anisotropy is specified in the NPF Package, if the XT3D option is used in the NPF Package, or if the SAVE\_SPECIFIC\_DISCHARGE option is specifed in the NPF Package. ANGLDEGX does not need to be specified if these conditions are not met. ANGLDEGX is of size NJA; values specified for vertical connections and for the diagonal position are not used. Note that ANGLDEGX is read in degrees, which is different from MODFLOW-USG, which reads a similar variable (ANGLEX) in radians. | +| GWE | DISU | VERTICES | IV | INTEGER | is the vertex number. Records in the VERTICES block must be listed in consecutive order from 1 to NVERT. | +| GWE | DISU | VERTICES | XV | DOUBLE PRECISION | is the x-coordinate for the vertex. | +| GWE | DISU | VERTICES | YV | DOUBLE PRECISION | is the y-coordinate for the vertex. | +| GWE | DISU | CELL2D | ICELL2D | INTEGER | is the cell2d number. Records in the CELL2D block must be listed in consecutive order from 1 to NODES. | +| GWE | DISU | CELL2D | XC | DOUBLE PRECISION | is the x-coordinate for the cell center. | +| GWE | DISU | CELL2D | YC | DOUBLE PRECISION | is the y-coordinate for the cell center. | +| GWE | DISU | CELL2D | NCVERT | INTEGER | is the number of vertices required to define the cell. There may be a different number of vertices for each cell. | +| GWE | DISU | CELL2D | ICVERT | INTEGER (NCVERT) | is an array of integer values containing vertex numbers (in the VERTICES block) used to define the cell. Vertices must be listed in clockwise order. | +| GWE | DSP | OPTIONS | XT3D_OFF | KEYWORD | deactivate the xt3d method and use the faster and less accurate approximation. This option may provide a fast and accurate solution under some circumstances, such as when flow aligns with the model grid, there is no mechanical dispersion, or when the longitudinal and transverse dispersivities are equal. This option may also be used to assess the computational demand of the XT3D approach by noting the run time differences with and without this option on. | +| GWE | DSP | OPTIONS | XT3D_RHS | KEYWORD | add xt3d terms to right-hand side, when possible. This option uses less memory, but may require more iterations. | +| GWE | DSP | GRIDDATA | ALH | DOUBLE PRECISION (NODES) | longitudinal dispersivity in horizontal direction. If flow is strictly horizontal, then this is the longitudinal dispersivity that will be used. If flow is not strictly horizontal or strictly vertical, then the longitudinal dispersivity is a function of both ALH and ALV. If mechanical dispersion is represented (by specifying any dispersivity values) then this array is required. | +| GWE | DSP | GRIDDATA | ALV | DOUBLE PRECISION (NODES) | longitudinal dispersivity in vertical direction. If flow is strictly vertical, then this is the longitudinal dispsersivity value that will be used. If flow is not strictly horizontal or strictly vertical, then the longitudinal dispersivity is a function of both ALH and ALV. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ALH. | +| GWE | DSP | GRIDDATA | ATH1 | DOUBLE PRECISION (NODES) | transverse dispersivity in horizontal direction. This is the transverse dispersivity value for the second ellipsoid axis. If flow is strictly horizontal and directed in the x direction (along a row for a regular grid), then this value controls spreading in the y direction. If mechanical dispersion is represented (by specifying any dispersivity values) then this array is required. | +| GWE | DSP | GRIDDATA | ATH2 | DOUBLE PRECISION (NODES) | transverse dispersivity in horizontal direction. This is the transverse dispersivity value for the third ellipsoid axis. If flow is strictly horizontal and directed in the x direction (along a row for a regular grid), then this value controls spreading in the z direction. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ATH1. | +| GWE | DSP | GRIDDATA | ATV | DOUBLE PRECISION (NODES) | transverse dispersivity when flow is in vertical direction. If flow is strictly vertical and directed in the z direction, then this value controls spreading in the x and y directions. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ATH2. | +| GWE | DSP | GRIDDATA | KTW | DOUBLE PRECISION (NODES) | thermal conductivity of the simulated fluid | +| GWE | DSP | GRIDDATA | KTS | DOUBLE PRECISION (NODES) | thermal conductivity of the aquifer material | +| GWE | IC | GRIDDATA | STRT | DOUBLE PRECISION (NODES) | is the initial (starting) temperature---that is, the temperature at the beginning of the GWE Model simulation. STRT must be specified for all GWE Model simulations. One value is read for every model cell. | +| GWE | MST | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that MST flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | +| GWE | MST | OPTIONS | ZERO_ORDER_DECAY | KEYWORD | is a text keyword to indicate that zero-order decay will occur. Use of this keyword requires that DECAY and DECAY\_SORBED (if sorption is active) are specified in the GRIDDATA block. | +| GWE | MST | OPTIONS | LATENT_HEAT_VAPORIZATION | KEYWORD | is a text keyword to indicate that cooling associated with evaporation will occur. Use of this keyword requires that LATHEATVAP are specified in the GRIDDATA block. While the MST package does not simulate evaporation, multiple other packages in a GWE simulation may. For example, evaporation may occur from the surface of streams or lakes. Owing to the energy consumed by the change in phase, the latent heat of vaporization is required. | +| GWE | MST | GRIDDATA | POROSITY | DOUBLE PRECISION (NODES) | is the mobile domain porosity, defined as the mobile domain pore volume per mobile domain volume. The GWE model does not support the concept of an immobile domain in the context of heat transport. | +| GWE | MST | GRIDDATA | DECAY | DOUBLE PRECISION (NODES) | is the rate coefficient for zero-order decay for the aqueous phase of the mobile domain. A negative value indicates heat (energy) production. The dimensions of decay for zero-order decay is energy per length cubed per time. Zero-order decay will have no effect on simulation results unless zero-order decay is specified in the options block. | +| GWE | MST | GRIDDATA | CPS | DOUBLE PRECISION (NODES) | is the mass-based heat capacity of dry solids (aquifer material). For example, units of J/kg/C may be used (or equivalent). | +| GWE | MST | GRIDDATA | RHOS | DOUBLE PRECISION (NODES) | is a user-specified value of the density of aquifer material not considering the voids. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. | +| GWE | MST | PACKAGEDATA | CPW | DOUBLE PRECISION | is the mass-based heat capacity of the simulated fluid. For example, units of J/kg/C may be used (or equivalent). | +| GWE | MST | PACKAGEDATA | RHOW | DOUBLE PRECISION | is a user-specified value of the density of water. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. | +| GWE | MST | PACKAGEDATA | LATHEATVAP | DOUBLE PRECISION | is the user-specified value for the latent heat of vaporization. For example, if working in SI units, values may be entered as kJ/kg. | +| GWE | NAM | OPTIONS | LIST | STRING | is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the '.lst' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. | +| GWE | NAM | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of all model stress package information will be written to the listing file immediately after it is read. | +| GWE | NAM | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of all model package flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | +| GWE | NAM | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that all model package flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | +| GWE | NAM | PACKAGES | FTYPE | STRING | is the file type, which must be one of the following character values shown in table~\ref{table:ftype}. Ftype may be entered in any combination of uppercase and lowercase. | +| GWE | NAM | PACKAGES | FNAME | STRING | is the name of the file containing the package input. The path to the file should be included if the file is not located in the folder where the program was run. | +| GWE | NAM | PACKAGES | PNAME | STRING | is the user-defined name for the package. PNAME is restricted to 16 characters. No spaces are allowed in PNAME. PNAME character values are read and stored by the program for stress packages only. These names may be useful for labeling purposes when multiple stress packages of the same type are located within a single GWE Model. If PNAME is specified for a stress package, then PNAME will be used in the flow budget table in the listing file; it will also be used for the text entry in the cell-by-cell budget file. PNAME is case insensitive and is stored in all upper case letters. | +| GWE | OC | OPTIONS | BUDGET | KEYWORD | keyword to specify that record corresponds to the budget. | +| GWE | OC | OPTIONS | FILEOUT | KEYWORD | keyword to specify that an output filename is expected next. | +| GWE | OC | OPTIONS | BUDGETFILE | STRING | name of the output file to write budget information. | +| GWE | OC | OPTIONS | BUDGETCSV | KEYWORD | keyword to specify that record corresponds to the budget CSV. | +| GWE | OC | OPTIONS | BUDGETCSVFILE | STRING | name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. | +| GWE | OC | OPTIONS | TEMPERATURE | KEYWORD | keyword to specify that record corresponds to temperature. | +| GWE | OC | OPTIONS | TEMPERATUREFILE | STRING | name of the output file to write conc information. | +| GWE | OC | OPTIONS | PRINT_FORMAT | KEYWORD | keyword to specify format for printing to the listing file. | +| GWE | OC | OPTIONS | COLUMNS | INTEGER | number of columns for writing data. | +| GWE | OC | OPTIONS | WIDTH | INTEGER | width for writing each number. | +| GWE | OC | OPTIONS | DIGITS | INTEGER | number of digits to use for writing a number. | +| GWE | OC | OPTIONS | FORMAT | STRING | write format can be EXPONENTIAL, FIXED, GENERAL, or SCIENTIFIC. | +| GWE | OC | PERIOD | IPER | INTEGER | integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. | +| GWE | OC | PERIOD | SAVE | KEYWORD | keyword to indicate that information will be saved this stress period. | +| GWE | OC | PERIOD | PRINT | KEYWORD | keyword to indicate that information will be printed this stress period. | +| GWE | OC | PERIOD | RTYPE | STRING | type of information to save or print. Can be BUDGET or TEMPERATURE. | +| GWE | OC | PERIOD | OCSETTING | KEYSTRING | specifies the steps for which the data will be saved. | +| GWE | OC | PERIOD | ALL | KEYWORD | keyword to indicate save for all time steps in period. | +| GWE | OC | PERIOD | FIRST | KEYWORD | keyword to indicate save for first step in period. This keyword may be used in conjunction with other keywords to print or save results for multiple time steps. | +| GWE | OC | PERIOD | LAST | KEYWORD | keyword to indicate save for last step in period. This keyword may be used in conjunction with other keywords to print or save results for multiple time steps. | +| GWE | OC | PERIOD | FREQUENCY | INTEGER | save at the specified time step frequency. This keyword may be used in conjunction with other keywords to print or save results for multiple time steps. | +| GWE | OC | PERIOD | STEPS | INTEGER ( 0: - name = vd['name'] - if 'block' in vd: - block = vd['block'] + name = vd["name"] + if "block" in vd: + block = vd["block"] key = (name, block) else: key = name if key in vardict: raise Exception( - 'Variable already exists in dictionary: ' + name) + "Variable already exists in dictionary: " + name + ) vardict[key] = vd vd = {} continue # skip comments - if '#' in line.strip()[0]: + if "#" in line.strip()[0]: continue ll = line.strip().split() if len(ll) > 1: k = ll[0] - istart = line.index(' ') + istart = line.index(" ") v = line[istart:].strip() if k in vd: - raise Exception('Attribute already exists in dictionary: ' + k) + raise Exception("Attribute already exists in dictionary: " + k) vd[k] = v if len(vd) > 0: - name = vd['name'] - if 'block' in vd: - block = vd['block'] + name = vd["name"] + if "block" in vd: + block = vd["block"] key = (name, block) else: key = name if key in vardict: - raise Exception( - 'Variable already exists in dictionary: ' + name) + raise Exception("Variable already exists in dictionary: " + name) vardict[key] = vd return vardict -COMMONDESCRIPTIONS = parse_mf6var_file(os.path.join('.', 'dfn', 'common.dfn')) +COMMONDESCRIPTIONS = parse_mf6var_file(os.path.join(".", "dfn", "common.dfn")) VALID_TYPES = [ - 'integer', - 'double precision', - 'string', - 'keystring', - 'keyword', - 'recarray', - 'record', + "integer", + "double precision", + "string", + "keystring", + "keyword", + "recarray", + "record", ] -def block_entry(varname, block, vardict, prefix=' '): +def block_entry(varname, block, vardict, prefix=" "): key = (varname, block) v = vardict[key] - s = '{}'.format(varname.upper()) - if 'tagged' in v: - if v['tagged'] == 'false': - s = '' + s = "{}".format(varname.upper()) + if "tagged" in v: + if v["tagged"] == "false": + s = "" # set up the time series marker @ - tsmarker = '' - if 'time_series' in v: - if v['time_series'] == 'true': - tsmarker = '@' + tsmarker = "" + if "time_series" in v: + if v["time_series"] == "true": + tsmarker = "@" # check valid type - vtype = v['type'] + vtype = v["type"] if vtype == "double precision": pass elif " " in vtype: @@ -234,65 +234,67 @@ def block_entry(varname, block, vardict, prefix=' '): if vtype not in VALID_TYPES: raise ValueError( "{}: {}: {!r} is not a valid type from {}".format( - fname, key, vtype, VALID_TYPES) + fname, key, vtype, VALID_TYPES + ) ) # record or recarray - if v['type'].startswith('rec'): - varnames = v['type'].strip().split()[1:] - s = '' + if v["type"].startswith("rec"): + varnames = v["type"].strip().split()[1:] + s = "" for vn in varnames: - blockentry = block_entry(vn, block, vardict, prefix='') - s += '{} '.format(blockentry.strip()) - if v['type'].startswith('recarray'): + blockentry = block_entry(vn, block, vardict, prefix="") + s += "{} ".format(blockentry.strip()) + if v["type"].startswith("recarray"): s = s.strip() - s = '{}{}\n{}{}\n{}{}'.format('', s, prefix, s, prefix, '...') + s = "{}{}\n{}{}\n{}{}".format("", s, prefix, s, prefix, "...") # layered - elif v['reader'] in ['readarray', 'u1ddbl', 'u2ddbl', 'u1dint']: - shape = v['shape'] - reader = v['reader'].upper() - layered = '' - if 'layered' in v: - if v['layered'] == 'true': - layered = ' [LAYERED]' - s = '{}{}\n{}{}<{}{}> -- {}'.format(s, layered, prefix, prefix, - varname, - shape, reader) + elif v["reader"] in ["readarray", "u1ddbl", "u2ddbl", "u1dint"]: + shape = v["shape"] + reader = v["reader"].upper() + layered = "" + if "layered" in v: + if v["layered"] == "true": + layered = " [LAYERED]" + s = "{}{}\n{}{}<{}{}> -- {}".format( + s, layered, prefix, prefix, varname, shape, reader + ) # keyword - elif v['type'] != 'keyword': + elif v["type"] != "keyword": vtmp = varname - if 'shape' in v: - shape = v['shape'] + if "shape" in v: + shape = v["shape"] vtmp += shape - s = '{} <{}{}{}>'.format(s, tsmarker, vtmp, tsmarker) + s = "{} <{}{}{}>".format(s, tsmarker, vtmp, tsmarker) # if optional, wrap string in square brackets - if 'optional' in v: - if v['optional'] == 'true': - s = '[{}]'.format(s.strip()) + if "optional" in v: + if v["optional"] == "true": + s = "[{}]".format(s.strip()) # prepend with prefix and return string - s = '{}{}'.format(prefix, s) + s = "{}{}".format(prefix, s) return s -def write_block(vardict, block, blk_var_list, varexcludeprefix=None, - indent=None): +def write_block( + vardict, block, blk_var_list, varexcludeprefix=None, indent=None +): if indent is None: prepend = "" else: prepend = indent * " " - s = prepend + 'BEGIN {}'.format(block.upper()) + s = prepend + "BEGIN {}".format(block.upper()) for variable in blk_var_list: ts = block_entry(variable[0], block, vardict).strip() if variable[1]: - s = '{} [{}]'.format(s, ts) + s = "{} [{}]".format(s, ts) else: - s = '{} {}'.format(s, ts) - s += '\n' + s = "{} {}".format(s, ts) + s += "\n" for iv, key in enumerate(vardict): name, b = key v = vardict[key] @@ -304,23 +306,23 @@ def write_block(vardict, block, blk_var_list, varexcludeprefix=None, n = name.upper() if n.startswith(varexcludeprefix.upper()): addv = False - if 'in_record' in v: - if v['in_record'] == 'true': + if "in_record" in v: + if v["in_record"] == "true": # do not separately include this variable # because it is part of a record addv = False - if 'block_variable' in v: - if v['block_variable'] == 'true': + if "block_variable" in v: + if v["block_variable"] == "true": # do not separately include this variable # because it is part of a record addv = False - if 'deprecated' in v: - if v['deprecated'] != '': + if "deprecated" in v: + if v["deprecated"] != "": addv = False if addv: ts = block_entry(name, block, vardict, prefix=" " + prepend) - s += '{}\n'.format(ts) - s += prepend + 'END {}'.format(block.upper()) + s += "{}\n".format(ts) + s += prepend + "END {}".format(block.upper()) return s @@ -330,11 +332,11 @@ def get_description(desc): substitutions if so. """ - if desc.strip().split()[0] == 'REPLACE': + if desc.strip().split()[0] == "REPLACE": bcoption = desc.strip().split()[1] - constantstring = COMMONDESCRIPTIONS[bcoption]['description'] - istart = desc.index('{') - istop = desc.rfind('}') + 1 + constantstring = COMMONDESCRIPTIONS[bcoption]["description"] + istart = desc.index("{") + istop = desc.rfind("}") + 1 d = eval(desc[istart:istop]) # d = eval(desc[desc.index('{'):]) for k in d: @@ -345,13 +347,13 @@ def get_description(desc): def write_desc(vardict, block, blk_var_list, varexcludeprefix=None): - s = '' + s = "" for iv, (name, b) in enumerate(vardict): v = vardict[(name, b)] - if v['block'] == block: - if 'block_variable' in v and v['block_variable']: - optional = 'optional' in v and v['optional'] == 'true' - blk_var_list.append((v['name'], optional)) + if v["block"] == block: + if "block_variable" in v and v["block_variable"]: + optional = "optional" in v and v["optional"] == "true" + blk_var_list.append((v["name"], optional)) addv = True if varexcludeprefix is not None: # exclude variables that start with `dev_`. These are @@ -359,61 +361,61 @@ def write_desc(vardict, block, blk_var_list, varexcludeprefix=None): n = name.upper() if n.startswith(varexcludeprefix.upper()): addv = False - if v['type'].startswith('rec'): + if v["type"].startswith("rec"): addv = False - if 'deprecated' in v: - if v['deprecated'] != '': + if "deprecated" in v: + if v["deprecated"] != "": addv = False - if 'removed' in v: - if v['removed'] != '': + if "removed" in v: + if v["removed"] != "": addv = False if addv: - if v['type'] == 'keyword': + if v["type"] == "keyword": n = name.upper() else: - if 'tagged' in v: + if "tagged" in v: # could be used in future to write tag and name - n = '{}'.format(name) + n = "{}".format(name) else: n = name - n = n.replace('_', '\\_') - if 'description' in v: - desc = get_description(v['description']) + n = n.replace("_", "\\_") + if "description" in v: + desc = get_description(v["description"]) else: - msg = '' + msg = "" for k, v in v.items(): - msg += ' {}: {}\n'.format(k, v) + msg += " {}: {}\n".format(k, v) print(msg) raise Exception(msg) - ss = '\\texttt{' + n + '}---' + desc - if 'time_series' in v: - if v['time_series'] == 'true': - fmt = '\\textcolor{blue}\{\}' - ss = '\\textcolor{blue}{' + ss + '}' + ss = "\\texttt{" + n + "}---" + desc + if "time_series" in v: + if v["time_series"] == "true": + fmt = "\\textcolor{blue}\{\}" + ss = "\\textcolor{blue}{" + ss + "}" # \textcolor{declared-color}{text} - s += '\\item ' + ss + '\n\n' + s += "\\item " + ss + "\n\n" - t = v['type'] - if t.startswith('keystring'): + t = v["type"] + if t.startswith("keystring"): # s += '\\begin{verbatim}\n' - s += '\\begin{lstlisting}[style=blockdefinition]\n' + s += "\\begin{lstlisting}[style=blockdefinition]\n" for vn in t.strip().split()[1:]: - blockentry = block_entry(vn, block, vardict, '') - s += '{}\n'.format(blockentry) + blockentry = block_entry(vn, block, vardict, "") + s += "{}\n".format(blockentry) # s += '\\end{verbatim}\n\n' - s += '\\end{lstlisting}\n\n' + s += "\\end{lstlisting}\n\n" return s def write_desc_md(vardict, block, blk_var_list, varexcludeprefix=None): - s = '' + s = "" for iv, (name, b) in enumerate(vardict): v = vardict[(name, b)] - if v['block'] == block: - if 'block_variable' in v and v['block_variable']: - optional = 'optional' in v and v['optional'] == 'true' - blk_var_list.append((v['name'], optional)) + if v["block"] == block: + if "block_variable" in v and v["block_variable"]: + optional = "optional" in v and v["optional"] == "true" + blk_var_list.append((v["name"], optional)) addv = True if varexcludeprefix is not None: # exclude variables that start with `dev_`. These are @@ -421,45 +423,45 @@ def write_desc_md(vardict, block, blk_var_list, varexcludeprefix=None): n = name.upper() if n.startswith(varexcludeprefix.upper()): addv = False - if v['type'].startswith('rec'): + if v["type"].startswith("rec"): addv = False - if 'deprecated' in v: - if v['deprecated'] != '': + if "deprecated" in v: + if v["deprecated"] != "": addv = False - if 'removed' in v: - if v['removed'] != '': + if "removed" in v: + if v["removed"] != "": addv = False if addv: - if v['type'] == 'keyword': + if v["type"] == "keyword": n = name.upper() else: - if 'tagged' in v: + if "tagged" in v: # could be used in future to write tag and name - n = '{}'.format(name) + n = "{}".format(name) else: n = name - if 'description' in v: - desc = get_description(v['description']) + if "description" in v: + desc = get_description(v["description"]) else: - msg = '' + msg = "" for k, v in v.items(): - msg += ' {}: {}\n'.format(k, v) + msg += " {}: {}\n".format(k, v) print(msg) raise Exception(msg) desc = md_replace(desc) - ss = '`' + n + '` ' + desc - if 'time_series' in v: - if v['time_series'] == 'true': - ss = '' + ss + '' - s += ' * ' + ss + '\n\n' - - t = v['type'] - if t.startswith('keystring'): + ss = "`" + n + "` " + desc + if "time_series" in v: + if v["time_series"] == "true": + ss = '' + ss + "" + s += " * " + ss + "\n\n" + + t = v["type"] + if t.startswith("keystring"): for vn in t.strip().split()[1:]: blockentry = md_replace( block_entry(vn, block, vardict, 10 * " ") ) - s += '{}\n'.format(blockentry) + s += "{}\n".format(blockentry) return s @@ -470,7 +472,7 @@ def md_replace(s): re.compile("\\\\cite{(.*?)\\}"): ("\\cite{{{}}}", None), re.compile("\\\\citep{(.*?)\\}"): ("\\citep{{{}}}", None), re.compile("\\\\texttt{(.*?)\\}"): ("\\texttt{{{}}}", "`{}`"), - re.compile("\\$(.*?)\\$"): ("${}$", '{}'), + re.compile("\\$(.*?)\\$"): ("${}$", "{}"), re.compile("\\^{(.*?)\\}"): ("^{{{}}}", "{}"), re.compile("\\^(.*?)\\ "): ("^{:.1}", "{:.1}"), re.compile("\\``(.*?)\\''"): ("``{}''", '"{}"'), @@ -487,7 +489,7 @@ def md_replace(s): # replace individual characters replace_dict = { - "\mf": 'MODFLOW 6', + "\mf": "MODFLOW 6", "~": " ", "@": "", "$": "", @@ -505,9 +507,12 @@ def md_replace(s): def get_examples(component): pth = os.path.join("examples") - files = [filename for filename in sorted(os.listdir(pth)) if - component.lower() in filename.lower() and - "-obs" not in filename.lower()] + files = [ + filename + for filename in sorted(os.listdir(pth)) + if component.lower() in filename.lower() + and "-obs" not in filename.lower() + ] s = "" for idx, filename in enumerate(files): if idx == 0: @@ -515,7 +520,7 @@ def get_examples(component): if len(files) > 1: s += "Example {}\n\n".format(idx + 1) fpth = os.path.join(pth, filename) - with open(fpth, 'r') as f: + with open(fpth, "r") as f: lines = f.readlines() s += "```\n" for line in lines: @@ -527,16 +532,18 @@ def get_examples(component): def get_obs_examples(component): pth = os.path.join("examples") - files = [filename for filename in sorted(os.listdir(pth)) if - component.lower() in filename.lower() and - "-obs" in filename.lower()] + files = [ + filename + for filename in sorted(os.listdir(pth)) + if component.lower() in filename.lower() and "-obs" in filename.lower() + ] s = "" for idx, filename in enumerate(files): s += "#### Example Observation Input File\n" if len(files) > 1: s += "Example {}\n\n".format(idx + 1) fpth = os.path.join(pth, filename) - with open(fpth, 'r') as f: + with open(fpth, "r") as f: lines = f.readlines() s += "```\n" for line in lines: @@ -548,17 +555,24 @@ def get_obs_examples(component): def get_obs_table(component): pth = os.path.join("..", "..", "Common") - files = [filename for filename in sorted(os.listdir(pth)) if - component.lower() in filename.lower() and - filename.lower().endswith("obs.tex")] + files = [ + filename + for filename in sorted(os.listdir(pth)) + if component.lower() in filename.lower() + and filename.lower().endswith("obs.tex") + ] s = "" if files: s += "#### Available Observation Types\n\n" - s += "| Stress Package | Observation Type | ID1 | ID2 | Description |\n" - s += "|----------------|------------------|-----|-----|-------------|\n" + s += ( + "| Stress Package | Observation Type | ID1 | ID2 | Description |\n" + ) + s += ( + "|----------------|------------------|-----|-----|-------------|\n" + ) for idx, filename in enumerate(files): fpth = os.path.join(pth, filename) - with open(fpth, 'r') as f: + with open(fpth, "r") as f: lines = f.readlines() for line in lines: line = md_replace(line.rstrip()) @@ -575,14 +589,15 @@ def get_obs_table(component): def write_md_header(f): - s = '# MODFLOW 6 INPUT VARIABLES\n\n' + s = "# MODFLOW 6 INPUT VARIABLES\n\n" fmd.write(s) - s = '| {} | {} | {} | {} | {} | {} |\n'.format('component', 'package', - 'block', 'variable name', - 'type', 'description') + s = "| {} | {} | {} | {} | {} | {} |\n".format( + "component", "package", "block", "variable name", "type", "description" + ) fmd.write(s) - s = '| {} | {} | {} | {} | {} | {} |\n'.format(':---:', ':---:', ':---:', - ':---:', ':---:', '---') + s = "| {} | {} | {} | {} | {} | {} |\n".format( + ":---:", ":---:", ":---:", ":---:", ":---:", "---" + ) fmd.write(s) return @@ -593,142 +608,169 @@ def write_md(f, vardict, component, package): for iv, (name, b) in enumerate(vardict): n = name.upper() v = vardict[(name, b)] - b = v['block'].upper() - t = v['type'].upper() - s = '' - if t.startswith('REC'): + b = v["block"].upper() + t = v["type"].upper() + s = "" + if t.startswith("REC"): pass else: - if t.startswith('KEYSTRING'): - t = 'KEYSTRING' - t = '{}'.format(t) - if 'shape' in v: - shape = v['shape'].upper() - t = '{} {}'.format(t, shape) - d = get_description(v['description']) - s = '| {} | {} | {} | {} | {} | {} |\n'.format(c, p, b, n, t, d) + if t.startswith("KEYSTRING"): + t = "KEYSTRING" + t = "{}".format(t) + if "shape" in v: + shape = v["shape"].upper() + t = "{} {}".format(t, shape) + d = get_description(v["description"]) + s = "| {} | {} | {} | {} | {} | {} |\n".format(c, p, b, n, t, d) f.write(s) return def write_appendix(texdir, allblocks): - fname = os.path.join(texdir, 'appendixA.tex') - with open(fname, 'w') as f: - f.write('\\small\n\\begin{longtable}{p{1.5cm} p{1.5cm} p{3cm} c}\n') + fname = os.path.join(texdir, "appendixA.tex") + with open(fname, "w") as f: + f.write("\\small\n\\begin{longtable}{p{1.5cm} p{1.5cm} p{3cm} c}\n") f.write( - '\\caption{List of block names organized by component and input file ' - 'type. OPEN/CLOSE indicates whether or not the block information ' - 'can be contained in separate file} \\tabularnewline \n\n') - f.write('\\hline\n\\hline\n') + "\\caption{List of block names organized by component and input file " + "type. OPEN/CLOSE indicates whether or not the block information " + "can be contained in separate file} \\tabularnewline \n\n" + ) + f.write("\\hline\n\\hline\n") f.write( - '\\textbf{Component} & \\textbf{FTYPE} & \\textbf{Blockname} & \\textbf{OPEN/CLOSE} \\\\\n') - f.write('\\hline\n\\endfirsthead\n\n\n') + "\\textbf{Component} & \\textbf{FTYPE} & \\textbf{Blockname} & \\textbf{OPEN/CLOSE} \\\\\n" + ) + f.write("\\hline\n\\endfirsthead\n\n\n") - f.write('\captionsetup{textformat=simple}\n') - f.write('\caption*{\\textbf{Table A--\\arabic{table}.}{\quad}List of block' - ' names organized by component and input file type. OPEN/CLOSE ' - 'indicates whether or not the block information can be contained ' - 'in separate file.---Continued} \\tabularnewline\n') + f.write("\captionsetup{textformat=simple}\n") + f.write( + "\caption*{\\textbf{Table A--\\arabic{table}.}{\quad}List of block" + " names organized by component and input file type. OPEN/CLOSE " + "indicates whether or not the block information can be contained " + "in separate file.---Continued} \\tabularnewline\n" + ) - f.write('\n\\hline\n\\hline\n') + f.write("\n\\hline\n\\hline\n") f.write( - '\\textbf{Component} & \\textbf{FTYPE} & \\textbf{Blockname} & \\textbf{OPEN/CLOSE} \\\\\n') - f.write('\\hline\n\\endhead\n\n\\hline\n\\endfoot\n\n\n') + "\\textbf{Component} & \\textbf{FTYPE} & \\textbf{Blockname} & \\textbf{OPEN/CLOSE} \\\\\n" + ) + f.write("\\hline\n\\endhead\n\n\\hline\n\\endfoot\n\n\n") - lastftype = '' + lastftype = "" for b in allblocks: - l = b.strip().split('-') + l = b.strip().split("-") component, ftype, blockname = l if lastftype != ftype: - f.write('\\hline\n') - oc = 'yes' - if 'griddata' in blockname.lower(): - oc = 'no' - if 'utl' in component.lower() and \ - 'tas' in ftype.lower() and 'time' in blockname.lower(): - oc = 'no' - s = '{} & {} & {} & {} \\\\ \n'.format(component.upper(), - ftype.upper(), - blockname.upper(), oc) + f.write("\\hline\n") + oc = "yes" + if "griddata" in blockname.lower(): + oc = "no" + if ( + "utl" in component.lower() + and "tas" in ftype.lower() + and "time" in blockname.lower() + ): + oc = "no" + s = "{} & {} & {} & {} \\\\ \n".format( + component.upper(), ftype.upper(), blockname.upper(), oc + ) f.write(s) lastftype = ftype f.write( - '\n\n\\hline\n\\end{longtable}\n\\label{table:blocks}\n\\normalsize\n') - - -if __name__ == '__main__': - - file_order = ['sim-nam', # dfn completed tex updated - 'sim-tdis', # dfn completed tex updated - 'exg-gwfgwf', # dfn completed tex updated - 'exg-gwfgwt', - 'exg-gwtgwt', - 'sln-ims', # dfn completed tex updated - 'sln-ems', # dfn completed tex updated - 'gwf-nam', # dfn completed tex updated - 'gwf-dis', # dfn completed tex updated - 'gwf-disv', # dfn completed tex updated - 'gwf-disu', # dfn completed tex updated - 'gwf-ic', # dfn completed tex updated - 'gwf-npf', # dfn completed tex updated - 'gwf-buy', # dfn completed tex updated - 'gwf-sto', # dfn completed tex updated - 'gwf-csub', # dfn completed tex updated - 'gwf-hfb', # dfn completed tex updated - 'gwf-chd', # dfn completed tex updated - 'gwf-wel', # dfn completed tex updated - 'gwf-drn', # dfn completed tex updated - 'gwf-riv', # dfn completed tex updated - 'gwf-ghb', # dfn completed tex updated - 'gwf-rch', # dfn completed tex updated - 'gwf-rcha', # dfn completed tex updated - 'gwf-evt', # dfn completed tex updated - 'gwf-evta', # dfn completed tex updated - 'gwf-maw', # dfn completed tex updated - 'gwf-sfr', # dfn completed tex updated - 'gwf-lak', # dfn completed tex updated - 'gwf-uzf', # dfn completed tex updated - 'gwf-mvr', # dfn completed tex updated - 'gwf-gnc', # dfn completed tex updated - 'gwf-oc', # dfn completed tex updated - 'gwf-vsc', - 'gwf-api', - 'gwt-adv', - 'gwt-dsp', - 'gwt-cnc', - 'gwt-dis', - 'gwt-disv', - 'gwt-disu', - 'gwt-ic', - 'gwt-nam', - 'gwt-oc', - 'gwt-ssm', - 'gwt-src', - 'gwt-mst', - 'gwt-ist', - 'gwt-sft', - 'gwt-lkt', - 'gwt-mwt', - 'gwt-uzt', - 'gwt-fmi', - 'gwt-mvt', - 'gwt-api', - 'utl-spc', - 'utl-spca', - 'utl-obs', - 'utl-laktab', - 'utl-sfrtab', - 'utl-ts', - 'utl-tas', - 'utl-ats', - 'utl-tvk', - 'utl-tvs'] + "\n\n\\hline\n\\end{longtable}\n\\label{table:blocks}\n\\normalsize\n" + ) + + +if __name__ == "__main__": + + file_order = [ + "sim-nam", # dfn completed tex updated + "sim-tdis", # dfn completed tex updated + "exg-gwfgwf", # dfn completed tex updated + "exg-gwfgwt", + "exg-gwtgwt", + "exg-gwfgwe", + "exg-gwegwe", + "sln-ims", # dfn completed tex updated + "sln-ems", # dfn completed tex updated + "gwf-nam", # dfn completed tex updated + "gwf-dis", # dfn completed tex updated + "gwf-disv", # dfn completed tex updated + "gwf-disu", # dfn completed tex updated + "gwf-ic", # dfn completed tex updated + "gwf-npf", # dfn completed tex updated + "gwf-buy", # dfn completed tex updated + "gwf-sto", # dfn completed tex updated + "gwf-csub", # dfn completed tex updated + "gwf-hfb", # dfn completed tex updated + "gwf-chd", # dfn completed tex updated + "gwf-wel", # dfn completed tex updated + "gwf-drn", # dfn completed tex updated + "gwf-riv", # dfn completed tex updated + "gwf-ghb", # dfn completed tex updated + "gwf-rch", # dfn completed tex updated + "gwf-rcha", # dfn completed tex updated + "gwf-evt", # dfn completed tex updated + "gwf-evta", # dfn completed tex updated + "gwf-maw", # dfn completed tex updated + "gwf-sfr", # dfn completed tex updated + "gwf-lak", # dfn completed tex updated + "gwf-uzf", # dfn completed tex updated + "gwf-mvr", # dfn completed tex updated + "gwf-gnc", # dfn completed tex updated + "gwf-oc", # dfn completed tex updated + "gwf-vsc", + "gwf-api", + "gwt-adv", + "gwt-dsp", + "gwt-cnc", + "gwt-dis", + "gwt-disv", + "gwt-disu", + "gwt-ic", + "gwt-nam", + "gwt-oc", + "gwt-ssm", + "gwt-src", + "gwt-mst", + "gwt-ist", + "gwt-sft", + "gwt-lkt", + "gwt-mwt", + "gwt-uzt", + "gwt-fmi", + "gwt-mvt", + "gwt-api", + "gwe-adv", + "gwe-cnt", + "gwe-dis", + "gwe-disv", + "gwe-disu", + "gwe-dsp", + "gwe-ic", + "gwe-mst", + "gwe-nam", + "gwe-oc", + "gwe-ssm", + "gwe-fmi", + "utl-spc", + "utl-spca", + "utl-spt", + "utl-spta", + "utl-obs", + "utl-laktab", + "utl-sfrtab", + "utl-ts", + "utl-tas", + "utl-ats", + "utl-tvk", + "utl-tvs", + ] # directories - dfndir = os.path.join('.', 'dfn') - texdir = os.path.join('.', 'tex') - mddir = os.path.join('.', 'md') + dfndir = os.path.join(".", "dfn") + texdir = os.path.join(".", "tex") + mddir = os.path.join(".", "md") docdir = os.path.join("..", "..", "..", ".build_rtd_docs", "_mf6io") # regenerate docdir @@ -740,20 +782,22 @@ def write_appendix(texdir, allblocks): allblocks = [] # setup a markdown file - fname = os.path.join(mddir, 'mf6ivar.md') - with open(fname, 'w') as fmd: + fname = os.path.join(mddir, "mf6ivar.md") + with open(fname, "w") as fmd: write_md_header(fmd) # construct list of dfn files to process in the order of file_order files = os.listdir(dfndir) for f in files: - if 'common' in f: + if "common" in f: continue - if '.DS_Store' in f: + if ".DS_Store" in f: continue if os.path.splitext(f)[0] not in file_order: - raise Exception('File not in file_order: ', f) - files = [fname + '.dfn' for fname in file_order if fname + '.dfn' in files] + raise Exception("File not in file_order: ", f) + files = [ + fname + ".dfn" for fname in file_order if fname + ".dfn" in files + ] # files = ['gwf-obs.dfn'] # # create rst file for markdown @@ -765,48 +809,57 @@ def write_appendix(texdir, allblocks): # frst.write(s) for txtname in files: - component, package = os.path.splitext(txtname)[0].split('-')[0:2] + component, package = os.path.splitext(txtname)[0].split("-")[0:2] vardict = parse_mf6var_file(os.path.join(dfndir, txtname)) # make list of unique block names blocks = [] for k in vardict: v = vardict[k] - b = v['block'] + b = v["block"] if b not in blocks: blocks.append(b) # add a full block name to allblocks for block in blocks: - b = '{}-{}-{}'.format(component, package, block) + b = "{}-{}-{}".format(component, package, block) allblocks.append(b) # go through each block and write information - desc = '% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py \n\n' + desc = "% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py \n\n" for b in blocks: blk_var_list = [] # Write the name of the block to the latex file - desc += '\item \\textbf{}\n\n'.format('{Block: ' + b.upper() + '}') - - desc += '\\begin{description}\n' - desc += write_desc(vardict, b, blk_var_list, - varexcludeprefix='dev_') - desc += '\\end{description}\n' - - fname = os.path.join(texdir, os.path.splitext(txtname)[ - 0] + '-' + b + '.dat') - f = open(fname, 'w') - s = write_block(vardict, b, blk_var_list, - varexcludeprefix='dev_') + '\n' + desc += "\item \\textbf{}\n\n".format( + "{Block: " + b.upper() + "}" + ) + + desc += "\\begin{description}\n" + desc += write_desc( + vardict, b, blk_var_list, varexcludeprefix="dev_" + ) + desc += "\\end{description}\n" + + fname = os.path.join( + texdir, os.path.splitext(txtname)[0] + "-" + b + ".dat" + ) + f = open(fname, "w") + s = ( + write_block( + vardict, b, blk_var_list, varexcludeprefix="dev_" + ) + + "\n" + ) f.write(s) if VERBOSE: print(s) f.close() - fname = os.path.join(texdir, - os.path.splitext(txtname)[0] + '-desc' + '.tex') - f = open(fname, 'w') - s = desc + '\n' + fname = os.path.join( + texdir, os.path.splitext(txtname)[0] + "-desc" + ".tex" + ) + f = open(fname, "w") + s = desc + "\n" f.write(s) if VERBOSE: print(s) @@ -814,8 +867,8 @@ def write_appendix(texdir, allblocks): # write markdown description mdname = os.path.splitext(txtname)[0] - fname = os.path.join(docdir, mdname + '.md') - f = open(fname, 'w') + fname = os.path.join(docdir, mdname + ".md") + f = open(fname, "w") f.write("### {}\n\n".format(mdname.upper())) f.write("#### Structure of Blocks\n\n") f.write("_FOR EACH SIMULATION_\n\n") @@ -824,17 +877,27 @@ def write_appendix(texdir, allblocks): blk_var_list = [] # Write the name of the block to the latex file - desc += '##### Block: {}\n\n'.format(b.upper()) + desc += "##### Block: {}\n\n".format(b.upper()) - desc += write_desc_md(vardict, b, blk_var_list, - varexcludeprefix='dev_') + desc += write_desc_md( + vardict, b, blk_var_list, varexcludeprefix="dev_" + ) if "period" in b.lower(): f.write("\n_FOR ANY STRESS PERIOD_\n\n") f.write("```\n") - s = md_replace(write_block(vardict, b, blk_var_list, - varexcludeprefix='dev_', - indent=4)) + "\n" + s = ( + md_replace( + write_block( + vardict, + b, + blk_var_list, + varexcludeprefix="dev_", + indent=4, + ) + ) + + "\n" + ) # s = s.replace("@", "") + "\n" f.write(s) f.write("```\n") @@ -877,5 +940,3 @@ def write_appendix(texdir, allblocks): for b in allblocks: print(b) write_appendix(texdir, allblocks) - - diff --git a/doc/mf6io/mf6ivar/tex/appendixA.tex b/doc/mf6io/mf6ivar/tex/appendixA.tex index 7cbb933e60e..e01d4311182 100644 --- a/doc/mf6io/mf6ivar/tex/appendixA.tex +++ b/doc/mf6io/mf6ivar/tex/appendixA.tex @@ -41,6 +41,10 @@ EXG & GWTGWT & DIMENSIONS & yes \\ EXG & GWTGWT & EXCHANGEDATA & yes \\ \hline +EXG & GWEGWE & OPTIONS & yes \\ +EXG & GWEGWE & DIMENSIONS & yes \\ +EXG & GWEGWE & EXCHANGEDATA & yes \\ +\hline SLN & IMS & OPTIONS & yes \\ SLN & IMS & NONLINEAR & yes \\ SLN & IMS & LINEAR & yes \\ @@ -240,6 +244,51 @@ GWT & API & OPTIONS & yes \\ GWT & API & DIMENSIONS & yes \\ \hline +GWE & ADV & OPTIONS & yes \\ +\hline +GWE & CNT & OPTIONS & yes \\ +GWE & CNT & DIMENSIONS & yes \\ +GWE & CNT & PERIOD & yes \\ +\hline +GWE & DIS & OPTIONS & yes \\ +GWE & DIS & DIMENSIONS & yes \\ +GWE & DIS & GRIDDATA & no \\ +\hline +GWE & DISV & OPTIONS & yes \\ +GWE & DISV & DIMENSIONS & yes \\ +GWE & DISV & GRIDDATA & no \\ +GWE & DISV & VERTICES & yes \\ +GWE & DISV & CELL2D & yes \\ +\hline +GWE & DISU & OPTIONS & yes \\ +GWE & DISU & DIMENSIONS & yes \\ +GWE & DISU & GRIDDATA & no \\ +GWE & DISU & CONNECTIONDATA & yes \\ +GWE & DISU & VERTICES & yes \\ +GWE & DISU & CELL2D & yes \\ +\hline +GWE & DSP & OPTIONS & yes \\ +GWE & DSP & GRIDDATA & no \\ +\hline +GWE & IC & GRIDDATA & no \\ +\hline +GWE & MST & OPTIONS & yes \\ +GWE & MST & GRIDDATA & no \\ +GWE & MST & PACKAGEDATA & yes \\ +\hline +GWE & NAM & OPTIONS & yes \\ +GWE & NAM & PACKAGES & yes \\ +\hline +GWE & OC & OPTIONS & yes \\ +GWE & OC & PERIOD & yes \\ +\hline +GWE & SSM & OPTIONS & yes \\ +GWE & SSM & SOURCES & yes \\ +GWE & SSM & FILEINPUT & yes \\ +\hline +GWE & FMI & OPTIONS & yes \\ +GWE & FMI & PACKAGEDATA & yes \\ +\hline UTL & SPC & OPTIONS & yes \\ UTL & SPC & DIMENSIONS & yes \\ UTL & SPC & PERIOD & yes \\ @@ -247,6 +296,13 @@ UTL & SPCA & OPTIONS & yes \\ UTL & SPCA & PERIOD & yes \\ \hline +UTL & SPT & OPTIONS & yes \\ +UTL & SPT & DIMENSIONS & yes \\ +UTL & SPT & PERIOD & yes \\ +\hline +UTL & SPTA & OPTIONS & yes \\ +UTL & SPTA & PERIOD & yes \\ +\hline UTL & OBS & OPTIONS & yes \\ UTL & OBS & CONTINUOUS & yes \\ \hline diff --git a/doc/mf6io/mf6ivar/tex/exg-gwegwe-desc.tex b/doc/mf6io/mf6ivar/tex/exg-gwegwe-desc.tex new file mode 100644 index 00000000000..9fb1bf5b633 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/exg-gwegwe-desc.tex @@ -0,0 +1,63 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{gwfmodelname1}---keyword to specify name of first corresponding GWF Model. In the simulation name file, the GWE6-GWE6 entry contains names for GWE Models (exgmnamea and exgmnameb). The GWE Model with the name exgmnamea must correspond to the GWF Model with the name gwfmodelname1. + +\item \texttt{gwfmodelname2}---keyword to specify name of second corresponding GWF Model. In the simulation name file, the GWE6-GWE6 entry contains names for GWE Models (exgmnamea and exgmnameb). The GWE Model with the name exgmnameb must correspond to the GWF Model with the name gwfmodelname2. + +\item \texttt{auxiliary}---an array of auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided. Most auxiliary variables will not be used by the GWF-GWF Exchange, but they will be available for use by other parts of the program. If an auxiliary variable with the name ``ANGLDEGX'' is found, then this information will be used as the angle (provided in degrees) between the connection face normal and the x axis, where a value of zero indicates that a normal vector points directly along the positive x axis. The connection face normal is a normal vector on the cell face shared between the cell in model 1 and the cell in model 2 pointing away from the model 1 cell. Additional information on ``ANGLDEGX'' is provided in the description of the DISU Package. If an auxiliary variable with the name ``CDIST'' is found, then this information will be used as the straight-line connection distance, including the vertical component, between the two cell centers. Both ANGLDEGX and CDIST are required if specific discharge is calculated for either of the groundwater models. + +\item \texttt{BOUNDNAMES}---keyword to indicate that boundary names may be provided with the list of GWE Exchange cells. + +\item \texttt{PRINT\_INPUT}---keyword to indicate that the list of exchange entries will be echoed to the listing file immediately after it is read. + +\item \texttt{PRINT\_FLOWS}---keyword to indicate that the list of exchange flow rates will be printed to the listing file for every stress period in which ``SAVE BUDGET'' is specified in Output Control. + +\item \texttt{SAVE\_FLOWS}---keyword to indicate that cell-by-cell flow terms will be written to the budget file for each model provided that the Output Control for the models are set up with the ``BUDGET SAVE FILE'' option. + +\item \texttt{adv\_scheme}---scheme used to solve the advection term. Can be upstream, central, or TVD. If not specified, upstream weighting is the default weighting scheme. + +\item \texttt{DSP\_XT3D\_OFF}---deactivate the xt3d method for the dispersive flux and use the faster and less accurate approximation for this exchange. + +\item \texttt{DSP\_XT3D\_RHS}---add xt3d dispersion terms to right-hand side, when possible, for this exchange. + +\item \texttt{FILEIN}---keyword to specify that an input filename is expected next. + +\item \texttt{MVE6}---keyword to specify that record corresponds to an energy transport mover file. + +\item \texttt{mve6\_filename}---is the file name of the transport mover input file to apply to this exchange. Information for the transport mover are provided in the file provided with these keywords. + +\item \texttt{OBS6}---keyword to specify that record corresponds to an observations file. + +\item \texttt{obs6\_filename}---is the file name of the observations input file for this exchange. See the ``Observation utility'' section for instructions for preparing observation input files. Table \ref{table:gwe-obstypetable} lists observation type(s) supported by the GWE-GWE package. + +\end{description} +\item \textbf{Block: DIMENSIONS} + +\begin{description} +\item \texttt{nexg}---keyword and integer value specifying the number of GWE-GWE exchanges. + +\end{description} +\item \textbf{Block: EXCHANGEDATA} + +\begin{description} +\item \texttt{cellidm1}---is the cellid of the cell in model 1 as specified in the simulation name file. For a structured grid that uses the DIS input file, CELLIDM1 is the layer, row, and column numbers of the cell. For a grid that uses the DISV input file, CELLIDM1 is the layer number and CELL2D number for the two cells. If the model uses the unstructured discretization (DISU) input file, then CELLIDM1 is the node number for the cell. + +\item \texttt{cellidm2}---is the cellid of the cell in model 2 as specified in the simulation name file. For a structured grid that uses the DIS input file, CELLIDM2 is the layer, row, and column numbers of the cell. For a grid that uses the DISV input file, CELLIDM2 is the layer number and CELL2D number for the two cells. If the model uses the unstructured discretization (DISU) input file, then CELLIDM2 is the node number for the cell. + +\item \texttt{ihc}---is an integer flag indicating the direction between node n and all of its m connections. If IHC = 0 then the connection is vertical. If IHC = 1 then the connection is horizontal. If IHC = 2 then the connection is horizontal for a vertically staggered grid. + +\item \texttt{cl1}---is the distance between the center of cell 1 and the its shared face with cell 2. + +\item \texttt{cl2}---is the distance between the center of cell 2 and the its shared face with cell 1. + +\item \texttt{hwva}---is the horizontal width of the flow connection between cell 1 and cell 2 if IHC $>$ 0, or it is the area perpendicular to flow of the vertical connection between cell 1 and cell 2 if IHC = 0. + +\item \texttt{aux}---represents the values of the auxiliary variables for each GWEGWE Exchange. The values of auxiliary variables must be present for each exchange. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. + +\item \texttt{boundname}---name of the GWE Exchange cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/exg-gwegwe-dimensions.dat b/doc/mf6io/mf6ivar/tex/exg-gwegwe-dimensions.dat new file mode 100644 index 00000000000..405fdc5cdf7 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/exg-gwegwe-dimensions.dat @@ -0,0 +1,3 @@ +BEGIN DIMENSIONS + NEXG +END DIMENSIONS diff --git a/doc/mf6io/mf6ivar/tex/exg-gwegwe-exchangedata.dat b/doc/mf6io/mf6ivar/tex/exg-gwegwe-exchangedata.dat new file mode 100644 index 00000000000..c11fc9ce016 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/exg-gwegwe-exchangedata.dat @@ -0,0 +1,5 @@ +BEGIN EXCHANGEDATA + [] [] + [] [] + ... +END EXCHANGEDATA diff --git a/doc/mf6io/mf6ivar/tex/exg-gwegwe-options.dat b/doc/mf6io/mf6ivar/tex/exg-gwegwe-options.dat new file mode 100644 index 00000000000..54e7e9d3695 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/exg-gwegwe-options.dat @@ -0,0 +1,14 @@ +BEGIN OPTIONS + GWFMODELNAME1 + GWFMODELNAME2 + [AUXILIARY ] + [BOUNDNAMES] + [PRINT_INPUT] + [PRINT_FLOWS] + [SAVE_FLOWS] + [ADV_SCHEME ] + [DSP_XT3D_OFF] + [DSP_XT3D_RHS] + [MVE6 FILEIN ] + [OBS6 FILEIN ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/exg-gwfgwe-desc.tex b/doc/mf6io/mf6ivar/tex/exg-gwfgwe-desc.tex new file mode 100644 index 00000000000..bf95ac4119f --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/exg-gwfgwe-desc.tex @@ -0,0 +1,3 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + + diff --git a/doc/mf6io/mf6ivar/tex/gwe-adv-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-adv-desc.tex new file mode 100644 index 00000000000..fc18c7d2f3b --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-adv-desc.tex @@ -0,0 +1,9 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{scheme}---scheme used to solve the advection term. Can be upstream, central, or TVD. If not specified, upstream weighting is the default weighting scheme. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-adv-options.dat b/doc/mf6io/mf6ivar/tex/gwe-adv-options.dat new file mode 100644 index 00000000000..9ecafe688f1 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-adv-options.dat @@ -0,0 +1,3 @@ +BEGIN OPTIONS + [SCHEME ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-cnt-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-cnt-desc.tex new file mode 100644 index 00000000000..5fd2b217104 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-cnt-desc.tex @@ -0,0 +1,49 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{auxiliary}---defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. + +\item \texttt{auxmultname}---name of auxiliary variable to be used as multiplier of temperature value. + +\item \texttt{BOUNDNAMES}---keyword to indicate that boundary names may be provided with the list of constant temperature cells. + +\item \texttt{PRINT\_INPUT}---keyword to indicate that the list of constant temperature information will be written to the listing file immediately after it is read. + +\item \texttt{PRINT\_FLOWS}---keyword to indicate that the list of constant temperature flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. + +\item \texttt{SAVE\_FLOWS}---keyword to indicate that constant temperature flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. + +\item \texttt{TS6}---keyword to specify that record corresponds to a time-series file. + +\item \texttt{FILEIN}---keyword to specify that an input filename is expected next. + +\item \texttt{ts6\_filename}---defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. + +\item \texttt{OBS6}---keyword to specify that record corresponds to an observations file. + +\item \texttt{obs6\_filename}---name of input file to define observations for the Constant Temperature package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the Constant Temperature package. + +\end{description} +\item \textbf{Block: DIMENSIONS} + +\begin{description} +\item \texttt{maxbound}---integer value specifying the maximum number of constant temperatures cells that will be specified for use during any stress period. + +\end{description} +\item \textbf{Block: PERIOD} + +\begin{description} +\item \texttt{iper}---integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. + +\item \texttt{cellid}---is the cell identifier, and depends on the type of grid that is used for the simulation. For a structured grid that uses the DIS input file, CELLID is the layer, row, and column. For a grid that uses the DISV input file, CELLID is the layer and CELL2D number. If the model uses the unstructured discretization (DISU) input file, CELLID is the node number for the cell. + +\item \textcolor{blue}{\texttt{temp}---is the constant temperature value. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{aux}---represents the values of the auxiliary variables for each constant temperature. The values of auxiliary variables must be present for each constant temperature. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \texttt{boundname}---name of the constant temperature cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-cnt-dimensions.dat b/doc/mf6io/mf6ivar/tex/gwe-cnt-dimensions.dat new file mode 100644 index 00000000000..7b4c7bf6ec7 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-cnt-dimensions.dat @@ -0,0 +1,3 @@ +BEGIN DIMENSIONS + MAXBOUND +END DIMENSIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-cnt-options.dat b/doc/mf6io/mf6ivar/tex/gwe-cnt-options.dat new file mode 100644 index 00000000000..0985bd51e40 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-cnt-options.dat @@ -0,0 +1,10 @@ +BEGIN OPTIONS + [AUXILIARY ] + [AUXMULTNAME ] + [BOUNDNAMES] + [PRINT_INPUT] + [PRINT_FLOWS] + [SAVE_FLOWS] + [TS6 FILEIN ] + [OBS6 FILEIN ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-cnt-period.dat b/doc/mf6io/mf6ivar/tex/gwe-cnt-period.dat new file mode 100644 index 00000000000..71db20fc4ec --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-cnt-period.dat @@ -0,0 +1,5 @@ +BEGIN PERIOD + <@temp@> [<@aux(naux)@>] [] + <@temp@> [<@aux(naux)@>] [] + ... +END PERIOD diff --git a/doc/mf6io/mf6ivar/tex/gwe-dis-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-dis-desc.tex new file mode 100644 index 00000000000..afef5a5fa76 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-dis-desc.tex @@ -0,0 +1,41 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{length\_units}---is the length units used for this model. Values can be ``FEET'', ``METERS'', or ``CENTIMETERS''. If not specified, the default is ``UNKNOWN''. + +\item \texttt{NOGRB}---keyword to deactivate writing of the binary grid file. + +\item \texttt{xorigin}---x-position of the lower-left corner of the model grid. A default value of zero is assigned if not specified. The value for XORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +\item \texttt{yorigin}---y-position of the lower-left corner of the model grid. If not specified, then a default value equal to zero is used. The value for YORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +\item \texttt{angrot}---counter-clockwise rotation angle (in degrees) of the lower-left corner of the model grid. If not specified, then a default value of 0.0 is assigned. The value for ANGROT does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +\end{description} +\item \textbf{Block: DIMENSIONS} + +\begin{description} +\item \texttt{nlay}---is the number of layers in the model grid. + +\item \texttt{nrow}---is the number of rows in the model grid. + +\item \texttt{ncol}---is the number of columns in the model grid. + +\end{description} +\item \textbf{Block: GRIDDATA} + +\begin{description} +\item \texttt{delr}---is the column spacing in the row direction. + +\item \texttt{delc}---is the row spacing in the column direction. + +\item \texttt{top}---is the top elevation for each cell in the top model layer. + +\item \texttt{botm}---is the bottom elevation for each cell. + +\item \texttt{idomain}---is an optional array that characterizes the existence status of a cell. If the IDOMAIN array is not specified, then all model cells exist within the solution. If the IDOMAIN value for a cell is 0, the cell does not exist in the simulation. Input and output values will be read and written for the cell, but internal to the program, the cell is excluded from the solution. If the IDOMAIN value for a cell is 1, the cell exists in the simulation. If the IDOMAIN value for a cell is -1, the cell does not exist in the simulation. Furthermore, the first existing cell above will be connected to the first existing cell below. This type of cell is referred to as a ``vertical pass through'' cell. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-dis-dimensions.dat b/doc/mf6io/mf6ivar/tex/gwe-dis-dimensions.dat new file mode 100644 index 00000000000..227d0e1f799 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-dis-dimensions.dat @@ -0,0 +1,5 @@ +BEGIN DIMENSIONS + NLAY + NROW + NCOL +END DIMENSIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-dis-griddata.dat b/doc/mf6io/mf6ivar/tex/gwe-dis-griddata.dat new file mode 100644 index 00000000000..daae94c0ee3 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-dis-griddata.dat @@ -0,0 +1,12 @@ +BEGIN GRIDDATA + DELR + -- READARRAY + DELC + -- READARRAY + TOP + -- READARRAY + BOTM [LAYERED] + -- READARRAY + [IDOMAIN [LAYERED] + -- READARRAY] +END GRIDDATA diff --git a/doc/mf6io/mf6ivar/tex/gwe-dis-options.dat b/doc/mf6io/mf6ivar/tex/gwe-dis-options.dat new file mode 100644 index 00000000000..67e3ed895ae --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-dis-options.dat @@ -0,0 +1,7 @@ +BEGIN OPTIONS + [LENGTH_UNITS ] + [NOGRB] + [XORIGIN ] + [YORIGIN ] + [ANGROT ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-disu-cell2d.dat b/doc/mf6io/mf6ivar/tex/gwe-disu-cell2d.dat new file mode 100644 index 00000000000..27900d67235 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-disu-cell2d.dat @@ -0,0 +1,5 @@ +BEGIN CELL2D + + + ... +END CELL2D diff --git a/doc/mf6io/mf6ivar/tex/gwe-disu-connectiondata.dat b/doc/mf6io/mf6ivar/tex/gwe-disu-connectiondata.dat new file mode 100644 index 00000000000..9623a8be839 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-disu-connectiondata.dat @@ -0,0 +1,14 @@ +BEGIN CONNECTIONDATA + IAC + -- READARRAY + JA + -- READARRAY + IHC + -- READARRAY + CL12 + -- READARRAY + HWVA + -- READARRAY + [ANGLDEGX + -- READARRAY] +END CONNECTIONDATA diff --git a/doc/mf6io/mf6ivar/tex/gwe-disu-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-disu-desc.tex new file mode 100644 index 00000000000..14d67b19f02 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-disu-desc.tex @@ -0,0 +1,81 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{length\_units}---is the length units used for this model. Values can be ``FEET'', ``METERS'', or ``CENTIMETERS''. If not specified, the default is ``UNKNOWN''. + +\item \texttt{NOGRB}---keyword to deactivate writing of the binary grid file. + +\item \texttt{xorigin}---x-position of the origin used for model grid vertices. This value should be provided in a real-world coordinate system. A default value of zero is assigned if not specified. The value for XORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +\item \texttt{yorigin}---y-position of the origin used for model grid vertices. This value should be provided in a real-world coordinate system. If not specified, then a default value equal to zero is used. The value for YORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +\item \texttt{angrot}---counter-clockwise rotation angle (in degrees) of the model grid coordinate system relative to a real-world coordinate system. If not specified, then a default value of 0.0 is assigned. The value for ANGROT does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +\item \texttt{vertical\_offset\_tolerance}---checks are performed to ensure that the top of a cell is not higher than the bottom of an overlying cell. This option can be used to specify the tolerance that is used for checking. If top of a cell is above the bottom of an overlying cell by a value less than this tolerance, then the program will not terminate with an error. The default value is zero. This option should generally not be used. + +\end{description} +\item \textbf{Block: DIMENSIONS} + +\begin{description} +\item \texttt{nodes}---is the number of cells in the model grid. + +\item \texttt{nja}---is the sum of the number of connections and NODES. When calculating the total number of connections, the connection between cell n and cell m is considered to be different from the connection between cell m and cell n. Thus, NJA is equal to the total number of connections, including n to m and m to n, and the total number of cells. + +\item \texttt{nvert}---is the total number of (x, y) vertex pairs used to define the plan-view shape of each cell in the model grid. If NVERT is not specified or is specified as zero, then the VERTICES and CELL2D blocks below are not read. NVERT and the accompanying VERTICES and CELL2D blocks should be specified for most simulations. If the XT3D or SAVE\_SPECIFIC\_DISCHARGE options are specified in the NPF Package, then this information is required. + +\end{description} +\item \textbf{Block: GRIDDATA} + +\begin{description} +\item \texttt{top}---is the top elevation for each cell in the model grid. + +\item \texttt{bot}---is the bottom elevation for each cell. + +\item \texttt{area}---is the cell surface area (in plan view). + +\item \texttt{idomain}---is an optional array that characterizes the existence status of a cell. If the IDOMAIN array is not specified, then all model cells exist within the solution. If the IDOMAIN value for a cell is 0, the cell does not exist in the simulation. Input and output values will be read and written for the cell, but internal to the program, the cell is excluded from the solution. If the IDOMAIN value for a cell is 1 or greater, the cell exists in the simulation. IDOMAIN values of -1 cannot be specified for the DISU Package. + +\end{description} +\item \textbf{Block: CONNECTIONDATA} + +\begin{description} +\item \texttt{iac}---is the number of connections (plus 1) for each cell. The sum of all the entries in IAC must be equal to NJA. + +\item \texttt{ja}---is a list of cell number (n) followed by its connecting cell numbers (m) for each of the m cells connected to cell n. The number of values to provide for cell n is IAC(n). This list is sequentially provided for the first to the last cell. The first value in the list must be cell n itself, and the remaining cells must be listed in an increasing order (sorted from lowest number to highest). Note that the cell and its connections are only supplied for the GWE cells and their connections to the other GWE cells. Also note that the JA list input may be divided such that every node and its connectivity list can be on a separate line for ease in readability of the file. To further ease readability of the file, the node number of the cell whose connectivity is subsequently listed, may be expressed as a negative number, the sign of which is subsequently converted to positive by the code. + +\item \texttt{ihc}---is an index array indicating the direction between node n and all of its m connections. If IHC = 0 then cell n and cell m are connected in the vertical direction. Cell n overlies cell m if the cell number for n is less than m; cell m overlies cell n if the cell number for m is less than n. If IHC = 1 then cell n and cell m are connected in the horizontal direction. If IHC = 2 then cell n and cell m are connected in the horizontal direction, and the connection is vertically staggered. A vertically staggered connection is one in which a cell is horizontally connected to more than one cell in a horizontal connection. + +\item \texttt{cl12}---is the array containing connection lengths between the center of cell n and the shared face with each adjacent m cell. + +\item \texttt{hwva}---is a symmetric array of size NJA. For horizontal connections, entries in HWVA are the horizontal width perpendicular to flow. For vertical connections, entries in HWVA are the vertical area for flow. Thus, values in the HWVA array contain dimensions of both length and area. Entries in the HWVA array have a one-to-one correspondence with the connections specified in the JA array. Likewise, there is a one-to-one correspondence between entries in the HWVA array and entries in the IHC array, which specifies the connection type (horizontal or vertical). Entries in the HWVA array must be symmetric; the program will terminate with an error if the value for HWVA for an n to m connection does not equal the value for HWVA for the corresponding n to m connection. + +\item \texttt{angldegx}---is the angle (in degrees) between the horizontal x-axis and the outward normal to the face between a cell and its connecting cells. The angle varies between zero and 360.0 degrees, where zero degrees points in the positive x-axis direction, and 90 degrees points in the positive y-axis direction. ANGLDEGX is only needed if horizontal anisotropy is specified in the NPF Package, if the XT3D option is used in the NPF Package, or if the SAVE\_SPECIFIC\_DISCHARGE option is specifed in the NPF Package. ANGLDEGX does not need to be specified if these conditions are not met. ANGLDEGX is of size NJA; values specified for vertical connections and for the diagonal position are not used. Note that ANGLDEGX is read in degrees, which is different from MODFLOW-USG, which reads a similar variable (ANGLEX) in radians. + +\end{description} +\item \textbf{Block: VERTICES} + +\begin{description} +\item \texttt{iv}---is the vertex number. Records in the VERTICES block must be listed in consecutive order from 1 to NVERT. + +\item \texttt{xv}---is the x-coordinate for the vertex. + +\item \texttt{yv}---is the y-coordinate for the vertex. + +\end{description} +\item \textbf{Block: CELL2D} + +\begin{description} +\item \texttt{icell2d}---is the cell2d number. Records in the CELL2D block must be listed in consecutive order from 1 to NODES. + +\item \texttt{xc}---is the x-coordinate for the cell center. + +\item \texttt{yc}---is the y-coordinate for the cell center. + +\item \texttt{ncvert}---is the number of vertices required to define the cell. There may be a different number of vertices for each cell. + +\item \texttt{icvert}---is an array of integer values containing vertex numbers (in the VERTICES block) used to define the cell. Vertices must be listed in clockwise order. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-disu-dimensions.dat b/doc/mf6io/mf6ivar/tex/gwe-disu-dimensions.dat new file mode 100644 index 00000000000..56d54756a40 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-disu-dimensions.dat @@ -0,0 +1,5 @@ +BEGIN DIMENSIONS + NODES + NJA + [NVERT ] +END DIMENSIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-disu-griddata.dat b/doc/mf6io/mf6ivar/tex/gwe-disu-griddata.dat new file mode 100644 index 00000000000..2978f43b84e --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-disu-griddata.dat @@ -0,0 +1,10 @@ +BEGIN GRIDDATA + TOP + -- READARRAY + BOT + -- READARRAY + AREA + -- READARRAY + [IDOMAIN + -- READARRAY] +END GRIDDATA diff --git a/doc/mf6io/mf6ivar/tex/gwe-disu-options.dat b/doc/mf6io/mf6ivar/tex/gwe-disu-options.dat new file mode 100644 index 00000000000..281b79a4a27 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-disu-options.dat @@ -0,0 +1,8 @@ +BEGIN OPTIONS + [LENGTH_UNITS ] + [NOGRB] + [XORIGIN ] + [YORIGIN ] + [ANGROT ] + [VERTICAL_OFFSET_TOLERANCE ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-disu-vertices.dat b/doc/mf6io/mf6ivar/tex/gwe-disu-vertices.dat new file mode 100644 index 00000000000..6831f23b5ff --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-disu-vertices.dat @@ -0,0 +1,5 @@ +BEGIN VERTICES + + + ... +END VERTICES diff --git a/doc/mf6io/mf6ivar/tex/gwe-disv-cell2d.dat b/doc/mf6io/mf6ivar/tex/gwe-disv-cell2d.dat new file mode 100644 index 00000000000..27900d67235 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-disv-cell2d.dat @@ -0,0 +1,5 @@ +BEGIN CELL2D + + + ... +END CELL2D diff --git a/doc/mf6io/mf6ivar/tex/gwe-disv-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-disv-desc.tex new file mode 100644 index 00000000000..dac7917328f --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-disv-desc.tex @@ -0,0 +1,61 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{length\_units}---is the length units used for this model. Values can be ``FEET'', ``METERS'', or ``CENTIMETERS''. If not specified, the default is ``UNKNOWN''. + +\item \texttt{NOGRB}---keyword to deactivate writing of the binary grid file. + +\item \texttt{xorigin}---x-position of the origin used for model grid vertices. This value should be provided in a real-world coordinate system. A default value of zero is assigned if not specified. The value for XORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +\item \texttt{yorigin}---y-position of the origin used for model grid vertices. This value should be provided in a real-world coordinate system. If not specified, then a default value equal to zero is used. The value for YORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +\item \texttt{angrot}---counter-clockwise rotation angle (in degrees) of the model grid coordinate system relative to a real-world coordinate system. If not specified, then a default value of 0.0 is assigned. The value for ANGROT does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. + +\end{description} +\item \textbf{Block: DIMENSIONS} + +\begin{description} +\item \texttt{nlay}---is the number of layers in the model grid. + +\item \texttt{ncpl}---is the number of cells per layer. This is a constant value for the grid and it applies to all layers. + +\item \texttt{nvert}---is the total number of (x, y) vertex pairs used to characterize the horizontal configuration of the model grid. + +\end{description} +\item \textbf{Block: GRIDDATA} + +\begin{description} +\item \texttt{top}---is the top elevation for each cell in the top model layer. + +\item \texttt{botm}---is the bottom elevation for each cell. + +\item \texttt{idomain}---is an optional array that characterizes the existence status of a cell. If the IDOMAIN array is not specified, then all model cells exist within the solution. If the IDOMAIN value for a cell is 0, the cell does not exist in the simulation. Input and output values will be read and written for the cell, but internal to the program, the cell is excluded from the solution. If the IDOMAIN value for a cell is 1, the cell exists in the simulation. If the IDOMAIN value for a cell is -1, the cell does not exist in the simulation. Furthermore, the first existing cell above will be connected to the first existing cell below. This type of cell is referred to as a ``vertical pass through'' cell. + +\end{description} +\item \textbf{Block: VERTICES} + +\begin{description} +\item \texttt{iv}---is the vertex number. Records in the VERTICES block must be listed in consecutive order from 1 to NVERT. + +\item \texttt{xv}---is the x-coordinate for the vertex. + +\item \texttt{yv}---is the y-coordinate for the vertex. + +\end{description} +\item \textbf{Block: CELL2D} + +\begin{description} +\item \texttt{icell2d}---is the CELL2D number. Records in the CELL2D block must be listed in consecutive order from the first to the last. + +\item \texttt{xc}---is the x-coordinate for the cell center. + +\item \texttt{yc}---is the y-coordinate for the cell center. + +\item \texttt{ncvert}---is the number of vertices required to define the cell. There may be a different number of vertices for each cell. + +\item \texttt{icvert}---is an array of integer values containing vertex numbers (in the VERTICES block) used to define the cell. Vertices must be listed in clockwise order. Cells that are connected must share vertices. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-disv-dimensions.dat b/doc/mf6io/mf6ivar/tex/gwe-disv-dimensions.dat new file mode 100644 index 00000000000..b05791a77b3 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-disv-dimensions.dat @@ -0,0 +1,5 @@ +BEGIN DIMENSIONS + NLAY + NCPL + NVERT +END DIMENSIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-disv-griddata.dat b/doc/mf6io/mf6ivar/tex/gwe-disv-griddata.dat new file mode 100644 index 00000000000..e263cb1d7bb --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-disv-griddata.dat @@ -0,0 +1,8 @@ +BEGIN GRIDDATA + TOP + -- READARRAY + BOTM [LAYERED] + -- READARRAY + [IDOMAIN [LAYERED] + -- READARRAY] +END GRIDDATA diff --git a/doc/mf6io/mf6ivar/tex/gwe-disv-options.dat b/doc/mf6io/mf6ivar/tex/gwe-disv-options.dat new file mode 100644 index 00000000000..67e3ed895ae --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-disv-options.dat @@ -0,0 +1,7 @@ +BEGIN OPTIONS + [LENGTH_UNITS ] + [NOGRB] + [XORIGIN ] + [YORIGIN ] + [ANGROT ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-disv-vertices.dat b/doc/mf6io/mf6ivar/tex/gwe-disv-vertices.dat new file mode 100644 index 00000000000..6831f23b5ff --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-disv-vertices.dat @@ -0,0 +1,5 @@ +BEGIN VERTICES + + + ... +END VERTICES diff --git a/doc/mf6io/mf6ivar/tex/gwe-dsp-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-dsp-desc.tex new file mode 100644 index 00000000000..c1d37b1c117 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-dsp-desc.tex @@ -0,0 +1,29 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{XT3D\_OFF}---deactivate the xt3d method and use the faster and less accurate approximation. This option may provide a fast and accurate solution under some circumstances, such as when flow aligns with the model grid, there is no mechanical dispersion, or when the longitudinal and transverse dispersivities are equal. This option may also be used to assess the computational demand of the XT3D approach by noting the run time differences with and without this option on. + +\item \texttt{XT3D\_RHS}---add xt3d terms to right-hand side, when possible. This option uses less memory, but may require more iterations. + +\end{description} +\item \textbf{Block: GRIDDATA} + +\begin{description} +\item \texttt{alh}---longitudinal dispersivity in horizontal direction. If flow is strictly horizontal, then this is the longitudinal dispersivity that will be used. If flow is not strictly horizontal or strictly vertical, then the longitudinal dispersivity is a function of both ALH and ALV. If mechanical dispersion is represented (by specifying any dispersivity values) then this array is required. + +\item \texttt{alv}---longitudinal dispersivity in vertical direction. If flow is strictly vertical, then this is the longitudinal dispsersivity value that will be used. If flow is not strictly horizontal or strictly vertical, then the longitudinal dispersivity is a function of both ALH and ALV. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ALH. + +\item \texttt{ath1}---transverse dispersivity in horizontal direction. This is the transverse dispersivity value for the second ellipsoid axis. If flow is strictly horizontal and directed in the x direction (along a row for a regular grid), then this value controls spreading in the y direction. If mechanical dispersion is represented (by specifying any dispersivity values) then this array is required. + +\item \texttt{ath2}---transverse dispersivity in horizontal direction. This is the transverse dispersivity value for the third ellipsoid axis. If flow is strictly horizontal and directed in the x direction (along a row for a regular grid), then this value controls spreading in the z direction. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ATH1. + +\item \texttt{atv}---transverse dispersivity when flow is in vertical direction. If flow is strictly vertical and directed in the z direction, then this value controls spreading in the x and y directions. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ATH2. + +\item \texttt{ktw}---thermal conductivity of the simulated fluid + +\item \texttt{kts}---thermal conductivity of the aquifer material + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-dsp-griddata.dat b/doc/mf6io/mf6ivar/tex/gwe-dsp-griddata.dat new file mode 100644 index 00000000000..ea8514e771b --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-dsp-griddata.dat @@ -0,0 +1,16 @@ +BEGIN GRIDDATA + [ALH [LAYERED] + -- READARRAY] + [ALV [LAYERED] + -- READARRAY] + [ATH1 [LAYERED] + -- READARRAY] + [ATH2 [LAYERED] + -- READARRAY] + [ATV [LAYERED] + -- READARRAY] + [KTW [LAYERED] + -- READARRAY] + [KTS [LAYERED] + -- READARRAY] +END GRIDDATA diff --git a/doc/mf6io/mf6ivar/tex/gwe-dsp-options.dat b/doc/mf6io/mf6ivar/tex/gwe-dsp-options.dat new file mode 100644 index 00000000000..8fd75f9d224 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-dsp-options.dat @@ -0,0 +1,4 @@ +BEGIN OPTIONS + [XT3D_OFF] + [XT3D_RHS] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-fmi-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-fmi-desc.tex new file mode 100644 index 00000000000..b9279ac8597 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-fmi-desc.tex @@ -0,0 +1,21 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{SAVE\_FLOWS}---keyword to indicate that FMI flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. + +\item \texttt{FLOW\_IMBALANCE\_CORRECTION}---correct for an imbalance in flows by assuming that any residual flow error comes in or leaves at the temperature of the cell. When this option is activated, the GWE Model budget written to the listing file will contain two additional entries: FLOW-ERROR and FLOW-CORRECTION. These two entries will be equal but opposite in sign. The FLOW-CORRECTION term is a mass flow that is added to offset the error caused by an imprecise flow balance. If these terms are not relatively small, the flow model should be rerun with stricter convergence tolerances. + +\end{description} +\item \textbf{Block: PACKAGEDATA} + +\begin{description} +\item \texttt{flowtype}---is the word GWFBUDGET, GWFHEAD, GWFMOVER or the name of an advanced GWF stress package. If GWFBUDGET is specified, then the corresponding file must be a budget file from a previous GWF Model run. If an advanced GWF stress package name appears then the corresponding file must be the budget file saved by a LAK, SFR, MAW or UZF Package. + +\item \texttt{FILEIN}---keyword to specify that an input filename is expected next. + +\item \texttt{fname}---is the name of the file containing flows. The path to the file should be included if the file is not located in the folder where the program was run. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-fmi-options.dat b/doc/mf6io/mf6ivar/tex/gwe-fmi-options.dat new file mode 100644 index 00000000000..d5ceb2575c8 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-fmi-options.dat @@ -0,0 +1,4 @@ +BEGIN OPTIONS + [SAVE_FLOWS] + [FLOW_IMBALANCE_CORRECTION] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-fmi-packagedata.dat b/doc/mf6io/mf6ivar/tex/gwe-fmi-packagedata.dat new file mode 100644 index 00000000000..85d840ad9ef --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-fmi-packagedata.dat @@ -0,0 +1,5 @@ +BEGIN PACKAGEDATA + FILEIN + FILEIN + ... +END PACKAGEDATA diff --git a/doc/mf6io/mf6ivar/tex/gwe-ic-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-ic-desc.tex new file mode 100644 index 00000000000..7cf8d73b07a --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-ic-desc.tex @@ -0,0 +1,9 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: GRIDDATA} + +\begin{description} +\item \texttt{strt}---is the initial (starting) temperature---that is, the temperature at the beginning of the GWE Model simulation. STRT must be specified for all GWE Model simulations. One value is read for every model cell. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-ic-griddata.dat b/doc/mf6io/mf6ivar/tex/gwe-ic-griddata.dat new file mode 100644 index 00000000000..260626850a7 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-ic-griddata.dat @@ -0,0 +1,4 @@ +BEGIN GRIDDATA + STRT [LAYERED] + -- READARRAY +END GRIDDATA diff --git a/doc/mf6io/mf6ivar/tex/gwe-mst-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-mst-desc.tex new file mode 100644 index 00000000000..4bc66c85094 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-mst-desc.tex @@ -0,0 +1,35 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{SAVE\_FLOWS}---keyword to indicate that MST flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. + +\item \texttt{ZERO\_ORDER\_DECAY}---is a text keyword to indicate that zero-order decay will occur. Use of this keyword requires that DECAY and DECAY\_SORBED (if sorption is active) are specified in the GRIDDATA block. + +\item \texttt{LATENT\_HEAT\_VAPORIZATION}---is a text keyword to indicate that cooling associated with evaporation will occur. Use of this keyword requires that LATHEATVAP are specified in the GRIDDATA block. While the MST package does not simulate evaporation, multiple other packages in a GWE simulation may. For example, evaporation may occur from the surface of streams or lakes. Owing to the energy consumed by the change in phase, the latent heat of vaporization is required. + +\end{description} +\item \textbf{Block: GRIDDATA} + +\begin{description} +\item \texttt{porosity}---is the mobile domain porosity, defined as the mobile domain pore volume per mobile domain volume. The GWE model does not support the concept of an immobile domain in the context of heat transport. + +\item \texttt{decay}---is the rate coefficient for zero-order decay for the aqueous phase of the mobile domain. A negative value indicates heat (energy) production. The dimensions of decay for zero-order decay is energy per length cubed per time. Zero-order decay will have no effect on simulation results unless zero-order decay is specified in the options block. + +\item \texttt{cps}---is the mass-based heat capacity of dry solids (aquifer material). For example, units of J/kg/C may be used (or equivalent). + +\item \texttt{rhos}---is a user-specified value of the density of aquifer material not considering the voids. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. + +\end{description} +\item \textbf{Block: PACKAGEDATA} + +\begin{description} +\item \texttt{cpw}---is the mass-based heat capacity of the simulated fluid. For example, units of J/kg/C may be used (or equivalent). + +\item \texttt{rhow}---is a user-specified value of the density of water. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. + +\item \texttt{latheatvap}---is the user-specified value for the latent heat of vaporization. For example, if working in SI units, values may be entered as kJ/kg. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-mst-griddata.dat b/doc/mf6io/mf6ivar/tex/gwe-mst-griddata.dat new file mode 100644 index 00000000000..b67c69b58c4 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-mst-griddata.dat @@ -0,0 +1,10 @@ +BEGIN GRIDDATA + POROSITY [LAYERED] + -- READARRAY + [DECAY [LAYERED] + -- READARRAY] + CPS [LAYERED] + -- READARRAY + RHOS [LAYERED] + -- READARRAY +END GRIDDATA diff --git a/doc/mf6io/mf6ivar/tex/gwe-mst-options.dat b/doc/mf6io/mf6ivar/tex/gwe-mst-options.dat new file mode 100644 index 00000000000..4b459df2f8f --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-mst-options.dat @@ -0,0 +1,5 @@ +BEGIN OPTIONS + [SAVE_FLOWS] + [ZERO_ORDER_DECAY] + [LATENT_HEAT_VAPORIZATION] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-mst-packagedata.dat b/doc/mf6io/mf6ivar/tex/gwe-mst-packagedata.dat new file mode 100644 index 00000000000..d94a5a61d14 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-mst-packagedata.dat @@ -0,0 +1,5 @@ +BEGIN PACKAGEDATA + + + ... +END PACKAGEDATA diff --git a/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex new file mode 100644 index 00000000000..b464804151c --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex @@ -0,0 +1,25 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{list}---is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the '.lst' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. + +\item \texttt{PRINT\_INPUT}---keyword to indicate that the list of all model stress package information will be written to the listing file immediately after it is read. + +\item \texttt{PRINT\_FLOWS}---keyword to indicate that the list of all model package flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. + +\item \texttt{SAVE\_FLOWS}---keyword to indicate that all model package flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. + +\end{description} +\item \textbf{Block: PACKAGES} + +\begin{description} +\item \texttt{ftype}---is the file type, which must be one of the following character values shown in table~\ref{table:ftype}. Ftype may be entered in any combination of uppercase and lowercase. + +\item \texttt{fname}---is the name of the file containing the package input. The path to the file should be included if the file is not located in the folder where the program was run. + +\item \texttt{pname}---is the user-defined name for the package. PNAME is restricted to 16 characters. No spaces are allowed in PNAME. PNAME character values are read and stored by the program for stress packages only. These names may be useful for labeling purposes when multiple stress packages of the same type are located within a single GWE Model. If PNAME is specified for a stress package, then PNAME will be used in the flow budget table in the listing file; it will also be used for the text entry in the cell-by-cell budget file. PNAME is case insensitive and is stored in all upper case letters. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-nam-options.dat b/doc/mf6io/mf6ivar/tex/gwe-nam-options.dat new file mode 100644 index 00000000000..a65ebd5e24d --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-nam-options.dat @@ -0,0 +1,6 @@ +BEGIN OPTIONS + [LIST ] + [PRINT_INPUT] + [PRINT_FLOWS] + [SAVE_FLOWS] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-nam-packages.dat b/doc/mf6io/mf6ivar/tex/gwe-nam-packages.dat new file mode 100644 index 00000000000..ee5dc814ee7 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-nam-packages.dat @@ -0,0 +1,5 @@ +BEGIN PACKAGES + [] + [] + ... +END PACKAGES diff --git a/doc/mf6io/mf6ivar/tex/gwe-oc-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-oc-desc.tex new file mode 100644 index 00000000000..5cf6ff3a1d4 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-oc-desc.tex @@ -0,0 +1,63 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{BUDGET}---keyword to specify that record corresponds to the budget. + +\item \texttt{FILEOUT}---keyword to specify that an output filename is expected next. + +\item \texttt{budgetfile}---name of the output file to write budget information. + +\item \texttt{BUDGETCSV}---keyword to specify that record corresponds to the budget CSV. + +\item \texttt{budgetcsvfile}---name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. + +\item \texttt{TEMPERATURE}---keyword to specify that record corresponds to temperature. + +\item \texttt{temperaturefile}---name of the output file to write conc information. + +\item \texttt{PRINT\_FORMAT}---keyword to specify format for printing to the listing file. + +\item \texttt{columns}---number of columns for writing data. + +\item \texttt{width}---width for writing each number. + +\item \texttt{digits}---number of digits to use for writing a number. + +\item \texttt{format}---write format can be EXPONENTIAL, FIXED, GENERAL, or SCIENTIFIC. + +\end{description} +\item \textbf{Block: PERIOD} + +\begin{description} +\item \texttt{iper}---integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. + +\item \texttt{SAVE}---keyword to indicate that information will be saved this stress period. + +\item \texttt{PRINT}---keyword to indicate that information will be printed this stress period. + +\item \texttt{rtype}---type of information to save or print. Can be BUDGET or TEMPERATURE. + +\item \texttt{ocsetting}---specifies the steps for which the data will be saved. + +\begin{lstlisting}[style=blockdefinition] +ALL +FIRST +LAST +FREQUENCY +STEPS +\end{lstlisting} + +\item \texttt{ALL}---keyword to indicate save for all time steps in period. + +\item \texttt{FIRST}---keyword to indicate save for first step in period. This keyword may be used in conjunction with other keywords to print or save results for multiple time steps. + +\item \texttt{LAST}---keyword to indicate save for last step in period. This keyword may be used in conjunction with other keywords to print or save results for multiple time steps. + +\item \texttt{frequency}---save at the specified time step frequency. This keyword may be used in conjunction with other keywords to print or save results for multiple time steps. + +\item \texttt{steps}---save for each step specified in STEPS. This keyword may be used in conjunction with other keywords to print or save results for multiple time steps. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-oc-options.dat b/doc/mf6io/mf6ivar/tex/gwe-oc-options.dat new file mode 100644 index 00000000000..aedf37e5832 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-oc-options.dat @@ -0,0 +1,6 @@ +BEGIN OPTIONS + [BUDGET FILEOUT ] + [BUDGETCSV FILEOUT ] + [TEMPERATURE FILEOUT ] + [TEMPERATURE PRINT_FORMAT COLUMNS WIDTH DIGITS ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-oc-period.dat b/doc/mf6io/mf6ivar/tex/gwe-oc-period.dat new file mode 100644 index 00000000000..abcceee3794 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-oc-period.dat @@ -0,0 +1,4 @@ +BEGIN PERIOD + [SAVE ] + [PRINT ] +END PERIOD diff --git a/doc/mf6io/mf6ivar/tex/gwe-ssm-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-ssm-desc.tex new file mode 100644 index 00000000000..41ce8867b95 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-ssm-desc.tex @@ -0,0 +1,35 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{PRINT\_FLOWS}---keyword to indicate that the list of SSM flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. + +\item \texttt{SAVE\_FLOWS}---keyword to indicate that SSM flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. + +\end{description} +\item \textbf{Block: SOURCES} + +\begin{description} +\item \texttt{pname}---name of the flow package for which an auxiliary variable contains a source temperature. If this flow package is represented using an advanced transport package (SFE, LKE, MWE, or UZE), then the advanced transport package will override SSM terms specified here. + +\item \texttt{srctype}---keyword indicating how temperature will be assigned for sources and sinks. Keyword must be specified as either AUX or AUXMIXED. For both options the user must provide an auxiliary variable in the corresponding flow package. The auxiliary variable must have the same name as the AUXNAME value that follows. If the AUX keyword is specified, then the auxiliary variable specified by the user will be assigned as the concenration value for groundwater sources (flows with a positive sign). For negative flow rates (sinks), groundwater will be withdrawn from the cell at the simulated temperature of the cell. The AUXMIXED option provides an alternative method for how to determine the temperature of sinks. If the cell temperature is larger than the user-specified auxiliary temperature, then the temperature of groundwater withdrawn from the cell will be assigned as the user-specified temperature. Alternatively, if the user-specified auxiliary temperature is larger than the cell temperature, then groundwater will be withdrawn at the cell temperature. Thus, the AUXMIXED option is designed to work with the Evapotranspiration (EVT) and Recharge (RCH) Packages where water may be withdrawn at a temperature that is less than the cell temperature. + +\item \texttt{auxname}---name of the auxiliary variable in the package PNAME. This auxiliary variable must exist and be specified by the user in that package. The values in this auxiliary variable will be used to set the temperature associated with the flows for that boundary package. + +\end{description} +\item \textbf{Block: FILEINPUT} + +\begin{description} +\item \texttt{pname}---name of the flow package for which an SPT6 input file contains a source temperature. If this flow package is represented using an advanced transport package (SFE, LKE, MWE, or UZE), then the advanced transport package will override SSM terms specified here. + +\item \texttt{SPT6}---keyword to specify that record corresponds to a source sink mixing input file. + +\item \texttt{FILEIN}---keyword to specify that an input filename is expected next. + +\item \texttt{spt6\_filename}---character string that defines the path and filename for the file containing source and sink input data for the flow package. The SPT6\_FILENAME file is a flexible input file that allows temperatures to be specified by stress period and with time series. Instructions for creating the SPT6\_FILENAME input file are provided in the next section on file input for boundary temperatures. + +\item \texttt{MIXED}---keyword to specify that these stress package boundaries will have the mixed condition. The MIXED condition is described in the SOURCES block for AUXMIXED. The MIXED condition allows for water to be withdrawn at a temperature that is less than the cell temperature. It is intended primarily for representing evapotranspiration. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-ssm-fileinput.dat b/doc/mf6io/mf6ivar/tex/gwe-ssm-fileinput.dat new file mode 100644 index 00000000000..9f931f3daf3 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-ssm-fileinput.dat @@ -0,0 +1,5 @@ +BEGIN FILEINPUT + SPT6 FILEIN [MIXED] + SPT6 FILEIN [MIXED] + ... +END FILEINPUT diff --git a/doc/mf6io/mf6ivar/tex/gwe-ssm-options.dat b/doc/mf6io/mf6ivar/tex/gwe-ssm-options.dat new file mode 100644 index 00000000000..de7ccf03076 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-ssm-options.dat @@ -0,0 +1,4 @@ +BEGIN OPTIONS + [PRINT_FLOWS] + [SAVE_FLOWS] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-ssm-sources.dat b/doc/mf6io/mf6ivar/tex/gwe-ssm-sources.dat new file mode 100644 index 00000000000..82557990b00 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-ssm-sources.dat @@ -0,0 +1,5 @@ +BEGIN SOURCES + + + ... +END SOURCES diff --git a/doc/mf6io/mf6ivar/tex/utl-spt-desc.tex b/doc/mf6io/mf6ivar/tex/utl-spt-desc.tex new file mode 100644 index 00000000000..5dcfc20c51e --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/utl-spt-desc.tex @@ -0,0 +1,37 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{PRINT\_INPUT}---keyword to indicate that the list of spt information will be written to the listing file immediately after it is read. + +\item \texttt{TS6}---keyword to specify that record corresponds to a time-series file. + +\item \texttt{FILEIN}---keyword to specify that an input filename is expected next. + +\item \texttt{ts6\_filename}---defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. + +\end{description} +\item \textbf{Block: DIMENSIONS} + +\begin{description} +\item \texttt{maxbound}---integer value specifying the maximum number of spt cells that will be specified for use during any stress period. + +\end{description} +\item \textbf{Block: PERIOD} + +\begin{description} +\item \texttt{iper}---integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. + +\item \texttt{bndno}---integer value that defines the boundary package feature number associated with the specified PERIOD data on the line. BNDNO must be greater than zero and less than or equal to MAXBOUND. + +\item \texttt{sptsetting}---line of information that is parsed into a keyword and values. Keyword values that can be used to start the SPTSETTING string include: TEMPERATURE. + +\begin{lstlisting}[style=blockdefinition] +TEMPERATURE <@temperature@> +\end{lstlisting} + +\item \textcolor{blue}{\texttt{temperature}---is the boundary temperature. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. By default, the TEMPERATURE for each boundary feature is zero.} + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/utl-spt-dimensions.dat b/doc/mf6io/mf6ivar/tex/utl-spt-dimensions.dat new file mode 100644 index 00000000000..7b4c7bf6ec7 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/utl-spt-dimensions.dat @@ -0,0 +1,3 @@ +BEGIN DIMENSIONS + MAXBOUND +END DIMENSIONS diff --git a/doc/mf6io/mf6ivar/tex/utl-spt-options.dat b/doc/mf6io/mf6ivar/tex/utl-spt-options.dat new file mode 100644 index 00000000000..1bbdfe99d14 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/utl-spt-options.dat @@ -0,0 +1,4 @@ +BEGIN OPTIONS + [PRINT_INPUT] + [TS6 FILEIN ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/utl-spt-period.dat b/doc/mf6io/mf6ivar/tex/utl-spt-period.dat new file mode 100644 index 00000000000..c2c27b1895c --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/utl-spt-period.dat @@ -0,0 +1,5 @@ +BEGIN PERIOD + + + ... +END PERIOD diff --git a/doc/mf6io/mf6ivar/tex/utl-spta-desc.tex b/doc/mf6io/mf6ivar/tex/utl-spta-desc.tex new file mode 100644 index 00000000000..819633c49b6 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/utl-spta-desc.tex @@ -0,0 +1,25 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{READASARRAYS}---indicates that array-based input will be used for the SPT Package. This keyword must be specified to use array-based input. + +\item \texttt{PRINT\_INPUT}---keyword to indicate that the list of spt information will be written to the listing file immediately after it is read. + +\item \texttt{TAS6}---keyword to specify that record corresponds to a time-array-series file. + +\item \texttt{FILEIN}---keyword to specify that an input filename is expected next. + +\item \texttt{tas6\_filename}---defines a time-array-series file defining a time-array series that can be used to assign time-varying values. See the Time-Variable Input section for instructions on using the time-array series capability. + +\end{description} +\item \textbf{Block: PERIOD} + +\begin{description} +\item \texttt{iper}---integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. + +\item \texttt{temperature}---is the temperature of the associated Recharge or Evapotranspiration stress package. The temperature array may be defined by a time-array series (see the "Using Time-Array Series in a Package" section). + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/utl-spta-options.dat b/doc/mf6io/mf6ivar/tex/utl-spta-options.dat new file mode 100644 index 00000000000..33922d8eaa7 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/utl-spta-options.dat @@ -0,0 +1,5 @@ +BEGIN OPTIONS + READASARRAYS + [PRINT_INPUT] + [TAS6 FILEIN ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/utl-spta-period.dat b/doc/mf6io/mf6ivar/tex/utl-spta-period.dat new file mode 100644 index 00000000000..4f3a67077fb --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/utl-spta-period.dat @@ -0,0 +1,4 @@ +BEGIN PERIOD + TEMPERATURE + -- READARRAY +END PERIOD diff --git a/doc/mf6io/obs/obs-gwe.tex b/doc/mf6io/obs/obs-gwe.tex new file mode 100644 index 00000000000..e1f8d191dd5 --- /dev/null +++ b/doc/mf6io/obs/obs-gwe.tex @@ -0,0 +1,7 @@ +Observations are available for GWE models and GWE stress packages. Available observation types have been listed for each package that supports observations (tables~\ref{table:gweobstype} to~\ref{table:gwe-cntobstype}). All available observation types are repeated in Table~\ref{table:gwe-obstypetable} for convenience. + +The sign convention adopted for transport observations are identical to the conventions used in budgets contained in listing files and used in the cell-by-cell budget output. For flow-ja-face observation types, negative and positive values represent a loss from and gain to the cellid specified for ID, respectively. For standard stress packages, negative and positive values represent a loss from and gain to the GWE model, respectively. For advanced transport packages (Package = LKE, MWE, SFE, and UZE), negative and positive values for exchanges with the GWE model (Observation type = lke, mwe, sfe, and uze) represent a loss from and gain to the GWE model, respectively. For other advanced stress package flow terms, negative and positive values represent a loss from and gain from the advanced package, respectively. + +\FloatBarrier +\input{../Common/gwe-obstypetable} +\FloatBarrier diff --git a/doc/mf6io/obs/obs.tex b/doc/mf6io/obs/obs.tex index d3223c62f80..618f6cdff95 100644 --- a/doc/mf6io/obs/obs.tex +++ b/doc/mf6io/obs/obs.tex @@ -33,3 +33,5 @@ \subsubsection{GWF Observations} \subsubsection{GWT Observations} \input{./obs/obs-gwt.tex} +\subsubsection{GWE Observations} +\input{./obs/obs-gwe.tex} diff --git a/make/makefile b/make/makefile index 229db4c9bc3..45a7b832d4c 100644 --- a/make/makefile +++ b/make/makefile @@ -1,40 +1,41 @@ -# makefile created by pymake (version 1.2.9.dev0) for the 'mf6' executable. +# makefile created by pymake (version 1.2.7) for the 'mf6' executable. include ./makedefaults # Define the source file directories SOURCEDIR1=../src -SOURCEDIR2=../src/Exchange -SOURCEDIR3=../src/Timing +SOURCEDIR2=../src/Distributed +SOURCEDIR3=../src/Exchange SOURCEDIR4=../src/Model SOURCEDIR5=../src/Model/Connection -SOURCEDIR6=../src/Model/ModelUtilities -SOURCEDIR7=../src/Model/GroundWaterFlow -SOURCEDIR8=../src/Model/Geometry -SOURCEDIR9=../src/Model/TransportModel -SOURCEDIR10=../src/Model/GroundWaterTransport -SOURCEDIR11=../src/Solution -SOURCEDIR12=../src/Solution/LinearMethods -SOURCEDIR13=../src/Solution/PETSc -SOURCEDIR14=../src/Distributed -SOURCEDIR15=../src/Utilities -SOURCEDIR16=../src/Utilities/TimeSeries -SOURCEDIR17=../src/Utilities/Idm -SOURCEDIR18=../src/Utilities/Idm/selector +SOURCEDIR6=../src/Model/Geometry +SOURCEDIR7=../src/Model/GroundWaterEnergy +SOURCEDIR8=../src/Model/GroundWaterFlow +SOURCEDIR9=../src/Model/GroundWaterTransport +SOURCEDIR10=../src/Model/ModelUtilities +SOURCEDIR11=../src/Model/TransportModel +SOURCEDIR12=../src/Solution +SOURCEDIR13=../src/Solution/LinearMethods +SOURCEDIR14=../src/Solution/PETSc +SOURCEDIR15=../src/Timing +SOURCEDIR16=../src/Utilities +SOURCEDIR17=../src/Utilities/ArrayRead +SOURCEDIR18=../src/Utilities/Idm SOURCEDIR19=../src/Utilities/Idm/mf6blockfile -SOURCEDIR20=../src/Utilities/ArrayRead -SOURCEDIR21=../src/Utilities/Memory -SOURCEDIR22=../src/Utilities/Matrix -SOURCEDIR23=../src/Utilities/Vector -SOURCEDIR24=../src/Utilities/Observation -SOURCEDIR25=../src/Utilities/OutputControl -SOURCEDIR26=../src/Utilities/Libraries -SOURCEDIR27=../src/Utilities/Libraries/rcm -SOURCEDIR28=../src/Utilities/Libraries/sparskit2 -SOURCEDIR29=../src/Utilities/Libraries/sparsekit -SOURCEDIR30=../src/Utilities/Libraries/blas -SOURCEDIR31=../src/Utilities/Libraries/daglib +SOURCEDIR20=../src/Utilities/Idm/selector +SOURCEDIR21=../src/Utilities/Libraries +SOURCEDIR22=../src/Utilities/Libraries/blas +SOURCEDIR23=../src/Utilities/Libraries/daglib +SOURCEDIR24=../src/Utilities/Libraries/rcm +SOURCEDIR25=../src/Utilities/Libraries/sparsekit +SOURCEDIR26=../src/Utilities/Libraries/sparskit2 +SOURCEDIR27=../src/Utilities/Matrix +SOURCEDIR28=../src/Utilities/Memory +SOURCEDIR29=../src/Utilities/Observation +SOURCEDIR30=../src/Utilities/OutputControl +SOURCEDIR31=../src/Utilities/TimeSeries +SOURCEDIR32=../src/Utilities/Vector VPATH = \ ${SOURCEDIR1} \ @@ -67,7 +68,8 @@ ${SOURCEDIR27} \ ${SOURCEDIR28} \ ${SOURCEDIR29} \ ${SOURCEDIR30} \ -${SOURCEDIR31} +${SOURCEDIR31} \ +${SOURCEDIR32} .SUFFIXES: .f90 .F90 .o @@ -115,6 +117,13 @@ $(OBJDIR)/gwf3disv8idm.o \ $(OBJDIR)/gwf3disu8idm.o \ $(OBJDIR)/gwf3dis8idm.o \ $(OBJDIR)/gwf3chd8idm.o \ +$(OBJDIR)/gwe1idm.o \ +$(OBJDIR)/gwe1ic1idm.o \ +$(OBJDIR)/gwe1dsp1idm.o \ +$(OBJDIR)/gwe1disv1idm.o \ +$(OBJDIR)/gwe1disu1idm.o \ +$(OBJDIR)/gwe1dis1idm.o \ +$(OBJDIR)/gwe1cnt1idm.o \ $(OBJDIR)/gwtgwtidm.o \ $(OBJDIR)/gwfgwtidm.o \ $(OBJDIR)/gwfgwfidm.o \ @@ -124,6 +133,7 @@ $(OBJDIR)/MemoryList.o \ $(OBJDIR)/IdmSimDfnSelector.o \ $(OBJDIR)/IdmGwtDfnSelector.o \ $(OBJDIR)/IdmGwfDfnSelector.o \ +$(OBJDIR)/IdmGweDfnSelector.o \ $(OBJDIR)/IdmExgDfnSelector.o \ $(OBJDIR)/TimeSeriesRecord.o \ $(OBJDIR)/MathUtil.o \ @@ -199,6 +209,7 @@ $(OBJDIR)/VirtualModel.o \ $(OBJDIR)/BaseExchange.o \ $(OBJDIR)/tsp1fmi1.o \ $(OBJDIR)/GwtSpc.o \ +$(OBJDIR)/GweInputData.o \ $(OBJDIR)/OutputControl.o \ $(OBJDIR)/tsp1ic1.o \ $(OBJDIR)/TspAdvOptions.o \ @@ -233,6 +244,7 @@ $(OBJDIR)/Mover.o \ $(OBJDIR)/GwfMvrPeriodData.o \ $(OBJDIR)/ims8misc.o \ $(OBJDIR)/GwfBuyInputData.o \ +$(OBJDIR)/GweDspOptions.o \ $(OBJDIR)/VirtualSolution.o \ $(OBJDIR)/SparseMatrix.o \ $(OBJDIR)/LinearSolverBase.o \ @@ -266,6 +278,9 @@ $(OBJDIR)/gwf3buy8.o \ $(OBJDIR)/GhostNode.o \ $(OBJDIR)/gwf3evt8.o \ $(OBJDIR)/gwf3chd8.o \ +$(OBJDIR)/gwe1mst1.o \ +$(OBJDIR)/gwe1dsp1.o \ +$(OBJDIR)/gwe1cnt1.o \ $(OBJDIR)/RouterBase.o \ $(OBJDIR)/ImsLinearSolver.o \ $(OBJDIR)/ims8base.o \ @@ -280,6 +295,7 @@ $(OBJDIR)/DistributedVariable.o \ $(OBJDIR)/gwt1.o \ $(OBJDIR)/gwf3.o \ $(OBJDIR)/GwfExchangeMover.o \ +$(OBJDIR)/gwe1.o \ $(OBJDIR)/SerialRouter.o \ $(OBJDIR)/Timer.o \ $(OBJDIR)/LinearSolverFactory.o \ @@ -295,6 +311,8 @@ $(OBJDIR)/GwtInterfaceModel.o \ $(OBJDIR)/GwtGwtExchange.o \ $(OBJDIR)/GwfInterfaceModel.o \ $(OBJDIR)/GwfGwfExchange.o \ +$(OBJDIR)/GweInterfaceModel.o \ +$(OBJDIR)/GweGweExchange.o \ $(OBJDIR)/RouterFactory.o \ $(OBJDIR)/NumericalSolution.o \ $(OBJDIR)/MappedMemory.o \ @@ -304,6 +322,7 @@ $(OBJDIR)/LoadMf6File.o \ $(OBJDIR)/ExplicitSolution.o \ $(OBJDIR)/GwtGwtConnection.o \ $(OBJDIR)/GwfGwfConnection.o \ +$(OBJDIR)/GweGweConnection.o \ $(OBJDIR)/VirtualDataManager.o \ $(OBJDIR)/Mapper.o \ $(OBJDIR)/IdmMf6File.o \ @@ -312,9 +331,12 @@ $(OBJDIR)/VirtualGwtModel.o \ $(OBJDIR)/VirtualGwtExchange.o \ $(OBJDIR)/VirtualGwfModel.o \ $(OBJDIR)/VirtualGwfExchange.o \ +$(OBJDIR)/VirtualGweModel.o \ +$(OBJDIR)/VirtualGweExchange.o \ $(OBJDIR)/SolutionGroup.o \ $(OBJDIR)/SolutionFactory.o \ $(OBJDIR)/GwfGwtExchange.o \ +$(OBJDIR)/GwfGweExchange.o \ $(OBJDIR)/RunControl.o \ $(OBJDIR)/SourceLoad.o \ $(OBJDIR)/ModelPackageInputs.o \ diff --git a/msvs/mf6core.vfproj b/msvs/mf6core.vfproj index 8d3b1c90737..c14b0150492 100644 --- a/msvs/mf6core.vfproj +++ b/msvs/mf6core.vfproj @@ -95,6 +95,8 @@ + + @@ -105,7 +107,9 @@ + + @@ -121,6 +125,8 @@ + + @@ -131,6 +137,18 @@ + + + + + + + + + + + + @@ -201,6 +219,8 @@ + + @@ -308,6 +328,7 @@ + @@ -401,6 +422,7 @@ + diff --git a/src/Distributed/VirtualDataContainer.f90 b/src/Distributed/VirtualDataContainer.f90 index d8ca55e4fed..3350bd64e5b 100644 --- a/src/Distributed/VirtualDataContainer.f90 +++ b/src/Distributed/VirtualDataContainer.f90 @@ -16,10 +16,13 @@ module VirtualDataContainerModule integer(I4B), public, parameter :: VDC_UNKNOWN_TYPE = 0 integer(I4B), public, parameter :: VDC_GWFMODEL_TYPE = 1 integer(I4B), public, parameter :: VDC_GWTMODEL_TYPE = 2 - integer(I4B), public, parameter :: VDC_GWFEXG_TYPE = 3 - integer(I4B), public, parameter :: VDC_GWTEXG_TYPE = 4 - integer(I4B), public, parameter :: VDC_GWFMVR_TYPE = 5 - integer(I4B), public, parameter :: VDC_GWTMVT_TYPE = 6 + integer(I4B), public, parameter :: VDC_GWEMODEL_TYPE = 3 + integer(I4B), public, parameter :: VDC_GWFEXG_TYPE = 4 + integer(I4B), public, parameter :: VDC_GWTEXG_TYPE = 5 + integer(I4B), public, parameter :: VDC_GWEEXG_TYPE = 6 + integer(I4B), public, parameter :: VDC_GWFMVR_TYPE = 7 + integer(I4B), public, parameter :: VDC_GWTMVT_TYPE = 8 + integer(I4B), public, parameter :: VDC_GWEMVE_TYPE = 9 !> @brief Wrapper for virtual data containers !! @@ -449,10 +452,13 @@ function VDC_TYPE_TO_STR(cntr_type) result(cntr_str) if (cntr_type == VDC_UNKNOWN_TYPE) then; cntr_str = "unknown" else if (cntr_type == VDC_GWFMODEL_TYPE) then; cntr_str = "GWF Model" else if (cntr_type == VDC_GWTMODEL_TYPE) then; cntr_str = "GWT Model" + else if (cntr_type == VDC_GWEMODEL_TYPE) then; cntr_str = "GWE Model" else if (cntr_type == VDC_GWFEXG_TYPE) then; cntr_str = "GWF Exchange" else if (cntr_type == VDC_GWTEXG_TYPE) then; cntr_str = "GWT Exchange" + else if (cntr_type == VDC_GWEEXG_TYPE) then; cntr_str = "GWE Exchange" else if (cntr_type == VDC_GWFMVR_TYPE) then; cntr_str = "GWF Mover" else if (cntr_type == VDC_GWTMVT_TYPE) then; cntr_str = "GWT Mover" + else if (cntr_type == VDC_GWEMVE_TYPE) then; cntr_str = "GWE Mover" else; cntr_str = "Undefined" end if diff --git a/src/Distributed/VirtualGweExchange.f90 b/src/Distributed/VirtualGweExchange.f90 new file mode 100644 index 00000000000..2cb9b6483c2 --- /dev/null +++ b/src/Distributed/VirtualGweExchange.f90 @@ -0,0 +1,109 @@ +module VirtualGweExchangeModule + use KindModule, only: I4B + use SimStagesModule + use VirtualBaseModule + use VirtualDataListsModule, only: virtual_exchange_list + use VirtualDataContainerModule, only: VDC_GWEEXG_TYPE + use VirtualExchangeModule + implicit none + private + + public :: add_virtual_gwe_exchange + + type, public, extends(VirtualExchangeType) :: VirtualGweExchangeType + type(VirtualDbl1dType), pointer :: gwfsimvals => null() + contains + procedure :: create => vtx_create + procedure :: destroy => vtx_destroy + procedure :: prepare_stage => vtx_prepare_stage + ! private + procedure, private :: init_virtual_data + procedure, private :: allocate_data + procedure, private :: deallocate_data + end type VirtualGweExchangeType + +contains + +!> @brief Add a virtual GWE-GWE exchange to the simulation +!< + subroutine add_virtual_gwe_exchange(name, exchange_id, model1_id, model2_id) + character(len=*) :: name + integer(I4B) :: exchange_id + integer(I4B) :: model1_id + integer(I4B) :: model2_id + ! local + class(VirtualGweExchangeType), pointer :: v_exg + class(*), pointer :: obj_ptr + + allocate (v_exg) + call v_exg%create(name, exchange_id, model1_id, model2_id) + + obj_ptr => v_exg + call virtual_exchange_list%Add(obj_ptr) + + end subroutine add_virtual_gwe_exchange + +!> @brief Create a virtual GWE-GWE exchange +!< + subroutine vtx_create(this, name, exg_id, m1_id, m2_id) + class(VirtualGweExchangeType) :: this + character(len=*) :: name + integer(I4B) :: exg_id + integer(I4B) :: m1_id + integer(I4B) :: m2_id + + ! create base + call this%VirtualExchangeType%create(name, exg_id, m1_id, m2_id) + this%container_type = VDC_GWEEXG_TYPE + + call this%allocate_data() + call this%init_virtual_data() + + end subroutine vtx_create + + subroutine init_virtual_data(this) + class(VirtualGweExchangeType) :: this + + call this%set(this%gwfsimvals%base(), 'GWFSIMVALS', '', MAP_ALL_TYPE) + + end subroutine init_virtual_data + + subroutine vtx_prepare_stage(this, stage) + class(VirtualGweExchangeType) :: this + integer(I4B) :: stage + ! local + integer(I4B) :: nexg + + ! prepare base exchange data items + call this%VirtualExchangeType%prepare_stage(stage) + + if (stage == STG_BFR_CON_AR) then + nexg = this%nexg%get() + call this%map(this%gwfsimvals%base(), nexg, (/STG_BFR_EXG_AD/)) + end if + + end subroutine vtx_prepare_stage + + subroutine vtx_destroy(this) + class(VirtualGweExchangeType) :: this + + call this%VirtualExchangeType%destroy() + call this%deallocate_data() + + end subroutine vtx_destroy + + subroutine allocate_data(this) + class(VirtualGweExchangeType) :: this + + allocate (this%gwfsimvals) + + end subroutine allocate_data + + subroutine deallocate_data(this) + class(VirtualGweExchangeType) :: this + + deallocate (this%gwfsimvals) + + end subroutine deallocate_data + +end module VirtualGweExchangeModule diff --git a/src/Distributed/VirtualGweModel.f90 b/src/Distributed/VirtualGweModel.f90 new file mode 100644 index 00000000000..6df7a32b666 --- /dev/null +++ b/src/Distributed/VirtualGweModel.f90 @@ -0,0 +1,202 @@ +module VirtualGweModelModule + use KindModule, only: I4B + use SimStagesModule + use VirtualBaseModule + use VirtualDataContainerModule, only: VDC_GWEMODEL_TYPE + use VirtualModelModule + use NumericalModelModule, only: NumericalModelType + implicit none + private + + public :: add_virtual_gwe_model + + type, extends(VirtualModelType) :: VirtualGweModelType + ! DSP + !type(VirtualIntType), pointer :: dsp_idiffc => null() + type(VirtualIntType), pointer :: dsp_idisp => null() + !type(VirtualDbl1dType), pointer :: dsp_diffc => null() + type(VirtualDbl1dType), pointer :: dsp_alh => null() + type(VirtualDbl1dType), pointer :: dsp_alv => null() + type(VirtualDbl1dType), pointer :: dsp_ath1 => null() + type(VirtualDbl1dType), pointer :: dsp_ath2 => null() + type(VirtualDbl1dType), pointer :: dsp_atv => null() + ! FMI + type(VirtualDbl1dType), pointer :: fmi_gwfhead => null() + type(VirtualDbl1dType), pointer :: fmi_gwfsat => null() + type(VirtualDbl2dType), pointer :: fmi_gwfspdis => null() + type(VirtualDbl1dType), pointer :: fmi_gwfflowja => null() + ! MST + type(VirtualDbl1dType), pointer :: mst_porosity => null() + ! GWE Model fields + type(VirtualIntType), pointer :: indsp => null() + type(VirtualIntType), pointer :: inmst => null() + contains + ! public + procedure :: create => vgwe_create + procedure :: prepare_stage => vgwe_prepare_stage + procedure :: destroy => vgwe_destroy + ! private + procedure, private :: init_virtual_data + procedure, private :: allocate_data + procedure, private :: deallocate_data + end type VirtualGweModelType + +contains + + subroutine add_virtual_gwe_model(model_id, model_name, model) + use VirtualDataListsModule, only: virtual_model_list + integer(I4B) :: model_id !< global model id + character(len=*) :: model_name !< model name + class(NumericalModelType), pointer :: model !< the actual model (can be null() when remote) + ! local + class(VirtualGweModelType), pointer :: virtual_gwe_model + class(*), pointer :: obj + + allocate (virtual_gwe_model) + call virtual_gwe_model%create(model_name, model_id, model) + + obj => virtual_gwe_model + call virtual_model_list%Add(obj) + + end subroutine add_virtual_gwe_model + + subroutine vgwe_create(this, name, id, model) + class(VirtualGweModelType) :: this + character(len=*) :: name + integer(I4B) :: id + class(NumericalModelType), pointer :: model + + ! create base + call this%VirtualModelType%create(name, id, model) + this%container_type = VDC_GWEMODEL_TYPE + + call this%allocate_data() + call this%init_virtual_data() + + end subroutine vgwe_create + + subroutine init_virtual_data(this) + class(VirtualGweModelType) :: this + + !call this%set(this%dsp_idiffc%base(), 'IDIFFC', 'DSP', MAP_ALL_TYPE) + call this%set(this%dsp_idisp%base(), 'IDISP', 'DSP', MAP_ALL_TYPE) + !call this%set(this%dsp_diffc%base(), 'DIFFC', 'DSP', MAP_NODE_TYPE) + call this%set(this%dsp_alh%base(), 'ALH', 'DSP', MAP_NODE_TYPE) + call this%set(this%dsp_alv%base(), 'ALV', 'DSP', MAP_NODE_TYPE) + call this%set(this%dsp_ath1%base(), 'ATH1', 'DSP', MAP_NODE_TYPE) + call this%set(this%dsp_ath2%base(), 'ATH2', 'DSP', MAP_NODE_TYPE) + call this%set(this%dsp_atv%base(), 'ATV', 'DSP', MAP_NODE_TYPE) + call this%set(this%fmi_gwfhead%base(), 'GWFHEAD', 'FMI', MAP_NODE_TYPE) + call this%set(this%fmi_gwfsat%base(), 'GWFSAT', 'FMI', MAP_NODE_TYPE) + call this%set(this%fmi_gwfspdis%base(), 'GWFSPDIS', 'FMI', MAP_NODE_TYPE) + call this%set(this%fmi_gwfflowja%base(), 'GWFFLOWJA', 'FMI', MAP_CONN_TYPE) + call this%set(this%mst_porosity%base(), 'POROSITY', 'MST', MAP_NODE_TYPE) + call this%set(this%indsp%base(), 'INDSP', '', MAP_ALL_TYPE) + call this%set(this%inmst%base(), 'INMST', '', MAP_ALL_TYPE) + + end subroutine init_virtual_data + + subroutine vgwe_prepare_stage(this, stage) + class(VirtualGweModelType) :: this + integer(I4B) :: stage + ! local + integer(I4B) :: nr_nodes, nr_conns + + ! prepare base (=numerical) model data items + call this%VirtualModelType%prepare_stage(stage) + + nr_nodes = 0 + nr_conns = 0 + + if (stage == STG_AFT_MDL_DF) then + + !call this%map(this%dsp_idiffc%base(), (/STG_AFT_MDL_DF/)) + call this%map(this%dsp_idisp%base(), (/STG_AFT_MDL_DF/)) + call this%map(this%indsp%base(), (/STG_AFT_MDL_DF/)) + call this%map(this%inmst%base(), (/STG_AFT_MDL_DF/)) + + else if (stage == STG_BFR_CON_AR) then + + nr_nodes = this%element_maps(MAP_NODE_TYPE)%nr_virt_elems + nr_conns = this%element_maps(MAP_CONN_TYPE)%nr_virt_elems + + call this%map(this%x%base(), nr_nodes, & + (/STG_BFR_CON_AR, STG_BFR_EXG_AD, STG_BFR_EXG_CF/)) + call this%map(this%ibound%base(), nr_nodes, (/STG_BFR_CON_AR/)) + + !if (this%dsp_idiffc%get() > 0) then + ! call this%map(this%dsp_diffc%base(), nr_nodes, (/STG_BFR_CON_AR/)) + !end if + + if (this%dsp_idisp%get() > 0) then + call this%map(this%dsp_alh%base(), nr_nodes, (/STG_BFR_CON_AR/)) + call this%map(this%dsp_alv%base(), nr_nodes, (/STG_BFR_CON_AR/)) + call this%map(this%dsp_ath1%base(), nr_nodes, (/STG_BFR_CON_AR/)) + call this%map(this%dsp_ath2%base(), nr_nodes, (/STG_BFR_CON_AR/)) + call this%map(this%dsp_atv%base(), nr_nodes, (/STG_BFR_CON_AR/)) + end if + + call this%map(this%fmi_gwfhead%base(), nr_nodes, (/STG_BFR_EXG_AD/)) + call this%map(this%fmi_gwfsat%base(), nr_nodes, (/STG_BFR_EXG_AD/)) + call this%map(this%fmi_gwfspdis%base(), 3, nr_nodes, (/STG_BFR_EXG_AD/)) + call this%map(this%fmi_gwfflowja%base(), nr_conns, (/STG_BFR_EXG_AD/)) + + if (this%indsp%get() > 0 .and. this%inmst%get() > 0) then + call this%map(this%mst_porosity%base(), nr_nodes, (/STG_AFT_CON_AR/)) + end if + + end if + + end subroutine vgwe_prepare_stage + + subroutine allocate_data(this) + class(VirtualGweModelType) :: this + + !allocate (this%dsp_idiffc) + allocate (this%dsp_idisp) + !allocate (this%dsp_diffc) + allocate (this%dsp_alh) + allocate (this%dsp_alv) + allocate (this%dsp_ath1) + allocate (this%dsp_ath2) + allocate (this%dsp_atv) + allocate (this%fmi_gwfhead) + allocate (this%fmi_gwfsat) + allocate (this%fmi_gwfspdis) + allocate (this%fmi_gwfflowja) + allocate (this%mst_porosity) + allocate (this%indsp) + allocate (this%inmst) + + end subroutine allocate_data + + subroutine deallocate_data(this) + class(VirtualGweModelType) :: this + + !deallocate (this%dsp_idiffc) + deallocate (this%dsp_idisp) + !deallocate (this%dsp_diffc) + deallocate (this%dsp_alh) + deallocate (this%dsp_alv) + deallocate (this%dsp_ath1) + deallocate (this%dsp_ath2) + deallocate (this%dsp_atv) + deallocate (this%fmi_gwfhead) + deallocate (this%fmi_gwfsat) + deallocate (this%fmi_gwfspdis) + deallocate (this%fmi_gwfflowja) + deallocate (this%mst_porosity) + deallocate (this%indsp) + deallocate (this%inmst) + + end subroutine deallocate_data + + subroutine vgwe_destroy(this) + class(VirtualGweModelType) :: this + + call this%VirtualModelType%destroy() + call this%deallocate_data() + + end subroutine vgwe_destroy + +end module VirtualGweModelModule diff --git a/src/Exchange/GweGweExchange.f90 b/src/Exchange/GweGweExchange.f90 new file mode 100644 index 00000000000..c2c127d1a3e --- /dev/null +++ b/src/Exchange/GweGweExchange.f90 @@ -0,0 +1,1367 @@ +!> @brief This module contains the GweGweExchangeModule Module +!! +!! This module contains the code for connecting two GWE Models. +!! The methods are based on the simple two point flux approximation +!! with the option to use ghost nodes to improve accuracy. This +!! exchange is used by GweGweConnection with the more sophisticated +!! interface model coupling approach when XT3D is needed. +!! +!< +module GweGweExchangeModule + + use KindModule, only: DP, I4B, LGP + use SimVariablesModule, only: errmsg, model_loc_idx + use SimModule, only: store_error + use BaseModelModule, only: BaseModelType, GetBaseModelFromList + use BaseExchangeModule, only: BaseExchangeType, AddBaseExchangeToList + use ConstantsModule, only: LENBOUNDNAME, NAMEDBOUNDFLAG, LINELENGTH, & + TABCENTER, TABLEFT, LENAUXNAME, DNODATA, & + LENMODELNAME + use ListModule, only: ListType + use ListsModule, only: basemodellist + use VirtualModelModule, only: get_virtual_model + use DisConnExchangeModule, only: DisConnExchangeType + use GweModule, only: GweModelType + use TspMvtModule, only: TspMvtType + use VirtualModelModule, only: VirtualModelType + use ObserveModule, only: ObserveType + use ObsModule, only: ObsType + use SimModule, only: count_errors, store_error, & + store_error_unit, ustop + use SimVariablesModule, only: errmsg + use BlockParserModule, only: BlockParserType + use TableModule, only: TableType, table_cr + use MatrixBaseModule + + implicit none + + private + public :: GweExchangeType + public :: gweexchange_create + public :: GetGweExchangeFromList + public :: CastAsGweExchange + + !> @brief Derived type for GwtExchangeType + !! + !! This derived type contains information and methods for + !! connecting two GWT models. + !! + !< + type, extends(DisConnExchangeType) :: GweExchangeType + ! + ! -- names of the GWF models that are connected by this exchange + character(len=LENMODELNAME) :: gwfmodelname1 = '' !< name of gwfmodel that corresponds to gwtmodel1 + character(len=LENMODELNAME) :: gwfmodelname2 = '' !< name of gwfmodel that corresponds to gwtmodel2 + real(DP), dimension(:), pointer, contiguous :: gwfsimvals => null() !< simulated gwf flow rate for each exchange + ! + ! -- pointers to gwt models + class(GweModelType), pointer :: gwemodel1 => null() !< pointer to GWT Model 1 + class(GweModelType), pointer :: gwemodel2 => null() !< pointer to GWT Model 2 + ! + ! -- GWT specific option block: + integer(I4B), pointer :: inewton => null() !< unneeded newton flag allows for mvt to be used here + integer(I4B), pointer :: iprflow => null() !< print flag for cell by cell flows + integer(I4B), pointer :: ipakcb => null() !< save flag for cell by cell flows + integer(I4B), pointer :: iAdvScheme !< the advection scheme at the interface: + !! 0 = upstream, 1 = central, 2 = TVD + ! + ! -- Mover transport package + integer(I4B), pointer :: inmvt => null() !< unit number for mover transport (0 if off) + type(TspMvtType), pointer :: mvt => null() !< water mover object + ! + ! -- Observation package + integer(I4B), pointer :: inobs => null() !< unit number for GWT-GWT observations + type(ObsType), pointer :: obs => null() !< observation object + ! + ! -- internal data + real(DP), dimension(:), pointer, contiguous :: cond => null() !< conductance + real(DP), dimension(:), pointer, contiguous :: simvals => null() !< simulated flow rate for each exchange + ! + ! -- table objects + type(TableType), pointer :: outputtab1 => null() + type(TableType), pointer :: outputtab2 => null() + + contains + + procedure :: exg_df => gwe_gwe_df + procedure :: exg_ar => gwe_gwe_ar + procedure :: exg_rp => gwe_gwe_rp + procedure :: exg_ad => gwe_gwe_ad + procedure :: exg_fc => gwe_gwe_fc + procedure :: exg_bd => gwe_gwe_bd + procedure :: exg_ot => gwe_gwe_ot + procedure :: exg_da => gwe_gwe_da + procedure :: exg_fp => gwe_gwe_fp + procedure :: connects_model => gwe_gwe_connects_model + procedure :: use_interface_model + procedure :: allocate_scalars + procedure :: allocate_arrays + procedure :: read_options + procedure :: parse_option + procedure :: read_mvt + procedure :: gwe_gwe_bdsav + procedure, private :: gwe_gwe_bdsav_model + procedure, private :: gwe_gwe_df_obs + procedure, private :: gwe_gwe_rp_obs + procedure, public :: gwe_gwe_save_simvals + procedure, private :: validate_exchange + end type GweExchangeType + +contains + + !> @ brief Create GWT GWT exchange + !! + !! Create a new GWT to GWT exchange object. + !< + subroutine gweexchange_create(filename, name, id, m1_id, m2_id) + ! -- modules + use ConstantsModule, only: LINELENGTH + use BaseModelModule, only: BaseModelType + use ListsModule, only: baseexchangelist + use ObsModule, only: obs_cr + use MemoryHelperModule, only: create_mem_path + ! -- dummy + character(len=*), intent(in) :: filename !< filename for reading + integer(I4B), intent(in) :: id !< id for the exchange + character(len=*) :: name !< the exchange name + integer(I4B), intent(in) :: m1_id !< id for model 1 + integer(I4B), intent(in) :: m2_id !< id for model 2 + ! -- local + type(GweExchangeType), pointer :: exchange + class(BaseModelType), pointer :: mb + class(BaseExchangeType), pointer :: baseexchange + integer(I4B) :: m1_index, m2_index + ! + ! -- Create a new exchange and add it to the baseexchangelist container + allocate (exchange) + baseexchange => exchange + call AddBaseExchangeToList(baseexchangelist, baseexchange) + ! + ! -- Assign id and name + exchange%id = id + exchange%name = name + exchange%memoryPath = create_mem_path(exchange%name) + ! + ! -- allocate scalars and set defaults + call exchange%allocate_scalars() + exchange%filename = filename + exchange%typename = 'GWE-GWE' + exchange%iAdvScheme = 0 + exchange%ixt3d = 1 + ! + ! -- set gwemodel1 + m1_index = model_loc_idx(m1_id) + mb => GetBaseModelFromList(basemodellist, m1_index) + if (m1_index > 0) then + select type (mb) + type is (GweModelType) + exchange%model1 => mb + exchange%gwemodel1 => mb + end select + end if + exchange%v_model1 => get_virtual_model(m1_id) + ! + ! -- set gwemodel2 + m2_index = model_loc_idx(m2_id) + if (m2_index > 0) then + mb => GetBaseModelFromList(basemodellist, m2_index) + select type (mb) + type is (GweModelType) + exchange%model2 => mb + exchange%gwemodel2 => mb + end select + end if + exchange%v_model2 => get_virtual_model(m2_id) + ! + ! -- Verify that gwt model1 is of the correct type + if (.not. associated(exchange%gwemodel1) .and. m1_index > 0) then + write (errmsg, '(3a)') 'Problem with GWE-GWE exchange ', & + trim(exchange%name), & + '. First specified GWE Model does not appear to be of the correct type.' + call store_error(errmsg, terminate=.true.) + end if + ! + ! -- Verify that gwe model2 is of the correct type + if (.not. associated(exchange%gwemodel2) .and. m2_index > 0) then + write (errmsg, '(3a)') 'Problem with GWE-GWE exchange ', & + trim(exchange%name), & + '. Second specified GWE Model does not appear to be of the correct type.' + call store_error(errmsg, terminate=.true.) + end if + ! + ! -- Create the obs package + call obs_cr(exchange%obs, exchange%inobs) + ! + ! -- Return + return + end subroutine gweexchange_create + + !> @ brief Define GWE GWE exchange + !! + !! Define GWE to GWE exchange object. + !< + subroutine gwe_gwe_df(this) + ! -- modules + use SimVariablesModule, only: iout + use InputOutputModule, only: getunit, openfile + use GhostNodeModule, only: gnc_cr + ! -- dummy + class(GweExchangeType) :: this !< GwtExchangeType + ! -- local + integer(I4B) :: inunit + ! + ! -- open the file + inunit = getunit() + write (iout, '(/a,a)') ' Creating exchange: ', this%name + call openfile(inunit, iout, this%filename, 'GWE-GWE') + ! + call this%parser%Initialize(inunit, iout) + ! + ! -- Ensure models are in same solution + if (associated(this%gwemodel1) .and. associated(this%gwemodel2)) then + if (this%gwemodel1%idsoln /= this%gwemodel2%idsoln) then + call store_error('Two models are connect in a GWE '// & + 'exchange but they are in different solutions. '// & + 'GWE models must be in same solution: '// & + trim(this%gwemodel1%name)//' '// & + trim(this%gwemodel2%name)) + call this%parser%StoreErrorUnit() + end if + end if + ! + ! -- read options + call this%read_options(iout) + ! + ! -- read dimensions + call this%read_dimensions(iout) + ! + ! -- allocate arrays + call this%allocate_arrays() + ! + ! -- read exchange data + call this%read_data(iout) + ! + ! -- Read mover information + if (this%inmvt > 0) then + call this%read_mvt(iout) + call this%mvt%mvt_df(this%gwemodel1%dis) + end if + ! + ! -- close the file + close (inunit) + ! + ! -- Store obs + call this%gwe_gwe_df_obs() + if (associated(this%gwemodel1)) then + call this%obs%obs_df(iout, this%name, 'GWE-GWE', this%gwemodel1%dis) + end if + ! + ! -- validate + call this%validate_exchange() + ! + ! -- Return + return + end subroutine gwe_gwe_df + + !> @brief validate exchange data after reading + !< + subroutine validate_exchange(this) + ! -- dummy + class(GweExchangeType) :: this !< GweExchangeType + ! + + ! Ensure gwfmodel names were entered + if (this%gwfmodelname1 == '') then + write (errmsg, '(3a)') 'GWE-GWE exchange ', trim(this%name), & + ' requires that GWFMODELNAME1 be entered in the & + &OPTIONS block.' + call store_error(errmsg) + end if + if (this%gwfmodelname2 == '') then + write (errmsg, '(3a)') 'GWE-GWE exchange ', trim(this%name), & + ' requires that GWFMODELNAME2 be entered in the & + &OPTIONS block.' + call store_error(errmsg) + end if + ! + ! Periodic boundary condition in exchange don't allow XT3D (=interface model) + if (associated(this%model1, this%model2)) then + if (this%ixt3d > 0) then + write (errmsg, '(3a)') 'GWE-GWE exchange ', trim(this%name), & + ' is a periodic boundary condition which cannot'// & + ' be configured with XT3D' + call store_error(errmsg) + end if + end if + ! + ! Check to see if dispersion is on in either model1 or model2. + ! If so, then ANGLDEGX must be provided as an auxiliary variable for this + ! GWE-GWE exchange (this%ianglex > 0). + if (associated(this%gwemodel1) .and. associated(this%gwemodel2)) then + if (this%gwemodel1%indsp /= 0 .or. this%gwemodel2%indsp /= 0) then + if (this%ianglex == 0) then + write (errmsg, '(3a)') 'GWE-GWE exchange ', trim(this%name), & + ' requires that ANGLDEGX be specified as an'// & + ' auxiliary variable because dispersion was '// & + 'specified in one or both transport models.' + call store_error(errmsg) + end if + end if + end if + ! + if (this%ixt3d > 0 .and. this%ianglex == 0) then + write (errmsg, '(3a)') 'GWE-GWE exchange ', trim(this%name), & + ' requires that ANGLDEGX be specified as an'// & + ' auxiliary variable because XT3D is enabled' + call store_error(errmsg) + end if + ! + if (count_errors() > 0) then + call ustop() + end if + ! + ! -- Return + return + end subroutine validate_exchange + + !> @ brief Allocate and read + !! + !! Allocated and read and calculate saturated conductance + !< + subroutine gwe_gwe_ar(this) + ! -- dummy + class(GweExchangeType) :: this !< GwtExchangeType + ! + ! -- If mover is active, then call ar routine + if (this%inmvt > 0) call this%mvt%mvt_ar() + ! + ! -- Observation AR + call this%obs%obs_ar() + ! + ! -- Return + return + end subroutine gwe_gwe_ar + + !> @ brief Read and prepare + !! + !! Read new data for mover and obs + !< + subroutine gwe_gwe_rp(this) + ! -- modules + use TdisModule, only: readnewdata + ! -- dummy + class(GweExchangeType) :: this !< GweExchangeType + ! + ! -- Check with TDIS on whether or not it is time to RP + if (.not. readnewdata) return + ! + ! -- Read and prepare for mover + if (this%inmvt > 0) call this%mvt%mvt_rp() + ! + ! -- Read and prepare for observations + call this%gwe_gwe_rp_obs() + ! + ! -- Return + return + end subroutine gwe_gwe_rp + + !> @ brief Advance + !! + !! Advance mover and obs + !< + subroutine gwe_gwe_ad(this) + ! -- dummy + class(GweExchangeType) :: this !< GweExchangeType + ! + ! -- Advance mover + !if(this%inmvt > 0) call this%mvt%mvt_ad() + ! + ! -- Push simulated values to preceding time step + call this%obs%obs_ad() + ! + ! -- Return + return + end subroutine gwe_gwe_ad + + !> @ brief Fill coefficients + !! + !! Calculate conductance and fill coefficient matrix + !< + subroutine gwe_gwe_fc(this, kiter, matrix_sln, rhs_sln, inwtflag) + ! -- dummy + class(GweExchangeType) :: this !< GwtExchangeType + integer(I4B), intent(in) :: kiter + class(MatrixBaseType), pointer :: matrix_sln + real(DP), dimension(:), intent(inout) :: rhs_sln + integer(I4B), optional, intent(in) :: inwtflag + ! + ! -- Call mvt fc routine + if (this%inmvt > 0) call this%mvt%mvt_fc(this%gwemodel1%x, this%gwemodel2%x) + ! + ! -- Return + return + end subroutine gwe_gwe_fc + + !> @ brief Budget + !! + !! Accumulate budget terms + !< + subroutine gwe_gwe_bd(this, icnvg, isuppress_output, isolnid) + ! -- modules + use ConstantsModule, only: DZERO, LENBUDTXT, LENPACKAGENAME + use BudgetModule, only: rate_accumulator + ! -- dummy + class(GweExchangeType) :: this !< GweExchangeType + integer(I4B), intent(inout) :: icnvg + integer(I4B), intent(in) :: isuppress_output + integer(I4B), intent(in) :: isolnid + ! -- local + character(len=LENBUDTXT), dimension(1) :: budtxt + real(DP), dimension(2, 1) :: budterm + real(DP) :: ratin, ratout + ! + ! -- initialize + budtxt(1) = ' FLOW-JA-FACE' + ! + ! -- Calculate ratin/ratout and pass to model budgets + call rate_accumulator(this%simvals, ratin, ratout) + ! + ! -- Add the budget terms to model 1 + if (associated(this%gwemodel1)) then + budterm(1, 1) = ratin + budterm(2, 1) = ratout + call this%gwemodel1%model_bdentry(budterm, budtxt, this%name) + end if + ! + ! -- Add the budget terms to model 2 + if (associated(this%gwemodel2)) then + budterm(1, 1) = ratout + budterm(2, 1) = ratin + call this%gwemodel2%model_bdentry(budterm, budtxt, this%name) + end if + ! + ! -- Call mvt bd routine + if (this%inmvt > 0) call this%mvt%mvt_bd(this%gwemodel1%x, this%gwemodel2%x) + ! + ! -- Return + return + end subroutine gwe_gwe_bd + + !> @ brief Budget save + !! + !! Output individual flows to listing file and binary budget files + !< + subroutine gwe_gwe_bdsav(this) + ! -- dummy + class(GweExchangeType) :: this !< GweExchangeType + ! -- local + integer(I4B) :: icbcfl, ibudfl + ! + ! -- budget for model1 + if (associated(this%gwemodel1)) then + call this%gwe_gwe_bdsav_model(this%gwemodel1) + end if + ! + ! -- budget for model2 + if (associated(this%gwemodel2)) then + call this%gwe_gwe_bdsav_model(this%gwemodel2) + end if + ! + ! -- Set icbcfl, ibudfl to zero so that flows will be printed and + ! saved, if the options were set in the MVT package + icbcfl = 1 + ibudfl = 1 + ! + ! -- Call mvt bd routine + !cdl todo: if(this%inmvt > 0) call this%mvt%mvt_bdsav(icbcfl, ibudfl, isuppress_output) + ! + ! -- Calculate and write simulated values for observations + if (this%inobs /= 0) then + call this%gwe_gwe_save_simvals() + end if + ! + ! -- Return + return + end subroutine gwe_gwe_bdsav + + !> @ brief Budget save + !! + !! Output individual flows to listing file and binary budget files + !< + subroutine gwe_gwe_bdsav_model(this, model) + ! -- modules + use ConstantsModule, only: DZERO, LENBUDTXT, LENPACKAGENAME + use TdisModule, only: kstp, kper + ! -- dummy + class(GweExchangeType) :: this !< GwtExchangeType + class(GweModelType), pointer :: model + ! -- local + character(len=LENBOUNDNAME) :: bname + character(len=LENPACKAGENAME + 4) :: packname + character(len=LENBUDTXT), dimension(1) :: budtxt + type(TableType), pointer :: output_tab + class(VirtualModelType), pointer :: nbr_model + character(len=20) :: nodestr + integer(I4B) :: ntabrows + integer(I4B) :: nodeu + integer(I4B) :: i, n1, n2, n1u, n2u + integer(I4B) :: ibinun + real(DP) :: ratin, ratout, rrate + logical(LGP) :: is_for_model1 + integer(I4B) :: isuppress_output + ! + ! -- initialize local variables + isuppress_output = 0 + budtxt(1) = ' FLOW-JA-FACE' + packname = 'EXG '//this%name + packname = adjustr(packname) + if (associated(model, this%gwemodel1)) then + output_tab => this%outputtab1 + nbr_model => this%v_model2 + is_for_model1 = .true. + else + output_tab => this%outputtab2 + nbr_model => this%v_model1 + is_for_model1 = .false. + end if + ! + ! -- update output tables + if (this%iprflow /= 0) then + ! + ! -- update titles + if (model%oc%oc_save('BUDGET')) then + call output_tab%set_title(packname) + end if + ! + ! -- set table kstp and kper + call output_tab%set_kstpkper(kstp, kper) + ! + ! -- update maxbound of tables + ntabrows = 0 + do i = 1, this%nexg + n1 = this%nodem1(i) + n2 = this%nodem2(i) + ! + ! -- If both cells are active then calculate flow rate + if (this%v_model1%ibound%get(n1) /= 0 .and. & + this%v_model2%ibound%get(n2) /= 0) then + ntabrows = ntabrows + 1 + end if + end do + if (ntabrows > 0) then + call output_tab%set_maxbound(ntabrows) + end if + end if + ! + ! -- Print and write budget terms for model 1 + ! + ! -- Set binary unit numbers for saving flows + if (this%ipakcb /= 0) then + ibinun = model%oc%oc_save_unit('BUDGET') + else + ibinun = 0 + end if + ! + ! -- If save budget flag is zero for this stress period, then + ! shut off saving + if (.not. model%oc%oc_save('BUDGET')) ibinun = 0 + if (isuppress_output /= 0) then + ibinun = 0 + end if + ! + ! -- If cell-by-cell flows will be saved as a list, write header. + if (ibinun /= 0) then + call model%dis%record_srcdst_list_header(budtxt(1), & + model%name, & + this%name, & + nbr_model%name, & + this%name, & + this%naux, this%auxname, & + ibinun, this%nexg, & + model%iout) + end if + ! + ! Initialize accumulators + ratin = DZERO + ratout = DZERO + ! + ! -- Loop through all exchanges + do i = 1, this%nexg + ! + ! -- Assign boundary name + if (this%inamedbound > 0) then + bname = this%boundname(i) + else + bname = '' + end if + ! + ! -- Calculate the flow rate between n1 and n2 + rrate = DZERO + n1 = this%nodem1(i) + n2 = this%nodem2(i) + ! + ! -- If both cells are active then calculate flow rate + if (this%v_model1%ibound%get(n1) /= 0 .and. & + this%v_model2%ibound%get(n2) /= 0) then + rrate = this%simvals(i) + ! + ! -- Print the individual rates to model list files if requested + if (this%iprflow /= 0) then + if (model%oc%oc_save('BUDGET')) then + ! + ! -- set nodestr and write outputtab table + if (is_for_model1) then + nodeu = model%dis%get_nodeuser(n1) + call model%dis%nodeu_to_string(nodeu, nodestr) + call output_tab%print_list_entry(i, trim(adjustl(nodestr)), & + rrate, bname) + else + nodeu = model%dis%get_nodeuser(n2) + call model%dis%nodeu_to_string(nodeu, nodestr) + call output_tab%print_list_entry(i, trim(adjustl(nodestr)), & + -rrate, bname) + end if + end if + end if + if (rrate < DZERO) then + ratout = ratout - rrate + else + ratin = ratin + rrate + end if + end if + ! + ! -- If saving cell-by-cell flows in list, write flow + n1u = this%v_model1%dis_get_nodeuser(n1) + n2u = this%v_model2%dis_get_nodeuser(n2) + if (ibinun /= 0) then + if (is_for_model1) then + call model%dis%record_mf6_list_entry( & + ibinun, n1u, n2u, rrate, this%naux, this%auxvar(:, i), & + .false., .false.) + else + call model%dis%record_mf6_list_entry( & + ibinun, n2u, n1u, -rrate, this%naux, this%auxvar(:, i), & + .false., .false.) + end if + end if + ! + end do + ! + ! -- Return + return + end subroutine gwe_gwe_bdsav_model + + !> @ brief Output + !! + !! Write output + !< + subroutine gwe_gwe_ot(this) + ! -- modules + use SimVariablesModule, only: iout + use ConstantsModule, only: DZERO, LINELENGTH + ! -- dummy + class(GweExchangeType) :: this !< GweExchangeType + ! -- local + integer(I4B) :: iexg, n1, n2 + integer(I4B) :: ibudfl + real(DP) :: flow + character(len=LINELENGTH) :: node1str, node2str + ! -- format + character(len=*), parameter :: fmtheader = & + "(/1x, 'SUMMARY OF EXCHANGE RATES FOR EXCHANGE ', a, ' WITH ID ', i0, /, & + &2a16, 5a16, /, 112('-'))" + character(len=*), parameter :: fmtheader2 = & + "(/1x, 'SUMMARY OF EXCHANGE RATES FOR EXCHANGE ', a, ' WITH ID ', i0, /, & + &2a16, 4a16, /, 96('-'))" + character(len=*), parameter :: fmtdata = & + "(2a16, 5(1pg16.6))" + ! + ! -- Call bdsave + call this%gwe_gwe_bdsav() + ! + ! -- Write a table of exchanges + if (this%iprflow /= 0) then + write (iout, fmtheader2) trim(adjustl(this%name)), this%id, 'NODEM1', & + 'NODEM2', 'COND', 'X_M1', 'X_M2', 'FLOW' + do iexg = 1, this%nexg + n1 = this%nodem1(iexg) + n2 = this%nodem2(iexg) + flow = this%simvals(iexg) + call this%v_model1%dis_noder_to_string(n1, node1str) + call this%v_model2%dis_noder_to_string(n2, node2str) + write (iout, fmtdata) trim(adjustl(node1str)), & + trim(adjustl(node2str)), & + this%cond(iexg), this%v_model1%x%get(n1), & + this%v_model2%x%get(n2), flow + end do + end if + ! + !cdl Implement when MVT is ready + ! -- Mover budget output + ibudfl = 1 + if (this%inmvt > 0) call this%mvt%mvt_ot_bdsummary(ibudfl) + ! + ! -- OBS output + call this%obs%obs_ot() + ! + ! -- Return + return + end subroutine gwe_gwe_ot + + !> @ brief Read options + !! + !! Read the options block + !< + subroutine read_options(this, iout) + ! -- modules + use ConstantsModule, only: LINELENGTH, LENAUXNAME, DEM6 + use MemoryManagerModule, only: mem_allocate + use SimModule, only: store_error, store_error_unit + ! -- dummy + class(GweExchangeType) :: this !< GweExchangeType + integer(I4B), intent(in) :: iout + ! -- local + character(len=LINELENGTH) :: keyword + logical :: isfound + logical :: endOfBlock + integer(I4B) :: ierr + ! + ! -- get options block + call this%parser%GetBlock('OPTIONS', isfound, ierr, & + supportOpenClose=.true., blockRequired=.false.) + ! + ! -- parse options block if detected + if (isfound) then + write (iout, '(1x,a)') 'PROCESSING GWE-GWE EXCHANGE OPTIONS' + do + call this%parser%GetNextLine(endOfBlock) + if (endOfBlock) then + exit + end if + call this%parser%GetStringCaps(keyword) + ! + ! first parse option in base + if (this%DisConnExchangeType%parse_option(keyword, iout)) then + cycle + end if + ! + ! it's probably ours + if (this%parse_option(keyword, iout)) then + cycle + end if + ! + ! unknown option + errmsg = "Unknown GWE-GWE exchange option '"//trim(keyword)//"'." + call store_error(errmsg) + call this%parser%StoreErrorUnit() + end do + ! + write (iout, '(1x,a)') 'END OF GWE-GWE EXCHANGE OPTIONS' + end if + ! + ! -- Return + return + end subroutine read_options + + !> @brief parse option from exchange file + !< + function parse_option(this, keyword, iout) result(parsed) + ! -- modules + use InputOutputModule, only: getunit, openfile + ! -- dummy + class(GweExchangeType) :: this !< GweExchangeType + character(len=LINELENGTH), intent(in) :: keyword !< the option name + integer(I4B), intent(in) :: iout !< for logging + logical(LGP) :: parsed !< true when parsed + ! -- local + character(len=LINELENGTH) :: fname + integer(I4B) :: inobs, ilen + character(len=LINELENGTH) :: subkey + ! + parsed = .true. + ! + select case (keyword) + case ('GWFMODELNAME1') + call this%parser%GetStringCaps(subkey) + ilen = len_trim(subkey) + if (ilen > LENMODELNAME) then + write (errmsg, '(a,a)') & + 'INVALID MODEL NAME: ', trim(subkey) + call store_error(errmsg) + call this%parser%StoreErrorUnit() + end if + if (this%gwfmodelname1 /= '') then + call store_error('GWFMODELNAME1 has already been set to ' & + //trim(this%gwfmodelname1)// & + '. Cannot set more than once.') + call this%parser%StoreErrorUnit() + end if + this%gwfmodelname1 = subkey(1:LENMODELNAME) + write (iout, '(4x,a,a)') & + 'GWFMODELNAME1 IS SET TO: ', trim(this%gwfmodelname1) + case ('GWFMODELNAME2') + call this%parser%GetStringCaps(subkey) + ilen = len_trim(subkey) + if (ilen > LENMODELNAME) then + write (errmsg, '(a,a)') & + 'INVALID MODEL NAME: ', trim(subkey) + call store_error(errmsg) + call this%parser%StoreErrorUnit() + end if + if (this%gwfmodelname2 /= '') then + call store_error('GWFMODELNAME2 has already been set to ' & + //trim(this%gwfmodelname2)// & + '. Cannot set more than once.') + call this%parser%StoreErrorUnit() + end if + this%gwfmodelname2 = subkey(1:LENMODELNAME) + write (iout, '(4x,a,a)') & + 'GWFMODELNAME2 IS SET TO: ', trim(this%gwfmodelname2) + case ('PRINT_FLOWS') + this%iprflow = 1 + write (iout, '(4x,a)') & + 'EXCHANGE FLOWS WILL BE PRINTED TO LIST FILES.' + case ('SAVE_FLOWS') + this%ipakcb = -1 + write (iout, '(4x,a)') & + 'EXCHANGE FLOWS WILL BE SAVED TO BINARY BUDGET FILES.' + case ('MVT6') + call this%parser%GetStringCaps(subkey) + if (subkey /= 'FILEIN') then + call store_error('MVT6 KEYWORD MUST BE FOLLOWED BY '// & + '"FILEIN" then by filename.') + call this%parser%StoreErrorUnit() + end if + call this%parser%GetString(fname) + if (fname == '') then + call store_error('NO MVT6 FILE SPECIFIED.') + call this%parser%StoreErrorUnit() + end if + this%inmvt = getunit() + call openfile(this%inmvt, iout, fname, 'MVT') + write (iout, '(4x,a)') & + 'WATER MOVER TRANSPORT INFORMATION WILL BE READ FROM ', trim(fname) + case ('OBS6') + call this%parser%GetStringCaps(subkey) + if (subkey /= 'FILEIN') then + call store_error('OBS8 KEYWORD MUST BE FOLLOWED BY '// & + '"FILEIN" then by filename.') + call this%parser%StoreErrorUnit() + end if + this%obs%active = .true. + call this%parser%GetString(this%obs%inputFilename) + inobs = GetUnit() + call openfile(inobs, iout, this%obs%inputFilename, 'OBS') + this%obs%inUnitObs = inobs + case ('ADV_SCHEME') + call this%parser%GetStringCaps(subkey) + select case (subkey) + case ('UPSTREAM') + this%iAdvScheme = 0 + case ('CENTRAL') + this%iAdvScheme = 1 + case ('TVD') + this%iAdvScheme = 2 + case default + errmsg = "Unknown weighting method for advection: '"//trim(subkey)//"'." + call store_error(errmsg) + call this%parser%StoreErrorUnit() + end select + write (iout, '(4x,a,a)') & + 'CELL AVERAGING METHOD HAS BEEN SET TO: ', trim(subkey) + case ('DSP_XT3D_OFF') + this%ixt3d = 0 + write (iout, '(4x,a)') 'XT3D FORMULATION HAS BEEN SHUT OFF.' + case ('DSP_XT3D_RHS') + this%ixt3d = 2 + write (iout, '(4x,a)') 'XT3D RIGHT-HAND SIDE FORMULATION IS SELECTED.' + case ('ADVSCHEME') + errmsg = 'ADVSCHEME is no longer a valid keyword. Use ADV_SCHEME & + &instead.' + call store_error(errmsg) + call this%parser%StoreErrorUnit() + case ('XT3D_OFF') + errmsg = 'XT3D_OFF is no longer a valid keyword. Use DSP_XT3D_OFF & + &instead.' + call store_error(errmsg) + call this%parser%StoreErrorUnit() + case ('XT3D_RHS') + errmsg = 'XT3D_RHS is no longer a valid keyword. Use DSP_XT3D_RHS & + &instead.' + call store_error(errmsg) + call this%parser%StoreErrorUnit() + case default + parsed = .false. + end select + ! + ! -- Return + return + end function parse_option + + !> @ brief Read mover + !! + !! Read and process movers + !< + subroutine read_mvt(this, iout) + ! -- modules + use TspMvtModule, only: mvt_cr + ! -- dummy + class(GweExchangeType) :: this !< GwtExchangeType + integer(I4B), intent(in) :: iout + ! + ! -- Create and initialize the mover object Here, fmi is set to the one + ! for gwtmodel1 so that a call to save flows has an associated dis + ! object. + call mvt_cr(this%mvt, this%name, this%inmvt, iout, this%gwemodel1%fmi, & + this%gwemodel1%eqnsclfac, & + gwfmodelname1=this%gwfmodelname1, & + gwfmodelname2=this%gwfmodelname2, & + fmi2=this%gwemodel2%fmi) + ! + ! -- Return + return + end subroutine read_mvt + + !> @ brief Allocate scalars + !! + !! Allocate scalar variables + !< + subroutine allocate_scalars(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + use ConstantsModule, only: DZERO + ! -- dummy + class(GweExchangeType) :: this !< GwtExchangeType + ! + call this%DisConnExchangeType%allocate_scalars() + ! + call mem_allocate(this%inewton, 'INEWTON', this%memoryPath) + call mem_allocate(this%iprflow, 'IPRFLOW', this%memoryPath) + call mem_allocate(this%ipakcb, 'IPAKCB', this%memoryPath) + call mem_allocate(this%inobs, 'INOBS', this%memoryPath) + call mem_allocate(this%iAdvScheme, 'IADVSCHEME', this%memoryPath) + this%inewton = 0 + this%iprpak = 0 + this%iprflow = 0 + this%ipakcb = 0 + this%inobs = 0 + this%iAdvScheme = 0 + ! + call mem_allocate(this%inmvt, 'INMVT', this%memoryPath) + this%inmvt = 0 + ! + ! -- Return + return + end subroutine allocate_scalars + + !> @ brief Deallocate + !! + !! Deallocate memory associated with this object + !< + subroutine gwe_gwe_da(this) + ! -- modules + use MemoryManagerModule, only: mem_deallocate + ! -- dummy + class(GweExchangeType) :: this !< GwtExchangeType + ! + ! -- objects + if (this%inmvt > 0) then + call this%mvt%mvt_da() + deallocate (this%mvt) + end if + call this%obs%obs_da() + deallocate (this%obs) + ! + ! -- arrays + call mem_deallocate(this%cond) + call mem_deallocate(this%simvals) + call mem_deallocate(this%gwfsimvals, 'GWFSIMVALS', this%memoryPath) ! linked memory + ! + ! -- output table objects + if (associated(this%outputtab1)) then + call this%outputtab1%table_da() + deallocate (this%outputtab1) + nullify (this%outputtab1) + end if + if (associated(this%outputtab2)) then + call this%outputtab2%table_da() + deallocate (this%outputtab2) + nullify (this%outputtab2) + end if + ! + ! -- scalars + deallocate (this%filename) + call mem_deallocate(this%inewton) + call mem_deallocate(this%iprflow) + call mem_deallocate(this%ipakcb) + call mem_deallocate(this%inobs) + call mem_deallocate(this%iAdvScheme) + call mem_deallocate(this%inmvt) + ! + ! -- deallocate base + call this%DisConnExchangeType%disconnex_da() + ! + ! -- Return + return + end subroutine gwe_gwe_da + + !> @ brief Allocate arrays + !! + !! Allocate arrays + !< + subroutine allocate_arrays(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweExchangeType) :: this !< GweExchangeType + ! -- local + character(len=LINELENGTH) :: text + integer(I4B) :: ntabcol, i + ! + call this%DisConnExchangeType%allocate_arrays() + ! + call mem_allocate(this%cond, this%nexg, 'COND', this%memoryPath) + call mem_allocate(this%simvals, this%nexg, 'SIMVALS', this%memoryPath) + ! + ! -- Initialize + do i = 1, this%nexg + this%cond(i) = DNODATA + end do + ! + ! -- allocate and initialize the output table + if (this%iprflow /= 0) then + ! + ! -- dimension table + ntabcol = 3 + if (this%inamedbound > 0) then + ntabcol = ntabcol + 1 + end if + ! + ! -- initialize the output table objects + ! outouttab1 + if (this%v_model1%is_local) then + call table_cr(this%outputtab1, this%name, ' ') + call this%outputtab1%table_df(this%nexg, ntabcol, this%gwemodel1%iout, & + transient=.TRUE.) + text = 'NUMBER' + call this%outputtab1%initialize_column(text, 10, alignment=TABCENTER) + text = 'CELLID' + call this%outputtab1%initialize_column(text, 20, alignment=TABLEFT) + text = 'RATE' + call this%outputtab1%initialize_column(text, 15, alignment=TABCENTER) + if (this%inamedbound > 0) then + text = 'NAME' + call this%outputtab1%initialize_column(text, 20, alignment=TABLEFT) + end if + end if + ! outouttab2 + if (this%v_model2%is_local) then + call table_cr(this%outputtab2, this%name, ' ') + call this%outputtab2%table_df(this%nexg, ntabcol, this%gwemodel2%iout, & + transient=.TRUE.) + text = 'NUMBER' + call this%outputtab2%initialize_column(text, 10, alignment=TABCENTER) + text = 'CELLID' + call this%outputtab2%initialize_column(text, 20, alignment=TABLEFT) + text = 'RATE' + call this%outputtab2%initialize_column(text, 15, alignment=TABCENTER) + if (this%inamedbound > 0) then + text = 'NAME' + call this%outputtab2%initialize_column(text, 20, alignment=TABLEFT) + end if + end if + end if + ! + ! -- Return + return + end subroutine allocate_arrays + + !> @ brief Define observations + !! + !! Define the observations associated with this object + !< + subroutine gwe_gwe_df_obs(this) + ! -- dummy + class(GweExchangeType) :: this !< GweExchangeType + ! -- local + integer(I4B) :: indx + ! + ! -- Store obs type and assign procedure pointer + ! for gwt-gwt observation type. + call this%obs%StoreObsType('flow-ja-face', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => gwe_gwe_process_obsID + ! + ! -- Return + return + end subroutine gwe_gwe_df_obs + + !> @ brief Read and prepare observations + !! + !! Handle observation exchanges exchange-boundary names. + !< + subroutine gwe_gwe_rp_obs(this) + ! -- modules + use ConstantsModule, only: DZERO + ! -- dummy + class(GweExchangeType) :: this !< GwtExchangeType + ! -- local + integer(I4B) :: i + integer(I4B) :: j + class(ObserveType), pointer :: obsrv => null() + character(len=LENBOUNDNAME) :: bname + logical :: jfound + ! -- formats +10 format('Exchange "', a, '" for observation "', a, & + '" is invalid in package "', a, '"') +20 format('Exchange id "', i0, '" for observation "', a, & + '" is invalid in package "', a, '"') + ! + do i = 1, this%obs%npakobs + obsrv => this%obs%pakobs(i)%obsrv + ! + ! -- indxbnds needs to be reset each stress period because + ! list of boundaries can change each stress period. + ! -- Not true for exchanges, but leave this in for now anyway. + call obsrv%ResetObsIndex() + obsrv%BndFound = .false. + ! + bname = obsrv%FeatureName + if (bname /= '') then + ! -- Observation location(s) is(are) based on a boundary name. + ! Iterate through all boundaries to identify and store + ! corresponding index(indices) in bound array. + jfound = .false. + do j = 1, this%nexg + if (this%boundname(j) == bname) then + jfound = .true. + obsrv%BndFound = .true. + obsrv%CurrentTimeStepEndValue = DZERO + call obsrv%AddObsIndex(j) + end if + end do + if (.not. jfound) then + write (errmsg, 10) trim(bname), trim(obsrv%ObsTypeId), trim(this%name) + call store_error(errmsg) + end if + else + ! -- Observation location is a single exchange number + if (obsrv%intPak1 <= this%nexg .and. obsrv%intPak1 > 0) then + jfound = .true. + obsrv%BndFound = .true. + obsrv%CurrentTimeStepEndValue = DZERO + call obsrv%AddObsIndex(obsrv%intPak1) + else + jfound = .false. + end if + if (.not. jfound) then + write (errmsg, 20) obsrv%intPak1, trim(obsrv%ObsTypeId), trim(this%name) + call store_error(errmsg) + end if + end if + end do + ! + ! -- write summary of error messages + if (count_errors() > 0) then + call store_error_unit(this%inobs) + end if + ! + ! -- Return + return + end subroutine gwe_gwe_rp_obs + + !> @ brief Final processing + !! + !! Conduct any final processing + !< + subroutine gwe_gwe_fp(this) + ! -- dummy + class(GweExchangeType) :: this !< GwtExchangeType + ! + ! -- Return + return + end subroutine gwe_gwe_fp + + !> @brief Return true when this exchange provides matrix coefficients for + !! solving @param model + !< + function gwe_gwe_connects_model(this, model) result(is_connected) + ! -- dummy + class(GweExchangeType) :: this !< GweExchangeType + class(BaseModelType), pointer, intent(in) :: model !< the model to which the exchange might hold a connection + ! -- return + logical(LGP) :: is_connected !< true, when connected + ! + is_connected = .false. + ! + ! only connected when model is GwtModelType of course + select type (model) + class is (GweModelType) + if (associated(this%gwemodel1, model)) then + is_connected = .true. + else if (associated(this%gwemodel2, model)) then + is_connected = .true. + end if + end select + ! + ! -- Return + return + end function gwe_gwe_connects_model + + !> @brief Should interface model be used for this exchange + !! + !! For now this always returns true, since we do not support + !! a classic-style two-point flux approximation for GWT-GWT. + !! If we ever add logic to support a simpler non-interface + !! model flux calculation, then logic should be added here to + !! set the return accordingly. + !< + function use_interface_model(this) result(use_im) + ! -- dummy + class(GweExchangeType) :: this !< GweExchangeType + ! -- return + logical(LGP) :: use_im !< true when interface model should be used + ! + ! For now set use_im to .true. since the interface model approach + ! must currently be used for any GWT-GWT exchange. + use_im = .true. + ! + ! -- Return + return + end function + + !> @ brief Save simulated flow observations + !! + !! Save the simulated flows for each exchange + !< + subroutine gwe_gwe_save_simvals(this) + ! -- dummy + use SimModule, only: store_error, store_error_unit + use SimVariablesModule, only: errmsg + use ConstantsModule, only: DZERO + use ObserveModule, only: ObserveType + class(GweExchangeType), intent(inout) :: this + ! -- local + integer(I4B) :: i + integer(I4B) :: j + integer(I4B) :: n1 + integer(I4B) :: n2 + integer(I4B) :: iexg + real(DP) :: v + type(ObserveType), pointer :: obsrv => null() + ! + ! -- Write simulated values for all gwt-gwt observations + if (this%obs%npakobs > 0) then + call this%obs%obs_bd_clear() + do i = 1, this%obs%npakobs + obsrv => this%obs%pakobs(i)%obsrv + do j = 1, obsrv%indxbnds_count + iexg = obsrv%indxbnds(j) + v = DZERO + select case (obsrv%ObsTypeId) + case ('FLOW-JA-FACE') + n1 = this%nodem1(iexg) + n2 = this%nodem2(iexg) + v = this%simvals(iexg) + case default + errmsg = 'Unrecognized observation type: '// & + trim(obsrv%ObsTypeId) + call store_error(errmsg) + call store_error_unit(this%inobs) + end select + call this%obs%SaveOneSimval(obsrv, v) + end do + end do + end if + ! + ! -- Return + return + end subroutine gwe_gwe_save_simvals + + !> @ brief Obs ID processer + !! + !! Process observations for this exchange + !< + subroutine gwe_gwe_process_obsID(obsrv, dis, inunitobs, iout) + ! -- modules + use ConstantsModule, only: LINELENGTH + use InputOutputModule, only: urword + use ObserveModule, only: ObserveType + use BaseDisModule, only: DisBaseType + ! -- dummy + type(ObserveType), intent(inout) :: obsrv + class(DisBaseType), intent(in) :: dis + integer(I4B), intent(in) :: inunitobs + integer(I4B), intent(in) :: iout + ! -- local + integer(I4B) :: n, iexg, istat + integer(I4B) :: icol, istart, istop + real(DP) :: r + character(len=LINELENGTH) :: strng + ! + strng = obsrv%IDstring + icol = 1 + ! -- get exchange index + call urword(strng, icol, istart, istop, 1, n, r, iout, inunitobs) + read (strng(istart:istop), '(i10)', iostat=istat) iexg + if (istat == 0) then + obsrv%intPak1 = iexg + else + ! Integer can't be read from strng; it's presumed to be an exchange + ! boundary name (already converted to uppercase) + obsrv%FeatureName = trim(adjustl(strng)) + ! -- Observation may require summing rates from multiple exchange + ! boundaries, so assign intPak1 as a value that indicates observation + ! is for a named exchange boundary or group of exchange boundaries. + obsrv%intPak1 = NAMEDBOUNDFLAG + end if + ! + ! -- Return + return + end subroutine gwe_gwe_process_obsID + + !> @ brief Cast polymorphic object as exchange + !! + !! Cast polymorphic object as exchange + !< + function CastAsGweExchange(obj) result(res) + implicit none + ! -- dummy + class(*), pointer, intent(inout) :: obj + ! -- return + class(GweExchangeType), pointer :: res + ! + res => null() + if (.not. associated(obj)) return + ! + select type (obj) + class is (GweExchangeType) + res => obj + end select + ! + ! -- Return + return + end function CastAsGweExchange + + !> @ brief Get exchange from list + !! + !! Return an exchange from the list for specified index + !< + function GetGweExchangeFromList(list, idx) result(res) + implicit none + ! -- dummy + type(ListType), intent(inout) :: list + integer(I4B), intent(in) :: idx + ! -- return + class(GweExchangeType), pointer :: res + ! -- local + class(*), pointer :: obj + ! + obj => list%GetItem(idx) + res => CastAsGweExchange(obj) + ! + ! -- Return + return + end function GetGweExchangeFromList + +end module GweGweExchangeModule + diff --git a/src/Exchange/GwfGweExchange.f90 b/src/Exchange/GwfGweExchange.f90 new file mode 100644 index 00000000000..fdb7d180fa4 --- /dev/null +++ b/src/Exchange/GwfGweExchange.f90 @@ -0,0 +1,546 @@ +module GwfGweExchangeModule + use KindModule, only: DP, I4B, LGP + use ConstantsModule, only: LENPACKAGENAME + use ListsModule, only: basemodellist, baseexchangelist, & + baseconnectionlist + use SimModule, only: store_error + use SimVariablesModule, only: errmsg + use BaseExchangeModule, only: BaseExchangeType, AddBaseExchangeToList + use SpatialModelConnectionModule, only: SpatialModelConnectionType, & + get_smc_from_list + use GweGweConnectionModule, only: GweGweConnectionType, CastAsGweGweConnection + use GwfGwfConnectionModule, only: GwfGwfConnectionType, CastAsGwfGwfConnection + use GwfGwfExchangeModule, only: GwfExchangeType, & + GetGwfExchangeFromList + use BaseModelModule, only: BaseModelType, GetBaseModelFromList + use GwfModule, only: GwfModelType + use GweModule, only: GweModelType + use BndModule, only: BndType, GetBndFromList + + implicit none + public :: GwfGweExchangeType + public :: gwfgwe_cr + + type, extends(BaseExchangeType) :: GwfGweExchangeType + + integer(I4B), pointer :: m1_idx => null() !< index into the list of base exchanges for model 1 + integer(I4B), pointer :: m2_idx => null() !< index into the list of base exchanges for model 2 + + contains + + procedure :: exg_df + procedure :: exg_ar + procedure :: exg_da + procedure, private :: set_model_pointers + procedure, private :: allocate_scalars + procedure, private :: gwfbnd2gwefmi + procedure, private :: gwfconn2gweconn + procedure, private :: link_connections + + end type GwfGweExchangeType + +contains + + !> @brief Create a new GWF to GWE exchange object + !< + subroutine gwfgwe_cr(filename, id, m1_id, m2_id) + ! -- modules + use SimVariablesModule, only: model_loc_idx + ! -- dummy + character(len=*), intent(in) :: filename + integer(I4B), intent(in) :: id + integer(I4B), intent(in) :: m1_id + integer(I4B), intent(in) :: m2_id + ! -- local + class(BaseExchangeType), pointer :: baseexchange => null() + type(GwfGweExchangeType), pointer :: exchange => null() + character(len=20) :: cint + ! + ! -- Create a new exchange and add it to the baseexchangelist container + allocate (exchange) + baseexchange => exchange + call AddBaseExchangeToList(baseexchangelist, baseexchange) + ! + ! -- Assign id and name + exchange%id = id + write (cint, '(i0)') id + exchange%name = 'GWF-GWE_'//trim(adjustl(cint)) + exchange%memoryPath = exchange%name + ! + ! -- allocate scalars + call exchange%allocate_scalars() + ! + ! -- NB: convert from id to local model index in base model list + exchange%m1_idx = model_loc_idx(m1_id) + exchange%m2_idx = model_loc_idx(m2_id) + ! + ! -- set model pointers + call exchange%set_model_pointers() + ! + ! -- Return + return + end subroutine gwfgwe_cr + + !> @brief Allocate and read + !< + subroutine set_model_pointers(this) + ! -- dummy + class(GwfGweExchangeType) :: this + ! -- local + class(BaseModelType), pointer :: mb => null() + type(GwfModelType), pointer :: gwfmodel => null() + type(GweModelType), pointer :: gwemodel => null() + ! + ! -- set gwfmodel + gwfmodel => null() + mb => GetBaseModelFromList(basemodellist, this%m1_idx) + select type (mb) + type is (GwfModelType) + gwfmodel => mb + end select + ! + ! -- set gwemodel + gwemodel => null() + mb => GetBaseModelFromList(basemodellist, this%m2_idx) + select type (mb) + type is (GweModelType) + gwemodel => mb + end select + ! + ! -- Verify that gwf model is of the correct type + if (.not. associated(gwfmodel)) then + write (errmsg, '(3a)') 'Problem with GWF-GWE exchange ', trim(this%name), & + '. Specified GWF Model does not appear to be of the correct type.' + call store_error(errmsg, terminate=.true.) + end if + ! + ! -- Verify that gwe model is of the correct type + if (.not. associated(gwemodel)) then + write (errmsg, '(3a)') 'Problem with GWF-GWE exchange ', trim(this%name), & + '. Specified GWF Model does not appear to be of the correct type.' + call store_error(errmsg, terminate=.true.) + end if + ! + ! -- Tell transport model fmi flows are not read from file + gwemodel%fmi%flows_from_file = .false. + ! + ! -- Set a pointer to the GWF bndlist. This will allow the transport model + ! to look through the flow packages and establish a link to GWF flows + gwemodel%fmi%gwfbndlist => gwfmodel%bndlist + ! + ! -- Return + return + end subroutine set_model_pointers + + !> @brief Define the GwfGwe Exchange object + !< + subroutine exg_df(this) + ! -- modules + use MemoryManagerModule, only: mem_checkin + ! -- dummy + class(GwfGweExchangeType) :: this + ! -- local + class(BaseModelType), pointer :: mb => null() + type(GwfModelType), pointer :: gwfmodel => null() + type(GweModelType), pointer :: gwemodel => null() + ! + ! -- set gwfmodel + mb => GetBaseModelFromList(basemodellist, this%m1_idx) + select type (mb) + type is (GwfModelType) + gwfmodel => mb + end select + ! + ! -- set gwemodel + mb => GetBaseModelFromList(basemodellist, this%m2_idx) + select type (mb) + type is (GweModelType) + gwemodel => mb + end select + ! + ! -- Check to make sure that flow is solved before transport and in a + ! different IMS solution + if (gwfmodel%idsoln >= gwemodel%idsoln) then + write (errmsg, '(3a)') 'Problem with GWF-GWE exchange ', trim(this%name), & + '. The GWF model must be solved by a different IMS than the GWE model. & + &Furthermore, the IMS specified for GWF must be listed in mfsim.nam & + &before the IMS for GWE.' + call store_error(errmsg, terminate=.true.) + end if + ! + ! -- Set pointer to flowja + gwemodel%fmi%gwfflowja => gwfmodel%flowja + call mem_checkin(gwemodel%fmi%gwfflowja, & + 'GWFFLOWJA', gwemodel%fmi%memoryPath, & + 'FLOWJA', gwfmodel%memoryPath) + + ! + ! -- Set the npf flag so that specific discharge is available for + ! transport calculations if dispersion is active + if (gwemodel%indsp > 0) then + gwfmodel%npf%icalcspdis = 1 + end if + ! + ! -- Return + return + end subroutine exg_df + + !> @brief Allocate and read + !< + subroutine exg_ar(this) + ! -- modules + use MemoryManagerModule, only: mem_checkin + ! -- dummy + class(GwfGweExchangeType) :: this + ! -- local + class(BaseModelType), pointer :: mb => null() + type(GwfModelType), pointer :: gwfmodel => null() + type(GweModelType), pointer :: gwemodel => null() + ! -- formats + character(len=*), parameter :: fmtdiserr = & + "('GWF and GWE Models do not have the same discretization for exchange& + & ',a,'.& + & GWF Model has ', i0, ' user nodes and ', i0, ' reduced nodes.& + & GWE Model has ', i0, ' user nodes and ', i0, ' reduced nodes.& + & Ensure discretization packages, including IDOMAIN, are identical.')" + ! + ! -- set gwfmodel + mb => GetBaseModelFromList(basemodellist, this%m1_idx) + select type (mb) + type is (GwfModelType) + gwfmodel => mb + end select + ! + ! -- set gwemodel + mb => GetBaseModelFromList(basemodellist, this%m2_idx) + select type (mb) + type is (GweModelType) + gwemodel => mb + end select + ! + ! -- Check to make sure sizes are identical + if (gwemodel%dis%nodes /= gwfmodel%dis%nodes .or. & + gwemodel%dis%nodesuser /= gwfmodel%dis%nodesuser) then + write (errmsg, fmtdiserr) trim(this%name), & + gwfmodel%dis%nodesuser, & + gwfmodel%dis%nodes, & + gwemodel%dis%nodesuser, & + gwemodel%dis%nodes + call store_error(errmsg, terminate=.TRUE.) + end if + ! + ! -- setup pointers to gwf variables allocated in gwf_ar + gwemodel%fmi%gwfhead => gwfmodel%x + call mem_checkin(gwemodel%fmi%gwfhead, & + 'GWFHEAD', gwemodel%fmi%memoryPath, & + 'X', gwfmodel%memoryPath) + gwemodel%fmi%gwfsat => gwfmodel%npf%sat + call mem_checkin(gwemodel%fmi%gwfsat, & + 'GWFSAT', gwemodel%fmi%memoryPath, & + 'SAT', gwfmodel%npf%memoryPath) + gwemodel%fmi%gwfspdis => gwfmodel%npf%spdis + call mem_checkin(gwemodel%fmi%gwfspdis, & + 'GWFSPDIS', gwemodel%fmi%memoryPath, & + 'SPDIS', gwfmodel%npf%memoryPath) + ! + ! -- setup pointers to the flow storage rates. GWF strg arrays are + ! available after the gwf_ar routine is called. + if (gwemodel%inmst > 0) then + if (gwfmodel%insto > 0) then + gwemodel%fmi%gwfstrgss => gwfmodel%sto%strgss + gwemodel%fmi%igwfstrgss = 1 + if (gwfmodel%sto%iusesy == 1) then + gwemodel%fmi%gwfstrgsy => gwfmodel%sto%strgsy + gwemodel%fmi%igwfstrgsy = 1 + end if + end if + end if + ! + ! -- Set a pointer to conc in buy + if (gwfmodel%inbuy > 0) then + call gwfmodel%buy%set_concentration_pointer(gwemodel%name, gwemodel%x, & + gwemodel%ibound) + end if + ! + ! -- Set a pointer to conc (which could be a temperature) in vsc + if (gwfmodel%invsc > 0) then + call gwfmodel%vsc%set_concentration_pointer(gwemodel%name, gwemodel%x, & + gwemodel%ibound, 1) + end if + ! + ! -- transfer the boundary package information from gwf to gwe + call this%gwfbnd2gwefmi() + ! + ! -- if mover package is active, then set a pointer to it's budget object + if (gwfmodel%inmvr /= 0) then + gwemodel%fmi%mvrbudobj => gwfmodel%mvr%budobj + end if + ! + ! -- connect Connections + call this%gwfconn2gweconn(gwfmodel, gwemodel) + ! + ! -- Return + return + end subroutine exg_ar + + !> @brief Link GWE connections to GWF connections or exchanges + !< + subroutine gwfconn2gweconn(this, gwfModel, gweModel) + ! -- modules + use SimModule, only: store_error + use SimVariablesModule, only: iout + use MemoryManagerModule, only: mem_checkin + ! -- dummy + class(GwfGweExchangeType) :: this !< this exchange + type(GwfModelType), pointer :: gwfModel !< the flow model + type(GweModelType), pointer :: gweModel !< the energy transport model + ! -- local + class(SpatialModelConnectionType), pointer :: conn => null() + class(*), pointer :: objPtr => null() + class(GweGweConnectionType), pointer :: gweConn => null() + class(GwfGwfConnectionType), pointer :: gwfConn => null() + class(GwfExchangeType), pointer :: gwfEx => null() + integer(I4B) :: ic1, ic2, iex + integer(I4B) :: gwfConnIdx, gwfExIdx + logical(LGP) :: areEqual + ! + ! loop over all connections + gweloop: do ic1 = 1, baseconnectionlist%Count() + ! + conn => get_smc_from_list(baseconnectionlist, ic1) + if (.not. associated(conn%owner, gweModel)) cycle gweloop + ! + ! start with a GWE conn. + objPtr => conn + gweConn => CastAsGweGweConnection(objPtr) + gwfConnIdx = -1 + gwfExIdx = -1 + ! + ! find matching GWF conn. in same list + gwfloop: do ic2 = 1, baseconnectionlist%Count() + conn => get_smc_from_list(baseconnectionlist, ic2) + ! + if (associated(conn%owner, gwfModel)) then + objPtr => conn + gwfConn => CastAsGwfGwfConnection(objPtr) + ! + ! for now, connecting the same nodes nrs will be + ! sufficient evidence of equality + areEqual = all(gwfConn%prim_exchange%nodem1 == & + gweConn%prim_exchange%nodem1) + areEqual = areEqual .and. all(gwfConn%prim_exchange%nodem2 == & + gweConn%prim_exchange%nodem2) + if (areEqual) then + ! same DIS, same exchange: link and go to next GWE conn. + write (iout, '(/6a)') 'Linking exchange ', & + trim(gweConn%prim_exchange%name), & + ' to ', trim(gwfConn%prim_exchange%name), & + ' (using interface model) for GWE model ', & + trim(gweModel%name) + gwfConnIdx = ic2 + call this%link_connections(gweConn, gwfConn) + exit gwfloop + end if + end if + end do gwfloop + ! + ! fallback option: coupling to old gwfgwf exchange, + ! (this will go obsolete at some point) + if (gwfConnIdx == -1) then + gwfloopexg: do iex = 1, baseexchangelist%Count() + gwfEx => GetGwfExchangeFromList(baseexchangelist, iex) + ! + ! -- There is no guarantee that iex is a gwfExg, in which case + ! it will return as null. cycle if so. + if (.not. associated(gwfEx)) cycle gwfloopexg + ! + if (associated(gwfEx%model1, gwfModel) .or. & + associated(gwfEx%model2, gwfModel)) then + + ! check exchanges have same node counts + areEqual = size(gwfEx%nodem1) == size(gweConn%prim_exchange%nodem1) + ! then, connecting the same nodes nrs will be + ! sufficient evidence of equality + if (areEqual) & + areEqual = all(gwfEx%nodem1 == gweConn%prim_exchange%nodem1) + if (areEqual) & + areEqual = all(gwfEx%nodem2 == gweConn%prim_exchange%nodem2) + if (areEqual) then + ! link exchange to connection + write (iout, '(/6a)') 'Linking exchange ', & + trim(gweConn%prim_exchange%name), & + ' to ', trim(gwfEx%name), ' for GWE model ', & + trim(gweModel%name) + gwfExIdx = iex + if (gweConn%owns_exchange) then + gweConn%gweExchange%gwfsimvals => gwfEx%simvals + call mem_checkin(gweConn%gweExchange%gwfsimvals, & + 'GWFSIMVALS', gweConn%gweExchange%memoryPath, & + 'SIMVALS', gwfEx%memoryPath) + end if + ! + !cdl link up mvt to mvr + if (gwfEx%inmvr > 0) then + if (gweConn%owns_exchange) then + !cdl todo: check and make sure gweEx has mvt active + call gweConn%gweExchange%mvt%set_pointer_mvrbudobj( & + gwfEx%mvr%budobj) + end if + end if + ! + if (associated(gwfEx%model2, gwfModel)) gweConn%exgflowSign = -1 + gweConn%gweInterfaceModel%fmi%flows_from_file = .false. + ! + exit gwfloopexg + end if + end if + ! + end do gwfloopexg + end if + ! + if (gwfConnIdx == -1 .and. gwfExIdx == -1) then + ! none found, report + write (errmsg, '(/6a)') 'Missing GWF-GWF exchange when connecting GWE'// & + ' model ', trim(gweModel%name), ' with exchange ', & + trim(gweConn%prim_exchange%name), ' to GWF model ', & + trim(gwfModel%name) + call store_error(errmsg, terminate=.true.) + end if + ! + end do gweloop + ! + ! -- Return + return + end subroutine gwfconn2gweconn + + !> @brief Links a GWE connection to its GWF counterpart + !< + subroutine link_connections(this, gweConn, gwfConn) + ! -- modules + use MemoryManagerModule, only: mem_checkin + ! -- dummy + class(GwfGweExchangeType) :: this !< this exchange + class(GweGweConnectionType), pointer :: gweConn !< GWE connection + class(GwfGwfConnectionType), pointer :: gwfConn !< GWF connection + ! + !gweConn%exgflowja => gwfConn%exgflowja + if (gweConn%owns_exchange) then + gweConn%gweExchange%gwfsimvals => gwfConn%gwfExchange%simvals + call mem_checkin(gweConn%gweExchange%gwfsimvals, & + 'GWFSIMVALS', gweConn%gweExchange%memoryPath, & + 'SIMVALS', gwfConn%gwfExchange%memoryPath) + end if + ! + !cdl link up mvt to mvr + if (gwfConn%gwfExchange%inmvr > 0) then + if (gweConn%owns_exchange) then + !cdl todo: check and make sure gweEx has mvt active + call gweConn%gweExchange%mvt%set_pointer_mvrbudobj( & + gwfConn%gwfExchange%mvr%budobj) + end if + end if + ! + if (associated(gwfConn%gwfExchange%model2, gwfConn%owner)) then + gweConn%exgflowSign = -1 + end if + ! + ! fmi flows are not read from file + gweConn%gweInterfaceModel%fmi%flows_from_file = .false. + ! + ! set concentration pointer for buoyancy + !call gwfConn%gwfInterfaceModel%buy%set_concentration_pointer( & + ! gweConn%gweModel%name, & + ! gweConn%conc, & + ! gweConn%icbound) + ! + ! -- Return + return + end subroutine link_connections + + !> @brief Deallocate memory + !< + subroutine exg_da(this) + ! -- modules + use MemoryManagerModule, only: mem_deallocate + ! -- dummy + class(GwfGweExchangeType) :: this + ! + call mem_deallocate(this%m1_idx) + call mem_deallocate(this%m2_idx) + ! + ! -- Return + return + end subroutine exg_da + + !> @brief Allocate GwfGwe exchange scalars + !< + subroutine allocate_scalars(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GwfGweExchangeType) :: this + ! + call mem_allocate(this%m1_idx, 'M1ID', this%memoryPath) + call mem_allocate(this%m2_idx, 'M2ID', this%memoryPath) + this%m1_idx = 0 + this%m2_idx = 0 + ! + ! -- Return + return + end subroutine allocate_scalars + + !> @brief Call routines in FMI that will set pointers to the necessary flow + !! data (SIMVALS and SIMTOMVR) stored within each GWF flow package + !< + subroutine gwfbnd2gwefmi(this) + ! -- dummy + class(GwfGweExchangeType) :: this + ! -- local + integer(I4B) :: ngwfpack, ip, iterm, imover + class(BaseModelType), pointer :: mb => null() + type(GwfModelType), pointer :: gwfmodel => null() + type(GweModelType), pointer :: gwemodel => null() + class(BndType), pointer :: packobj => null() + ! + ! -- set gwfmodel + mb => GetBaseModelFromList(basemodellist, this%m1_idx) + select type (mb) + type is (GwfModelType) + gwfmodel => mb + end select + ! + ! -- set gwemodel + mb => GetBaseModelFromList(basemodellist, this%m2_idx) + select type (mb) + type is (GweModelType) + gwemodel => mb + end select + ! + ! -- Call routines in FMI that will set pointers to the necessary flow + ! data (SIMVALS and SIMTOMVR) stored within each GWF flow package + ngwfpack = gwfmodel%bndlist%Count() + iterm = 1 + do ip = 1, ngwfpack + packobj => GetBndFromList(gwfmodel%bndlist, ip) + call gwemodel%fmi%gwfpackages(iterm)%set_pointers( & + 'SIMVALS', & + packobj%memoryPath, packobj%input_mempath) + iterm = iterm + 1 + ! + ! -- If a mover is active for this package, then establish a separate + ! pointer link for the mover flows stored in SIMTOMVR + imover = packobj%imover + if (packobj%isadvpak /= 0) imover = 0 + if (imover /= 0) then + call gwemodel%fmi%gwfpackages(iterm)%set_pointers( & + 'SIMTOMVR', & + packobj%memoryPath, packobj%input_mempath) + iterm = iterm + 1 + end if + end do + ! + ! -- Return + return + end subroutine gwfbnd2gwefmi + +end module GwfGweExchangeModule diff --git a/src/Exchange/GwfGwtExchange.f90 b/src/Exchange/GwfGwtExchange.f90 index 9313efcce59..65a33bc0a8b 100644 --- a/src/Exchange/GwfGwtExchange.f90 +++ b/src/Exchange/GwfGwtExchange.f90 @@ -132,7 +132,7 @@ subroutine set_model_pointers(this) return end subroutine set_model_pointers - !> @brief Define GwfGwt Exchange object + !> @brief Define the GwfGwt Exchange object !< subroutine exg_df(this) ! -- modules diff --git a/src/Model/Connection/GweGweConnection.f90 b/src/Model/Connection/GweGweConnection.f90 new file mode 100644 index 00000000000..8f4acc8d94d --- /dev/null +++ b/src/Model/Connection/GweGweConnection.f90 @@ -0,0 +1,505 @@ +module GweGweConnectionModule + use KindModule, only: I4B, DP, LGP + use ConstantsModule, only: LINELENGTH, LENCOMPONENTNAME, DZERO, LENBUDTXT + use CsrUtilsModule, only: getCSRIndex + use SimModule, only: ustop + use MemoryManagerModule, only: mem_allocate, mem_deallocate, mem_checkin + use SpatialModelConnectionModule + use NumericalModelModule + use GweModule + use DisConnExchangeModule + use GweGweExchangeModule + use GweInterfaceModelModule + use SparseModule, only: sparsematrix + use ConnectionsModule, only: ConnectionsType + use CellWithNbrsModule, only: GlobalCellType + use DistVariableModule + use SimStagesModule + use MatrixBaseModule + + implicit none + private + + public :: CastAsGweGweConnection + + !> Connects a GWE model to other GWE models in space. Derives + !! from NumericalExchangeType so the solution can use it to + !! fetch the coefficients for this connection. + !< + type, public, extends(SpatialModelConnectionType) :: GweGweConnectionType + + class(GweModelType), pointer :: gweModel => null() !< the model for which this connection exists + class(GweExchangeType), pointer :: gweExchange => null() !< the primary exchange, cast to GWE-GWE + class(GweInterfaceModelType), pointer :: gweInterfaceModel => null() !< the interface model + integer(I4B), pointer :: iIfaceAdvScheme => null() !< the advection scheme at the interface: + !! 0 = upstream, 1 = central, 2 = TVD + integer(I4B), pointer :: iIfaceXt3d => null() !< XT3D in the interface DSP package: 0 = no, 1 = lhs, 2 = rhs + integer(I4B), pointer :: exgflowSign => null() !< indicates the flow direction of exgflowja + real(DP), dimension(:), pointer, contiguous :: exgflowjaGwe => null() !< gwe-flowja at the interface (this is a subset of the GWT + !! interface model flowja's) + + real(DP), dimension(:), pointer, contiguous :: gwfflowja => null() !< gwfflowja for the interface model + real(DP), dimension(:), pointer, contiguous :: gwfsat => null() !< gwfsat for the interface model + real(DP), dimension(:), pointer, contiguous :: gwfhead => null() !< gwfhead for the interface model + real(DP), dimension(:, :), pointer, contiguous :: gwfspdis => null() !< gwfspdis for the interface model + + real(DP), dimension(:), pointer, contiguous :: conc => null() !< pointer to concentration array + integer(I4B), dimension(:), pointer, contiguous :: icbound => null() !< store pointer to gwe ibound array + + integer(I4B) :: iout = 0 !< the list file for the interface model + + contains + + procedure, pass(this) :: gweGweConnection_ctor + generic, public :: construct => gweGweConnection_ctor + + procedure :: exg_ar => gwegwecon_ar + procedure :: exg_df => gwegwecon_df + procedure :: exg_rp => gwegwecon_rp + procedure :: exg_ad => gwegwecon_ad + procedure :: exg_fc => gwegwecon_fc + procedure :: exg_da => gwegwecon_da + procedure :: exg_cq => gwegwecon_cq + procedure :: exg_bd => gwegwecon_bd + procedure :: exg_ot => gwegwecon_ot + + ! overriding 'protected' + procedure :: validateConnection + + ! local stuff + procedure, private :: allocate_scalars + procedure, private :: allocate_arrays + procedure, private :: cfg_dist_vars + procedure, private :: setGridExtent + procedure, private :: setFlowToExchange + + end type GweGweConnectionType + +contains + + !> @brief Basic construction of the connection + !< + subroutine gweGweConnection_ctor(this, model, gweEx) + use InputOutputModule, only: openfile + class(GweGweConnectionType) :: this !< the connection + class(NumericalModelType), pointer :: model !< the model owning this connection, + !! this must be a GweModelType + class(DisConnExchangeType), pointer :: gweEx !< the GWE-GWE exchange the interface model is created for + ! local + character(len=LINELENGTH) :: fname + character(len=LENCOMPONENTNAME) :: name + class(*), pointer :: objPtr + logical(LGP) :: write_ifmodel_listfile = .false. + + objPtr => model + this%gweModel => CastAsGweModel(objPtr) + objPtr => gweEx + this%gweExchange => CastAsGweExchange(objPtr) + + if (gweEx%v_model1%is_local .and. gweEx%v_model2%is_local) then + this%owns_exchange = associated(model, gweEx%model1) + else + this%owns_exchange = .true. + end if + + if (gweEx%v_model1 == model) then + write (name, '(a,i0)') 'GWECON1_', gweEx%id + else + write (name, '(a,i0)') 'GWECON2_', gweEx%id + end if + + ! .lst file for interface model + if (write_ifmodel_listfile) then + fname = trim(name)//'.im.lst' + call openfile(this%iout, 0, fname, 'LIST', filstat_opt='REPLACE') + write (this%iout, '(4a)') 'Creating GWE-GWE connection for model ', & + trim(this%gweModel%name), 'from exchange ', & + trim(gweEx%name) + end if + + ! first call base constructor + call this%SpatialModelConnectionType%spatialConnection_ctor(model, & + gweEx, & + name) + + call this%allocate_scalars() + this%typename = 'GWE-GWE' + this%iIfaceAdvScheme = 0 + this%iIfaceXt3d = 0 + this%exgflowSign = 1 + + allocate (this%gweInterfaceModel) + this%interface_model => this%gweInterfaceModel + + end subroutine gweGweConnection_ctor + + !> @brief Allocate scalar variables for this connection + !< + subroutine allocate_scalars(this) + class(GweGweConnectionType) :: this !< the connection + + call mem_allocate(this%iIfaceAdvScheme, 'IADVSCHEME', this%memoryPath) + call mem_allocate(this%iIfaceXt3d, 'IXT3D', this%memoryPath) + call mem_allocate(this%exgflowSign, 'EXGFLOWSIGN', this%memoryPath) + + end subroutine allocate_scalars + + !> @brief define the GWE-GWE connection + !< + subroutine gwegwecon_df(this) + class(GweGweConnectionType) :: this !< the connection + ! local + character(len=LENCOMPONENTNAME) :: imName + + ! determine advection scheme (the GWE-GWE exchange + ! has been read at this point) + this%iIfaceAdvScheme = this%gweExchange%iAdvScheme + ! + ! determine xt3d setting on interface + this%iIfaceXt3d = this%gweExchange%ixt3d + + ! turn off when off in the owning model + if (this%gweModel%indsp > 0) then + this%iIfaceXt3d = this%gweModel%dsp%ixt3d + end if + + ! determine the required size of the interface model grid + call this%setGridExtent() + + ! now set up the GridConnection + call this%spatialcon_df() + + ! we have to 'catch up' and create the interface model + ! here, then the remainder of this routine will be define + if (this%prim_exchange%v_model1 == this%owner) then + write (imName, '(a,i0)') 'GWEIM1_', this%gweExchange%id + else + write (imName, '(a,i0)') 'GWEIM2_', this%gweExchange%id + end if + call this%gweInterfaceModel%gweifmod_cr(imName, & + this%iout, & + this%ig_builder) + call this%gweInterfaceModel%set_idsoln(this%gweModel%idsoln) + this%gweInterfaceModel%iAdvScheme = this%iIfaceAdvScheme + this%gweInterfaceModel%ixt3d = this%iIfaceXt3d + call this%gweInterfaceModel%model_df() + + call this%cfg_dist_vars() + + call this%allocate_arrays() + call this%gweInterfaceModel%allocate_fmi() + + ! connect X, RHS, IBOUND, and flowja + call this%spatialcon_setmodelptrs() + + ! connect pointers (used by BUY) + this%conc => this%gweInterfaceModel%x + this%icbound => this%gweInterfaceModel%ibound + + ! add connections from the interface model to solution matrix + call this%spatialcon_connect() + + end subroutine gwegwecon_df + + !> @brief Configure distributed variables for this interface model + !< + subroutine cfg_dist_vars(this) + class(GweGweConnectionType) :: this !< the connection + + call this%cfg_dv('X', '', SYNC_NDS, & + (/STG_BFR_CON_AR, STG_BFR_EXG_AD, STG_BFR_EXG_CF/)) + call this%cfg_dv('IBOUND', '', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('TOP', 'DIS', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('BOT', 'DIS', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('AREA', 'DIS', SYNC_NDS, (/STG_BFR_CON_AR/)) + !if (this%gweInterfaceModel%dsp%idiffc > 0) then + ! call this%cfg_dv('DIFFC', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) + !end if + if (this%gweInterfaceModel%dsp%idisp > 0) then + call this%cfg_dv('ALH', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('ALV', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('ATH1', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('ATH2', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('ATV', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) + end if + call this%cfg_dv('GWFHEAD', 'FMI', SYNC_NDS, (/STG_BFR_EXG_AD/)) + call this%cfg_dv('GWFSAT', 'FMI', SYNC_NDS, (/STG_BFR_EXG_AD/)) + call this%cfg_dv('GWFSPDIS', 'FMI', SYNC_NDS, (/STG_BFR_EXG_AD/)) + call this%cfg_dv('GWFFLOWJA', 'FMI', SYNC_CON, (/STG_BFR_EXG_AD/)) + call this%cfg_dv('GWFFLOWJA', 'FMI', SYNC_EXG, (/STG_BFR_EXG_AD/), & + exg_var_name='GWFSIMVALS') + ! fill porosity from mst packages, needed for dsp + if (this%gweModel%indsp > 0 .and. this%gweModel%inmst > 0) then + call this%cfg_dv('POROSITY', 'MST', SYNC_NDS, (/STG_AFT_CON_AR/)) + end if + + end subroutine cfg_dist_vars + + !> @brief Allocate array variables for this connection + !< + subroutine allocate_arrays(this) + class(GweGweConnectionType) :: this !< the connection + + call mem_allocate(this%exgflowjaGwe, this%ig_builder%nrOfBoundaryCells, & + 'EXGFLOWJAGWT', this%memoryPath) + + end subroutine allocate_arrays + + !> @brief Set required extent of the interface grid from + !< the configuration + subroutine setGridExtent(this) + class(GweGweConnectionType) :: this !< the connection + ! local + logical(LGP) :: hasAdv, hasDsp + + hasAdv = this%gweModel%inadv > 0 + hasDsp = this%gweModel%indsp > 0 + + if (hasAdv) then + if (this%iIfaceAdvScheme == 2) then + this%exg_stencil_depth = 2 + if (this%gweModel%adv%iadvwt == 2) then + this%int_stencil_depth = 2 + end if + end if + end if + + if (hasDsp) then + if (this%iIfaceXt3d > 0) then + this%exg_stencil_depth = 2 + if (this%gweModel%dsp%ixt3d > 0) then + this%int_stencil_depth = 2 + end if + end if + end if + + end subroutine setGridExtent + + !> @brief allocate and read/set the connection's data structures + !< + subroutine gwegwecon_ar(this) + class(GweGweConnectionType) :: this !< the connection + + ! check if we can construct an interface model + ! NB: only makes sense after the models' allocate&read have been + ! called, which is why we do it here + call this%validateConnection() + + ! allocate and read base + call this%spatialcon_ar() + + ! ... and now the interface model + call this%gweInterfaceModel%model_ar() + + ! AR the movers and obs through the exchange + if (this%owns_exchange) then + !cdl implement this when MVT is ready + !cdl if (this%gweExchange%inmvt > 0) then + !cdl call this%gweExchange%mvt%mvt_ar() + !cdl end if + if (this%gweExchange%inobs > 0) then + call this%gweExchange%obs%obs_ar() + end if + end if + + end subroutine gwegwecon_ar + + !> @brief validate this connection prior to constructing + !< the interface model + subroutine validateConnection(this) + use SimVariablesModule, only: errmsg + use SimModule, only: count_errors, store_error + class(GweGweConnectionType) :: this !< this connection + + ! base validation, the spatial/geometry part + call this%SpatialModelConnectionType%validateConnection() + + ! we cannot validate this (yet) in parallel mode + if (.not. this%gweExchange%v_model1%is_local) return + if (.not. this%gweExchange%v_model2%is_local) return + + ! GWE related matters + if ((this%gweExchange%gwemodel1%inadv > 0 .and. & + this%gweExchange%gwemodel2%inadv == 0) .or. & + (this%gweExchange%gwemodel2%inadv > 0 .and. & + this%gweExchange%gwemodel1%inadv == 0)) then + write (errmsg, '(1x,a,a,a)') 'Cannot connect GWE models in exchange ', & + trim(this%gweExchange%name), ' because one model is configured with ADV & + &and the other one is not' + call store_error(errmsg) + end if + + if ((this%gweExchange%gwemodel1%indsp > 0 .and. & + this%gweExchange%gwemodel2%indsp == 0) .or. & + (this%gweExchange%gwemodel2%indsp > 0 .and. & + this%gweExchange%gwemodel1%indsp == 0)) then + write (errmsg, '(1x,a,a,a)') 'Cannot connect GWE models in exchange ', & + trim(this%gweExchange%name), ' because one model is configured with DSP & + &and the other one is not' + call store_error(errmsg) + end if + + ! abort on errors + if (count_errors() > 0) then + write (errmsg, '(a)') 'Errors occurred while processing exchange(s)' + call ustop() + end if + + end subroutine validateConnection + + subroutine gwegwecon_rp(this) + class(GweGweConnectionType) :: this !< the connection + + ! Call exchange rp routines + if (this%owns_exchange) then + call this%gweExchange%exg_rp() + end if + + end subroutine gwegwecon_rp + + !> @brief Advance this connection + !< + subroutine gwegwecon_ad(this) + class(GweGweConnectionType) :: this !< this connection + + ! recalculate dispersion ellipse + if (this%gweInterfaceModel%indsp > 0) call this%gweInterfaceModel%dsp%dsp_ad() + + if (this%owns_exchange) then + call this%gweExchange%exg_ad() + end if + + end subroutine gwegwecon_ad + + subroutine gwegwecon_fc(this, kiter, matrix_sln, rhs_sln, inwtflag) + class(GweGweConnectionType) :: this !< the connection + integer(I4B), intent(in) :: kiter !< the iteration counter + class(MatrixBaseType), pointer :: matrix_sln !< the system matrix + real(DP), dimension(:), intent(inout) :: rhs_sln !< global right-hand-side + integer(I4B), optional, intent(in) :: inwtflag !< newton-raphson flag + ! + call this%SpatialModelConnectionType%spatialcon_fc( & + kiter, matrix_sln, rhs_sln, inwtflag) + ! + ! FC the movers through the exchange + if (this%owns_exchange) then + if (this%gweExchange%inmvt > 0) then + call this%gweExchange%mvt%mvt_fc(this%gweExchange%gwemodel1%x, & + this%gweExchange%gwemodel2%x) + end if + end if + + end subroutine gwegwecon_fc + + subroutine gwegwecon_cq(this, icnvg, isuppress_output, isolnid) + class(GweGweConnectionType) :: this !< the connection + integer(I4B), intent(inout) :: icnvg !< convergence flag + integer(I4B), intent(in) :: isuppress_output !< suppress output when =1 + integer(I4B), intent(in) :: isolnid !< solution id + + call this%gweInterfaceModel%model_cq(icnvg, isuppress_output) + call this%setFlowToExchange() + + end subroutine gwegwecon_cq + + !> @brief Set the flows (flowja from interface model) to the + !< simvals in the exchange, leaving the budget calcution in there + subroutine setFlowToExchange(this) + use IndexMapModule + class(GweGweConnectionType) :: this !< this connection + ! local + integer(I4B) :: i + class(GweExchangeType), pointer :: gweEx + type(IndexMapSgnType), pointer :: map + + if (this%owns_exchange) then + gweEx => this%gweExchange + map => this%interface_map%exchange_maps(this%interface_map%prim_exg_idx) + + ! use (half of) the exchange map in reverse: + do i = 1, size(map%src_idx) + if (map%sign(i) < 0) cycle ! simvals is defined from exg%m1 => exg%m2 + gweEx%simvals(map%src_idx(i)) = & + this%gweInterfaceModel%flowja(map%tgt_idx(i)) + end do + end if + + end subroutine setFlowToExchange + + subroutine gwegwecon_bd(this, icnvg, isuppress_output, isolnid) + use BudgetModule, only: rate_accumulator + class(GweGweConnectionType) :: this !< the connection + integer(I4B), intent(inout) :: icnvg !< convergence flag + integer(I4B), intent(in) :: isuppress_output !< suppress output when =1 + integer(I4B), intent(in) :: isolnid !< solution id + + ! call exchange budget routine, also calls bd + ! for movers. + if (this%owns_exchange) then + call this%gweExchange%exg_bd(icnvg, isuppress_output, isolnid) + end if + + end subroutine gwegwecon_bd + + subroutine gwegwecon_ot(this) + class(GweGweConnectionType) :: this !< the connection + + ! Call exg_ot() here as it handles all output processing + ! based on gweExchange%simvals(:), which was correctly + ! filled from gwegwecon + if (this%owns_exchange) then + call this%gweExchange%exg_ot() + end if + + end subroutine gwegwecon_ot + + subroutine gwegwecon_da(this) + class(GweGweConnectionType) :: this !< the connection + ! local + logical(LGP) :: isOpen + + ! scalars + call mem_deallocate(this%iIfaceAdvScheme) + call mem_deallocate(this%iIfaceXt3d) + call mem_deallocate(this%exgflowSign) + + ! arrays + call mem_deallocate(this%exgflowjaGwe) + + ! interface model + call this%gweInterfaceModel%model_da() + deallocate (this%gweInterfaceModel) + + ! dealloc base + call this%spatialcon_da() + + inquire (this%iout, opened=isOpen) + if (isOpen) then + close (this%iout) + end if + + ! we need to deallocate the exchange we own: + if (this%owns_exchange) then + call this%gweExchange%exg_da() + end if + + end subroutine gwegwecon_da + + !> @brief Cast to GweGweConnectionType + !< + function CastAsGweGweConnection(obj) result(res) + implicit none + class(*), pointer, intent(inout) :: obj !< object to be cast + class(GweGweConnectionType), pointer :: res !< the GweGweConnection + + res => null() + if (.not. associated(obj)) return + + select type (obj) + class is (GweGweConnectionType) + res => obj + end select + return + end function CastAsGweGweConnection + +end module diff --git a/src/Model/Connection/GweInterfaceModel.f90 b/src/Model/Connection/GweInterfaceModel.f90 new file mode 100644 index 00000000000..5cdb422dc38 --- /dev/null +++ b/src/Model/Connection/GweInterfaceModel.f90 @@ -0,0 +1,267 @@ +module GweInterfaceModelModule + use KindModule, only: I4B, DP + use ConstantsModule, only: DONE + use MemoryManagerModule, only: mem_allocate, mem_deallocate, mem_reallocate + use MemoryHelperModule, only: create_mem_path + use NumericalModelModule, only: NumericalModelType + use GweModule, only: GweModelType, CastAsGweModel + use GwfDisuModule, only: disu_cr, CastAsDisuType + use TspFmiModule, only: fmi_cr, TspFmiType + use TspAdvModule, only: adv_cr, TspAdvType + use TspAdvOptionsModule, only: TspAdvOptionsType + use GweDspModule, only: dsp_cr, GweDspType + use GweDspOptionsModule, only: GweDspOptionsType + use GweMstModule, only: mst_cr + use TspObsModule, only: tsp_obs_cr + use GridConnectionModule + + implicit none + private + + !> The GWE Interface Model is a utility to calculate the solution's exchange + !! coefficients from the interface between a GWE model and its GWE neighbors. + !! The interface model itself will not be part of the solution, it is not + !! being solved. + !< + type, public, extends(GweModelType) :: GweInterfaceModelType + + integer(i4B), pointer :: iAdvScheme => null() !< the advection scheme: 0 = up, 1 = central, 2 = tvd + integer(i4B), pointer :: ixt3d => null() !< xt3d setting: 0 = off, 1 = lhs, 2 = rhs + real(DP), pointer :: ieqnsclfac => null() !< governing eqn scaling factor: 1: GWT, >1: GWE + + class(GridConnectionType), pointer :: gridConnection => null() !< The grid connection class will provide the interface grid + class(GweModelType), private, pointer :: owner => null() !< the real GWE model for which the exchange coefficients + !! are calculated with this interface model + + real(DP), dimension(:), pointer, contiguous :: porosity => null() !< to be filled with MST porosity + + contains + + procedure, pass(this) :: gweifmod_cr + procedure :: model_df => gweifmod_df + procedure :: model_ar => gweifmod_ar + procedure :: model_da => gweifmod_da + procedure, public :: allocate_fmi + procedure :: allocate_scalars + end type GweInterfaceModelType + +contains + + !> @brief Create the interface model, analogously to what + !< happens in gwe_cr + subroutine gweifmod_cr(this, name, iout, gridConn) + ! -- dummy + class(GweInterfaceModelType) :: this !< the GWE interface model + character(len=*), intent(in) :: name !< the interface model's name + integer(I4B), intent(in) :: iout !< the output unit + class(GridConnectionType), pointer, intent(in) :: gridConn !< the grid connection data for creating a DISU + ! local + class(*), pointer :: modelPtr + integer(I4B), target :: inobs + integer(I4B) :: adv_unit, dsp_unit + ! + this%memoryPath = create_mem_path(name) + call this%allocate_scalars(name) + ! + ! defaults + this%iAdvScheme = 0 + this%ixt3d = 0 + this%ieqnsclfac = DONE + ! + this%iout = iout + this%gridConnection => gridConn + modelPtr => gridConn%model + this%owner => CastAsGweModel(modelPtr) + ! + inobs = 0 + adv_unit = 0 + dsp_unit = 0 + if (this%owner%inadv > 0) then + this%inadv = huge(1_I4B) + adv_unit = huge(1_I4B) + end if + if (this%owner%indsp > 0) then + this%indsp = huge(1_I4B) + dsp_unit = huge(1_I4B) + end if + ! + ! create dis and packages + call disu_cr(this%dis, this%name, '', -1, this%iout) + call fmi_cr(this%fmi, this%name, 0, this%iout, this%ieqnsclfac, & + this%depvartype) + call adv_cr(this%adv, this%name, adv_unit, this%iout, this%fmi, & + this%ieqnsclfac) + call dsp_cr(this%dsp, this%name, '', -dsp_unit, this%iout, this%fmi, & + this%eqnsclfac, this%gwecommon) + call tsp_obs_cr(this%obs, inobs) + ! + ! -- Return + return + end subroutine gweifmod_cr + + !> @brief Allocate scalars associated with the interface model object + !< + subroutine allocate_scalars(this, modelname) + ! -- dummy + class(GweInterfaceModelType) :: this !< the GWE interface model + character(len=*), intent(in) :: modelname !< the model name + ! + call this%GweModelType%allocate_scalars(modelname) + ! + call mem_allocate(this%iAdvScheme, 'ADVSCHEME', this%memoryPath) + call mem_allocate(this%ixt3d, 'IXT3D', this%memoryPath) + call mem_allocate(this%ieqnsclfac, 'IEQNSCLFAC', this%memoryPath) + ! + ! -- Return + return + end subroutine allocate_scalars + + !> @brief Allocate a Flow Model Interface (FMI) object for the interface model + !< + subroutine allocate_fmi(this) + ! -- dummy + class(GweInterfaceModelType) :: this !< the GWT interface model + ! + call mem_allocate(this%fmi%gwfflowja, this%nja, 'GWFFLOWJA', & + this%fmi%memoryPath) + call mem_allocate(this%fmi%gwfhead, this%neq, 'GWFHEAD', & + this%fmi%memoryPath) + call mem_allocate(this%fmi%gwfsat, this%neq, 'GWFSAT', & + this%fmi%memoryPath) + call mem_allocate(this%fmi%gwfspdis, 3, this%neq, 'GWFSPDIS', & + this%fmi%memoryPath) + ! + ! -- Return + return + end subroutine allocate_fmi + + !> @brief Define the GWE interface model + !< + subroutine gweifmod_df(this) + ! -- dummy + class(GweInterfaceModelType) :: this !< the GWE interface model + ! -- local + class(*), pointer :: disPtr + type(TspAdvOptionsType) :: adv_options + type(GweDspOptionsType) :: dsp_options + ! + this%moffset = 0 + adv_options%iAdvScheme = this%iAdvScheme + dsp_options%ixt3d = this%ixt3d + ! + ! define DISU + disPtr => this%dis + call this%gridConnection%getDiscretization(CastAsDisuType(disPtr)) + call this%fmi%fmi_df(this%dis, 0) + ! + if (this%inadv > 0) then + call this%adv%adv_df(adv_options) + end if + if (this%indsp > 0) then + !this%dsp%idiffc = this%owner%dsp%idiffc + this%dsp%idisp = this%owner%dsp%idisp + call this%dsp%dsp_df(this%dis, dsp_options) + !if (this%dsp%idiffc > 0) then + ! call mem_reallocate(this%dsp%diffc, this%dis%nodes, 'DIFFC', & + ! trim(this%dsp%memoryPath)) + !end if + if (this%dsp%idisp > 0) then + call mem_reallocate(this%dsp%alh, this%dis%nodes, 'ALH', & + trim(this%dsp%memoryPath)) + call mem_reallocate(this%dsp%alv, this%dis%nodes, 'ALV', & + trim(this%dsp%memoryPath)) + call mem_reallocate(this%dsp%ath1, this%dis%nodes, 'ATH1', & + trim(this%dsp%memoryPath)) + call mem_reallocate(this%dsp%ath2, this%dis%nodes, 'ATH2', & + trim(this%dsp%memoryPath)) + call mem_reallocate(this%dsp%atv, this%dis%nodes, 'ATV', & + trim(this%dsp%memoryPath)) + call mem_reallocate(this%dsp%ktw, this%dis%nodes, 'KTW', & + trim(this%dsp%memoryPath)) + call mem_reallocate(this%dsp%kts, this%dis%nodes, 'KTS', & + trim(this%dsp%memoryPath)) + end if + allocate (this%mst) + call mem_allocate(this%mst%porosity, this%dis%nodes, & + 'POROSITY', create_mem_path(this%name, 'MST')) + end if + ! + ! assign or point model members to dis members + this%neq = this%dis%nodes + this%nja = this%dis%nja + this%ia => this%dis%con%ia + this%ja => this%dis%con%ja + ! + ! allocate model arrays, now that neq and nja are assigned + call this%allocate_arrays() + ! + ! -- Return + return + end subroutine gweifmod_df + + !> @brief Override allocate and read the GWE interface model and its packages + !! so that we can create stuff from memory instead of input files + !< + subroutine gweifmod_ar(this) + ! -- dummy + class(GweInterfaceModelType) :: this !< the GWE interface model + ! + call this%fmi%fmi_ar(this%ibound) + if (this%inadv > 0) then + call this%adv%adv_ar(this%dis, this%ibound) + end if + if (this%indsp > 0) then + call this%dsp%dsp_ar(this%ibound, this%mst%porosity) + end if + ! + ! -- Return + return + end subroutine gweifmod_ar + + !> @brief Clean up resources + !< + subroutine gweifmod_da(this) + ! -- dummy + class(GweInterfaceModelType) :: this !< the GWE interface model + ! + ! this + call mem_deallocate(this%iAdvScheme) + call mem_deallocate(this%ixt3d) + call mem_deallocate(this%ieqnsclfac) + ! + ! gwe packages + call this%dis%dis_da() + call this%fmi%fmi_da() + call this%adv%adv_da() + call this%dsp%dsp_da() + ! + deallocate (this%dis) + deallocate (this%fmi) + deallocate (this%adv) + deallocate (this%dsp) + ! + if (associated(this%mst)) then + call mem_deallocate(this%mst%porosity) + deallocate (this%mst) + end if + ! + ! gwe scalars + call mem_deallocate(this%inic) + call mem_deallocate(this%infmi) + call mem_deallocate(this%inadv) + call mem_deallocate(this%indsp) + call mem_deallocate(this%inssm) + call mem_deallocate(this%inmst) + call mem_deallocate(this%inmvt) + call mem_deallocate(this%inoc) + call mem_deallocate(this%inobs) + call mem_deallocate(this%eqnsclfac) + ! + ! base + call this%NumericalModelType%model_da() + ! + ! -- Return + return + end subroutine gweifmod_da + +end module GweInterfaceModelModule diff --git a/src/Model/Connection/GwtGwtConnection.f90 b/src/Model/Connection/GwtGwtConnection.f90 index 0f8ea2eb798..87b8352cbe4 100644 --- a/src/Model/Connection/GwtGwtConnection.f90 +++ b/src/Model/Connection/GwtGwtConnection.f90 @@ -154,7 +154,7 @@ subroutine gwtgwtcon_df(this) ! determine advection scheme (the GWT-GWT exchange ! has been read at this point) this%iIfaceAdvScheme = this%gwtExchange%iAdvScheme - + ! ! determine xt3d setting on interface- (TODO_MJR: default is on?) this%iIfaceXt3d = this%gwtExchange%ixt3d @@ -377,11 +377,11 @@ subroutine gwtgwtcon_fc(this, kiter, matrix_sln, rhs_sln, inwtflag) class(MatrixBaseType), pointer :: matrix_sln !< the system matrix real(DP), dimension(:), intent(inout) :: rhs_sln !< global right-hand-side integer(I4B), optional, intent(in) :: inwtflag !< newton-raphson flag - ! local + ! call this%SpatialModelConnectionType%spatialcon_fc( & kiter, matrix_sln, rhs_sln, inwtflag) - + ! ! FC the movers through the exchange if (this%owns_exchange) then if (this%gwtExchange%inmvt > 0) then diff --git a/src/Model/Connection/GwtInterfaceModel.f90 b/src/Model/Connection/GwtInterfaceModel.f90 index 4adfda4c36d..59d5eec3827 100644 --- a/src/Model/Connection/GwtInterfaceModel.f90 +++ b/src/Model/Connection/GwtInterfaceModel.f90 @@ -18,10 +18,11 @@ module GwtInterfaceModelModule implicit none private - !> The GWT Interface Model is a utility to calculate the solution's - !! exchange coefficients from the interface between a GWT model and - !! its GWT neighbors. The interface model itself will not be part - !! of the solution, it is not being solved. + !> The GWT Interface Model is a utility to calculate the solution's exchange + !! coefficients from the interface between a GWT model and its GWT neighbors. + !! The interface model itself will not be part of the solution, it is not + !! being solved. + !< type, public, extends(GwtModelType) :: GwtInterfaceModelType integer(i4B), pointer :: iAdvScheme => null() !< the advection scheme: 0 = up, 1 = central, 2 = tvd @@ -46,6 +47,7 @@ module GwtInterfaceModelModule !> @brief Create the interface model, analogously to what !< happens in gwt_cr subroutine gwtifmod_cr(this, name, iout, gridConn) + ! -- dummy class(GwtInterfaceModelType) :: this !< the GWT interface model character(len=*), intent(in) :: name !< the interface model's name integer(I4B), intent(in) :: iout !< the output unit @@ -54,20 +56,20 @@ subroutine gwtifmod_cr(this, name, iout, gridConn) class(*), pointer :: modelPtr integer(I4B), target :: inobs integer(I4B) :: adv_unit, dsp_unit - + ! this%memoryPath = create_mem_path(name) call this%allocate_scalars(name) - + ! ! defaults this%iAdvScheme = 0 this%ixt3d = 0 this%ieqnsclfac = DONE - + ! this%iout = iout this%gridConnection => gridConn modelPtr => gridConn%model this%owner => CastAsGwtModel(modelPtr) - + ! inobs = 0 adv_unit = 0 dsp_unit = 0 @@ -79,7 +81,7 @@ subroutine gwtifmod_cr(this, name, iout, gridConn) this%indsp = huge(1_I4B) dsp_unit = huge(1_I4B) end if - + ! ! create dis and packages call disu_cr(this%dis, this%name, '', -1, this%iout) call fmi_cr(this%fmi, this%name, 0, this%iout, this%ieqnsclfac, & @@ -88,24 +90,34 @@ subroutine gwtifmod_cr(this, name, iout, gridConn) this%ieqnsclfac) call dsp_cr(this%dsp, this%name, '', -dsp_unit, this%iout, this%fmi) call tsp_obs_cr(this%obs, inobs) - + ! + ! -- Return + return end subroutine gwtifmod_cr + !> @brief Allocate scalars associated with the interface model object + !< subroutine allocate_scalars(this, modelname) + ! -- dummy class(GwtInterfaceModelType) :: this !< the GWT interface model character(len=*), intent(in) :: modelname !< the model name - + ! call this%GwtModelType%allocate_scalars(modelname) - + ! call mem_allocate(this%iAdvScheme, 'ADVSCHEME', this%memoryPath) call mem_allocate(this%ixt3d, 'IXT3D', this%memoryPath) call mem_allocate(this%ieqnsclfac, 'IEQNSCLFAC', this%memoryPath) - + ! + ! -- Return + return end subroutine allocate_scalars + !> @brief Allocate a Flow Model Interface (FMI) object for the interface model + !< subroutine allocate_fmi(this) + ! -- dummy class(GwtInterfaceModelType) :: this !< the GWT interface model - + ! call mem_allocate(this%fmi%gwfflowja, this%nja, 'GWFFLOWJA', & this%fmi%memoryPath) call mem_allocate(this%fmi%gwfhead, this%neq, 'GWFHEAD', & @@ -114,27 +126,30 @@ subroutine allocate_fmi(this) this%fmi%memoryPath) call mem_allocate(this%fmi%gwfspdis, 3, this%neq, 'GWFSPDIS', & this%fmi%memoryPath) - + ! + ! -- Return + return end subroutine allocate_fmi !> @brief Define the GWT interface model !< subroutine gwtifmod_df(this) + ! -- dummy class(GwtInterfaceModelType) :: this !< the GWT interface model - ! local + ! -- local class(*), pointer :: disPtr type(TspAdvOptionsType) :: adv_options type(GwtDspOptionsType) :: dsp_options - + ! this%moffset = 0 adv_options%iAdvScheme = this%iAdvScheme dsp_options%ixt3d = this%ixt3d - + ! ! define DISU disPtr => this%dis call this%gridConnection%getDiscretization(CastAsDisuType(disPtr)) - call this%fmi%fmi_df(this%dis) - + call this%fmi%fmi_df(this%dis, 1) + ! if (this%inadv > 0) then call this%adv%adv_df(adv_options) end if @@ -162,7 +177,7 @@ subroutine gwtifmod_df(this) call mem_allocate(this%mst%thetam, this%dis%nodes, & 'THETAM', create_mem_path(this%name, 'MST')) end if - + ! ! assign or point model members to dis members this%neq = this%dis%nodes this%nja = this%dis%nja @@ -171,15 +186,18 @@ subroutine gwtifmod_df(this) ! ! allocate model arrays, now that neq and nja are assigned call this%allocate_arrays() - + ! + ! -- Return + return end subroutine gwtifmod_df - !> @brief Override allocate and read the GWT interface model and its - !! packages so that we can create stuff from memory instead of input - !< files + !> @brief Override allocate and read the GWT interface model and its packages + !! so that we can create stuff from memory instead of input files + !< subroutine gwtifmod_ar(this) + ! -- dummy class(GwtInterfaceModelType) :: this !< the GWT interface model - + ! call this%fmi%fmi_ar(this%ibound) if (this%inadv > 0) then call this%adv%adv_ar(this%dis, this%ibound) @@ -187,35 +205,39 @@ subroutine gwtifmod_ar(this) if (this%indsp > 0) then call this%dsp%dsp_ar(this%ibound, this%mst%thetam) end if - + ! + ! -- Return + return end subroutine gwtifmod_ar !> @brief Clean up resources !< subroutine gwtifmod_da(this) + ! -- dummy class(GwtInterfaceModelType) :: this !< the GWT interface model + ! ! this call mem_deallocate(this%iAdvScheme) call mem_deallocate(this%ixt3d) call mem_deallocate(this%ieqnsclfac) - + ! ! gwt packages call this%dis%dis_da() call this%fmi%fmi_da() call this%adv%adv_da() call this%dsp%dsp_da() - + ! deallocate (this%dis) deallocate (this%fmi) deallocate (this%adv) deallocate (this%dsp) - + ! if (associated(this%mst)) then call mem_deallocate(this%mst%thetam) deallocate (this%mst) end if - + ! ! gwt scalars call mem_deallocate(this%inic) call mem_deallocate(this%infmi) @@ -227,10 +249,12 @@ subroutine gwtifmod_da(this) call mem_deallocate(this%inoc) call mem_deallocate(this%inobs) call mem_deallocate(this%eqnsclfac) - + ! ! base call this%NumericalModelType%model_da() - + ! + ! -- Return + return end subroutine gwtifmod_da end module GwtInterfaceModelModule diff --git a/src/Model/GroundWaterEnergy/gwe1.f90 b/src/Model/GroundWaterEnergy/gwe1.f90 new file mode 100644 index 00000000000..1053a132959 --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1.f90 @@ -0,0 +1,993 @@ +! Groundwater Energy Transport (GWE) Model + +module GweModule + + use KindModule, only: DP, I4B + use InputOutputModule, only: ParseLine, upcase + use ConstantsModule, only: LENFTYPE, LENMEMPATH, DZERO, LENPAKLOC, & + LENVARNAME, LENPACKAGETYPE + use VersionModule, only: write_listfile_header + use NumericalModelModule, only: NumericalModelType + use BaseModelModule, only: BaseModelType + use BndModule, only: BndType, AddBndToList, GetBndFromList + use GweDspModule, only: GweDspType + use GweMstModule, only: GweMstType + use BudgetModule, only: BudgetType + use GweInputDataModule, only: GweInputDataType + use TransportModelModule + use MatrixBaseModule + + implicit none + + private + public :: gwe_cr + public :: GweModelType + public :: CastAsGweModel + + public :: GWE_NBASEPKG, GWE_NMULTIPKG + public :: GWE_BASEPKG, GWE_MULTIPKG + character(len=LENVARNAME), parameter :: dvt = 'TEMPERATURE ' !< dependent variable type, varies based on model type + character(len=LENVARNAME), parameter :: dvu = 'ENERGY ' !< dependent variable unit of measure, either "mass" or "energy" + character(len=LENVARNAME), parameter :: dvua = 'E ' !< abbreviation of the dependent variable unit of measure, either "M" or "E" + + type, extends(TransportModelType) :: GweModelType + + type(GweInputDataType), pointer :: gwecommon => null() !< container for data shared with multiple packages + type(GweMstType), pointer :: mst => null() !< mass storage and transfer package + type(GweDspType), pointer :: dsp => null() !< dispersion package + integer(I4B), pointer :: inmst => null() ! unit number MST + integer(I4B), pointer :: indsp => null() ! unit number DSP + + contains + + procedure :: model_df => gwe_df + procedure :: model_ac => gwe_ac + procedure :: model_mc => gwe_mc + procedure :: model_ar => gwe_ar + procedure :: model_rp => gwe_rp + procedure :: model_ad => gwe_ad + procedure :: model_cf => gwe_cf + procedure :: model_fc => gwe_fc + procedure :: model_cc => gwe_cc + procedure :: model_cq => gwe_cq + procedure :: model_bd => gwe_bd + procedure :: model_ot => gwe_ot + procedure :: model_da => gwe_da + procedure :: model_bdentry => gwe_bdentry + procedure :: allocate_scalars + procedure :: get_iasym => gwe_get_iasym + procedure :: create_packages => create_gwe_packages + procedure, private :: create_bndpkgs + procedure, private :: package_create + + end type GweModelType + + !> @brief GWE base package array descriptors + !! + !! GWE6 model base package types. Only listed packages are candidates + !! for input and these will be loaded in the order specified. + !< + integer(I4B), parameter :: GWE_NBASEPKG = 50 + character(len=LENPACKAGETYPE), dimension(GWE_NBASEPKG) :: GWE_BASEPKG + data GWE_BASEPKG/'DIS6 ', 'DISV6', 'DISU6', ' ', ' ', & ! 5 + &'IC6 ', 'FMI6 ', 'MST6 ', 'ADV6 ', ' ', & ! 10 + &'DSP6 ', 'SSM6 ', 'MVT6 ', 'OC6 ', ' ', & ! 15 + &'OBS6 ', ' ', ' ', ' ', ' ', & ! 20 + &30*' '/ ! 50 + + !> @brief GWE multi package array descriptors + !! + !! GWE6 model multi-instance package types. Only listed packages are + !! candidates for input and these will be loaded in the order specified. + !< + integer(I4B), parameter :: GWE_NMULTIPKG = 50 + character(len=LENPACKAGETYPE), dimension(GWE_NMULTIPKG) :: GWE_MULTIPKG + data GWE_MULTIPKG/'CNT6 ', 'SRC6 ', 'LKE6 ', 'SFE6 ', ' ', & ! 5 + &'MWE6 ', 'UZE6 ', 'API6 ', ' ', ' ', & ! 10 + &40*' '/ ! 50 + + ! -- size of supported model package arrays + integer(I4B), parameter :: NIUNIT_GWE = GWE_NBASEPKG + GWE_NMULTIPKG + +contains + + !> @brief Create a new groundwater energy transport model object + !< + subroutine gwe_cr(filename, id, modelname) + ! -- modules + use ListsModule, only: basemodellist + use BaseModelModule, only: AddBaseModelToList + use ConstantsModule, only: LINELENGTH, LENPACKAGENAME + use MemoryHelperModule, only: create_mem_path + use MemoryManagerExtModule, only: mem_set_value + use GwfNamInputModule, only: GwfNamParamFoundType + use BudgetModule, only: budget_cr + use GweInputDataModule, only: gweshared_dat_cr + ! -- dummy + character(len=*), intent(in) :: filename + integer(I4B), intent(in) :: id + character(len=*), intent(in) :: modelname + ! -- local + integer(I4B) :: indis + type(GweModelType), pointer :: this + class(BaseModelType), pointer :: model + ! + ! -- Allocate a new GWE Model (this) and add it to basemodellist + allocate (this) + ! + ! -- Set memory path before allocation in memory manager can be done + this%memoryPath = create_mem_path(modelname) + ! + ! -- Allocate scalars and add model to basemodellist + call this%allocate_scalars(modelname) + ! + ! -- Set labels for transport model - needed by create_packages() below + call this%set_tsp_labels(this%macronym, dvt, dvu, dvua) + ! + model => this + call AddBaseModelToList(basemodellist, model) + ! + ! -- Instantiate shared data container + call gweshared_dat_cr(this%gwecommon) + ! + ! -- Call parent class routine + call this%tsp_cr(filename, id, modelname, 'GWE', indis, this%gwecommon) + ! + ! -- create model packages + call this%create_packages(indis) + ! + ! -- Return + return + end subroutine gwe_cr + + !> @brief Define packages of the GWE model + !! + !! This subroutine defines a gwe model type. Steps include: + !! - call df routines for each package + !! - set variables and pointers + !< + subroutine gwe_df(this) + ! -- modules + use SimModule, only: store_error + use GweInputDataModule, only: gweshared_dat_df + ! -- dummy + class(GweModelType) :: this + ! -- local + integer(I4B) :: ip + class(BndType), pointer :: packobj + ! + ! -- Define packages and utility objects + call this%dis%dis_df() + call this%fmi%fmi_df(this%dis, 0) + if (this%inmvt > 0) call this%mvt%mvt_df(this%dis) + if (this%inadv > 0) call this%adv%adv_df() + if (this%indsp > 0) call this%dsp%dsp_df(this%dis) + if (this%inssm > 0) call this%ssm%ssm_df() + call this%oc%oc_df() + call this%budget%budget_df(NIUNIT_GWE, this%depvarunit, & + this%depvarunitabbrev) + ! + ! -- Check for SSM package + if (this%inssm == 0) then + if (this%fmi%nflowpack > 0) then + call store_error('Flow model has boundary packages, but there & + &is no SSM package. The SSM package must be activated.', & + terminate=.TRUE.) + end if + end if + ! + ! -- Assign or point model members to dis members + this%neq = this%dis%nodes + this%nja = this%dis%nja + this%ia => this%dis%con%ia + this%ja => this%dis%con%ja + ! + ! -- Define shared data (cpw, rhow, latent heat of vaporization) + call this%gwecommon%gweshared_dat_df(this%neq) + ! + ! -- Allocate model arrays, now that neq and nja are assigned + call this%allocate_arrays() + ! + ! -- Define packages and assign iout for time series managers + do ip = 1, this%bndlist%Count() + packobj => GetBndFromList(this%bndlist, ip) + call packobj%bnd_df(this%neq, this%dis) + packobj%TsManager%iout = this%iout + packobj%TasManager%iout = this%iout + end do + ! + ! -- Store information needed for observations + call this%obs%obs_df(this%iout, this%name, 'GWE', this%dis) + ! + ! -- Return + return + end subroutine gwe_df + + !> @brief Add the internal connections of this model to the sparse matrix + !< + subroutine gwe_ac(this, sparse) + ! -- modules + use SparseModule, only: sparsematrix + ! -- dummy + class(GweModelType) :: this + type(sparsematrix), intent(inout) :: sparse + ! -- local + class(BndType), pointer :: packobj + integer(I4B) :: ip + ! + ! -- Add the internal connections of this model to sparse + call this%dis%dis_ac(this%moffset, sparse) + if (this%indsp > 0) & + call this%dsp%dsp_ac(this%moffset, sparse) + ! + ! -- Add any package connections + do ip = 1, this%bndlist%Count() + packobj => GetBndFromList(this%bndlist, ip) + call packobj%bnd_ac(this%moffset, sparse) + end do + ! + ! -- Return + return + end subroutine gwe_ac + + !> @brief Map the positions of the GWE model connections in the numerical + !! solution coefficient matrix. + !< + subroutine gwe_mc(this, matrix_sln) + ! -- dummy + class(GweModelType) :: this + class(MatrixBaseType), pointer :: matrix_sln !< global system matrix + ! -- local + class(BndType), pointer :: packobj + integer(I4B) :: ip + ! + ! -- Find the position of each connection in the global ia, ja structure + ! and store them in idxglo. + call this%dis%dis_mc(this%moffset, this%idxglo, matrix_sln) + ! + if (this%indsp > 0) call this%dsp%dsp_mc(this%moffset, matrix_sln) + ! + ! -- Map any package connections + do ip = 1, this%bndlist%Count() + packobj => GetBndFromList(this%bndlist, ip) + call packobj%bnd_mc(this%moffset, matrix_sln) + end do + ! + ! -- Return + return + end subroutine gwe_mc + + !> @brief GWE Model Allocate and Read + !! + !! This subroutine: + !! - allocates and reads packages that are part of this model, + !! - allocates memory for arrays used by this model object + !< + subroutine gwe_ar(this) + ! -- modules + use ConstantsModule, only: DHNOFLO + ! -- dummy + class(GweModelType) :: this + ! -- locals + integer(I4B) :: ip + class(BndType), pointer :: packobj + ! + ! -- Allocate and read modules attached to model + call this%fmi%fmi_ar(this%ibound) + if (this%inmvt > 0) call this%mvt%mvt_ar() + if (this%inic > 0) call this%ic%ic_ar(this%x) + if (this%inmst > 0) call this%mst%mst_ar(this%dis, this%ibound) + if (this%inadv > 0) call this%adv%adv_ar(this%dis, this%ibound) + if (this%indsp > 0) call this%dsp%dsp_ar(this%ibound, this%mst%porosity) + if (this%inssm > 0) call this%ssm%ssm_ar(this%dis, this%ibound, this%x) + if (this%inobs > 0) call this%obs%tsp_obs_ar(this%ic, this%x, this%flowja) + ! + ! -- Set governing equation scale factor + this%eqnsclfac = this%gwecommon%gwerhow * this%gwecommon%gwecpw + ! + ! -- Call dis_ar to write binary grid file + !call this%dis%dis_ar(this%npf%icelltype) + ! + ! -- set up output control + call this%oc%oc_ar(this%x, this%dis, DHNOFLO, this%depvartype) + call this%budget%set_ibudcsv(this%oc%ibudcsv) + ! + ! -- Package input files now open, so allocate and read + do ip = 1, this%bndlist%Count() + packobj => GetBndFromList(this%bndlist, ip) + call packobj%set_pointers(this%dis%nodes, this%ibound, this%x, & + this%xold, this%flowja) + ! -- Read and allocate package + call packobj%bnd_ar() + end do + ! + ! -- Return + return + end subroutine gwe_ar + + !> @brief GWE Model Read and Prepare + !! + !! This subroutine calls the attached packages' read and prepare routines + !< + subroutine gwe_rp(this) + ! -- modules + use TdisModule, only: readnewdata + ! -- dummy + class(GweModelType) :: this + ! -- local + class(BndType), pointer :: packobj + integer(I4B) :: ip + ! + ! -- In fmi, check for mvt and mvrbudobj consistency + call this%fmi%fmi_rp(this%inmvt) + if (this%inmvt > 0) call this%mvt%mvt_rp() + ! + ! -- Check with TDIS on whether or not it is time to RP + if (.not. readnewdata) return + ! + ! -- Read and prepare + if (this%inoc > 0) call this%oc%oc_rp() + if (this%inssm > 0) call this%ssm%ssm_rp() + do ip = 1, this%bndlist%Count() + packobj => GetBndFromList(this%bndlist, ip) + call packobj%bnd_rp() + call packobj%bnd_rp_obs() + end do + ! + ! -- Return + return + end subroutine gwe_rp + + !> @brief GWE Model Time Step Advance + !! + !! This subroutine calls the attached packages' advance subroutines + !< + subroutine gwe_ad(this) + ! -- modules + use SimVariablesModule, only: isimcheck, iFailedStepRetry + ! -- dummy + class(GweModelType) :: this + class(BndType), pointer :: packobj + ! -- local + integer(I4B) :: irestore + integer(I4B) :: ip, n + ! + ! -- Reset state variable + irestore = 0 + if (iFailedStepRetry > 0) irestore = 1 + if (irestore == 0) then + ! + ! -- copy x into xold + do n = 1, this%dis%nodes + if (this%ibound(n) == 0) then + this%xold(n) = DZERO + else + this%xold(n) = this%x(n) + end if + end do + else + ! + ! -- copy xold into x if this time step is a redo + do n = 1, this%dis%nodes + this%x(n) = this%xold(n) + end do + end if + ! + ! -- Advance fmi + call this%fmi%fmi_ad(this%x) + ! + ! -- Advance + if (this%indsp > 0) call this%dsp%dsp_ad() + if (this%inssm > 0) call this%ssm%ssm_ad() + do ip = 1, this%bndlist%Count() + packobj => GetBndFromList(this%bndlist, ip) + call packobj%bnd_ad() + if (isimcheck > 0) then + call packobj%bnd_ck() + end if + end do + ! + ! -- Push simulated values to preceding time/subtime step + call this%obs%obs_ad() + ! + ! -- Return + return + end subroutine gwe_ad + + !> @brief GWE Model calculate coefficients + !! + !! This subroutine calls the attached packages' calculate coefficients + !! subroutines + !< + subroutine gwe_cf(this, kiter) + ! -- modules + ! -- dummy + class(GweModelType) :: this + integer(I4B), intent(in) :: kiter + ! -- local + class(BndType), pointer :: packobj + integer(I4B) :: ip + ! + ! -- Call package cf routines + do ip = 1, this%bndlist%Count() + packobj => GetBndFromList(this%bndlist, ip) + call packobj%bnd_cf() + end do + ! + ! -- Return + return + end subroutine gwe_cf + + !> @brief GWE Model fill coefficients + !! + !! This subroutine calls the attached packages' fill coefficients + !! subroutines + !< + subroutine gwe_fc(this, kiter, matrix_sln, inwtflag) + ! -- modules + ! -- dummy + class(GweModelType) :: this + integer(I4B), intent(in) :: kiter + class(MatrixBaseType), pointer :: matrix_sln + integer(I4B), intent(in) :: inwtflag + ! -- local + class(BndType), pointer :: packobj + integer(I4B) :: ip + ! + ! -- call fc routines + call this%fmi%fmi_fc(this%dis%nodes, this%xold, this%nja, matrix_sln, & + this%idxglo, this%rhs) + if (this%inmvt > 0) then + call this%mvt%mvt_fc(this%x, this%x) + end if + if (this%inmst > 0) then + call this%mst%mst_fc(this%dis%nodes, this%xold, this%nja, matrix_sln, & + this%idxglo, this%x, this%rhs, kiter) + end if + if (this%inadv > 0) then + call this%adv%adv_fc(this%dis%nodes, matrix_sln, this%idxglo, this%x, & + this%rhs) + end if + if (this%indsp > 0) then + call this%dsp%dsp_fc(kiter, this%dis%nodes, this%nja, matrix_sln, & + this%idxglo, this%rhs, this%x) + end if + if (this%inssm > 0) then + call this%ssm%ssm_fc(matrix_sln, this%idxglo, this%rhs) + end if + ! + ! -- packages + do ip = 1, this%bndlist%Count() + packobj => GetBndFromList(this%bndlist, ip) + call packobj%bnd_fc(this%rhs, this%ia, this%idxglo, matrix_sln) + end do + ! + ! -- Return + return + end subroutine gwe_fc + + !> @brief GWE Model Final Convergence Check + !! + !! If MVR/MVT is active, this subroutine calls the MVR convergence check + !! subroutines. + !< + subroutine gwe_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak) + ! -- dummy + class(GweModelType) :: this + integer(I4B), intent(in) :: innertot + integer(I4B), intent(in) :: kiter + integer(I4B), intent(in) :: iend + integer(I4B), intent(in) :: icnvgmod + character(len=LENPAKLOC), intent(inout) :: cpak + integer(I4B), intent(inout) :: ipak + real(DP), intent(inout) :: dpak + ! -- local + ! -- formats + ! + ! -- If mover is on, then at least 2 outers required + if (this%inmvt > 0) call this%mvt%mvt_cc(kiter, iend, icnvgmod, cpak, dpak) + ! + ! -- Return + return + end subroutine gwe_cc + + !> @brief GWE Model calculate flow + !! + !! This subroutine calls the attached packages' intercell flows (flow ja) + !< + subroutine gwe_cq(this, icnvg, isuppress_output) + ! -- modules + use SparseModule, only: csr_diagsum + ! -- dummy + class(GweModelType) :: this + integer(I4B), intent(in) :: icnvg + integer(I4B), intent(in) :: isuppress_output + ! -- local + integer(I4B) :: i + integer(I4B) :: ip + class(BndType), pointer :: packobj + ! + ! -- Construct the flowja array. Flowja is calculated each time, even if + ! output is suppressed. (flowja is positive into a cell.) The diagonal + ! position of the flowja array will contain the flow residual after + ! these routines are called, so each package is responsible for adding + ! its flow to this diagonal position. + do i = 1, this%nja + this%flowja(i) = DZERO + end do + if (this%inadv > 0) call this%adv%adv_cq(this%x, this%flowja) + if (this%indsp > 0) call this%dsp%dsp_cq(this%x, this%flowja) + if (this%inmst > 0) call this%mst%mst_cq(this%dis%nodes, this%x, this%xold, & + this%flowja) + if (this%inssm > 0) call this%ssm%ssm_cq(this%flowja) + if (this%infmi > 0) call this%fmi%fmi_cq(this%x, this%flowja) + ! + ! -- Go through packages and call cq routines. cf() routines are called + ! first to regenerate non-linear terms to be consistent with the final + ! conc solution. + do ip = 1, this%bndlist%Count() + packobj => GetBndFromList(this%bndlist, ip) + call packobj%bnd_cf() + call packobj%bnd_cq(this%x, this%flowja) + end do + ! + ! -- Finalize calculation of flowja by adding face flows to the diagonal. + ! This results in the flow residual being stored in the diagonal + ! position for each cell. + call csr_diagsum(this%dis%con%ia, this%flowja) + ! + ! -- Return + return + end subroutine gwe_cq + + !> @brief GWE Model Budget + !! + !! This subroutine: + !! - calculates intercell flows (flowja) + !! - calculates package contributions to the model budget + !< + subroutine gwe_bd(this, icnvg, isuppress_output) + use ConstantsModule, only: DZERO + ! -- dummy + class(GweModelType) :: this + integer(I4B), intent(in) :: icnvg + integer(I4B), intent(in) :: isuppress_output + ! -- local + integer(I4B) :: ip + class(BndType), pointer :: packobj + ! + ! -- Save the solution convergence flag + this%icnvg = icnvg + ! + ! -- Budget routines (start by resetting). Sole purpose of this section + ! is to add in and outs to model budget. All ins and out for a model + ! should be added here to this%budget. In a subsequent exchange call, + ! exchange flows might also be added. + call this%budget%reset() + if (this%inmst > 0) call this%mst%mst_bd(isuppress_output, this%budget) + if (this%inssm > 0) call this%ssm%ssm_bd(isuppress_output, this%budget) + if (this%infmi > 0) call this%fmi%fmi_bd(isuppress_output, this%budget) + if (this%inmvt > 0) call this%mvt%mvt_bd(this%x, this%x) + do ip = 1, this%bndlist%Count() + packobj => GetBndFromList(this%bndlist, ip) + call packobj%bnd_bd(this%budget) + end do + ! + ! -- Return + return + end subroutine gwe_bd + + !> @brief GWE Model Output + !! + !! This subroutine calls the parent class output routine. + !< + subroutine gwe_ot(this) + ! -- dummy + class(GweModelType) :: this + ! -- local + integer(I4B) :: icbcfl + integer(I4B) :: icbcun + ! -- formats + ! + ! -- Initialize + icbcfl = 0 + ! + ! -- Because mst belongs to gwe, call mst_ot_flow directly (and not from parent) + if (this%oc%oc_save('BUDGET')) icbcfl = 1 + icbcun = this%oc%oc_save_unit('BUDGET') + if (this%inmst > 0) call this%mst%mst_ot_flow(icbcfl, icbcun) + ! + ! -- Call parent class _ot routines. + call this%tsp_ot(this%inmst) + ! + ! -- Return + return + end subroutine gwe_ot + + !> @brief Deallocate + !! + !! Deallocate memmory at conclusion of model run + !< + subroutine gwe_da(this) + ! -- modules + use MemoryManagerModule, only: mem_deallocate + use MemoryManagerExtModule, only: memorylist_remove + use SimVariablesModule, only: idm_context + ! -- dummy + class(GweModelType) :: this + ! -- local + integer(I4B) :: ip + class(BndType), pointer :: packobj + ! + ! -- Deallocate idm memory + call memorylist_remove(this%name, 'NAM', idm_context) + call memorylist_remove(component=this%name, context=idm_context) + ! + ! -- Internal flow packages deallocate + call this%dis%dis_da() + call this%ic%ic_da() + call this%fmi%fmi_da() + call this%adv%adv_da() + call this%dsp%dsp_da() + call this%ssm%ssm_da() + call this%mst%mst_da() + call this%mvt%mvt_da() + call this%budget%budget_da() + call this%oc%oc_da() + call this%obs%obs_da() + call this%gwecommon%gweshared_dat_da() + ! + ! -- Internal package objects + deallocate (this%dis) + deallocate (this%ic) + deallocate (this%fmi) + deallocate (this%adv) + deallocate (this%dsp) + deallocate (this%ssm) + deallocate (this%mst) + deallocate (this%mvt) + deallocate (this%budget) + deallocate (this%oc) + deallocate (this%obs) + nullify (this%gwecommon) + ! + ! -- Boundary packages + do ip = 1, this%bndlist%Count() + packobj => GetBndFromList(this%bndlist, ip) + call packobj%bnd_da() + deallocate (packobj) + end do + ! + ! -- Scalars + call mem_deallocate(this%inmst) + call mem_deallocate(this%indsp) + ! + ! -- Parent class members + call this%TransportModelType%tsp_da() + ! + ! -- NumericalModelType + call this%NumericalModelType%model_da() + ! + ! -- Return + return + end subroutine gwe_da + + !> @brief GroundWater Energy Transport Model Budget Entry + !! + !! This subroutine adds a budget entry to the flow budget. It was added as + !! a method for the gwe model object so that the exchange object could add its + !! contributions. + !< + subroutine gwe_bdentry(this, budterm, budtxt, rowlabel) + ! -- modules + use ConstantsModule, only: LENBUDTXT + use TdisModule, only: delt + ! -- dummy + class(GweModelType) :: this + real(DP), dimension(:, :), intent(in) :: budterm + character(len=LENBUDTXT), dimension(:), intent(in) :: budtxt + character(len=*), intent(in) :: rowlabel + ! + call this%budget%addentry(budterm, delt, budtxt, rowlabel=rowlabel) + ! + ! -- Return + return + end subroutine gwe_bdentry + + !> @brief return 1 if any package causes the matrix to be asymmetric. + !! Otherwise return 0. + !< + function gwe_get_iasym(this) result(iasym) + class(GweModelType) :: this + ! -- local + integer(I4B) :: iasym + integer(I4B) :: ip + class(BndType), pointer :: packobj + ! + ! -- Start by setting iasym to zero + iasym = 0 + ! + ! -- ADV + if (this%inadv > 0) then + if (this%adv%iasym /= 0) iasym = 1 + end if + ! + ! -- DSP + if (this%indsp > 0) then + if (this%dsp%ixt3d /= 0) iasym = 1 + end if + ! + ! -- Check for any packages that introduce matrix asymmetry + do ip = 1, this%bndlist%Count() + packobj => GetBndFromList(this%bndlist, ip) + if (packobj%iasym /= 0) iasym = 1 + end do + ! + ! -- Return + return + end function gwe_get_iasym + + !> Allocate memory for non-allocatable members + !! + !! A subroutine for allocating the scalars specific to the GWE model type. + !! Additional scalars used by the parent class are allocated by the parent + !! class. + !< + subroutine allocate_scalars(this, modelname) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweModelType) :: this + character(len=*), intent(in) :: modelname + ! + ! -- allocate parent class scalars + call this%allocate_tsp_scalars(modelname) + ! + ! -- allocate members that are part of model class + call mem_allocate(this%inmst, 'INMST', this%memoryPath) + call mem_allocate(this%indsp, 'INDSP', this%memoryPath) + ! + this%inmst = 0 + this%indsp = 0 + ! + ! -- Return + return + end subroutine allocate_scalars + + !> @brief Create boundary condition packages for this model + !! + !! This subroutine calls the package create routines for packages activated + !! by the user. + !< + subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & + inunit, iout) + ! -- modules + use ConstantsModule, only: LINELENGTH + use SimModule, only: store_error + use GweCntModule, only: cnt_create + !use GweSrcModule, only: src_create + !use GweLkeModule, only: lke_create + !use GweSfeModule, only: sfe_create + !use GweMweModule, only: mwe_create + !use GweUzeModule, only: uze_create + use ApiModule, only: api_create + ! -- dummy + class(GweModelType) :: this + character(len=*), intent(in) :: filtyp + character(len=LINELENGTH) :: errmsg + integer(I4B), intent(in) :: ipakid + integer(I4B), intent(in) :: ipaknum + character(len=*), intent(in) :: pakname + character(len=*), intent(in) :: mempath + integer(I4B), intent(in) :: inunit + integer(I4B), intent(in) :: iout + ! -- local + class(BndType), pointer :: packobj + class(BndType), pointer :: packobj2 + integer(I4B) :: ip + ! + ! -- This part creates the package object + select case (filtyp) + case ('CNT6') + call cnt_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + pakname, this%depvartype, mempath) + !case ('SRC6') + ! call src_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + ! pakname, this%tsplab, this%gwecommon) + !case ('LKE6') + ! call lke_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + ! pakname, this%fmi, this%tsplab, this%eqnsclfac, & + ! this%gwecommon) + !case ('SFE6') + ! call sfe_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + ! pakname, this%fmi, this%tsplab, this%eqnsclfac, & + ! this%gwecommon) + !case ('MWE6') + ! call mwe_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + ! pakname, this%fmi, this%tsplab, this%eqnsclfac, & + ! this%gwecommon) + !case ('UZE6') + ! call uze_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + ! pakname, this%fmi, this%tsplab, this%eqnsclfac, & + ! this%gwecommon) + !case('API6') + ! call api_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + ! pakname) + case default + write (errmsg, *) 'Invalid package type: ', filtyp + call store_error(errmsg, terminate=.TRUE.) + end select + ! + ! -- Packages is the bndlist that is associated with the parent model + ! -- The following statement puts a pointer to this package in the ipakid + ! -- position of packages. + do ip = 1, this%bndlist%Count() + packobj2 => GetBndFromList(this%bndlist, ip) + if (packobj2%packName == pakname) then + write (errmsg, '(a,a)') 'Cannot create package. Package name '// & + 'already exists: ', trim(pakname) + call store_error(errmsg, terminate=.TRUE.) + end if + end do + call AddBndToList(this%bndlist, packobj) + ! + ! -- Return + return + end subroutine package_create + + !> @brief Cast to GweModelType + !< + function CastAsGweModel(model) result(gwemodel) + class(*), pointer :: model !< The object to be cast + class(GweModelType), pointer :: gwemodel !< The GWE model + + gwemodel => null() + if (.not. associated(model)) return + select type (model) + type is (GweModelType) + gwemodel => model + end select + ! + ! -- Return + return + end function CastAsGweModel + + !> @brief Source package info and begin to process + !< + subroutine create_bndpkgs(this, bndpkgs, pkgtypes, pkgnames, & + mempaths, inunits) + ! -- modules + use ConstantsModule, only: LINELENGTH, LENPACKAGENAME + use CharacterStringModule, only: CharacterStringType + ! -- dummy + class(GweModelType) :: this + integer(I4B), dimension(:), allocatable, intent(inout) :: bndpkgs + type(CharacterStringType), dimension(:), contiguous, & + pointer, intent(inout) :: pkgtypes + type(CharacterStringType), dimension(:), contiguous, & + pointer, intent(inout) :: pkgnames + type(CharacterStringType), dimension(:), contiguous, & + pointer, intent(inout) :: mempaths + integer(I4B), dimension(:), contiguous, & + pointer, intent(inout) :: inunits + ! -- local + integer(I4B) :: ipakid, ipaknum + character(len=LENFTYPE) :: pkgtype, bndptype + character(len=LENPACKAGENAME) :: pkgname + character(len=LENMEMPATH) :: mempath + integer(I4B), pointer :: inunit + integer(I4B) :: n + + if (allocated(bndpkgs)) then + ! + ! -- create stress packages + ipakid = 1 + bndptype = '' + do n = 1, size(bndpkgs) + ! + pkgtype = pkgtypes(bndpkgs(n)) + pkgname = pkgnames(bndpkgs(n)) + mempath = mempaths(bndpkgs(n)) + inunit => inunits(bndpkgs(n)) + ! + if (bndptype /= pkgtype) then + ipaknum = 1 + bndptype = pkgtype + end if + ! + call this%package_create(pkgtype, ipakid, ipaknum, pkgname, mempath, & + inunit, this%iout) + ipakid = ipakid + 1 + ipaknum = ipaknum + 1 + end do + ! + ! -- cleanup + deallocate (bndpkgs) + end if + ! + ! -- Return + return + end subroutine create_bndpkgs + + !> @brief Source package info and begin to process + !< + subroutine create_gwe_packages(this, indis) + ! -- modules + use ConstantsModule, only: LINELENGTH, LENPACKAGENAME + use CharacterStringModule, only: CharacterStringType + use ArrayHandlersModule, only: expandarray + use MemoryManagerModule, only: mem_setptr + use MemoryHelperModule, only: create_mem_path + use SimVariablesModule, only: idm_context + use GweMstModule, only: mst_cr + use GweDspModule, only: dsp_cr + ! -- dummy + class(GweModelType) :: this + integer(I4B), intent(in) :: indis + ! -- local + type(CharacterStringType), dimension(:), contiguous, & + pointer :: pkgtypes => null() + type(CharacterStringType), dimension(:), contiguous, & + pointer :: pkgnames => null() + type(CharacterStringType), dimension(:), contiguous, & + pointer :: mempaths => null() + integer(I4B), dimension(:), contiguous, & + pointer :: inunits => null() + character(len=LENMEMPATH) :: model_mempath + character(len=LENFTYPE) :: pkgtype + character(len=LENPACKAGENAME) :: pkgname + character(len=LENMEMPATH) :: mempath + integer(I4B), pointer :: inunit + integer(I4B), dimension(:), allocatable :: bndpkgs + integer(I4B) :: n + character(len=LENMEMPATH) :: mempathdsp = '' + ! + ! -- set input memory paths, input/model and input/model/namfile + model_mempath = create_mem_path(component=this%name, context=idm_context) + ! + ! -- set pointers to model path package info + call mem_setptr(pkgtypes, 'PKGTYPES', model_mempath) + call mem_setptr(pkgnames, 'PKGNAMES', model_mempath) + call mem_setptr(mempaths, 'MEMPATHS', model_mempath) + call mem_setptr(inunits, 'INUNITS', model_mempath) + ! + do n = 1, size(pkgtypes) + ! + ! attributes for this input package + pkgtype = pkgtypes(n) + pkgname = pkgnames(n) + mempath = mempaths(n) + inunit => inunits(n) + ! + ! -- create dis package as it is a prerequisite for other packages + select case (pkgtype) + case ('MST6') + this%inmst = inunit + case ('DSP6') + this%indsp = 1 + mempathdsp = mempath + case ('CNT6', 'SRC6', 'LKE6', 'SFE6', & + 'MWE6', 'UZE6', 'API6') + call expandarray(bndpkgs) + bndpkgs(size(bndpkgs)) = n + case default + ! TODO + end select + end do + ! + ! -- Create packages that are tied directly to model + call mst_cr(this%mst, this%name, this%inmst, this%iout, this%fmi, & + this%eqnsclfac, this%gwecommon) + call dsp_cr(this%dsp, this%name, mempathdsp, this%indsp, this%iout, & + this%fmi, this%eqnsclfac, this%gwecommon) + ! + ! -- Check to make sure that required ftype's have been specified + call this%ftype_check(indis, this%inmst) + ! + call this%create_bndpkgs(bndpkgs, pkgtypes, pkgnames, mempaths, inunits) + ! + ! -- Return + return + end subroutine create_gwe_packages + +end module GweModule diff --git a/src/Model/GroundWaterEnergy/gwe1cnt1.f90 b/src/Model/GroundWaterEnergy/gwe1cnt1.f90 new file mode 100644 index 00000000000..0d65110eba3 --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1cnt1.f90 @@ -0,0 +1,533 @@ +module GweCntModule + ! + use KindModule, only: DP, I4B + use ConstantsModule, only: DZERO, DONE, NAMEDBOUNDFLAG, LENFTYPE, & + LENPACKAGENAME, LENVARNAME + use SimVariablesModule, only: errmsg + use SimModule, only: count_errors, store_error, store_error_filename + use ObsModule, only: DefaultObsIdProcessor + use BndModule, only: BndType + use BndExtModule, only: BndExtType + use ObserveModule, only: ObserveType + use TimeSeriesLinkModule, only: TimeSeriesLinkType, & + GetTimeSeriesLinkFromList + use InputOutputModule, only: str_pad_left + use MatrixBaseModule + ! + implicit none + ! + private + public :: cnt_create + ! + character(len=LENFTYPE) :: ftype = 'CNT' + character(len=LENPACKAGENAME) :: text = ' CNT' + ! + type, extends(BndExtType) :: GweCntType + + real(DP), dimension(:), pointer, contiguous :: tspvar => null() !< constant temperature array + real(DP), dimension(:), pointer, contiguous :: ratecntin => null() !< simulated flows into constant temperature (excluding other CNTs) + real(DP), dimension(:), pointer, contiguous :: ratecntout => null() !< simulated flows out of constant temperature (excluding to other CNTs) + character(len=LENVARNAME) :: depvartype = '' !< stores string of dependent variable type, depending on model type + contains + procedure :: bnd_rp => cnt_rp + procedure :: bnd_ad => cnt_ad + procedure :: bnd_ck => cnt_ck + procedure :: bnd_fc => cnt_fc + procedure :: bnd_cq => cnt_cq + procedure :: bnd_bd => cnt_bd + procedure :: bnd_da => cnt_da + procedure :: allocate_arrays => cnt_allocate_arrays + procedure :: define_listlabel + procedure :: bound_value => cnt_bound_value + procedure :: temp_mult + ! -- methods for observations + procedure, public :: bnd_obs_supported => cnt_obs_supported + procedure, public :: bnd_df_obs => cnt_df_obs + ! -- method for time series + procedure, public :: bnd_rp_ts => cnt_rp_ts + end type GweCntType + +contains + + !> @brief Create a new constant temperature package + !! + !! Routine points packobj to the newly created package + !< + subroutine cnt_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, & + depvartype, mempath) + ! -- dummy + class(BndType), pointer :: packobj + integer(I4B), intent(in) :: id + integer(I4B), intent(in) :: ibcnum + integer(I4B), intent(in) :: inunit + integer(I4B), intent(in) :: iout + character(len=*), intent(in) :: namemodel + character(len=*), intent(in) :: pakname + character(len=LENVARNAME), intent(in) :: depvartype + character(len=*), intent(in) :: mempath + ! -- local + type(GweCntType), pointer :: cntobj + ! + ! -- allocate the object and assign values to object variables + allocate (cntobj) + packobj => cntobj + ! + ! -- create name and memory path + call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath) + packobj%text = text + ! + ! -- allocate scalars + call cntobj%allocate_scalars() + ! + ! -- initialize package + call packobj%pack_initialize() + ! + ! -- store values + packobj%inunit = inunit + packobj%iout = iout + packobj%id = id + packobj%ibcnum = ibcnum + packobj%ncolbnd = 1 + packobj%iscloc = 1 + ! + ! -- Store the appropriate label based on the dependent variable + cntobj%depvartype = depvartype + ! + ! -- Return + return + end subroutine cnt_create + + !> @brief Allocate arrays specific to the constant temperature package + !< + subroutine cnt_allocate_arrays(this, nodelist, auxvar) + ! -- modules + use MemoryManagerModule, only: mem_allocate, mem_setptr, mem_checkin + ! -- dummy + class(GweCntType) :: this + integer(I4B), dimension(:), pointer, contiguous, optional :: nodelist + real(DP), dimension(:, :), pointer, contiguous, optional :: auxvar + ! -- local + integer(I4B) :: i + ! + ! -- call standard BndType allocate scalars + call this%BndExtType%allocate_arrays(nodelist, auxvar) + ! + ! -- allocate ratecntex + call mem_allocate(this%ratecntin, this%maxbound, 'RATECNTIN', this%memoryPath) + call mem_allocate(this%ratecntout, this%maxbound, 'RATECNTOUT', & + this%memoryPath) + do i = 1, this%maxbound + this%ratecntin(i) = DZERO + this%ratecntout(i) = DZERO + end do + ! -- set constant head array input context pointer + call mem_setptr(this%tspvar, 'TSPVAR', this%input_mempath) + ! + ! -- checkin constant head array input context pointer + call mem_checkin(this%tspvar, 'TSPVAR', this%memoryPath, & + 'TSPVAR', this%input_mempath) + ! + ! + ! -- Return + return + end subroutine cnt_allocate_arrays + + !> @brief Constant temperature read and prepare (rp) routine + !< + subroutine cnt_rp(this) + ! -- modules + use SimModule, only: store_error + use InputOutputModule, only: lowcase + implicit none + ! -- dummy + class(GweCntType), intent(inout) :: this + ! -- local + integer(I4B) :: i, node, ibd, ierr + character(len=30) :: nodestr + character(len=LENVARNAME) :: dvtype + ! + ! -- Reset previous CNTs to active cell + do i = 1, this%nbound + node = this%nodelist(i) + this%ibound(node) = this%ibcnum + end do + ! + ! -- Call the parent class read and prepare + call this%BndExtType%bnd_rp() + ! + ! -- Set ibound to -(ibcnum + 1) for constant temperature cells + ierr = 0 + do i = 1, this%nbound + node = this%nodelist(i) + ibd = this%ibound(node) + if (ibd < 0) then + call this%dis%noder_to_string(node, nodestr) + dvtype = trim(this%depvartype) + call lowcase(dvtype) + call store_error('Cell is already a constant ' & + //dvtype//': '//trim(adjustl(nodestr))) + ierr = ierr + 1 + else + this%ibound(node) = -this%ibcnum + end if + end do + ! + ! -- Stop if errors detected + if (ierr > 0) then + call store_error_filename(this%input_fname) + end if + ! + ! -- Write the list to iout if requested + if (this%iprpak /= 0) then + call this%write_list() + end if + ! + ! -- Return + return + end subroutine cnt_rp + + !> @brief Constant temperature package advance routine + !! + !! Add package connections to matrix + !< + subroutine cnt_ad(this) + ! -- dummy + class(GweCntType) :: this + ! -- local + integer(I4B) :: i, node + real(DP) :: cb + ! + ! -- Advance the time series + call this%TsManager%ad() + ! + ! -- Process each entry in the constant temperature cell list + do i = 1, this%nbound + node = this%nodelist(i) + cb = this%temp_mult(i) + ! + this%xnew(node) = cb + this%xold(node) = this%xnew(node) + end do + ! + ! -- For each observation, push simulated value and corresponding + ! simulation time from "current" to "preceding" and reset + ! "current" value. + call this%obs%obs_ad() + ! + ! -- Return + return + end subroutine cnt_ad + + !> @brief Check constant temperature boundary condition data + !< + subroutine cnt_ck(this) + ! -- dummy + class(GweCntType), intent(inout) :: this + ! -- local + character(len=30) :: nodestr + integer(I4B) :: i + integer(I4B) :: node + ! -- formats + character(len=*), parameter :: fmtcnterr = & + &"('Specified dependent variable boundary ',i0, & + &' temperature (',g0,') is less than zero for cell', a)" + ! + ! -- check stress period data + do i = 1, this%nbound + node = this%nodelist(i) + ! -- accumulate errors + if (this%temp_mult(i) < DZERO) then + call this%dis%noder_to_string(node, nodestr) + write (errmsg, fmt=fmtcnterr) i, this%tspvar(i), trim(nodestr) + call store_error(errmsg) + end if + end do + ! + ! -- write summary of cnt package error messages + if (count_errors() > 0) then + call store_error_filename(this%input_fname) + end if + ! + ! -- Return + return + end subroutine cnt_ck + + !> @brief Override bnd_fc and do nothing + !! + !! For constant temperature boundary type, the call to bnd_fc needs to be + !! overwritten to prevent logic found in bnd from being executed + !< + subroutine cnt_fc(this, rhs, ia, idxglo, matrix_sln) + ! -- dummy + class(GweCntType) :: this + real(DP), dimension(:), intent(inout) :: rhs + integer(I4B), dimension(:), intent(in) :: ia + integer(I4B), dimension(:), intent(in) :: idxglo + class(MatrixBaseType), pointer :: matrix_sln + ! + ! -- Return + return + end subroutine cnt_fc + + !> @brief Calculate flow associated with constant temperature boundary + !! + !! This method overrides bnd_cq() + !< + subroutine cnt_cq(this, x, flowja, iadv) + ! -- dummy + class(GweCntType), intent(inout) :: this + real(DP), dimension(:), intent(in) :: x + real(DP), dimension(:), contiguous, intent(inout) :: flowja + integer(I4B), optional, intent(in) :: iadv + ! -- local + integer(I4B) :: i + integer(I4B) :: ipos + integer(I4B) :: node + integer(I4B) :: n2 + integer(I4B) :: idiag + real(DP) :: rate + real(DP) :: ratein, rateout + real(DP) :: q + ! + ! -- If no boundaries, skip flow calculations. + if (this%nbound > 0) then + ! + ! -- Loop through each boundary calculating flow. + do i = 1, this%nbound + node = this%nodelist(i) + idiag = this%dis%con%ia(node) + rate = DZERO + ratein = DZERO + rateout = DZERO + ! + ! -- Calculate the flow rate into the cell. + do ipos = this%dis%con%ia(node) + 1, & + this%dis%con%ia(node + 1) - 1 + q = flowja(ipos) + rate = rate - q + ! -- Only accumulate chin and chout for active + ! connected cells + n2 = this%dis%con%ja(ipos) + if (this%ibound(n2) > 0) then + if (q < DZERO) then + ratein = ratein - q + else + rateout = rateout + q + end if + end if + end do + ! + ! -- For CNT, store total flow in rhs so it is available for other + ! calculations + this%rhs(i) = -rate + this%hcof(i) = DZERO + ! + ! -- Save simulated value to simvals array. + this%simvals(i) = rate + this%ratecntin(i) = ratein + this%ratecntout(i) = rateout + flowja(idiag) = flowja(idiag) + rate + ! + end do + ! + end if + ! + ! -- Return + return + end subroutine cnt_cq + + !> @brief Add package ratin/ratout to model budget + !< + subroutine cnt_bd(this, model_budget) + ! -- modules + use TdisModule, only: delt + use BudgetModule, only: BudgetType, rate_accumulator + ! -- dummy + class(GweCntType) :: this + ! -- local + type(BudgetType), intent(inout) :: model_budget + real(DP) :: ratin + real(DP) :: ratout + real(DP) :: dum + integer(I4B) :: isuppress_output + ! + isuppress_output = 0 + call rate_accumulator(this%ratecntin(1:this%nbound), ratin, dum) + call rate_accumulator(this%ratecntout(1:this%nbound), ratout, dum) + call model_budget%addentry(ratin, ratout, delt, this%text, & + isuppress_output, this%packName) + ! + ! -- Return + return + end subroutine cnt_bd + + !> @brief Deallocate memory + !! + !! Method to deallocate memory for the package. + !< + subroutine cnt_da(this) + ! -- modules + use MemoryManagerModule, only: mem_deallocate + ! -- dummy + class(GweCntType) :: this + ! + ! -- Deallocate parent package + call this%BndExtType%bnd_da() + ! + ! -- arrays + call mem_deallocate(this%ratecntin) + call mem_deallocate(this%ratecntout) + call mem_deallocate(this%tspvar, 'TSPVAR', this%memoryPath) + ! + ! -- Return + return + end subroutine cnt_da + + !> @brief Define labels used in list file + !! + !! Define the list heading that is written to iout when PRINT_INPUT option + !! is used. + !< + subroutine define_listlabel(this) + ! -- dummy + class(GweCntType), intent(inout) :: this + ! + ! -- create the header list label + this%listlabel = trim(this%filtyp)//' NO.' + if (this%dis%ndim == 3) then + write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER' + write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW' + write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL' + elseif (this%dis%ndim == 2) then + write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER' + write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D' + else + write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE' + end if + write (this%listlabel, '(a, a16)') trim(this%listlabel), & + trim(this%depvartype) + if (this%inamedbound == 1) then + write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME' + end if + ! + ! -- Return + return + end subroutine define_listlabel + + !> @brief Procedure related to observation processing + !! + !! This routine: + !! - returns true because the SDV package supports observations, + !! - overrides packagetype%_obs_supported() + logical function cnt_obs_supported(this) + ! -- dummy + class(GweCntType) :: this + ! + cnt_obs_supported = .true. + ! + ! -- Return + return + end function cnt_obs_supported + + !> @brief Procedure related to observation processing + !! + !! This routine: + !! - defines observations + !! - stores observation types supported by either of the SDV packages + !! (CNT or CNT), + !! - overrides BndExtType%bnd_df_obs + !< + subroutine cnt_df_obs(this) + ! -- dummy + class(GweCntType) :: this + ! -- local + integer(I4B) :: indx + ! + call this%obs%StoreObsType(this%filtyp, .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => DefaultObsIdProcessor + ! + ! -- Return + return + end subroutine cnt_df_obs + + ! -- Procedure related to time series + + !> @brief Procedure related to time series + !! + !! Assign tsLink%Text appropriately for all time series in use by package. + !! For the constant temperature packages, the dependent variable can also be + !! controlled by a time series. + !< + subroutine cnt_rp_ts(this) + ! -- dummy + class(GweCntType), intent(inout) :: this + ! -- local + integer(I4B) :: i, nlinks + type(TimeSeriesLinkType), pointer :: tslink => null() + ! + nlinks = this%TsManager%boundtslinks%Count() + do i = 1, nlinks + tslink => GetTimeSeriesLinkFromList(this%TsManager%boundtslinks, i) + if (associated(tslink)) then + select case (tslink%JCol) + case (1) + tslink%Text = trim(this%depvartype) + end select + end if + end do + ! + ! -- Return + return + end subroutine cnt_rp_ts + + !> @brief Apply auxiliary multiplier to specified temperature if + !< appropriate + function temp_mult(this, row) result(temp) + ! -- modules + use ConstantsModule, only: DZERO + ! -- dummy + class(GweCntType), intent(inout) :: this !< BndExtType object + integer(I4B), intent(in) :: row + ! -- result + real(DP) :: temp + ! + if (this%iauxmultcol > 0) then + temp = this%tspvar(row) * this%auxvar(this%iauxmultcol, row) + else + temp = this%tspvar(row) + end if + ! + ! -- Return + return + end function temp_mult + + !> @ brief Return a bound value + !! + !! Return a bound value associated with an ncolbnd index and row. + !< + function cnt_bound_value(this, col, row) result(bndval) + ! -- modules + use ConstantsModule, only: DZERO + ! -- dummy variables + class(GweCntType), intent(inout) :: this !< BndExtType object + integer(I4B), intent(in) :: col + integer(I4B), intent(in) :: row + ! -- result + real(DP) :: bndval + ! + select case (col) + case (1) + bndval = this%temp_mult(row) + case default + write (errmsg, '(3a)') 'Programming error. ', & + & adjustl(trim(this%filtyp)), ' bound value requested column '& + &'outside range of ncolbnd (1).' + call store_error(errmsg) + call store_error_filename(this%input_fname) + end select + ! + ! -- Return + return + end function cnt_bound_value + +end module GweCntModule diff --git a/src/Model/GroundWaterEnergy/gwe1cnt1idm.f90 b/src/Model/GroundWaterEnergy/gwe1cnt1idm.f90 new file mode 100644 index 00000000000..47f61e1c23d --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1cnt1idm.f90 @@ -0,0 +1,411 @@ +! ** Do Not Modify! MODFLOW 6 system generated file. ** +module GweCntInputModule + use ConstantsModule, only: LENVARNAME + use InputDefinitionModule, only: InputParamDefinitionType, & + InputBlockDefinitionType + private + public gwe_cnt_param_definitions + public gwe_cnt_aggregate_definitions + public gwe_cnt_block_definitions + public GweCntParamFoundType + public gwe_cnt_multi_package + + type GweCntParamFoundType + logical :: auxiliary = .false. + logical :: auxmultname = .false. + logical :: boundnames = .false. + logical :: iprflow = .false. + logical :: ipakcb = .false. + logical :: iprpak = .false. + logical :: ts_filerecord = .false. + logical :: ts6 = .false. + logical :: filein = .false. + logical :: ts6_filename = .false. + logical :: obs_filerecord = .false. + logical :: obs6 = .false. + logical :: obs6_filename = .false. + logical :: maxbound = .false. + logical :: cellid = .false. + logical :: tspvar = .false. + logical :: auxvar = .false. + logical :: boundname = .false. + end type GweCntParamFoundType + + logical :: gwe_cnt_multi_package = .true. + + type(InputParamDefinitionType), parameter :: & + gwecnt_auxiliary = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'OPTIONS', & ! block + 'AUXILIARY', & ! tag name + 'AUXILIARY', & ! fortran variable + 'STRING', & ! type + 'NAUX', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_auxmultname = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'OPTIONS', & ! block + 'AUXMULTNAME', & ! tag name + 'AUXMULTNAME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_boundnames = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'OPTIONS', & ! block + 'BOUNDNAMES', & ! tag name + 'BOUNDNAMES', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_iprflow = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'OPTIONS', & ! block + 'PRINT_INPUT', & ! tag name + 'IPRFLOW', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_ipakcb = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'OPTIONS', & ! block + 'PRINT_FLOWS', & ! tag name + 'IPAKCB', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_iprpak = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'OPTIONS', & ! block + 'SAVE_FLOWS', & ! tag name + 'IPRPAK', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_ts_filerecord = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'OPTIONS', & ! block + 'TS_FILERECORD', & ! tag name + 'TS_FILERECORD', & ! fortran variable + 'RECORD TS6 FILEIN TS6_FILENAME', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_ts6 = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'OPTIONS', & ! block + 'TS6', & ! tag name + 'TS6', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_filein = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'OPTIONS', & ! block + 'FILEIN', & ! tag name + 'FILEIN', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_ts6_filename = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'OPTIONS', & ! block + 'TS6_FILENAME', & ! tag name + 'TS6_FILENAME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .true., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_obs_filerecord = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'OPTIONS', & ! block + 'OBS_FILERECORD', & ! tag name + 'OBS_FILERECORD', & ! fortran variable + 'RECORD OBS6 FILEIN OBS6_FILENAME', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_obs6 = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'OPTIONS', & ! block + 'OBS6', & ! tag name + 'OBS6', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_obs6_filename = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'OPTIONS', & ! block + 'OBS6_FILENAME', & ! tag name + 'OBS6_FILENAME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .true., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_maxbound = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'DIMENSIONS', & ! block + 'MAXBOUND', & ! tag name + 'MAXBOUND', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_cellid = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'PERIOD', & ! block + 'CELLID', & ! tag name + 'CELLID', & ! fortran variable + 'INTEGER1D', & ! type + 'NCELLDIM', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_tspvar = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'PERIOD', & ! block + 'TEMP', & ! tag name + 'TSPVAR', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .true. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_auxvar = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'PERIOD', & ! block + 'AUX', & ! tag name + 'AUXVAR', & ! fortran variable + 'DOUBLE1D', & ! type + 'NAUX', & ! shape + .false., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .true. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwecnt_boundname = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'PERIOD', & ! block + 'BOUNDNAME', & ! tag name + 'BOUNDNAME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .false., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwe_cnt_param_definitions(*) = & + [ & + gwecnt_auxiliary, & + gwecnt_auxmultname, & + gwecnt_boundnames, & + gwecnt_iprflow, & + gwecnt_ipakcb, & + gwecnt_iprpak, & + gwecnt_ts_filerecord, & + gwecnt_ts6, & + gwecnt_filein, & + gwecnt_ts6_filename, & + gwecnt_obs_filerecord, & + gwecnt_obs6, & + gwecnt_obs6_filename, & + gwecnt_maxbound, & + gwecnt_cellid, & + gwecnt_tspvar, & + gwecnt_auxvar, & + gwecnt_boundname & + ] + + type(InputParamDefinitionType), parameter :: & + gwecnt_spd = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'CNT', & ! subcomponent + 'PERIOD', & ! block + 'STRESS_PERIOD_DATA', & ! tag name + 'SPD', & ! fortran variable + 'RECARRAY CELLID TEMP AUX BOUNDNAME', & ! type + 'MAXBOUND', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwe_cnt_aggregate_definitions(*) = & + [ & + gwecnt_spd & + ] + + type(InputBlockDefinitionType), parameter :: & + gwe_cnt_block_definitions(*) = & + [ & + InputBlockDefinitionType( & + 'OPTIONS', & ! blockname + .false., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'DIMENSIONS', & ! blockname + .true., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'PERIOD', & ! blockname + .true., & ! required + .true., & ! aggregate + .true. & ! block_variable + ) & + ] + +end module GweCntInputModule diff --git a/src/Model/GroundWaterEnergy/gwe1dis1idm.f90 b/src/Model/GroundWaterEnergy/gwe1dis1idm.f90 new file mode 100644 index 00000000000..cda16809731 --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1dis1idm.f90 @@ -0,0 +1,313 @@ +! ** Do Not Modify! MODFLOW 6 system generated file. ** +module GweDisInputModule + use ConstantsModule, only: LENVARNAME + use InputDefinitionModule, only: InputParamDefinitionType, & + InputBlockDefinitionType + private + public gwe_dis_param_definitions + public gwe_dis_aggregate_definitions + public gwe_dis_block_definitions + public GweDisParamFoundType + public gwe_dis_multi_package + + type GweDisParamFoundType + logical :: length_units = .false. + logical :: nogrb = .false. + logical :: xorigin = .false. + logical :: yorigin = .false. + logical :: angrot = .false. + logical :: nlay = .false. + logical :: nrow = .false. + logical :: ncol = .false. + logical :: delr = .false. + logical :: delc = .false. + logical :: top = .false. + logical :: botm = .false. + logical :: idomain = .false. + end type GweDisParamFoundType + + logical :: gwe_dis_multi_package = .false. + + type(InputParamDefinitionType), parameter :: & + gwedis_length_units = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DIS', & ! subcomponent + 'OPTIONS', & ! block + 'LENGTH_UNITS', & ! tag name + 'LENGTH_UNITS', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedis_nogrb = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DIS', & ! subcomponent + 'OPTIONS', & ! block + 'NOGRB', & ! tag name + 'NOGRB', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedis_xorigin = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DIS', & ! subcomponent + 'OPTIONS', & ! block + 'XORIGIN', & ! tag name + 'XORIGIN', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedis_yorigin = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DIS', & ! subcomponent + 'OPTIONS', & ! block + 'YORIGIN', & ! tag name + 'YORIGIN', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedis_angrot = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DIS', & ! subcomponent + 'OPTIONS', & ! block + 'ANGROT', & ! tag name + 'ANGROT', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedis_nlay = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DIS', & ! subcomponent + 'DIMENSIONS', & ! block + 'NLAY', & ! tag name + 'NLAY', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedis_nrow = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DIS', & ! subcomponent + 'DIMENSIONS', & ! block + 'NROW', & ! tag name + 'NROW', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedis_ncol = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DIS', & ! subcomponent + 'DIMENSIONS', & ! block + 'NCOL', & ! tag name + 'NCOL', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedis_delr = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DIS', & ! subcomponent + 'GRIDDATA', & ! block + 'DELR', & ! tag name + 'DELR', & ! fortran variable + 'DOUBLE1D', & ! type + 'NCOL', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedis_delc = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DIS', & ! subcomponent + 'GRIDDATA', & ! block + 'DELC', & ! tag name + 'DELC', & ! fortran variable + 'DOUBLE1D', & ! type + 'NROW', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedis_top = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DIS', & ! subcomponent + 'GRIDDATA', & ! block + 'TOP', & ! tag name + 'TOP', & ! fortran variable + 'DOUBLE2D', & ! type + 'NCOL NROW', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedis_botm = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DIS', & ! subcomponent + 'GRIDDATA', & ! block + 'BOTM', & ! tag name + 'BOTM', & ! fortran variable + 'DOUBLE3D', & ! type + 'NCOL NROW NLAY', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .true., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedis_idomain = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DIS', & ! subcomponent + 'GRIDDATA', & ! block + 'IDOMAIN', & ! tag name + 'IDOMAIN', & ! fortran variable + 'INTEGER3D', & ! type + 'NCOL NROW NLAY', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .true., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwe_dis_param_definitions(*) = & + [ & + gwedis_length_units, & + gwedis_nogrb, & + gwedis_xorigin, & + gwedis_yorigin, & + gwedis_angrot, & + gwedis_nlay, & + gwedis_nrow, & + gwedis_ncol, & + gwedis_delr, & + gwedis_delc, & + gwedis_top, & + gwedis_botm, & + gwedis_idomain & + ] + + type(InputParamDefinitionType), parameter :: & + gwe_dis_aggregate_definitions(*) = & + [ & + InputParamDefinitionType & + ( & + '', & ! component + '', & ! subcomponent + '', & ! block + '', & ! tag name + '', & ! fortran variable + '', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) & + ] + + type(InputBlockDefinitionType), parameter :: & + gwe_dis_block_definitions(*) = & + [ & + InputBlockDefinitionType( & + 'OPTIONS', & ! blockname + .false., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'DIMENSIONS', & ! blockname + .true., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'GRIDDATA', & ! blockname + .true., & ! required + .false., & ! aggregate + .false. & ! block_variable + ) & + ] + +end module GweDisInputModule diff --git a/src/Model/GroundWaterEnergy/gwe1disu1idm.f90 b/src/Model/GroundWaterEnergy/gwe1disu1idm.f90 new file mode 100644 index 00000000000..4e61f3935b2 --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1disu1idm.f90 @@ -0,0 +1,618 @@ +! ** Do Not Modify! MODFLOW 6 system generated file. ** +module GweDisuInputModule + use ConstantsModule, only: LENVARNAME + use InputDefinitionModule, only: InputParamDefinitionType, & + InputBlockDefinitionType + private + public gwe_disu_param_definitions + public gwe_disu_aggregate_definitions + public gwe_disu_block_definitions + public GweDisuParamFoundType + public gwe_disu_multi_package + + type GweDisuParamFoundType + logical :: length_units = .false. + logical :: nogrb = .false. + logical :: xorigin = .false. + logical :: yorigin = .false. + logical :: angrot = .false. + logical :: voffsettol = .false. + logical :: nodes = .false. + logical :: nja = .false. + logical :: nvert = .false. + logical :: top = .false. + logical :: bot = .false. + logical :: area = .false. + logical :: idomain = .false. + logical :: iac = .false. + logical :: ja = .false. + logical :: ihc = .false. + logical :: cl12 = .false. + logical :: hwva = .false. + logical :: angldegx = .false. + logical :: iv = .false. + logical :: xv = .false. + logical :: yv = .false. + logical :: icell2d = .false. + logical :: xc = .false. + logical :: yc = .false. + logical :: ncvert = .false. + logical :: icvert = .false. + end type GweDisuParamFoundType + + logical :: gwe_disu_multi_package = .false. + + type(InputParamDefinitionType), parameter :: & + gwedisu_length_units = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'OPTIONS', & ! block + 'LENGTH_UNITS', & ! tag name + 'LENGTH_UNITS', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_nogrb = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'OPTIONS', & ! block + 'NOGRB', & ! tag name + 'NOGRB', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_xorigin = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'OPTIONS', & ! block + 'XORIGIN', & ! tag name + 'XORIGIN', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_yorigin = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'OPTIONS', & ! block + 'YORIGIN', & ! tag name + 'YORIGIN', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_angrot = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'OPTIONS', & ! block + 'ANGROT', & ! tag name + 'ANGROT', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_voffsettol = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'OPTIONS', & ! block + 'VERTICAL_OFFSET_TOLERANCE', & ! tag name + 'VOFFSETTOL', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_nodes = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'DIMENSIONS', & ! block + 'NODES', & ! tag name + 'NODES', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_nja = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'DIMENSIONS', & ! block + 'NJA', & ! tag name + 'NJA', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_nvert = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'DIMENSIONS', & ! block + 'NVERT', & ! tag name + 'NVERT', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_top = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'GRIDDATA', & ! block + 'TOP', & ! tag name + 'TOP', & ! fortran variable + 'DOUBLE1D', & ! type + 'NODES', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_bot = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'GRIDDATA', & ! block + 'BOT', & ! tag name + 'BOT', & ! fortran variable + 'DOUBLE1D', & ! type + 'NODES', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_area = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'GRIDDATA', & ! block + 'AREA', & ! tag name + 'AREA', & ! fortran variable + 'DOUBLE1D', & ! type + 'NODES', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_idomain = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'GRIDDATA', & ! block + 'IDOMAIN', & ! tag name + 'IDOMAIN', & ! fortran variable + 'INTEGER1D', & ! type + 'NODES', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_iac = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'CONNECTIONDATA', & ! block + 'IAC', & ! tag name + 'IAC', & ! fortran variable + 'INTEGER1D', & ! type + 'NODES', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_ja = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'CONNECTIONDATA', & ! block + 'JA', & ! tag name + 'JA', & ! fortran variable + 'INTEGER1D', & ! type + 'NJA', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_ihc = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'CONNECTIONDATA', & ! block + 'IHC', & ! tag name + 'IHC', & ! fortran variable + 'INTEGER1D', & ! type + 'NJA', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_cl12 = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'CONNECTIONDATA', & ! block + 'CL12', & ! tag name + 'CL12', & ! fortran variable + 'DOUBLE1D', & ! type + 'NJA', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_hwva = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'CONNECTIONDATA', & ! block + 'HWVA', & ! tag name + 'HWVA', & ! fortran variable + 'DOUBLE1D', & ! type + 'NJA', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_angldegx = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'CONNECTIONDATA', & ! block + 'ANGLDEGX', & ! tag name + 'ANGLDEGX', & ! fortran variable + 'DOUBLE1D', & ! type + 'NJA', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_iv = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'VERTICES', & ! block + 'IV', & ! tag name + 'IV', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_xv = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'VERTICES', & ! block + 'XV', & ! tag name + 'XV', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_yv = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'VERTICES', & ! block + 'YV', & ! tag name + 'YV', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_icell2d = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'CELL2D', & ! block + 'ICELL2D', & ! tag name + 'ICELL2D', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_xc = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'CELL2D', & ! block + 'XC', & ! tag name + 'XC', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_yc = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'CELL2D', & ! block + 'YC', & ! tag name + 'YC', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_ncvert = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'CELL2D', & ! block + 'NCVERT', & ! tag name + 'NCVERT', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_icvert = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'CELL2D', & ! block + 'ICVERT', & ! tag name + 'ICVERT', & ! fortran variable + 'INTEGER1D', & ! type + 'NCVERT', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwe_disu_param_definitions(*) = & + [ & + gwedisu_length_units, & + gwedisu_nogrb, & + gwedisu_xorigin, & + gwedisu_yorigin, & + gwedisu_angrot, & + gwedisu_voffsettol, & + gwedisu_nodes, & + gwedisu_nja, & + gwedisu_nvert, & + gwedisu_top, & + gwedisu_bot, & + gwedisu_area, & + gwedisu_idomain, & + gwedisu_iac, & + gwedisu_ja, & + gwedisu_ihc, & + gwedisu_cl12, & + gwedisu_hwva, & + gwedisu_angldegx, & + gwedisu_iv, & + gwedisu_xv, & + gwedisu_yv, & + gwedisu_icell2d, & + gwedisu_xc, & + gwedisu_yc, & + gwedisu_ncvert, & + gwedisu_icvert & + ] + + type(InputParamDefinitionType), parameter :: & + gwedisu_vertices = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'VERTICES', & ! block + 'VERTICES', & ! tag name + 'VERTICES', & ! fortran variable + 'RECARRAY IV XV YV', & ! type + 'NVERT', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisu_cell2d = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISU', & ! subcomponent + 'CELL2D', & ! block + 'CELL2D', & ! tag name + 'CELL2D', & ! fortran variable + 'RECARRAY ICELL2D XC YC NCVERT ICVERT', & ! type + 'NODES', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwe_disu_aggregate_definitions(*) = & + [ & + gwedisu_vertices, & + gwedisu_cell2d & + ] + + type(InputBlockDefinitionType), parameter :: & + gwe_disu_block_definitions(*) = & + [ & + InputBlockDefinitionType( & + 'OPTIONS', & ! blockname + .false., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'DIMENSIONS', & ! blockname + .true., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'GRIDDATA', & ! blockname + .true., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'CONNECTIONDATA', & ! blockname + .true., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'VERTICES', & ! blockname + .true., & ! required + .true., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'CELL2D', & ! blockname + .true., & ! required + .true., & ! aggregate + .false. & ! block_variable + ) & + ] + +end module GweDisuInputModule diff --git a/src/Model/GroundWaterEnergy/gwe1disv1idm.f90 b/src/Model/GroundWaterEnergy/gwe1disv1idm.f90 new file mode 100644 index 00000000000..e109482271f --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1disv1idm.f90 @@ -0,0 +1,460 @@ +! ** Do Not Modify! MODFLOW 6 system generated file. ** +module GweDisvInputModule + use ConstantsModule, only: LENVARNAME + use InputDefinitionModule, only: InputParamDefinitionType, & + InputBlockDefinitionType + private + public gwe_disv_param_definitions + public gwe_disv_aggregate_definitions + public gwe_disv_block_definitions + public GweDisvParamFoundType + public gwe_disv_multi_package + + type GweDisvParamFoundType + logical :: length_units = .false. + logical :: nogrb = .false. + logical :: xorigin = .false. + logical :: yorigin = .false. + logical :: angrot = .false. + logical :: nlay = .false. + logical :: ncpl = .false. + logical :: nvert = .false. + logical :: top = .false. + logical :: botm = .false. + logical :: idomain = .false. + logical :: iv = .false. + logical :: xv = .false. + logical :: yv = .false. + logical :: icell2d = .false. + logical :: xc = .false. + logical :: yc = .false. + logical :: ncvert = .false. + logical :: icvert = .false. + end type GweDisvParamFoundType + + logical :: gwe_disv_multi_package = .false. + + type(InputParamDefinitionType), parameter :: & + gwedisv_length_units = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'OPTIONS', & ! block + 'LENGTH_UNITS', & ! tag name + 'LENGTH_UNITS', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_nogrb = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'OPTIONS', & ! block + 'NOGRB', & ! tag name + 'NOGRB', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_xorigin = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'OPTIONS', & ! block + 'XORIGIN', & ! tag name + 'XORIGIN', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_yorigin = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'OPTIONS', & ! block + 'YORIGIN', & ! tag name + 'YORIGIN', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_angrot = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'OPTIONS', & ! block + 'ANGROT', & ! tag name + 'ANGROT', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_nlay = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'DIMENSIONS', & ! block + 'NLAY', & ! tag name + 'NLAY', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_ncpl = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'DIMENSIONS', & ! block + 'NCPL', & ! tag name + 'NCPL', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_nvert = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'DIMENSIONS', & ! block + 'NVERT', & ! tag name + 'NVERT', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_top = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'GRIDDATA', & ! block + 'TOP', & ! tag name + 'TOP', & ! fortran variable + 'DOUBLE1D', & ! type + 'NCPL', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_botm = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'GRIDDATA', & ! block + 'BOTM', & ! tag name + 'BOTM', & ! fortran variable + 'DOUBLE2D', & ! type + 'NCPL NLAY', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .true., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_idomain = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'GRIDDATA', & ! block + 'IDOMAIN', & ! tag name + 'IDOMAIN', & ! fortran variable + 'INTEGER2D', & ! type + 'NCPL NLAY', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .true., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_iv = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'VERTICES', & ! block + 'IV', & ! tag name + 'IV', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_xv = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'VERTICES', & ! block + 'XV', & ! tag name + 'XV', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_yv = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'VERTICES', & ! block + 'YV', & ! tag name + 'YV', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_icell2d = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'CELL2D', & ! block + 'ICELL2D', & ! tag name + 'ICELL2D', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_xc = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'CELL2D', & ! block + 'XC', & ! tag name + 'XC', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_yc = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'CELL2D', & ! block + 'YC', & ! tag name + 'YC', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_ncvert = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'CELL2D', & ! block + 'NCVERT', & ! tag name + 'NCVERT', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_icvert = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'CELL2D', & ! block + 'ICVERT', & ! tag name + 'ICVERT', & ! fortran variable + 'INTEGER1D', & ! type + 'NCVERT', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwe_disv_param_definitions(*) = & + [ & + gwedisv_length_units, & + gwedisv_nogrb, & + gwedisv_xorigin, & + gwedisv_yorigin, & + gwedisv_angrot, & + gwedisv_nlay, & + gwedisv_ncpl, & + gwedisv_nvert, & + gwedisv_top, & + gwedisv_botm, & + gwedisv_idomain, & + gwedisv_iv, & + gwedisv_xv, & + gwedisv_yv, & + gwedisv_icell2d, & + gwedisv_xc, & + gwedisv_yc, & + gwedisv_ncvert, & + gwedisv_icvert & + ] + + type(InputParamDefinitionType), parameter :: & + gwedisv_vertices = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'VERTICES', & ! block + 'VERTICES', & ! tag name + 'VERTICES', & ! fortran variable + 'RECARRAY IV XV YV', & ! type + 'NVERT', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedisv_cell2d = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DISV', & ! subcomponent + 'CELL2D', & ! block + 'CELL2D', & ! tag name + 'CELL2D', & ! fortran variable + 'RECARRAY ICELL2D XC YC NCVERT ICVERT', & ! type + 'NCPL', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwe_disv_aggregate_definitions(*) = & + [ & + gwedisv_vertices, & + gwedisv_cell2d & + ] + + type(InputBlockDefinitionType), parameter :: & + gwe_disv_block_definitions(*) = & + [ & + InputBlockDefinitionType( & + 'OPTIONS', & ! blockname + .false., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'DIMENSIONS', & ! blockname + .true., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'GRIDDATA', & ! blockname + .true., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'VERTICES', & ! blockname + .true., & ! required + .true., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'CELL2D', & ! blockname + .true., & ! required + .true., & ! aggregate + .false. & ! block_variable + ) & + ] + +end module GweDisvInputModule diff --git a/src/Model/GroundWaterEnergy/gwe1dsp1.f90 b/src/Model/GroundWaterEnergy/gwe1dsp1.f90 new file mode 100644 index 00000000000..0bc274e5c8f --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1dsp1.f90 @@ -0,0 +1,942 @@ +module GweDspModule + + use KindModule, only: DP, I4B + use ConstantsModule, only: DONE, DZERO, DHALF, DPI + use NumericalPackageModule, only: NumericalPackageType + use BaseDisModule, only: DisBaseType + use TspFmiModule, only: TspFmiType + use Xt3dModule, only: Xt3dType, xt3d_cr + use GweDspOptionsModule, only: GweDspOptionsType + use GweInputDataModule, only: GweInputDataType + use MatrixBaseModule + + implicit none + private + public :: GweDspType + public :: dsp_cr + + type, extends(NumericalPackageType) :: GweDspType + + integer(I4B), dimension(:), pointer, contiguous :: ibound => null() ! pointer to GWE model ibound + type(TspFmiType), pointer :: fmi => null() ! pointer to GWE fmi object + type(GweInputDataType), pointer :: gwecommon => null() !< pointer to shared gwe data used by multiple packages but set in mst + real(DP), dimension(:), pointer, contiguous :: porosity => null() ! pointer to GWE storage porosity + real(DP), dimension(:), pointer, contiguous :: alh => null() ! longitudinal horizontal dispersivity + real(DP), dimension(:), pointer, contiguous :: alv => null() ! longitudinal vertical dispersivity + real(DP), dimension(:), pointer, contiguous :: ath1 => null() ! transverse horizontal dispersivity + real(DP), dimension(:), pointer, contiguous :: ath2 => null() ! transverse horizontal dispersivity + real(DP), dimension(:), pointer, contiguous :: atv => null() ! transverse vertical dispersivity + real(DP), dimension(:), pointer, contiguous :: ktw => null() ! thermal conductivity of water + real(DP), dimension(:), pointer, contiguous :: kts => null() ! thermal conductivity of aquifer material + integer(I4B), pointer :: idisp => null() ! flag indicating mechanical dispersion is active + integer(I4B), pointer :: ialh => null() ! longitudinal horizontal dispersivity data flag + integer(I4B), pointer :: ialv => null() ! longitudinal vertical dispersivity data flag + integer(I4B), pointer :: iath1 => null() ! transverse horizontal dispersivity data flag + integer(I4B), pointer :: iath2 => null() ! transverse horizontal dispersivity data flag + integer(I4B), pointer :: iatv => null() ! transverse vertical dispersivity data flag + integer(I4B), pointer :: ixt3doff => null() ! xt3d off flag, xt3d is set inactive if 1 + integer(I4B), pointer :: ixt3drhs => null() ! xt3d rhs flag, xt3d rhs is set active if 1 + integer(I4B), pointer :: iktw => null() ! thermal conductivity of water data flag + integer(I4B), pointer :: ikts => null() ! thermal conductivity of aquifer material data flag + integer(I4B), pointer :: ixt3d => null() ! flag indicating xt3d is active + type(Xt3dType), pointer :: xt3d => null() ! xt3d object + real(DP), dimension(:), pointer, contiguous :: dispcoef => null() ! disp coefficient (only if xt3d not active) + integer(I4B), pointer :: id22 => null() ! flag indicating d22 is available + integer(I4B), pointer :: id33 => null() ! flag indicating d33 is available + real(DP), dimension(:), pointer, contiguous :: d11 => null() ! dispersion coefficient + real(DP), dimension(:), pointer, contiguous :: d22 => null() ! dispersion coefficient + real(DP), dimension(:), pointer, contiguous :: d33 => null() ! dispersion coefficient + real(DP), dimension(:), pointer, contiguous :: angle1 => null() ! rotation angle 1 + real(DP), dimension(:), pointer, contiguous :: angle2 => null() ! rotation angle 2 + real(DP), dimension(:), pointer, contiguous :: angle3 => null() ! rotation angle 3 + integer(I4B), pointer :: iangle1 => null() ! flag indicating angle1 is available + integer(I4B), pointer :: iangle2 => null() ! flag indicating angle2 is available + integer(I4B), pointer :: iangle3 => null() ! flag indicating angle3 is available + real(DP), pointer :: eqnsclfac => null() !< governing equation scale factor; =rhow*cpw for energy + + contains + + procedure :: dsp_df + procedure :: dsp_ac + procedure :: dsp_mc + procedure :: dsp_ar + procedure :: dsp_ad + procedure :: dsp_fc + procedure :: dsp_cq + procedure :: dsp_da + procedure :: allocate_scalars + procedure :: allocate_arrays + procedure, private :: source_options + procedure, private :: source_griddata + procedure, private :: log_options + procedure, private :: log_griddata + procedure, private :: calcdispellipse + procedure, private :: calcdispcoef + + end type GweDspType + +contains + + !> @brief Create a new DSP object + !! + !! Create a new MST package + !< + subroutine dsp_cr(dspobj, name_model, input_mempath, inunit, iout, fmi, & + eqnsclfac, gwecommon) + ! -- modules + use KindModule, only: LGP + use MemoryManagerExtModule, only: mem_set_value + ! -- dummy + type(GweDspType), pointer :: dspobj + character(len=*), intent(in) :: name_model + character(len=*), intent(in) :: input_mempath + integer(I4B), intent(in) :: inunit + integer(I4B), intent(in) :: iout + type(TspFmiType), intent(in), target :: fmi + real(DP), intent(in), pointer :: eqnsclfac !< governing equation scale factor + type(GweInputDataType), intent(in), target :: gwecommon !< shared data container for use by multiple GWE packages + ! -- locals + ! -- formats + character(len=*), parameter :: fmtdsp = & + "(1x,/1x,'DSP-- THERMAL CONDUCTION AND DISPERSION PACKAGE, VERSION 1, ', & + &'01/01/2024, INPUT READ FROM MEMPATH ', A, //)" + ! + ! -- Create the object + allocate (dspobj) + ! + ! -- create name and memory path + call dspobj%set_names(1, name_model, 'DSP', 'DSP', input_mempath) + ! + ! -- Allocate scalars + call dspobj%allocate_scalars() + ! + ! -- Set variables + dspobj%inunit = inunit + dspobj%iout = iout + dspobj%fmi => fmi + dspobj%eqnsclfac => eqnsclfac + dspobj%gwecommon => gwecommon + ! + if (dspobj%inunit > 0) then + ! + ! -- Print a message identifying the dispersion package. + if (dspobj%iout > 0) then + write (dspobj%iout, fmtdsp) input_mempath + end if + end if + ! + ! -- Return + return + end subroutine dsp_cr + + !> @brief Define DSP object + !< + subroutine dsp_df(this, dis, dspOptions) + ! -- modules + ! -- dummy + class(GweDspType) :: this + class(DisBaseType), pointer :: dis + type(GweDspOptionsType), optional, intent(in) :: dspOptions !< the optional DSP options, used when not + !! creating DSP from file + ! + ! -- Store pointer to dis + this%dis => dis + ! + ! + ! -- set default xt3d representation to on and lhs + this%ixt3d = 1 + ! + ! -- Read dispersion options + if (present(dspOptions)) then + this%ixt3d = dspOptions%ixt3d + ! + ! -- Allocate only, grid data will not be read from file + call this%allocate_arrays(this%dis%nodes) + else + ! + ! -- Source options + call this%source_options() + call this%allocate_arrays(this%dis%nodes) + ! + ! -- Source dispersion data + call this%source_griddata() + end if + ! + ! -- xt3d create + if (this%ixt3d > 0) then + call xt3d_cr(this%xt3d, this%name_model, this%inunit, this%iout, & + ldispopt=.true.) + this%xt3d%ixt3d = this%ixt3d + call this%xt3d%xt3d_df(dis) + end if + ! + ! -- Return + return + end subroutine dsp_df + + !> @brief Add connections to DSP + !! + !! Add connections for extended neighbors to the sparse matrix + !< + subroutine dsp_ac(this, moffset, sparse) + ! -- modules + use SparseModule, only: sparsematrix + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweDspType) :: this + integer(I4B), intent(in) :: moffset + type(sparsematrix), intent(inout) :: sparse + ! + ! -- Add extended neighbors (neighbors of neighbors) + if (this%ixt3d > 0) call this%xt3d%xt3d_ac(moffset, sparse) + ! + ! -- Return + return + end subroutine dsp_ac + + !> @brief Map DSP connections + !! + !! Map connections and construct iax, jax, and idxglox + !< + subroutine dsp_mc(this, moffset, matrix_sln) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweDspType) :: this + integer(I4B), intent(in) :: moffset + class(MatrixBaseType), pointer :: matrix_sln + ! + ! -- Call xt3d map connections + if (this%ixt3d > 0) call this%xt3d%xt3d_mc(moffset, matrix_sln) + ! + ! -- Return + return + end subroutine dsp_mc + + !> @brief Allocate and read method for package + !! + !! Method to allocate and read static data for the package. + !< + subroutine dsp_ar(this, ibound, porosity) + ! -- modules + ! -- dummy + class(GweDspType) :: this + integer(I4B), dimension(:), pointer, contiguous :: ibound + real(DP), dimension(:), pointer, contiguous :: porosity + ! -- local + ! -- formats + character(len=*), parameter :: fmtdsp = & + "(1x,/1x,'DSP-- THERMAL CONDUCTION AND DISPERSION PACKAGE, VERSION 1, ', & + &'5/01/2023, INPUT READ FROM UNIT ', i0, //)" + ! + ! -- dsp pointers to arguments that were passed in + this%ibound => ibound + this%porosity => porosity + ! + ! -- Return + return + end subroutine dsp_ar + + !> @brief Advance method for the package + !< + subroutine dsp_ad(this) + ! -- modules + use TdisModule, only: kstp, kper + ! -- dummy + class(GweDspType) :: this + ! + ! -- xt3d + ! TODO: might consider adding a new mf6 level set pointers method, and + ! doing this stuff there instead of in the time step loop. + if (kstp * kper == 1) then + if (this%ixt3d > 0) then + call this%xt3d%xt3d_ar(this%fmi%ibdgwfsat0, this%d11, this%id33, & + this%d33, this%fmi%gwfsat, this%id22, this%d22, & + this%iangle1, this%iangle2, this%iangle3, & + this%angle1, this%angle2, this%angle3) + end if + end if + ! + ! -- Fill d11, d22, d33, angle1, angle2, angle3 using specific discharge + call this%calcdispellipse() + ! + ! -- Recalculate dispersion coefficients if the flows were updated + if (this%fmi%iflowsupdated == 1) then + if (this%ixt3d == 0) then + call this%calcdispcoef() + else if (this%ixt3d > 0) then + call this%xt3d%xt3d_fcpc(this%dis%nodes, .true.) + end if + end if + ! + ! -- Return + return + end subroutine dsp_ad + + !> @brief Fill coefficient method for package + !! + !! Method to calculate and fill coefficients for the package. + !< + subroutine dsp_fc(this, kiter, nodes, nja, matrix_sln, idxglo, rhs, cnew) + ! -- dummy + class(GweDspType) :: this + integer(I4B) :: kiter + integer(I4B), intent(in) :: nodes + integer(I4B), intent(in) :: nja + class(MatrixBaseType), pointer :: matrix_sln + integer(I4B), intent(in), dimension(nja) :: idxglo + real(DP), intent(inout), dimension(nodes) :: rhs + real(DP), intent(inout), dimension(nodes) :: cnew + ! -- local + integer(I4B) :: n, m, idiag, idiagm, ipos, isympos, isymcon + real(DP) :: dnm + ! + if (this%ixt3d > 0) then + call this%xt3d%xt3d_fc(kiter, matrix_sln, idxglo, rhs, cnew) + else + do n = 1, nodes + if (this%fmi%ibdgwfsat0(n) == 0) cycle + idiag = this%dis%con%ia(n) + do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1 + if (this%dis%con%mask(ipos) == 0) cycle + m = this%dis%con%ja(ipos) + if (m < n) cycle + if (this%fmi%ibdgwfsat0(m) == 0) cycle + isympos = this%dis%con%jas(ipos) + dnm = this%dispcoef(isympos) + ! + ! -- Contribution to row n + call matrix_sln%add_value_pos(idxglo(ipos), dnm) + call matrix_sln%add_value_pos(idxglo(idiag), -dnm) + ! + ! -- Contribution to row m + idiagm = this%dis%con%ia(m) + isymcon = this%dis%con%isym(ipos) + call matrix_sln%add_value_pos(idxglo(isymcon), dnm) + call matrix_sln%add_value_pos(idxglo(idiagm), -dnm) + end do + end do + end if + ! + ! -- Return + return + end subroutine dsp_fc + + !> @ brief Calculate flows for package + !! + !! Method to calculate dispersion contribution to flowja + !< + subroutine dsp_cq(this, cnew, flowja) + ! -- modules + ! -- dummy + class(GweDspType) :: this + real(DP), intent(inout), dimension(:) :: cnew + real(DP), intent(inout), dimension(:) :: flowja + ! -- local + integer(I4B) :: n, m, ipos, isympos + real(DP) :: dnm, qnm + ! + ! -- Calculate dispersion and add to flowja + if (this%ixt3d > 0) then + call this%xt3d%xt3d_flowja(cnew, flowja) + else + do n = 1, this%dis%nodes + if (this%fmi%ibdgwfsat0(n) == 0) cycle + do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1 + m = this%dis%con%ja(ipos) + if (this%fmi%ibdgwfsat0(m) == 0) cycle + isympos = this%dis%con%jas(ipos) + dnm = this%dispcoef(isympos) +!! qnm = dnm * (cnew(m) - cnew(n)) * this%eqnsclfac + qnm = dnm * (cnew(m) - cnew(n)) + flowja(ipos) = flowja(ipos) + qnm + end do + end do + end if + ! + ! -- Return + return + end subroutine dsp_cq + + !> @ brief Allocate scalar variables for package + !! + !! Method to allocate scalar variables for the package. + !< + subroutine allocate_scalars(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + use ConstantsModule, only: DZERO + ! -- dummy + class(GweDspType) :: this + ! + ! -- allocate scalars in NumericalPackageType + call this%NumericalPackageType%allocate_scalars() + ! + ! -- Allocate + call mem_allocate(this%idisp, 'IDISP', this%memoryPath) + call mem_allocate(this%ialh, 'IALH', this%memoryPath) + call mem_allocate(this%ialv, 'IALV', this%memoryPath) + call mem_allocate(this%iath1, 'IATH1', this%memoryPath) + call mem_allocate(this%iath2, 'IATH2', this%memoryPath) + call mem_allocate(this%iatv, 'IATV', this%memoryPath) + call mem_allocate(this%ixt3doff, 'IXT3DOFF', this%memoryPath) + call mem_allocate(this%ixt3drhs, 'IXT3DRHS', this%memoryPath) + call mem_allocate(this%ixt3d, 'IXT3D', this%memoryPath) + call mem_allocate(this%id22, 'ID22', this%memoryPath) + call mem_allocate(this%id33, 'ID33', this%memoryPath) + call mem_allocate(this%iangle1, 'IANGLE1', this%memoryPath) + call mem_allocate(this%iangle2, 'IANGLE2', this%memoryPath) + call mem_allocate(this%iangle3, 'IANGLE3', this%memoryPath) + call mem_allocate(this%iktw, 'IKTW', this%memoryPath) + call mem_allocate(this%ikts, 'IKTS', this%memoryPath) + ! + ! -- Initialize + this%idisp = 0 + this%ialh = 0 + this%ialv = 0 + this%iath1 = 0 + this%iath2 = 0 + this%iatv = 0 + this%ixt3doff = 0 + this%ixt3drhs = 0 + this%ixt3d = 0 + this%id22 = 1 + this%id33 = 1 + this%iangle1 = 1 + this%iangle2 = 1 + this%iangle3 = 1 + this%iktw = 1 + this%ikts = 1 + ! + ! -- Return + return + end subroutine allocate_scalars + + !> @ brief Allocate arrays for package + !! + !! Method to allocate arrays for the package. + !< + subroutine allocate_arrays(this, nodes) + ! -- modules + use MemoryManagerModule, only: mem_allocate + use ConstantsModule, only: DZERO + ! -- dummy + class(GweDspType) :: this + integer(I4B), intent(in) :: nodes + ! + ! -- Allocate + call mem_allocate(this%alh, nodes, 'ALH', trim(this%memoryPath)) + call mem_allocate(this%alv, nodes, 'ALV', trim(this%memoryPath)) + call mem_allocate(this%ath1, nodes, 'ATH1', trim(this%memoryPath)) + call mem_allocate(this%ath2, nodes, 'ATH2', trim(this%memoryPath)) + call mem_allocate(this%atv, nodes, 'ATV', trim(this%memoryPath)) + call mem_allocate(this%d11, nodes, 'D11', trim(this%memoryPath)) + call mem_allocate(this%d22, nodes, 'D22', trim(this%memoryPath)) + call mem_allocate(this%d33, nodes, 'D33', trim(this%memoryPath)) + call mem_allocate(this%angle1, nodes, 'ANGLE1', trim(this%memoryPath)) + call mem_allocate(this%angle2, nodes, 'ANGLE2', trim(this%memoryPath)) + call mem_allocate(this%angle3, nodes, 'ANGLE3', trim(this%memoryPath)) + call mem_allocate(this%ktw, nodes, 'KTW', trim(this%memoryPath)) + call mem_allocate(this%kts, nodes, 'KTS', trim(this%memoryPath)) + ! + ! -- Allocate dispersion coefficient array if xt3d not in use + if (this%ixt3d == 0) then + call mem_allocate(this%dispcoef, this%dis%njas, 'DISPCOEF', & + trim(this%memoryPath)) + else + call mem_allocate(this%dispcoef, 0, 'DISPCOEF', trim(this%memoryPath)) + end if + ! + ! -- Return + return + end subroutine allocate_arrays + + !> @ brief Deallocate memory + !! + !! Method to deallocate memory for the package. + !< + subroutine dsp_da(this) + ! -- modules + use MemoryManagerModule, only: mem_deallocate + use MemoryManagerExtModule, only: memorylist_remove + use SimVariablesModule, only: idm_context + ! -- dummy + class(GweDspType) :: this + ! -- local + ! + ! -- Deallocate input memory + call memorylist_remove(this%name_model, 'DSP', idm_context) + ! + ! -- deallocate arrays + if (this%inunit /= 0) then + call mem_deallocate(this%alh) + call mem_deallocate(this%alv, 'ALV', trim(this%memoryPath)) + call mem_deallocate(this%ath1) + call mem_deallocate(this%ath2, 'ATH2', trim(this%memoryPath)) + call mem_deallocate(this%atv, 'ATV', trim(this%memoryPath)) + call mem_deallocate(this%d11) + call mem_deallocate(this%d22) + call mem_deallocate(this%d33) + call mem_deallocate(this%angle1) + call mem_deallocate(this%angle2) + call mem_deallocate(this%angle3) + call mem_deallocate(this%ktw) + call mem_deallocate(this%kts) + call mem_deallocate(this%dispcoef) + if (this%ixt3d > 0) call this%xt3d%xt3d_da() + end if + ! + ! -- deallocate objects + if (this%ixt3d > 0) deallocate (this%xt3d) + nullify (this%gwecommon) + ! + ! -- deallocate scalars + call mem_deallocate(this%idisp) + call mem_deallocate(this%ialh) + call mem_deallocate(this%ialv) + call mem_deallocate(this%iath1) + call mem_deallocate(this%iath2) + call mem_deallocate(this%iatv) + call mem_deallocate(this%ixt3doff) + call mem_deallocate(this%ixt3drhs) + call mem_deallocate(this%ixt3d) + call mem_deallocate(this%id22) + call mem_deallocate(this%id33) + call mem_deallocate(this%iangle1) + call mem_deallocate(this%iangle2) + call mem_deallocate(this%iangle3) + call mem_deallocate(this%iktw) + call mem_deallocate(this%ikts) + ! + ! -- deallocate variables in NumericalPackageType + call this%NumericalPackageType%da() + ! + ! -- Return + return + end subroutine dsp_da + + !> @brief Write user options to list file + !< + subroutine log_options(this, found) + use GweDspInputModule, only: GweDspParamFoundType + class(GweDspType) :: this + type(GweDspParamFoundType), intent(in) :: found + ! + write (this%iout, '(1x,a)') 'Setting DSP Options' + write (this%iout, '(4x,a,i0)') 'XT3D formulation [0=INACTIVE, 1=ACTIVE, & + &3=ACTIVE RHS] set to: ', this%ixt3d + write (this%iout, '(1x,a,/)') 'End Setting DSP Options' + ! -- Return + return + end subroutine log_options + + !> @brief Update simulation mempath options + !< + subroutine source_options(this) + ! -- modules + use MemoryManagerExtModule, only: mem_set_value + use GweDspInputModule, only: GweDspParamFoundType + ! -- dummy + class(GweDspType) :: this + ! -- locals + type(GweDspParamFoundType) :: found + ! + ! -- update defaults with idm sourced values + call mem_set_value(this%ixt3doff, 'XT3D_OFF', this%input_mempath, & + found%xt3d_off) + call mem_set_value(this%ixt3drhs, 'XT3D_RHS', this%input_mempath, & + found%xt3d_rhs) + ! + ! -- set xt3d state flag + if (found%xt3d_off) this%ixt3d = 0 + if (found%xt3d_rhs) this%ixt3d = 2 + ! + ! -- log options + if (this%iout > 0) then + call this%log_options(found) + end if + ! + ! -- Return + return + end subroutine source_options + + !> @brief Write dimensions to list file + !< + subroutine log_griddata(this, found) + use GweDspInputModule, only: GweDspParamFoundType + class(GweDspType) :: this + type(GweDspParamFoundType), intent(in) :: found + ! + write (this%iout, '(1x,a)') 'Setting DSP Griddata' + ! + if (found%alh) then + write (this%iout, '(4x,a)') 'ALH set from input file' + end if + ! + if (found%alv) then + write (this%iout, '(4x,a)') 'ALV set from input file' + end if + ! + if (found%ath1) then + write (this%iout, '(4x,a)') 'ATH1 set from input file' + end if + ! + if (found%ath2) then + write (this%iout, '(4x,a)') 'ATH2 set from input file' + end if + ! + if (found%atv) then + write (this%iout, '(4x,a)') 'ATV set from input file' + end if + ! + if (found%ktw) then + write (this%iout, '(4x,a)') 'KTW set from input file' + end if + ! + if (found%kts) then + write (this%iout, '(4x,a)') 'KTS set from input file' + end if + ! + write (this%iout, '(1x,a,/)') 'End Setting DSP Griddata' + ! + ! -- Return + return + end subroutine log_griddata + + !> @brief Update DSP simulation data from input mempath + !< + subroutine source_griddata(this) + ! -- modules + use SimModule, only: count_errors, store_error + use MemoryManagerModule, only: mem_reallocate, mem_reassignptr + use MemoryManagerExtModule, only: mem_set_value + use ConstantsModule, only: LENMEMPATH, LINELENGTH + use GweDspInputModule, only: GweDspParamFoundType + ! -- dummy + class(GweDspType) :: this + ! -- locals + character(len=LINELENGTH) :: errmsg + type(GweDspParamFoundType) :: found + integer(I4B), dimension(:), pointer, contiguous :: map + ! -- formats + ! + ! -- set map + map => null() + if (this%dis%nodes < this%dis%nodesuser) map => this%dis%nodeuser + ! + ! -- update defaults with idm sourced values + call mem_set_value(this%alh, 'ALH', this%input_mempath, map, found%alh) + call mem_set_value(this%alv, 'ALV', this%input_mempath, map, found%alv) + call mem_set_value(this%ath1, 'ATH1', this%input_mempath, map, found%ath1) + call mem_set_value(this%ath2, 'ATH2', this%input_mempath, map, found%ath2) + call mem_set_value(this%atv, 'ATV', this%input_mempath, map, found%atv) + call mem_set_value(this%ktw, 'KTW', this%input_mempath, map, found%ktw) + call mem_set_value(this%kts, 'KTS', this%input_mempath, map, found%kts) + ! + ! -- set active flags + if (found%alh) this%ialh = 1 + if (found%alv) this%ialv = 1 + if (found%ath1) this%iath1 = 1 + if (found%ath2) this%iath2 = 1 + if (found%atv) this%iatv = 1 + if (found%ktw) this%iktw = 1 + if (found%kts) this%ikts = 1 + ! + ! -- set this%idisp flag + if (found%alh) this%idisp = this%idisp + 1 + if (found%alv) this%idisp = this%idisp + 1 + if (found%ath1) this%idisp = this%idisp + 1 + if (found%ath2) this%idisp = this%idisp + 1 + ! + ! -- manage dispersion arrays + if (this%idisp > 0) then + if (.not. (found%alh .and. found%ath1)) then + write (errmsg, '(1x,a)') & + 'if dispersivities are specified then ALH and ATH1 are required.' + call store_error(errmsg) + end if + ! -- If alv not specified then point it to alh + if (.not. found%alv) & + call mem_reassignptr(this%alv, 'ALV', trim(this%memoryPath), & + 'ALH', trim(this%memoryPath)) + ! -- If ath2 not specified then point it to ath1 + if (.not. found%ath2) & + call mem_reassignptr(this%ath2, 'ATH2', trim(this%memoryPath), & + 'ATH1', trim(this%memoryPath)) + ! -- If atv not specified then point it to ath2 + if (.not. found%atv) & + call mem_reassignptr(this%atv, 'ATV', trim(this%memoryPath), & + 'ATH2', trim(this%memoryPath)) + else + call mem_reallocate(this%alh, 0, 'ALH', trim(this%memoryPath)) + call mem_reallocate(this%alv, 0, 'ALV', trim(this%memoryPath)) + call mem_reallocate(this%ath1, 0, 'ATH1', trim(this%memoryPath)) + call mem_reallocate(this%ath2, 0, 'ATH2', trim(this%memoryPath)) + call mem_reallocate(this%atv, 0, 'ATV', trim(this%memoryPath)) + end if + ! + ! -- log griddata + if (this%iout > 0) then + call this%log_griddata(found) + end if + ! + ! -- Return + return + end subroutine source_griddata + + !> @brief Calculate dispersion coefficients + !< + subroutine calcdispellipse(this) + ! -- modules + ! -- dummy + class(GweDspType) :: this + ! -- local + integer(I4B) :: nodes, n + real(DP) :: q, qx, qy, qz + real(DP) :: alh, alv, ath1, ath2, atv, a + real(DP) :: al, at1, at2 + real(DP) :: qzoqsquared + real(DP) :: ktbulk ! TODO: Implement additional options for characterizing ktbulk (see Markle refs) + real(DP) :: dstar + real(DP) :: qsw + ! + ! -- loop through and calculate dispersion coefficients and angles + nodes = size(this%d11) + do n = 1, nodes + ! + ! -- initialize + this%d11(n) = DZERO + this%d22(n) = DZERO + this%d33(n) = DZERO + this%angle1(n) = DZERO + this%angle2(n) = DZERO + this%angle3(n) = DZERO + if (this%fmi%ibdgwfsat0(n) == 0) cycle + ! + ! -- specific discharge + qx = DZERO + qy = DZERO + qz = DZERO + q = DZERO + qx = this%fmi%gwfspdis(1, n) + qy = this%fmi%gwfspdis(2, n) + qz = this%fmi%gwfspdis(3, n) + q = qx**2 + qy**2 + qz**2 + if (q > DZERO) q = sqrt(q) + ! + ! -- dispersion coefficients + alh = DZERO + alv = DZERO + ath1 = DZERO + ath2 = DZERO + atv = DZERO + if (this%idisp > 0) then + alh = this%alh(n) + alv = this%alv(n) + ath1 = this%ath1(n) + ath2 = this%ath2(n) + atv = this%atv(n) + end if + ! + ! -- calculate + ktbulk = DZERO + if (this%iktw > 0) ktbulk = ktbulk + this%porosity(n) * this%ktw(n) * & + this%fmi%gwfsat(n) + if (this%ikts > 0) ktbulk = ktbulk + (DONE - this%porosity(n)) * this%kts(n) + ! + ! -- The division by rhow*cpw below is done to render dstar in the form + ! of a thermal diffusivity, and not because the governing equation + ! is scaled by rhow*cpw. Because of this conceptual distinction, + ! ktbulk is divided by the explicitly calculated product rhow*cpw, + ! and not by the equivalent scale factor eqnsclfac, even though it + ! should make no practical difference in the result. + dstar = ktbulk / (this%gwecommon%gwecpw * this%gwecommon%gwerhow) ! kluge note eqnsclfac, define product + ! + ! -- Calculate the longitudal and transverse dispersivities + al = DZERO + at1 = DZERO + at2 = DZERO + if (q > DZERO) then + qzoqsquared = (qz / q)**2 + al = alh * (DONE - qzoqsquared) + alv * qzoqsquared + at1 = ath1 * (DONE - qzoqsquared) + atv * qzoqsquared + at2 = ath2 * (DONE - qzoqsquared) + atv * qzoqsquared + end if + ! + ! -- Calculate and save the diagonal components of the dispersion tensor + qsw = q * this%fmi%gwfsat(n) * this%eqnsclfac + this%d11(n) = al * qsw + ktbulk + this%d22(n) = at1 * qsw + ktbulk + this%d33(n) = at2 * qsw + ktbulk + ! + ! -- Angles of rotation if velocity based dispersion tensor + if (this%idisp > 0) then + ! + ! -- angle3 is zero + this%angle3(n) = DZERO + ! + ! -- angle2 + a = DZERO + if (q > DZERO) a = qz / q + this%angle2(n) = asin(a) + ! + ! -- angle1 + a = q * cos(this%angle2(n)) + if (a /= DZERO) then + a = qx / a + else + a = DZERO + end if + ! + ! -- acos(1) not defined, so set to zero if necessary + if (a <= -DONE) then + this%angle1(n) = DPI + elseif (a >= DONE) then + this%angle1(n) = DZERO + else + this%angle1(n) = acos(a) + end if + ! + end if + end do + ! + ! -- Return + return + end subroutine calcdispellipse + + !> @brief Calculate dispersion coefficients + !< + subroutine calcdispcoef(this) + ! -- modules + use GwfNpfModule, only: hyeff_calc + ! -- dummy + class(GweDspType) :: this + ! -- local + integer(I4B) :: nodes, n, m, idiag, ipos + real(DP) :: clnm, clmn, dn, dm + real(DP) :: vg1, vg2, vg3 + integer(I4B) :: ihc, isympos + integer(I4B) :: iavgmeth + real(DP) :: satn, satm, topn, topm, botn, botm + real(DP) :: hwva, cond, cn, cm, denom + real(DP) :: anm, amn, thksatn, thksatm, sill_top, sill_bot, tpn, tpm + ! + ! -- set iavgmeth = 1 to use arithmetic averaging for effective dispersion + iavgmeth = 1 + ! + ! -- Process connections + nodes = size(this%d11) + do n = 1, nodes + if (this%fmi%ibdgwfsat0(n) == 0) cycle + idiag = this%dis%con%ia(n) + do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1 + ! + ! -- Set m to connected cell + m = this%dis%con%ja(ipos) + ! + ! -- skip for lower triangle + if (m < n) cycle + isympos = this%dis%con%jas(ipos) + this%dispcoef(isympos) = DZERO + if (this%fmi%ibdgwfsat0(m) == 0) cycle + ! + ! -- cell dimensions + hwva = this%dis%con%hwva(isympos) + clnm = this%dis%con%cl1(isympos) + clmn = this%dis%con%cl2(isympos) + ihc = this%dis%con%ihc(isympos) + topn = this%dis%top(n) + topm = this%dis%top(m) + botn = this%dis%bot(n) + botm = this%dis%bot(m) + ! + ! -- flow model information + satn = this%fmi%ibdgwfsat0(n) + satm = this%fmi%ibdgwfsat0(m) + ! + ! -- Calculate dispersion coefficient for cell n in the direction + ! normal to the shared n-m face and for cell m in the direction + ! normal to the shared n-m face. + call this%dis%connection_normal(n, m, ihc, vg1, vg2, vg3, ipos) + dn = hyeff_calc(this%d11(n), this%d22(n), this%d33(n), & + this%angle1(n), this%angle2(n), this%angle3(n), & + vg1, vg2, vg3, iavgmeth) + dm = hyeff_calc(this%d11(m), this%d22(m), this%d33(m), & + this%angle1(m), this%angle2(m), this%angle3(m), & + vg1, vg2, vg3, iavgmeth) + ! + ! -- Calculate dispersion conductance based on NPF subroutines and the + ! effective dispersion coefficients dn and dm. + if (ihc == 0) then + clnm = satn * (topn - botn) * DHALF + clmn = satm * (topm - botm) * DHALF + anm = hwva + ! + ! -- n is convertible and unsaturated + if (satn == DZERO) then + anm = DZERO + else if (n > m .and. satn < DONE) then + anm = DZERO + end if + ! + ! -- m is convertible and unsaturated + if (satm == DZERO) then + anm = DZERO + else if (m > n .and. satm < DONE) then + anm = DZERO + end if + ! + ! -- amn is the same as anm for vertical flow + amn = anm + ! + else + ! + ! -- horizontal conductance + thksatn = (topn - botn) * satn + thksatm = (topm - botm) * satm + ! + ! -- handle vertically staggered case + if (ihc == 2) then + sill_top = min(topn, topm) + sill_bot = max(botn, botm) + tpn = botn + thksatn + tpm = botm + thksatm + thksatn = max(min(tpn, sill_top) - sill_bot, DZERO) + thksatm = max(min(tpm, sill_top) - sill_bot, DZERO) + end if + ! + ! -- calculate the saturated area term + anm = thksatn * hwva + amn = thksatm * hwva + ! + ! -- n or m is unsaturated, so no dispersion + if (satn == DZERO .or. satm == DZERO) then + anm = DZERO + amn = DZERO + end if + ! + end if + ! + ! -- calculate conductance using the two half cell conductances + cn = DZERO + if (clnm > DZERO) cn = dn * anm / clnm + cm = DZERO + if (clmn > DZERO) cm = dm * amn / clmn + denom = cn + cm + if (denom > DZERO) then + cond = cn * cm / denom + else + cond = DZERO + end if + ! + ! -- Assign the calculated dispersion conductance + this%dispcoef(isympos) = cond + ! + end do + end do + ! + ! -- Return + return + end subroutine calcdispcoef + +end module GweDspModule diff --git a/src/Model/GroundWaterEnergy/gwe1dsp1idm.f90 b/src/Model/GroundWaterEnergy/gwe1dsp1idm.f90 new file mode 100644 index 00000000000..b98fe8f3307 --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1dsp1idm.f90 @@ -0,0 +1,231 @@ +! ** Do Not Modify! MODFLOW 6 system generated file. ** +module GweDspInputModule + use ConstantsModule, only: LENVARNAME + use InputDefinitionModule, only: InputParamDefinitionType, & + InputBlockDefinitionType + private + public gwe_dsp_param_definitions + public gwe_dsp_aggregate_definitions + public gwe_dsp_block_definitions + public GweDspParamFoundType + public gwe_dsp_multi_package + + type GweDspParamFoundType + logical :: xt3d_off = .false. + logical :: xt3d_rhs = .false. + logical :: alh = .false. + logical :: alv = .false. + logical :: ath1 = .false. + logical :: ath2 = .false. + logical :: atv = .false. + logical :: ktw = .false. + logical :: kts = .false. + end type GweDspParamFoundType + + logical :: gwe_dsp_multi_package = .false. + + type(InputParamDefinitionType), parameter :: & + gwedsp_xt3d_off = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DSP', & ! subcomponent + 'OPTIONS', & ! block + 'XT3D_OFF', & ! tag name + 'XT3D_OFF', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedsp_xt3d_rhs = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DSP', & ! subcomponent + 'OPTIONS', & ! block + 'XT3D_RHS', & ! tag name + 'XT3D_RHS', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedsp_alh = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DSP', & ! subcomponent + 'GRIDDATA', & ! block + 'ALH', & ! tag name + 'ALH', & ! fortran variable + 'DOUBLE1D', & ! type + 'NODES', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .true., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedsp_alv = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DSP', & ! subcomponent + 'GRIDDATA', & ! block + 'ALV', & ! tag name + 'ALV', & ! fortran variable + 'DOUBLE1D', & ! type + 'NODES', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .true., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedsp_ath1 = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DSP', & ! subcomponent + 'GRIDDATA', & ! block + 'ATH1', & ! tag name + 'ATH1', & ! fortran variable + 'DOUBLE1D', & ! type + 'NODES', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .true., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedsp_ath2 = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DSP', & ! subcomponent + 'GRIDDATA', & ! block + 'ATH2', & ! tag name + 'ATH2', & ! fortran variable + 'DOUBLE1D', & ! type + 'NODES', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .true., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedsp_atv = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DSP', & ! subcomponent + 'GRIDDATA', & ! block + 'ATV', & ! tag name + 'ATV', & ! fortran variable + 'DOUBLE1D', & ! type + 'NODES', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .true., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedsp_ktw = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DSP', & ! subcomponent + 'GRIDDATA', & ! block + 'KTW', & ! tag name + 'KTW', & ! fortran variable + 'DOUBLE1D', & ! type + 'NODES', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .true., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwedsp_kts = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'DSP', & ! subcomponent + 'GRIDDATA', & ! block + 'KTS', & ! tag name + 'KTS', & ! fortran variable + 'DOUBLE1D', & ! type + 'NODES', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .true., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwe_dsp_param_definitions(*) = & + [ & + gwedsp_xt3d_off, & + gwedsp_xt3d_rhs, & + gwedsp_alh, & + gwedsp_alv, & + gwedsp_ath1, & + gwedsp_ath2, & + gwedsp_atv, & + gwedsp_ktw, & + gwedsp_kts & + ] + + type(InputParamDefinitionType), parameter :: & + gwe_dsp_aggregate_definitions(*) = & + [ & + InputParamDefinitionType & + ( & + '', & ! component + '', & ! subcomponent + '', & ! block + '', & ! tag name + '', & ! fortran variable + '', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) & + ] + + type(InputBlockDefinitionType), parameter :: & + gwe_dsp_block_definitions(*) = & + [ & + InputBlockDefinitionType( & + 'OPTIONS', & ! blockname + .false., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'GRIDDATA', & ! blockname + .false., & ! required + .false., & ! aggregate + .false. & ! block_variable + ) & + ] + +end module GweDspInputModule diff --git a/src/Model/GroundWaterEnergy/gwe1ic1idm.f90 b/src/Model/GroundWaterEnergy/gwe1ic1idm.f90 new file mode 100644 index 00000000000..95dd79e256d --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1ic1idm.f90 @@ -0,0 +1,79 @@ +! ** Do Not Modify! MODFLOW 6 system generated file. ** +module GweIcInputModule + use ConstantsModule, only: LENVARNAME + use InputDefinitionModule, only: InputParamDefinitionType, & + InputBlockDefinitionType + private + public gwe_ic_param_definitions + public gwe_ic_aggregate_definitions + public gwe_ic_block_definitions + public GweIcParamFoundType + public gwe_ic_multi_package + + type GweIcParamFoundType + logical :: strt = .false. + end type GweIcParamFoundType + + logical :: gwe_ic_multi_package = .false. + + type(InputParamDefinitionType), parameter :: & + gweic_strt = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'IC', & ! subcomponent + 'GRIDDATA', & ! block + 'STRT', & ! tag name + 'STRT', & ! fortran variable + 'DOUBLE1D', & ! type + 'NODES', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .true., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwe_ic_param_definitions(*) = & + [ & + gweic_strt & + ] + + type(InputParamDefinitionType), parameter :: & + gwe_ic_aggregate_definitions(*) = & + [ & + InputParamDefinitionType & + ( & + '', & ! component + '', & ! subcomponent + '', & ! block + '', & ! tag name + '', & ! fortran variable + '', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) & + ] + + type(InputBlockDefinitionType), parameter :: & + gwe_ic_block_definitions(*) = & + [ & + InputBlockDefinitionType( & + 'OPTIONS', & ! blockname + .false., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'GRIDDATA', & ! blockname + .true., & ! required + .false., & ! aggregate + .false. & ! block_variable + ) & + ] + +end module GweIcInputModule diff --git a/src/Model/GroundWaterEnergy/gwe1idm.f90 b/src/Model/GroundWaterEnergy/gwe1idm.f90 new file mode 100644 index 00000000000..14d85843018 --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1idm.f90 @@ -0,0 +1,196 @@ +! ** Do Not Modify! MODFLOW 6 system generated file. ** +module GweNamInputModule + use ConstantsModule, only: LENVARNAME + use InputDefinitionModule, only: InputParamDefinitionType, & + InputBlockDefinitionType + private + public gwe_nam_param_definitions + public gwe_nam_aggregate_definitions + public gwe_nam_block_definitions + public GweNamParamFoundType + public gwe_nam_multi_package + + type GweNamParamFoundType + logical :: list = .false. + logical :: print_input = .false. + logical :: print_flows = .false. + logical :: save_flows = .false. + logical :: ftype = .false. + logical :: fname = .false. + logical :: pname = .false. + end type GweNamParamFoundType + + logical :: gwe_nam_multi_package = .false. + + type(InputParamDefinitionType), parameter :: & + gwenam_list = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'NAM', & ! subcomponent + 'OPTIONS', & ! block + 'LIST', & ! tag name + 'LIST', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .true., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwenam_print_input = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'NAM', & ! subcomponent + 'OPTIONS', & ! block + 'PRINT_INPUT', & ! tag name + 'PRINT_INPUT', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwenam_print_flows = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'NAM', & ! subcomponent + 'OPTIONS', & ! block + 'PRINT_FLOWS', & ! tag name + 'PRINT_FLOWS', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwenam_save_flows = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'NAM', & ! subcomponent + 'OPTIONS', & ! block + 'SAVE_FLOWS', & ! tag name + 'SAVE_FLOWS', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwenam_ftype = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'NAM', & ! subcomponent + 'PACKAGES', & ! block + 'FTYPE', & ! tag name + 'FTYPE', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwenam_fname = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'NAM', & ! subcomponent + 'PACKAGES', & ! block + 'FNAME', & ! tag name + 'FNAME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .true., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwenam_pname = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'NAM', & ! subcomponent + 'PACKAGES', & ! block + 'PNAME', & ! tag name + 'PNAME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .false., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwe_nam_param_definitions(*) = & + [ & + gwenam_list, & + gwenam_print_input, & + gwenam_print_flows, & + gwenam_save_flows, & + gwenam_ftype, & + gwenam_fname, & + gwenam_pname & + ] + + type(InputParamDefinitionType), parameter :: & + gwenam_packages = InputParamDefinitionType & + ( & + 'GWE', & ! component + 'NAM', & ! subcomponent + 'PACKAGES', & ! block + 'PACKAGES', & ! tag name + 'PACKAGES', & ! fortran variable + 'RECARRAY FTYPE FNAME PNAME', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + gwe_nam_aggregate_definitions(*) = & + [ & + gwenam_packages & + ] + + type(InputBlockDefinitionType), parameter :: & + gwe_nam_block_definitions(*) = & + [ & + InputBlockDefinitionType( & + 'OPTIONS', & ! blockname + .false., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'PACKAGES', & ! blockname + .true., & ! required + .true., & ! aggregate + .false. & ! block_variable + ) & + ] + +end module GweNamInputModule diff --git a/src/Model/GroundWaterEnergy/gwe1mst1.f90 b/src/Model/GroundWaterEnergy/gwe1mst1.f90 new file mode 100644 index 00000000000..289417f3ca6 --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1mst1.f90 @@ -0,0 +1,912 @@ +!> -- @ brief Mobile Storage and Transfer (MST) Module +!! +!! The GweMstModule contains the GweMstType, which is related +!! to GwtMstModule; however, there are some important differences +!! owing to the fact that a sorbed phase is not considered. +!! Instead, a single temperature is simulated for each grid +!! cell and is represenative of both the aqueous and solid +!! phases (i.e., instantaneous thermal equilibrium is +!! assumed). Also, "thermal bleeding" is accomodated, where +!! conductive processes can transport into, through, or +!! out of dry cells that are part of the active domain. +!< +module GweMstModule + + use KindModule, only: DP, I4B + use ConstantsModule, only: DONE, DZERO, DTWO, DHALF, LENBUDTXT + use SimVariablesModule, only: errmsg, warnmsg + use SimModule, only: store_error, count_errors, & + store_warning + use MatrixBaseModule + use NumericalPackageModule, only: NumericalPackageType + use BaseDisModule, only: DisBaseType + use TspFmiModule, only: TspFmiType + use GweInputDataModule, only: GweInputDataType + + implicit none + public :: GweMstType + public :: mst_cr + ! + integer(I4B), parameter :: NBDITEMS = 2 + character(len=LENBUDTXT), dimension(NBDITEMS) :: budtxt + data budtxt/' STORAGE-CELLBLK', ' DECAY-AQUEOUS'/ + + !> @ brief Mobile storage and transfer + !! + !! Data and methods for handling changes in temperature + !< + type, extends(NumericalPackageType) :: GweMstType + ! + ! -- storage + real(DP), pointer :: cpw => null() !< heat capacity of water + real(DP), pointer :: rhow => null() !< density of water + real(DP), dimension(:), pointer, contiguous :: cps => null() !< heat capacity of solid + real(DP), dimension(:), pointer, contiguous :: rhos => null() !< density of solid + real(DP), dimension(:), pointer, contiguous :: porosity => null() !< porosity + real(DP), dimension(:), pointer, contiguous :: ratesto => null() !< rate of mobile storage + ! + ! -- decay + integer(I4B), pointer :: idcy => null() !< order of decay rate (0:none, 1:first, 2:zero) + integer(I4B), pointer :: ilhv => null() !< latent heat of vaporization for calculating temperature change associcated with evaporation (0: not specified, not 0: specified) + real(DP), dimension(:), pointer, contiguous :: decay => null() !< first or zero order decay rate (aqueous) + real(DP), dimension(:), pointer, contiguous :: ratedcy => null() !< rate of decay + real(DP), dimension(:), pointer, contiguous :: decaylast => null() !< decay rate used for last iteration (needed for zero order decay) + ! + ! -- misc + integer(I4B), dimension(:), pointer, contiguous :: ibound => null() !< pointer to model ibound + type(TspFmiType), pointer :: fmi => null() !< pointer to fmi object + type(GweInputDataType), pointer :: gwecommon => null() !< pointer to shared gwe data used by multiple packages but set in mst + real(DP), pointer :: latheatvap => null() !< latent heat of vaporization + real(DP), pointer :: eqnsclfac => null() !< governing equation scale factor; =rhow*cpw for energy + + contains + + procedure :: mst_ar + procedure :: mst_fc + procedure :: mst_fc_sto + procedure :: mst_fc_dcy + procedure :: mst_cq + procedure :: mst_cq_sto + procedure :: mst_cq_dcy + procedure :: mst_bd + procedure :: mst_ot_flow + procedure :: mst_da + procedure :: allocate_scalars + procedure, private :: allocate_arrays + procedure, private :: read_options + procedure, private :: read_data + procedure, private :: read_packagedata + + end type GweMstType + +contains + + !> @ brief Create a new MST package object + !! + !! Create a new MST package + !< + subroutine mst_cr(mstobj, name_model, inunit, iout, fmi, eqnsclfac, gwecommon) + ! -- dummy + type(GweMstType), pointer :: mstobj !< unallocated new mst object to create + character(len=*), intent(in) :: name_model !< name of the model + integer(I4B), intent(in) :: inunit !< unit number of WEL package input file + integer(I4B), intent(in) :: iout !< unit number of model listing file + type(TspFmiType), intent(in), target :: fmi !< fmi package for this GWE model + real(DP), intent(in), pointer :: eqnsclfac !< governing equation scale factor + type(GweInputDataType), intent(in), target :: gwecommon !< shared data container for use by multiple GWE packages + ! + ! -- Create the object + allocate (mstobj) + ! + ! -- create name and memory path + call mstobj%set_names(1, name_model, 'MST', 'MST') + ! + ! -- Allocate scalars + call mstobj%allocate_scalars() + ! + ! -- Set variables + mstobj%inunit = inunit + mstobj%iout = iout + mstobj%fmi => fmi + mstobj%eqnsclfac => eqnsclfac + mstobj%gwecommon => gwecommon + ! + ! -- Initialize block parser + call mstobj%parser%Initialize(mstobj%inunit, mstobj%iout) + ! + ! -- Return + return + end subroutine mst_cr + + !> @ brief Allocate and read method for package + !! + !! Method to allocate and read static data for the package. + !< + subroutine mst_ar(this, dis, ibound) + ! -- modules + use GweInputDataModule, only: set_gwe_dat_ptrs + ! -- dummy + class(GweMstType), intent(inout) :: this !< GweMstType object + class(DisBaseType), pointer, intent(in) :: dis !< pointer to dis package + integer(I4B), dimension(:), pointer, contiguous :: ibound !< pointer to GWE ibound array + ! -- local + ! -- formats + character(len=*), parameter :: fmtmst = & + "(1x,/1x,'MST -- MOBILE STORAGE AND TRANSFER PACKAGE, VERSION 1, & + &7/29/2020 INPUT READ FROM UNIT ', i0, //)" + ! + ! --print a message identifying the mobile storage and transfer package. + write (this%iout, fmtmst) this%inunit + ! + ! -- Read options + call this%read_options() + ! + ! -- store pointers to arguments that were passed in + this%dis => dis + this%ibound => ibound + ! + ! -- Allocate arrays + call this%allocate_arrays(dis%nodes) + ! + ! -- read the gridded data + call this%read_data() + ! + ! -- read package data that is not gridded + call this%read_packagedata() + ! + ! -- set pointers for data required by other packages + if (this%ilhv == 1) then + call this%gwecommon%set_gwe_dat_ptrs(this%rhow, this%cpw, this%rhow, & + this%cpw, this%latheatvap) + else + call this%gwecommon%set_gwe_dat_ptrs(this%rhow, this%cpw, this%rhow, & + this%cpw) + end if + ! + ! -- Return + return + end subroutine mst_ar + + !> @ brief Fill coefficient method for package + !! + !! Method to calculate and fill coefficients for the package. + !< + subroutine mst_fc(this, nodes, cold, nja, matrix_sln, idxglo, cnew, & + rhs, kiter) + ! -- modules + ! -- dummy + class(GweMstType) :: this !< GweMstType object + integer, intent(in) :: nodes !< number of nodes + real(DP), intent(in), dimension(nodes) :: cold !< temperature at end of last time step + integer(I4B), intent(in) :: nja !< number of GWE connections + class(MatrixBaseType), pointer :: matrix_sln !< solution matrix + integer(I4B), intent(in), dimension(nja) :: idxglo !< mapping vector for model (local) to solution (global) + real(DP), intent(inout), dimension(nodes) :: rhs !< right-hand side vector for model + real(DP), intent(in), dimension(nodes) :: cnew !< temperature at end of this time step + integer(I4B), intent(in) :: kiter !< solution outer iteration number + ! -- local + ! + ! -- storage contribution + call this%mst_fc_sto(nodes, cold, nja, matrix_sln, idxglo, rhs) + ! + ! -- decay contribution + if (this%idcy /= 0) then + call this%mst_fc_dcy(nodes, cold, cnew, nja, matrix_sln, idxglo, & + rhs, kiter) + end if + ! + ! -- Return + return + end subroutine mst_fc + + !> @ brief Fill storage coefficient method for package + !! + !! Method to calculate and fill storage coefficients for the package. + !< + subroutine mst_fc_sto(this, nodes, cold, nja, matrix_sln, idxglo, rhs) + ! -- modules + use TdisModule, only: delt + ! -- dummy + class(GweMstType) :: this !< GweMstType object + integer, intent(in) :: nodes !< number of nodes + real(DP), intent(in), dimension(nodes) :: cold !< temperature at end of last time step + integer(I4B), intent(in) :: nja !< number of GWE connections + class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix + integer(I4B), intent(in), dimension(nja) :: idxglo !< mapping vector for model (local) to solution (global) + real(DP), intent(inout), dimension(nodes) :: rhs !< right-hand side vector for model + ! -- local + integer(I4B) :: n, idiag + real(DP) :: tled + real(DP) :: hhcof, rrhs + real(DP) :: vnew, vold, vcell, vsolid, term + ! + ! -- set variables + tled = DONE / delt + ! + ! -- loop through and calculate storage contribution to hcof and rhs + do n = 1, this%dis%nodes + ! + ! -- skip if transport inactive + if (this%ibound(n) <= 0) cycle + ! + ! -- calculate new and old water volumes and solid volume + vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n)) + vnew = vcell * this%fmi%gwfsat(n) * this%porosity(n) + vold = vnew + if (this%fmi%igwfstrgss /= 0) vold = vold + this%fmi%gwfstrgss(n) * delt + if (this%fmi%igwfstrgsy /= 0) vold = vold + this%fmi%gwfstrgsy(n) * delt + vsolid = vcell * (DONE - this%porosity(n)) + ! + ! -- add terms to diagonal and rhs accumulators + term = (this%rhos(n) * this%cps(n)) * vsolid + hhcof = -(this%eqnsclfac * vnew + term) * tled + rrhs = -(this%eqnsclfac * vold + term) * tled * cold(n) + idiag = this%dis%con%ia(n) + call matrix_sln%add_value_pos(idxglo(idiag), hhcof) + rhs(n) = rhs(n) + rrhs + end do + ! + ! -- Return + return + end subroutine mst_fc_sto + + !> @ brief Fill decay coefficient method for package + !! + !! Method to calculate and fill decay coefficients for the package. + !< + subroutine mst_fc_dcy(this, nodes, cold, cnew, nja, matrix_sln, & + idxglo, rhs, kiter) + ! -- modules + use TdisModule, only: delt + ! -- dummy + class(GweMstType) :: this !< GweMstType object + integer, intent(in) :: nodes !< number of nodes + real(DP), intent(in), dimension(nodes) :: cold !< temperature at end of last time step + real(DP), intent(in), dimension(nodes) :: cnew !< temperature at end of this time step + integer(I4B), intent(in) :: nja !< number of GWE connections + class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix + integer(I4B), intent(in), dimension(nja) :: idxglo !< mapping vector for model (local) to solution (global) + real(DP), intent(inout), dimension(nodes) :: rhs !< right-hand side vector for model + integer(I4B), intent(in) :: kiter !< solution outer iteration number + ! -- local + integer(I4B) :: n, idiag + real(DP) :: hhcof, rrhs + real(DP) :: swtpdt + real(DP) :: vcell + real(DP) :: decay_rate + ! + ! -- loop through and calculate decay contribution to hcof and rhs + do n = 1, this%dis%nodes + ! + ! -- skip if transport inactive + if (this%ibound(n) <= 0) cycle + ! + ! -- calculate new and old water volumes + vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n)) + swtpdt = this%fmi%gwfsat(n) + ! + ! -- add decay rate terms to accumulators + idiag = this%dis%con%ia(n) + if (this%idcy == 1) then + ! + ! -- first order decay rate is a function of temperature, so add ! note: May want to remove first-order decay for temperature and support only zero-order + ! to left hand side + hhcof = -this%decay(n) * vcell * swtpdt * this%porosity(n) & + * this%eqnsclfac + call matrix_sln%add_value_pos(idxglo(idiag), hhcof) + elseif (this%idcy == 2) then + ! + ! -- Call function to get zero-order decay rate, which may be changed + ! from the user-specified rate to prevent negative temperatures ! Important note: still need to think through negative temps + decay_rate = get_zero_order_decay(this%decay(n), this%decaylast(n), & + kiter, cold(n), cnew(n), delt) + ! -- This term does get divided by eqnsclfac for fc purposes because it + ! should start out being a rate of energy + this%decaylast(n) = decay_rate + rrhs = decay_rate * vcell * swtpdt * this%porosity(n) + rhs(n) = rhs(n) + rrhs + end if + ! + end do + ! + ! -- Return + return + end subroutine mst_fc_dcy + + !> @ brief Calculate flows for package + !! + !! Method to calculate flows for the package. + !< + subroutine mst_cq(this, nodes, cnew, cold, flowja) + ! -- modules + ! -- dummy + class(GweMstType) :: this !< GweMstType object + integer(I4B), intent(in) :: nodes !< number of nodes + real(DP), intent(in), dimension(nodes) :: cnew !< temperature at end of this time step + real(DP), intent(in), dimension(nodes) :: cold !< temperature at end of last time step + real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow between two connected control volumes + ! -- local + ! + ! - storage + call this%mst_cq_sto(nodes, cnew, cold, flowja) + ! + ! -- decay + if (this%idcy /= 0) then + call this%mst_cq_dcy(nodes, cnew, cold, flowja) + end if + ! + ! -- Return + return + end subroutine mst_cq + + !> @ brief Calculate storage terms for package + !! + !! Method to calculate storage terms for the package. + !< + subroutine mst_cq_sto(this, nodes, cnew, cold, flowja) + ! -- modules + use TdisModule, only: delt + ! -- dummy + class(GweMstType) :: this !< GweMstType object + integer(I4B), intent(in) :: nodes !< number of nodes + real(DP), intent(in), dimension(nodes) :: cnew !< temperature at end of this time step + real(DP), intent(in), dimension(nodes) :: cold !< temperature at end of last time step + real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow between two connected control volumes + ! -- local + integer(I4B) :: n + integer(I4B) :: idiag + real(DP) :: rate + real(DP) :: tled + real(DP) :: vwatnew, vwatold, vcell, vsolid, term + real(DP) :: hhcof, rrhs + ! + ! -- initialize + tled = DONE / delt + ! + ! -- Calculate storage change + do n = 1, nodes + this%ratesto(n) = DZERO + ! + ! -- skip if transport inactive + if (this%ibound(n) <= 0) cycle + ! + ! -- calculate new and old water volumes and solid volume + vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n)) + vwatnew = vcell * this%fmi%gwfsat(n) * this%porosity(n) + vwatold = vwatnew + if (this%fmi%igwfstrgss /= 0) vwatold = vwatold + this%fmi%gwfstrgss(n) & + * delt + if (this%fmi%igwfstrgsy /= 0) vwatold = vwatold + this%fmi%gwfstrgsy(n) & + * delt + vsolid = vcell * (DONE - this%porosity(n)) + ! + ! -- calculate rate + term = (this%rhos(n) * this%cps(n)) * vsolid + hhcof = -(this%eqnsclfac * vwatnew + term) * tled + rrhs = -(this%eqnsclfac * vwatold + term) * tled * cold(n) + rate = hhcof * cnew(n) - rrhs + this%ratesto(n) = rate + idiag = this%dis%con%ia(n) + flowja(idiag) = flowja(idiag) + rate + end do + ! + ! -- Return + return + end subroutine mst_cq_sto + + !> @ brief Calculate decay terms for package + !! + !! Method to calculate decay terms for the package. + !< + subroutine mst_cq_dcy(this, nodes, cnew, cold, flowja) ! Important note: this handles only decay in water; need to add zero-order (but not first-order?) decay in solid + ! -- modules + use TdisModule, only: delt + ! -- dummy + class(GweMstType) :: this !< GweMstType object + integer(I4B), intent(in) :: nodes !< number of nodes + real(DP), intent(in), dimension(nodes) :: cnew !< temperature at end of this time step + real(DP), intent(in), dimension(nodes) :: cold !< temperature at end of last time step + real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow between two connected control volumes + ! -- local + integer(I4B) :: n + integer(I4B) :: idiag + real(DP) :: rate + real(DP) :: swtpdt + real(DP) :: hhcof, rrhs + real(DP) :: vcell + real(DP) :: decay_rate + ! + ! -- initialize + ! + ! -- Calculate decay change + do n = 1, nodes + ! + ! -- skip if transport inactive + this%ratedcy(n) = DZERO + if (this%ibound(n) <= 0) cycle + ! + ! -- calculate new and old water volumes + vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n)) + swtpdt = this%fmi%gwfsat(n) + ! + ! -- calculate decay gains and losses + rate = DZERO + hhcof = DZERO + rrhs = DZERO + if (this%idcy == 1) then ! Important note: do we need/want first-order decay for temperature??? + hhcof = -this%decay(n) * vcell * swtpdt * this%porosity(n) & + * this%eqnsclfac + elseif (this%idcy == 2) then + decay_rate = get_zero_order_decay(this%decay(n), this%decaylast(n), & + 0, cold(n), cnew(n), delt) + rrhs = decay_rate * vcell * swtpdt * this%porosity(n) ! Important note: this term does NOT get multiplied by eqnsclfac for cq purposes because it should already be a rate of energy + end if + rate = hhcof * cnew(n) - rrhs + this%ratedcy(n) = rate + idiag = this%dis%con%ia(n) + flowja(idiag) = flowja(idiag) + rate + ! + end do + ! + ! -- Return + return + end subroutine mst_cq_dcy + + !> @ brief Calculate budget terms for package + !! + !! Method to calculate budget terms for the package. + !< + subroutine mst_bd(this, isuppress_output, model_budget) + ! -- modules + use TdisModule, only: delt + use BudgetModule, only: BudgetType, rate_accumulator + ! -- dummy + class(GweMstType) :: this !< GweMstType object + integer(I4B), intent(in) :: isuppress_output !< flag to supress output + type(BudgetType), intent(inout) :: model_budget !< model budget object + ! -- local + real(DP) :: rin + real(DP) :: rout + ! + ! -- sto + call rate_accumulator(this%ratesto, rin, rout) + call model_budget%addentry(rin, rout, delt, budtxt(1), & + isuppress_output, rowlabel=this%packName) + ! + ! -- dcy + if (this%idcy /= 0) then + call rate_accumulator(this%ratedcy, rin, rout) + call model_budget%addentry(rin, rout, delt, budtxt(2), & + isuppress_output, rowlabel=this%packName) + end if + ! + ! -- Return + return + end subroutine mst_bd + + !> @ brief Output flow terms for package + !! + !! Method to output terms for the package. + !< + subroutine mst_ot_flow(this, icbcfl, icbcun) + ! -- dummy + class(GweMstType) :: this !< GweMstType object + integer(I4B), intent(in) :: icbcfl !< flag and unit number for cell-by-cell output + integer(I4B), intent(in) :: icbcun !< flag indication if cell-by-cell data should be saved + ! -- local + integer(I4B) :: ibinun + !character(len=16), dimension(2) :: aname + integer(I4B) :: iprint, nvaluesp, nwidthp + character(len=1) :: cdatafmp = ' ', editdesc = ' ' + real(DP) :: dinact + ! + ! -- Set unit number for binary output + if (this%ipakcb < 0) then + ibinun = icbcun + elseif (this%ipakcb == 0) then + ibinun = 0 + else + ibinun = this%ipakcb + end if + if (icbcfl == 0) ibinun = 0 + ! + ! -- Record the storage rate if requested + if (ibinun /= 0) then + iprint = 0 + dinact = DZERO + ! + ! -- sto + call this%dis%record_array(this%ratesto, this%iout, iprint, -ibinun, & + budtxt(1), cdatafmp, nvaluesp, & + nwidthp, editdesc, dinact) + ! + ! -- dcy + if (this%idcy /= 0) & + call this%dis%record_array(this%ratedcy, this%iout, iprint, -ibinun, & + budtxt(2), cdatafmp, nvaluesp, & + nwidthp, editdesc, dinact) + end if + ! + ! -- Return + return + end subroutine mst_ot_flow + + !> @brief Deallocate memory + !! + !! Method to deallocate memory for the package. + !< + subroutine mst_da(this) + ! -- modules + use MemoryManagerModule, only: mem_deallocate + ! -- dummy + class(GweMstType) :: this !< GweMstType object + ! + ! -- Deallocate arrays if package was active + if (this%inunit > 0) then + call mem_deallocate(this%porosity) + call mem_deallocate(this%ratesto) + call mem_deallocate(this%idcy) + call mem_deallocate(this%ilhv) + call mem_deallocate(this%decay) + call mem_deallocate(this%ratedcy) + call mem_deallocate(this%decaylast) + call mem_deallocate(this%cpw) + call mem_deallocate(this%cps) + call mem_deallocate(this%rhow) + call mem_deallocate(this%rhos) + call mem_deallocate(this%latheatvap) + this%ibound => null() + this%fmi => null() + end if + ! + ! -- Scalars + ! + ! -- deallocate parent + call this%NumericalPackageType%da() + ! + ! -- Return + return + end subroutine mst_da + + !> @ brief Allocate scalar variables for package + !! + !! Method to allocate scalar variables for the package. + !< + subroutine allocate_scalars(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate, mem_setptr + ! -- dummy + class(GweMstType) :: this !< GweMstType object + ! -- local + ! + ! -- Allocate scalars in NumericalPackageType + call this%NumericalPackageType%allocate_scalars() + ! + ! -- Allocate + call mem_allocate(this%cpw, 'CPW', this%memoryPath) + call mem_allocate(this%rhow, 'RHOW', this%memoryPath) + call mem_allocate(this%latheatvap, 'LATHEATVAP', this%memoryPath) + call mem_allocate(this%idcy, 'IDCY', this%memoryPath) + call mem_allocate(this%ilhv, 'ILHV', this%memoryPath) + ! + ! -- Initialize + this%cpw = DZERO + this%rhow = DZERO + this%latheatvap = DZERO + this%idcy = 0 + this%ilhv = 0 + ! + ! -- Return + return + end subroutine allocate_scalars + + !> @ brief Allocate arrays for package + !! + !! Method to allocate arrays for the package. + !< + subroutine allocate_arrays(this, nodes) + ! -- modules + use MemoryManagerModule, only: mem_allocate + use ConstantsModule, only: DZERO + ! -- dummy + class(GweMstType) :: this !< GweMstType object + integer(I4B), intent(in) :: nodes !< number of nodes + ! -- local + integer(I4B) :: n + ! + ! -- Allocate + ! -- sto + call mem_allocate(this%porosity, nodes, 'POROSITY', this%memoryPath) + call mem_allocate(this%ratesto, nodes, 'RATESTO', this%memoryPath) + call mem_allocate(this%cps, nodes, 'CPS', this%memoryPath) + call mem_allocate(this%rhos, nodes, 'RHOS', this%memoryPath) + ! + ! -- dcy + if (this%idcy == 0) then + call mem_allocate(this%ratedcy, 1, 'RATEDCY', this%memoryPath) + call mem_allocate(this%decay, 1, 'DECAY', this%memoryPath) + call mem_allocate(this%decaylast, 1, 'DECAYLAST', this%memoryPath) + else + call mem_allocate(this%ratedcy, this%dis%nodes, 'RATEDCY', this%memoryPath) + call mem_allocate(this%decay, nodes, 'DECAY', this%memoryPath) + call mem_allocate(this%decaylast, nodes, 'DECAYLAST', this%memoryPath) + end if + ! + ! -- Initialize + do n = 1, nodes + this%porosity(n) = DZERO + this%ratesto(n) = DZERO + this%cps(n) = DZERO + this%rhos(n) = DZERO + end do + do n = 1, size(this%decay) + this%decay(n) = DZERO + this%ratedcy(n) = DZERO + this%decaylast(n) = DZERO + end do + ! + ! -- Return + return + end subroutine allocate_arrays + + !> @ brief Read options for package + !! + !! Method to read options for the package. + !< + subroutine read_options(this) + ! -- modules + use ConstantsModule, only: LINELENGTH + ! -- dummy + class(GweMstType) :: this !< GweMstType object + ! -- local + character(len=LINELENGTH) :: keyword + integer(I4B) :: ierr + logical :: isfound, endOfBlock + ! -- formats + character(len=*), parameter :: fmtisvflow = & + &"(4x,'CELL-BY-CELL FLOW INFORMATION WILL BE SAVED TO BINARY "// & + &"FILE WHENEVER ICBCFL IS NOT ZERO.')" + character(len=*), parameter :: fmtidcy1 = & + "(4x,'FIRST-ORDER DECAY IS ACTIVE. ')" + character(len=*), parameter :: fmtidcy2 = & + "(4x,'ZERO-ORDER DECAY IS ACTIVE. ')" + character(len=*), parameter :: fmtilhv = & + "(4x,'LATENT HEAT OF VAPORIZATION WILL BE & + &USED IN EVAPORATION CALCULATIONS.')" + ! + ! -- get options block + call this%parser%GetBlock('OPTIONS', isfound, ierr, blockRequired=.false., & + supportOpenClose=.true.) + ! + ! -- parse options block if detected + if (isfound) then + write (this%iout, '(1x,a)') 'PROCESSING MOBILE STORAGE AND TRANSFER OPTIONS' + do + call this%parser%GetNextLine(endOfBlock) + if (endOfBlock) exit + call this%parser%GetStringCaps(keyword) + select case (keyword) + case ('SAVE_FLOWS') + this%ipakcb = -1 + write (this%iout, fmtisvflow) + case ('FIRST_ORDER_DECAY') + this%idcy = 1 + write (this%iout, fmtidcy1) + case ('ZERO_ORDER_DECAY') + this%idcy = 2 + write (this%iout, fmtidcy2) + case ('LATENT_HEAT_VAPORIZATION') + this%ilhv = 1 + write (this%iout, fmtilhv) + case default + write (errmsg, '(a,a)') 'UNKNOWN MST OPTION: ', trim(keyword) + call store_error(errmsg) + call this%parser%StoreErrorUnit() + end select + end do + write (this%iout, '(1x,a)') 'END OF MOBILE STORAGE AND TRANSFER OPTIONS' + end if + ! + ! -- Return + return + end subroutine read_options + + !> @ brief Read data for package + !! + !! Method to read data for the package. + !< + subroutine read_data(this) + ! -- modules + use ConstantsModule, only: LINELENGTH + use MemoryManagerModule, only: mem_reallocate, mem_reassignptr + ! -- dummy + class(GweMstType) :: this !< GweMstType object + ! -- local + character(len=LINELENGTH) :: keyword + character(len=:), allocatable :: line + integer(I4B) :: istart, istop, lloc, ierr + logical :: isfound, endOfBlock + logical, dimension(4) :: lname + character(len=24), dimension(4) :: aname + ! -- formats + ! -- data + data aname(1)/' MOBILE DOMAIN POROSITY'/ + data aname(2)/' DECAY RATE'/ + data aname(3)/' HEAT CAPACITY OF SOLIDS'/ + data aname(4)/' DENSITY OF SOLIDS'/ + ! + ! -- initialize + isfound = .false. + lname(:) = .false. + ! + ! -- get griddata block + call this%parser%GetBlock('GRIDDATA', isfound, ierr) + if (isfound) then + write (this%iout, '(1x,a)') 'PROCESSING GRIDDATA' + do + call this%parser%GetNextLine(endOfBlock) + if (endOfBlock) exit + call this%parser%GetStringCaps(keyword) + call this%parser%GetRemainingLine(line) + lloc = 1 + select case (keyword) + case ('POROSITY') + call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, & + this%parser%iuactive, this%porosity, & + aname(1)) + lname(1) = .true. + case ('DECAY') + if (this%idcy == 0) & + call mem_reallocate(this%decay, this%dis%nodes, 'DECAY', & + trim(this%memoryPath)) + call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, & + this%parser%iuactive, this%decay, & + aname(2)) + lname(2) = .true. + case ('CPS') + call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, & + this%parser%iuactive, this%cps, & + aname(3)) + lname(3) = .true. + case ('RHOS') + call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, & + this%parser%iuactive, this%rhos, & + aname(4)) + lname(4) = .true. + case default + write (errmsg, '(a,a)') 'UNKNOWN GRIDDATA TAG: ', trim(keyword) + call store_error(errmsg) + call this%parser%StoreErrorUnit() + end select + end do + write (this%iout, '(1x,a)') 'END PROCESSING GRIDDATA' + else + write (errmsg, '(a)') 'REQUIRED GRIDDATA BLOCK NOT FOUND.' + call store_error(errmsg) + call this%parser%StoreErrorUnit() + end if + ! + ! -- Check for required porosity + if (.not. lname(1)) then + write (errmsg, '(a)') 'POROSITY NOT SPECIFIED IN GRIDDATA BLOCK.' + call store_error(errmsg) + end if + if (.not. lname(3)) then + write (errmsg, '(a)') 'CPS NOT SPECIFIED IN GRIDDATA BLOCK.' + call store_error(errmsg) + end if + if (.not. lname(4)) then + write (errmsg, '(a)') 'RHOS NOT SPECIFIED IN GRIDDATA BLOCK.' + call store_error(errmsg) + end if + ! + ! -- Check for required decay/production rate coefficients + if (this%idcy > 0) then + if (.not. lname(2)) then + write (errmsg, '(a)') 'FIRST OR ZERO ORDER DECAY IS & + &ACTIVE BUT THE FIRST RATE COEFFICIENT IS NOT SPECIFIED. DECAY & + &MUST BE SPECIFIED IN GRIDDATA BLOCK.' + call store_error(errmsg) + end if + else + if (lname(2)) then + write (warnmsg, '(a)') 'FIRST OR ZERO ORER DECAY & + &IS NOT ACTIVE BUT DECAY WAS SPECIFIED. DECAY WILL & + &HAVE NO AFFECT ON SIMULATION RESULTS.' + call store_warning(warnmsg) + write (this%iout, '(1x,a)') 'WARNING. '//warnmsg + end if + end if + ! + ! -- terminate if errors + if (count_errors() > 0) then + call this%parser%StoreErrorUnit() + end if + ! + ! -- Return + return + end subroutine read_data + + !> @ brief Read data for package + !! + !! Method to read data for the package. + !< + subroutine read_packagedata(this) + ! -- modules + ! -- dummy + class(GweMstType) :: this !< GweMstType object + ! -- local + logical :: isfound + logical :: endOfBlock + integer(I4B) :: ierr + ! + call this%parser%GetBlock('PACKAGEDATA', isfound, ierr, & + supportopenclose=.true.) + ! + ! -- parse locations block if detected + if (isfound) then + write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%packName))// & + ' PACKAGEDATA' + do + call this%parser%GetNextLine(endOfBlock) + if (endOfBlock) then + exit + end if + ! + ! -- get fluid constants + this%cpw = this%parser%GetDouble() + this%rhow = this%parser%GetDouble() + end do + end if + ! + ! -- Return + return + end subroutine read_packagedata + + !> @ brief Calculate zero-order decay rate and constrain if necessary + !! + !! Function to calculate the zero-order decay rate from the user specified + !! decay rate. If the decay rate is positive, then the decay rate must + !! be constrained so that more energy is not removed than is available. + !! Without this constraint, negative temperatures could result from + !! zero-order decay (no freezing). + !< + function get_zero_order_decay(decay_rate_usr, decay_rate_last, kiter, & + cold, cnew, delt) result(decay_rate) + ! -- dummy + real(DP), intent(in) :: decay_rate_usr !< user-entered decay rate + real(DP), intent(in) :: decay_rate_last !< decay rate used for last iteration + integer(I4B), intent(in) :: kiter !< Picard iteration counter + real(DP), intent(in) :: cold !< temperature at end of last time step + real(DP), intent(in) :: cnew !< temperature at end of this time step + real(DP), intent(in) :: delt !< length of time step + ! -- Return + real(DP) :: decay_rate !< returned value for decay rate + ! + ! -- Return user rate if production, otherwise constrain, if necessary + if (decay_rate_usr < DZERO) then + ! + ! -- Production, no need to limit rate + decay_rate = decay_rate_usr + else + ! + ! -- Need to ensure decay does not result in negative + ! temperature, so reduce the rate if it would result in + ! removing more energy than is in the cell. ! kluge note: think through + if (kiter == 1) then + decay_rate = min(decay_rate_usr, cold / delt) ! kluge note: actually want to use rhow*cpw*cold and rhow*cpw*cnew for rates here and below + else + decay_rate = decay_rate_last + if (cnew < DZERO) then + decay_rate = decay_rate_last + cnew / delt + else if (cnew > cold) then + decay_rate = decay_rate_last + cnew / delt + end if + decay_rate = min(decay_rate_usr, decay_rate) + end if + decay_rate = max(decay_rate, DZERO) + end if + return + end function get_zero_order_decay + +end module GweMstModule diff --git a/src/Model/GroundWaterTransport/gwt1.f90 b/src/Model/GroundWaterTransport/gwt1.f90 index 8f32e270e72..ad8dd762bba 100644 --- a/src/Model/GroundWaterTransport/gwt1.f90 +++ b/src/Model/GroundWaterTransport/gwt1.f90 @@ -155,7 +155,7 @@ subroutine gwt_df(this) ! ! -- Define packages and utility objects call this%dis%dis_df() - call this%fmi%fmi_df(this%dis) + call this%fmi%fmi_df(this%dis, 1) if (this%inmvt > 0) call this%mvt%mvt_df(this%dis) if (this%inadv > 0) call this%adv%adv_df() if (this%indsp > 0) call this%dsp%dsp_df(this%dis) @@ -377,7 +377,6 @@ subroutine gwt_ad(this) call this%fmi%fmi_ad(this%x) ! ! -- Advance - !if(this%inmst > 0) call this%mst%mst_ad() if (this%indsp > 0) call this%dsp%dsp_ad() if (this%inssm > 0) call this%ssm%ssm_ad() do ip = 1, this%bndlist%Count() diff --git a/src/Model/GroundWaterTransport/gwt1cnc1.f90 b/src/Model/GroundWaterTransport/gwt1cnc1.f90 index 366a094c2a1..39b00d2abbd 100644 --- a/src/Model/GroundWaterTransport/gwt1cnc1.f90 +++ b/src/Model/GroundWaterTransport/gwt1cnc1.f90 @@ -134,10 +134,13 @@ end subroutine cnc_allocate_arrays !> @brief Constant concentration/temperature read and prepare (rp) routine !< subroutine cnc_rp(this) + ! -- modules use SimModule, only: store_error use InputOutputModule, only: lowcase implicit none + ! -- dummy class(GwtCncType), intent(inout) :: this + ! -- local integer(I4B) :: i, node, ibd, ierr character(len=30) :: nodestr character(len=LENVARNAME) :: dvtype diff --git a/src/Model/GroundWaterTransport/gwt1dsp1.f90 b/src/Model/GroundWaterTransport/gwt1dsp1.f90 index 427c7701e86..0cd1f598b55 100644 --- a/src/Model/GroundWaterTransport/gwt1dsp1.f90 +++ b/src/Model/GroundWaterTransport/gwt1dsp1.f90 @@ -806,7 +806,7 @@ subroutine calcdispcoef(this) ! -- set iavgmeth = 1 to use arithmetic averaging for effective dispersion iavgmeth = 1 ! - ! -- Proces connections + ! -- Process connections nodes = size(this%d11) do n = 1, nodes if (this%fmi%ibdgwfsat0(n) == 0) cycle diff --git a/src/Model/ModelUtilities/FlowModelInterface.f90 b/src/Model/ModelUtilities/FlowModelInterface.f90 index 73b539a40af..993a70f34c4 100644 --- a/src/Model/ModelUtilities/FlowModelInterface.f90 +++ b/src/Model/ModelUtilities/FlowModelInterface.f90 @@ -29,6 +29,7 @@ module FlowModelInterfaceModule real(DP), dimension(:), pointer, contiguous :: gwfhead => null() !< pointer to the GWF head array real(DP), dimension(:), pointer, contiguous :: gwfsat => null() !< pointer to the GWF saturation array integer(I4B), dimension(:), pointer, contiguous :: ibdgwfsat0 => null() !< mark cells with saturation = 0 to exclude from dispersion + integer(I4B), pointer :: idryinactive => null() !< mark cells with an additional flag to exclude from deactivation (gwe will simulate conduction through dry cells) real(DP), dimension(:), pointer, contiguous :: gwfstrgss => null() !< pointer to flow model QSTOSS real(DP), dimension(:), pointer, contiguous :: gwfstrgsy => null() !< pointer to flow model QSTOSY integer(I4B), pointer :: igwfstrgss => null() !< indicates if gwfstrgss is available @@ -72,12 +73,13 @@ module FlowModelInterfaceModule !> @brief Define the flow model interface !< - subroutine fmi_df(this, dis) + subroutine fmi_df(this, dis, idryinactive) ! -- modules use SimModule, only: store_error ! -- dummy class(FlowModelInterfaceType) :: this class(DisBaseType), pointer, intent(in) :: dis + integer(I4B), intent(in) :: idryinactive ! -- formats character(len=*), parameter :: fmtfmi = & "(1x,/1x,'FMI -- FLOW MODEL INTERFACE, VERSION 2, 8/17/2023', & @@ -85,7 +87,7 @@ subroutine fmi_df(this, dis) character(len=*), parameter :: fmtfmi0 = & "(1x,/1x,'FMI -- FLOW MODEL INTERFACE,'& &' VERSION 2, 8/17/2023')" - + ! ! --print a message identifying the FMI package. if (this%iout > 0) then if (this%inunit /= 0) then @@ -120,6 +122,11 @@ subroutine fmi_df(this, dis) call this%initialize_gwfterms_from_gwfbndlist() end if ! + ! -- Set flag that stops dry flows from being deactivated in a GWE + ! transport model since conduction will still be simulated. + ! 0: GWE (skip deactivation step); 1: GWT (default: use existing code) + this%idryinactive = idryinactive + ! ! -- Return return end subroutine fmi_df @@ -181,6 +188,7 @@ subroutine fmi_da(this) call mem_deallocate(this%iuhds) call mem_deallocate(this%iumvr) call mem_deallocate(this%nflowpack) + call mem_deallocate(this%idryinactive) ! ! -- deallocate parent call this%NumericalPackageType%da() @@ -210,6 +218,7 @@ subroutine allocate_scalars(this) call mem_allocate(this%iuhds, 'IUHDS', this%memoryPath) call mem_allocate(this%iumvr, 'IUMVR', this%memoryPath) call mem_allocate(this%nflowpack, 'NFLOWPACK', this%memoryPath) + call mem_allocate(this%idryinactive, "IDRYINACTIVE", this%memoryPath) ! ! ! ! -- Initialize @@ -221,6 +230,7 @@ subroutine allocate_scalars(this) this%iuhds = 0 this%iumvr = 0 this%nflowpack = 0 + this%idryinactive = 1 ! ! -- Return return diff --git a/src/Model/ModelUtilities/GweDspOptions.f90 b/src/Model/ModelUtilities/GweDspOptions.f90 new file mode 100644 index 00000000000..85e8d52cbc9 --- /dev/null +++ b/src/Model/ModelUtilities/GweDspOptions.f90 @@ -0,0 +1,12 @@ +module GweDspOptionsModule + use KindModule, only: I4B + implicit none + private + + !> @brief data structure (and helpers) for passing dsp option data + !< into the package, as opposed to reading it from file + type, public :: GweDspOptionsType + integer(I4B) :: ixt3d !< flag indicating xt3d is active: 1 = enabled, 2 = rhs + end type GweDspOptionsType + +end module GweDspOptionsModule diff --git a/src/Model/ModelUtilities/GweInputData.f90 b/src/Model/ModelUtilities/GweInputData.f90 new file mode 100644 index 00000000000..f7d4f670723 --- /dev/null +++ b/src/Model/ModelUtilities/GweInputData.f90 @@ -0,0 +1,211 @@ +module GweInputDataModule + + use KindModule, only: I4B, DP + use ConstantsModule, only: DZERO, LENMEMPATH + + implicit none + private + public :: GweInputDataType + public :: gweshared_dat_cr + public :: gweshared_dat_df + public :: set_gwe_dat_ptrs + + !> Data for sharing among multiple packages. Originally read in from + !< the MST package + + type GweInputDataType + + ! dim + integer(I4B) :: nnodes !< number of cells + + ! strings + character(len=LENMEMPATH) :: memoryPath = '' !< the location in the memory manager where the variables are stored + + ! mst data to be share across multiple packages + real(DP), pointer :: gwerhow => null() !< Density of water (for GWE purposes, a constant scalar) + real(DP), pointer :: gwecpw => null() !< Heat capacity of water (non-spatially varying) + real(DP), pointer :: gwelatheatvap => null() !< latent heat of vaporization + real(DP), dimension(:), pointer, contiguous :: gwerhos => null() !< Density of the aquifer material + real(DP), dimension(:), pointer, contiguous :: gwecps => null() !< Heat capacity of solids (spatially varying) + + contains + + ! -- public + procedure, public :: gweshared_dat_df + procedure, public :: set_gwe_dat_ptrs + procedure, public :: gweshared_dat_da + ! -- private + procedure, private :: allocate_shared_vars + procedure, private :: set_gwe_shared_scalars + procedure, private :: set_gwe_shared_arrays + + end type GweInputDataType + +contains + +!> @brief Allocate the shared data +!< + subroutine gweshared_dat_cr(this) + ! -- modules + ! -- dummy + type(GweInputDataType), pointer :: this !< the input data block + ! + ! -- Create the object + allocate (this) + ! + ! -- Return + return + end subroutine gweshared_dat_cr + +!> @brief Define the shared data +!< + subroutine gweshared_dat_df(this, nodes) + ! -- dummy + class(GweInputDataType) :: this !< the input data block + integer(I4B), intent(in) :: nodes + ! -- local + ! + ! -- Allocate variables + call this%allocate_shared_vars(nodes) + ! + ! -- Return + return + end subroutine gweshared_dat_df + + !> @brief Define the information this object holds + !! + !! Allocate strings for storing label names + !! Intended to be analogous to allocate_scalars() + !< + subroutine allocate_shared_vars(this, nodes) + ! -- dummy + class(GweInputDataType) :: this !< TspLabelsType object + integer(I4B), intent(in) :: nodes + ! -- local + integer(I4B) :: i + ! + allocate (this%gwecpw) + allocate (this%gwerhow) + allocate (this%gwelatheatvap) + allocate (this%gwerhos(nodes)) + allocate (this%gwecps(nodes)) + ! + ! -- Initialize values + this%gwecpw = DZERO + this%gwerhow = DZERO + this%gwelatheatvap = DZERO + do i = 1, nodes + this%gwecps(i) = DZERO + this%gwerhos(i) = DZERO + end do + ! + ! -- Return + return + end subroutine allocate_shared_vars + + !> @brief Allocate and read data from MST + !! + !! MST data, including heat capacity of water (cpw), density of water + !! (rhow), latent heat of vaporization (latheatvap), heat capacity of + !! the aquifer material (cps), and density of the aquifer material + !! (rhow) is used among other packages and is therefore stored in a + !! separate class + subroutine set_gwe_dat_ptrs(this, gwerhow, gwecpw, gwerhos, gwecps, & + gwelatheatvap) + ! -- dummy + class(GweInputDataType) :: this !< the input data block + real(DP), intent(in) :: gwerhow !< ptr to density of water specified in MST + real(DP), intent(in) :: gwecpw !< ptr to heat capacity of water specified in MST + real(DP), intent(in) :: gwerhos !< ptr to sptially-variably density of aquifer material specified in MST + real(DP), intent(in) :: gwecps !< ptr to sptially-variably heat capacity of aquifer material specified in MST + real(DP), intent(in), optional :: gwelatheatvap !< ptr to latent heat of vaporization specified in MST + ! + ! -- Allocate scalars + if (present(gwelatheatvap)) then + call this%set_gwe_shared_scalars(gwerhow, gwecpw, gwelatheatvap) + else + call this%set_gwe_shared_scalars(gwerhow, gwecpw) + end if + ! + ! -- Allocate arrays + call this%set_gwe_shared_arrays(gwerhos, gwecps) + ! + ! -- Return + return + end subroutine set_gwe_dat_ptrs + + !> @brief Set pointers to scalars read by the MST package + !! for use by other packages + !! + !! Set pointers to GWE-related scalars and arrays for use + !! by multiple packages. For example, a package capable of + !! simulating evaporation will need access to latent heat of + !! of vaporization. + !< + subroutine set_gwe_shared_scalars(this, gwerhow, gwecpw, gwelatheatvap) + ! -- dummy + class(GweInputDataType) :: this !< GweInputDataType object + real(DP), intent(in) :: gwerhow + real(DP), intent(in) :: gwecpw + real(DP), intent(in), optional :: gwelatheatvap + ! -- local + ! + ! -- Set the pointers + ! -- Fixed density of water to be used by GWE + this%gwerhow = gwerhow + ! -- Spatially constant heat capacity of water ! kluge note: "specific heat" (which is heat capacity per unit mass) is probably the more correct term + this%gwecpw = gwecpw + ! -- Latent heat of vaporization + if (present(gwelatheatvap)) then + this%gwelatheatvap = gwelatheatvap + end if + ! + ! -- Return + return + end subroutine set_gwe_shared_scalars + + !> @brief Set pointers to data arrays read by the MST package + !! for use by other packages + !! + !! Set pointers to GWE-related arrays for use + !! by multiple packages. + !< + subroutine set_gwe_shared_arrays(this, gwerhos, gwecps) + ! -- dummy + class(GweInputDataType) :: this !< GweInputDataType object + real(DP), intent(in) :: gwerhos + real(DP), intent(in) :: gwecps + ! -- local + ! + ! -- Set the pointers + ! -- Spatially-variable density of aquifer solid material + this%gwerhos = gwerhos + ! -- Spatially-variable heat capacity of aquifer solid material + this%gwecps = gwecps + ! + ! -- Return + return + end subroutine set_gwe_shared_arrays + + !> @ breif Deallocate memory + !! + !! Deallocate GWE shared data array memory + !< + subroutine gweshared_dat_da(this) + ! -- dummy + class(GweInputDataType) :: this !< the input data block + ! + ! -- Scalars + deallocate (this%gwelatheatvap) + deallocate (this%gwerhow) + deallocate (this%gwecpw) + ! + ! -- Arrays + deallocate (this%gwerhos) + deallocate (this%gwecps) + ! + ! -- Return + return + end subroutine gweshared_dat_da + +end module GweInputDataModule diff --git a/src/Model/ModelUtilities/ModelPackageInput.f90 b/src/Model/ModelUtilities/ModelPackageInput.f90 index 09782fd08d8..c60486c2569 100644 --- a/src/Model/ModelUtilities/ModelPackageInput.f90 +++ b/src/Model/ModelUtilities/ModelPackageInput.f90 @@ -14,8 +14,11 @@ module ModelPackageInputModule GWF_BASEPKG, GWF_MULTIPKG use GwtModule, only: GWT_NBASEPKG, GWT_NMULTIPKG, & GWT_BASEPKG, GWT_MULTIPKG + use GweModule, only: GWE_NBASEPKG, GWE_NMULTIPKG, & + GWE_BASEPKG, GWE_MULTIPKG implicit none + private public :: supported_model_packages public :: multi_package_type @@ -49,6 +52,11 @@ subroutine supported_model_packages(mtype, pkgtypes, numpkgs) allocate (pkgtypes(numpkgs)) pkgtypes = [GWT_BASEPKG, GWT_MULTIPKG] ! + case ('GWE6') + numpkgs = GWE_NBASEPKG + GWE_NMULTIPKG + allocate (pkgtypes(numpkgs)) + pkgtypes = [GWE_BASEPKG, GWE_MULTIPKG] + ! case default end select ! @@ -89,6 +97,14 @@ function multi_package_type(mtype_component, ptype_component, pkgtype) & end if end do ! + case ('GWE') + do n = 1, GWE_NMULTIPKG + if (GWE_MULTIPKG(n) == pkgtype) then + multi_package = .true. + exit + end if + end do + ! case default end select ! diff --git a/src/Model/ModelUtilities/Xt3dInterface.f90 b/src/Model/ModelUtilities/Xt3dInterface.f90 index f7ca17e1e81..d72f8a3e798 100644 --- a/src/Model/ModelUtilities/Xt3dInterface.f90 +++ b/src/Model/ModelUtilities/Xt3dInterface.f90 @@ -520,7 +520,7 @@ subroutine xt3d_fcpc(this, nodes, lsat) ! -- dummy class(Xt3dType) :: this integer(I4B), intent(in) :: nodes - logical, intent(in) :: lsat !< if true, then calculations made with saturated areas (should be false for dispersion) + logical, intent(in) :: lsat !< if true, then calculations made with saturated areas (should be false for solute dispersion; should be true for heat) ! -- local integer(I4B) :: n, m, ipos ! diff --git a/src/Model/TransportModel/tsp1.f90 b/src/Model/TransportModel/tsp1.f90 index f1de33b333a..ced3996ff4c 100644 --- a/src/Model/TransportModel/tsp1.f90 +++ b/src/Model/TransportModel/tsp1.f90 @@ -20,6 +20,7 @@ module TransportModelModule use TspOcModule, only: TspOcType use TspObsModule, only: TspObsType use BudgetModule, only: BudgetType + use GweInputDataModule, only: GweInputDataType use MatrixBaseModule implicit none @@ -91,7 +92,7 @@ module TransportModelModule !! !! Create a new transport model that will be further refined into GWT or GWE !< - subroutine tsp_cr(this, filename, id, modelname, macronym, indis) + subroutine tsp_cr(this, filename, id, modelname, macronym, indis, gwecommon) ! -- modules use MemoryHelperModule, only: create_mem_path use MemoryManagerExtModule, only: mem_set_value @@ -105,6 +106,7 @@ subroutine tsp_cr(this, filename, id, modelname, macronym, indis) integer(I4B), intent(inout) :: indis character(len=*), intent(in) :: modelname character(len=*), intent(in) :: macronym + type(GweInputDataType), intent(in), optional :: gwecommon !< shared data container for use by multiple GWE packages ! -- local character(len=LENMEMPATH) :: input_mempath character(len=LINELENGTH) :: lst_fname @@ -144,7 +146,11 @@ subroutine tsp_cr(this, filename, id, modelname, macronym, indis) call budget_cr(this%budget, this%name) ! ! -- create model packages - call this%create_tsp_packages(indis) + if (present(gwecommon)) then + call this%create_tsp_packages(indis, gwecommon) + else + call this%create_tsp_packages(indis) + end if ! ! -- Return return @@ -769,7 +775,7 @@ end subroutine log_namfile_options !> @brief Source package info and begin to process !< - subroutine create_tsp_packages(this, indis) + subroutine create_tsp_packages(this, indis, gwecommon) ! -- modules use ConstantsModule, only: LINELENGTH, LENPACKAGENAME use CharacterStringModule, only: CharacterStringType @@ -790,6 +796,7 @@ subroutine create_tsp_packages(this, indis) ! -- dummy class(TransportModelType) :: this integer(I4B), intent(inout) :: indis ! DIS enabled flag + type(GweInputDataType), intent(in), optional :: gwecommon !< shared data container for use by multiple GWE packages ! -- local type(CharacterStringType), dimension(:), contiguous, & pointer :: pkgtypes => null() @@ -866,7 +873,7 @@ subroutine create_tsp_packages(this, indis) call adv_cr(this%adv, this%name, this%inadv, this%iout, this%fmi, & this%eqnsclfac) call ssm_cr(this%ssm, this%name, this%inssm, this%iout, this%fmi, & - this%eqnsclfac, this%depvartype) + this%eqnsclfac, this%depvartype, gwecommon) call mvt_cr(this%mvt, this%name, this%inmvt, this%iout, this%fmi, & this%eqnsclfac) call oc_cr(this%oc, this%name, this%inoc, this%iout) diff --git a/src/Model/TransportModel/tsp1fmi1.f90 b/src/Model/TransportModel/tsp1fmi1.f90 index fe92e15fdcf..d2725cc5609 100644 --- a/src/Model/TransportModel/tsp1fmi1.f90 +++ b/src/Model/TransportModel/tsp1fmi1.f90 @@ -63,6 +63,7 @@ module TspFmiModule procedure :: read_options => gwtfmi_read_options procedure :: set_aptbudobj_pointer procedure :: read_packagedata => gwtfmi_read_packagedata + procedure :: set_active_status end type TspFmiType @@ -186,6 +187,11 @@ subroutine fmi_ad(this, cnew) end do end if ! + ! -- set inactive transport cell status + if (this%idryinactive /= 0) then + call this%set_active_status(cnew) + end if + ! ! -- if flow cell is dry, then set gwt%ibound = 0 and conc to dry do n = 1, this%dis%nodes ! @@ -422,6 +428,7 @@ subroutine gwtfmi_da(this) call mem_deallocate(this%iuhds) call mem_deallocate(this%iumvr) call mem_deallocate(this%nflowpack) + call mem_deallocate(this%idryinactive) ! ! -- deallocate parent call this%NumericalPackageType%da() @@ -489,6 +496,96 @@ subroutine gwtfmi_allocate_arrays(this, nodes) return end subroutine gwtfmi_allocate_arrays + !> @brief Set gwt transport cell status + !! + !! Dry GWF cells are treated differently by GWT and GWE. Transport does not + !! occur in deactivated GWF cells; however, GWE still simulates conduction + !! through dry cells. + !< + subroutine set_active_status(this, cnew) + ! -- modules + use ConstantsModule, only: DHDRY + ! -- dummy + class(TspFmiType) :: this + real(DP), intent(inout), dimension(:) :: cnew + ! -- local + integer(I4B) :: n + integer(I4B) :: m + integer(I4B) :: ipos + real(DP) :: crewet, tflow, flownm + character(len=15) :: nodestr + character(len=LINELENGTH) :: cstr + ! -- formats + character(len=*), parameter :: fmtoutmsg1 = & + &"(1x,'WARNING: DRY CELL ENCOUNTERED AT', a,'; RESET AS INACTIVE WITH & + &DRY', a, '=', G13.5)" + character(len=*), parameter :: fmtoutmsg2 = & + &"(1x,'DRY CELL REACTIVATED AT', a, 'WITH STARTING', a, '=', G13.5)" + ! + do n = 1, this%dis%nodes + ! -- Calculate the ibound-like array that has 0 if saturation + ! is zero and 1 otherwise + if (this%gwfsat(n) > DZERO) then + this%ibdgwfsat0(n) = 1 + else + this%ibdgwfsat0(n) = 0 + end if + ! + ! -- Check if active transport cell is inactive for flow + if (this%ibound(n) > 0) then + if (this%gwfhead(n) == DHDRY) then + ! -- transport cell should be made inactive + this%ibound(n) = 0 + cnew(n) = DHDRY + call this%dis%noder_to_string(n, nodestr) + write (cstr, fmtoutmsg1) trim(nodestr), & + trim(adjustl(this%depvartype)), DHDRY + write (this%iout, cstr) + end if + end if + end do + ! + ! -- if flow cell is dry, then set gwt%ibound = 0 and conc to dry + do n = 1, this%dis%nodes + ! + ! -- Convert dry transport cell to active if flow has rewet + if (cnew(n) == DHDRY) then + if (this%gwfhead(n) /= DHDRY) then + ! + ! -- obtain weighted concentration/temperature + crewet = DZERO + tflow = DZERO + do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1 + m = this%dis%con%ja(ipos) + flownm = this%gwfflowja(ipos) + if (flownm > 0) then + if (this%ibound(m) /= 0) then + crewet = crewet + cnew(m) * flownm ! kluge note: apparently no need to multiply flows by eqnsclfac + tflow = tflow + this%gwfflowja(ipos) ! since it will divide out below anyway + end if + end if + end do + if (tflow > DZERO) then + crewet = crewet / tflow + else + crewet = DZERO + end if + ! + ! -- cell is now wet + this%ibound(n) = 1 + cnew(n) = crewet + call this%dis%noder_to_string(n, nodestr) + write (cstr, fmtoutmsg2) trim(nodestr), & + trim(adjustl(this%depvartype)), crewet + write (this%iout, cstr) + end if + end if + end do + ! + ! -- Return + return + end subroutine set_active_status + !> @brief Calculate the previous saturation level !! !! Calculate the groundwater cell head saturation for the end of diff --git a/src/Model/TransportModel/tsp1ic1.f90 b/src/Model/TransportModel/tsp1ic1.f90 index e36ca15a88e..1a82f0230a7 100644 --- a/src/Model/TransportModel/tsp1ic1.f90 +++ b/src/Model/TransportModel/tsp1ic1.f90 @@ -48,6 +48,9 @@ subroutine ic_cr(ic, name_model, input_mempath, inunit, iout, dis, depvartype) ! ! -- Give package access to the assigned labelsd based on dependent variable ic%depvartype = depvartype + ! + ! -- Return + return end subroutine ic_cr end module TspIcModule diff --git a/src/Model/TransportModel/tsp1ssm1.f90 b/src/Model/TransportModel/tsp1ssm1.f90 index ef1e806da4d..9cddf3e2e2e 100644 --- a/src/Model/TransportModel/tsp1ssm1.f90 +++ b/src/Model/TransportModel/tsp1ssm1.f90 @@ -16,6 +16,7 @@ module TspSsmModule use NumericalPackageModule, only: NumericalPackageType use BaseDisModule, only: DisBaseType use TspFmiModule, only: TspFmiType + use GweInputDataModule, only: GweInputDataType use TableModule, only: TableType, table_cr use GwtSpcModule, only: GwtSpcType use MatrixBaseModule @@ -45,6 +46,7 @@ module TspSsmModule type(GwtSpcType), dimension(:), pointer :: ssmivec => null() !< array of stress package concentration objects real(DP), pointer :: eqnsclfac => null() !< governing equation scale factor; =1. for solute; =rhow*cpw for energy character(len=LENVARNAME) :: depvartype = '' + type(GweInputDataType), pointer :: gwecommon => null() !< pointer to shared gwe data used by multiple packages but set in mst contains @@ -79,7 +81,7 @@ module TspSsmModule !! and initializing the parser. !< subroutine ssm_cr(ssmobj, name_model, inunit, iout, fmi, eqnsclfac, & - depvartype) + depvartype, gwecommon) ! -- dummy type(TspSsmType), pointer :: ssmobj !< TspSsmType object character(len=*), intent(in) :: name_model !< name of the model @@ -87,7 +89,8 @@ subroutine ssm_cr(ssmobj, name_model, inunit, iout, fmi, eqnsclfac, & integer(I4B), intent(in) :: iout !< fortran unit for output type(TspFmiType), intent(in), target :: fmi !< Transport FMI package real(DP), intent(in), pointer :: eqnsclfac !< governing equation scale factor - character(len=LENVARNAME), intent(in) :: depvartype + character(len=LENVARNAME), intent(in) :: depvartype !< dependent variable type ('concentration' or 'temperature') + type(GweInputDataType), intent(in), target, optional :: gwecommon !< shared data container for use by multiple GWE packages ! ! -- Create the object allocate (ssmobj) @@ -111,6 +114,11 @@ subroutine ssm_cr(ssmobj, name_model, inunit, iout, fmi, eqnsclfac, & ! package has access to the corresponding dependent variable type ssmobj%depvartype = depvartype ! + ! -- Give package access to the shared heat transport variables assigned in MST + if (present(gwecommon)) then + ssmobj%gwecommon => gwecommon + end if + ! ! -- Return return end subroutine ssm_cr @@ -718,6 +726,9 @@ subroutine ssm_da(this) ! -- Scalars call mem_deallocate(this%nbound) ! + ! -- Pointers + nullify (this%gwecommon) + ! ! -- deallocate parent call this%NumericalPackageType%da() ! diff --git a/src/SimulationCreate.f90 b/src/SimulationCreate.f90 index 8aebdb1742a..427aba8ed61 100644 --- a/src/SimulationCreate.f90 +++ b/src/SimulationCreate.f90 @@ -213,9 +213,11 @@ subroutine models_create() use SimVariablesModule, only: idm_context use GwfModule, only: gwf_cr use GwtModule, only: gwt_cr + use GweModule, only: gwe_cr use NumericalModelModule, only: NumericalModelType, GetNumericalModelFromList use VirtualGwfModelModule, only: add_virtual_gwf_model use VirtualGwtModelModule, only: add_virtual_gwt_model + use VirtualGweModelModule, only: add_virtual_gwe_model use ConstantsModule, only: LENMODELNAME ! -- dummy ! -- locals @@ -292,6 +294,16 @@ subroutine models_create() model_loc_idx(n) = im end if call add_virtual_gwt_model(n, model_names(n), num_model) + case ('GWE6') + if (model_ranks(n) == proc_id) then + im = im + 1 + write (iout, '(4x,2a,i0,a)') trim(model_type), ' model ', & + n, ' will be created' + call gwe_cr(fname, n, model_names(n)) + num_model => GetNumericalModelFromList(basemodellist, im) + model_loc_idx(n) = im + end if + call add_virtual_gwe_model(n, model_names(n), num_model) case default write (errmsg, '(a,a)') & 'Unknown simulation model type: ', trim(model_type) @@ -322,9 +334,12 @@ subroutine exchanges_create() use SimVariablesModule, only: idm_context use GwfGwfExchangeModule, only: gwfexchange_create use GwfGwtExchangeModule, only: gwfgwt_cr + use GwfGweExchangeModule, only: gwfgwe_cr use GwtGwtExchangeModule, only: gwtexchange_create + use GweGweExchangeModule, only: gweexchange_create use VirtualGwfExchangeModule, only: add_virtual_gwf_exchange use VirtualGwtExchangeModule, only: add_virtual_gwt_exchange + use VirtualGweExchangeModule, only: add_virtual_gwe_exchange ! -- dummy ! -- locals character(len=LENMEMPATH) :: input_mempath @@ -415,6 +430,10 @@ subroutine exchanges_create() if (both_local) then call gwfgwt_cr(fname, exg_id, m1_id, m2_id) end if + case ('GWF6-GWE6') + if (both_local) then + call gwfgwe_cr(fname, exg_id, m1_id, m2_id) + end if case ('GWT6-GWT6') write (exg_name, '(a,i0)') 'GWT-GWT_', exg_id if (.not. both_remote) then @@ -422,6 +441,12 @@ subroutine exchanges_create() exg_mempath) end if call add_virtual_gwt_exchange(exg_name, exg_id, m1_id, m2_id) + case ('GWE6-GWE6') + write (exg_name, '(a,i0)') 'GWE-GWE_', exg_id + if (.not. both_remote) then + call gweexchange_create(fname, exg_name, exg_id, m1_id, m2_id) + end if + call add_virtual_gwe_exchange(exg_name, exg_id, m1_id, m2_id) case default write (errmsg, '(a,a)') & 'Unknown simulation exchange type: ', trim(exgtype) diff --git a/src/Utilities/Idm/selector/IdmDfnSelector.f90 b/src/Utilities/Idm/selector/IdmDfnSelector.f90 index a7b6190f6ff..4e304b707f8 100644 --- a/src/Utilities/Idm/selector/IdmDfnSelector.f90 +++ b/src/Utilities/Idm/selector/IdmDfnSelector.f90 @@ -8,6 +8,7 @@ module IdmDfnSelectorModule use IdmGwfDfnSelectorModule use IdmGwtDfnSelectorModule use IdmExgDfnSelectorModule + use IdmGweDfnSelectorModule use IdmSimDfnSelectorModule implicit none @@ -31,6 +32,8 @@ function param_definitions(component, subcomponent) result(input_definition) input_definition => gwf_param_definitions(subcomponent) case ('GWT') input_definition => gwt_param_definitions(subcomponent) + case ('GWE') + input_definition => gwe_param_definitions(subcomponent) case ('EXG') input_definition => exg_param_definitions(subcomponent) case ('SIM') @@ -50,6 +53,8 @@ function aggregate_definitions(component, subcomponent) result(input_definition) input_definition => gwf_aggregate_definitions(subcomponent) case ('GWT') input_definition => gwt_aggregate_definitions(subcomponent) + case ('GWE') + input_definition => gwe_aggregate_definitions(subcomponent) case ('EXG') input_definition => exg_aggregate_definitions(subcomponent) case ('SIM') @@ -69,6 +74,8 @@ function block_definitions(component, subcomponent) result(input_definition) input_definition => gwf_block_definitions(subcomponent) case ('GWT') input_definition => gwt_block_definitions(subcomponent) + case ('GWE') + input_definition => gwe_block_definitions(subcomponent) case ('EXG') input_definition => exg_block_definitions(subcomponent) case ('SIM') @@ -87,6 +94,8 @@ function idm_multi_package(component, subcomponent) result(multi_package) multi_package = gwf_idm_multi_package(subcomponent) case ('GWT') multi_package = gwt_idm_multi_package(subcomponent) + case ('GWE') + multi_package = gwe_idm_multi_package(subcomponent) case ('EXG') multi_package = exg_idm_multi_package(subcomponent) case ('SIM') @@ -109,6 +118,8 @@ function idm_integrated(component, subcomponent) result(integrated) integrated = gwf_idm_integrated(subcomponent) case ('GWT') integrated = gwt_idm_integrated(subcomponent) + case ('GWE') + integrated = gwe_idm_integrated(subcomponent) case ('EXG') integrated = exg_idm_integrated(subcomponent) case ('SIM') @@ -127,6 +138,8 @@ function idm_component(component) result(integrated) integrated = .true. case ('GWT') integrated = .true. + case ('GWE') + integrated = .true. case ('EXG') integrated = .true. case ('SIM') diff --git a/src/Utilities/Idm/selector/IdmGweDfnSelector.f90 b/src/Utilities/Idm/selector/IdmGweDfnSelector.f90 new file mode 100644 index 00000000000..08f2c670780 --- /dev/null +++ b/src/Utilities/Idm/selector/IdmGweDfnSelector.f90 @@ -0,0 +1,160 @@ +! ** Do Not Modify! MODFLOW 6 system generated file. ** +module IdmGweDfnSelectorModule + + use ConstantsModule, only: LENVARNAME + use SimModule, only: store_error + use InputDefinitionModule, only: InputParamDefinitionType, & + InputBlockDefinitionType + use GweDisInputModule + use GweDisuInputModule + use GweDisvInputModule + use GweDspInputModule + use GweCntInputModule + use GweIcInputModule + use GweNamInputModule + + implicit none + private + public :: gwe_param_definitions + public :: gwe_aggregate_definitions + public :: gwe_block_definitions + public :: gwe_idm_multi_package + public :: gwe_idm_integrated + +contains + + subroutine set_param_pointer(input_dfn, input_dfn_target) + type(InputParamDefinitionType), dimension(:), pointer :: input_dfn + type(InputParamDefinitionType), dimension(:), target :: input_dfn_target + input_dfn => input_dfn_target + end subroutine set_param_pointer + + subroutine set_block_pointer(input_dfn, input_dfn_target) + type(InputBlockDefinitionType), dimension(:), pointer :: input_dfn + type(InputBlockDefinitionType), dimension(:), target :: input_dfn_target + input_dfn => input_dfn_target + end subroutine set_block_pointer + + function gwe_param_definitions(subcomponent) result(input_definition) + character(len=*), intent(in) :: subcomponent + type(InputParamDefinitionType), dimension(:), pointer :: input_definition + nullify (input_definition) + select case (subcomponent) + case ('DIS') + call set_param_pointer(input_definition, gwe_dis_param_definitions) + case ('DISU') + call set_param_pointer(input_definition, gwe_disu_param_definitions) + case ('DISV') + call set_param_pointer(input_definition, gwe_disv_param_definitions) + case ('DSP') + call set_param_pointer(input_definition, gwe_dsp_param_definitions) + case ('CNT') + call set_param_pointer(input_definition, gwe_cnt_param_definitions) + case ('IC') + call set_param_pointer(input_definition, gwe_ic_param_definitions) + case ('NAM') + call set_param_pointer(input_definition, gwe_nam_param_definitions) + case default + end select + return + end function gwe_param_definitions + + function gwe_aggregate_definitions(subcomponent) result(input_definition) + character(len=*), intent(in) :: subcomponent + type(InputParamDefinitionType), dimension(:), pointer :: input_definition + nullify (input_definition) + select case (subcomponent) + case ('DIS') + call set_param_pointer(input_definition, gwe_dis_aggregate_definitions) + case ('DISU') + call set_param_pointer(input_definition, gwe_disu_aggregate_definitions) + case ('DISV') + call set_param_pointer(input_definition, gwe_disv_aggregate_definitions) + case ('DSP') + call set_param_pointer(input_definition, gwe_dsp_aggregate_definitions) + case ('CNT') + call set_param_pointer(input_definition, gwe_cnt_aggregate_definitions) + case ('IC') + call set_param_pointer(input_definition, gwe_ic_aggregate_definitions) + case ('NAM') + call set_param_pointer(input_definition, gwe_nam_aggregate_definitions) + case default + end select + return + end function gwe_aggregate_definitions + + function gwe_block_definitions(subcomponent) result(input_definition) + character(len=*), intent(in) :: subcomponent + type(InputBlockDefinitionType), dimension(:), pointer :: input_definition + nullify (input_definition) + select case (subcomponent) + case ('DIS') + call set_block_pointer(input_definition, gwe_dis_block_definitions) + case ('DISU') + call set_block_pointer(input_definition, gwe_disu_block_definitions) + case ('DISV') + call set_block_pointer(input_definition, gwe_disv_block_definitions) + case ('DSP') + call set_block_pointer(input_definition, gwe_dsp_block_definitions) + case ('CNT') + call set_block_pointer(input_definition, gwe_cnt_block_definitions) + case ('IC') + call set_block_pointer(input_definition, gwe_ic_block_definitions) + case ('NAM') + call set_block_pointer(input_definition, gwe_nam_block_definitions) + case default + end select + return + end function gwe_block_definitions + + function gwe_idm_multi_package(subcomponent) result(multi_package) + character(len=*), intent(in) :: subcomponent + logical :: multi_package + select case (subcomponent) + case ('DIS') + multi_package = gwe_dis_multi_package + case ('DISU') + multi_package = gwe_disu_multi_package + case ('DISV') + multi_package = gwe_disv_multi_package + case ('DSP') + multi_package = gwe_dsp_multi_package + case ('CNT') + multi_package = gwe_cnt_multi_package + case ('IC') + multi_package = gwe_ic_multi_package + case ('NAM') + multi_package = gwe_nam_multi_package + case default + call store_error('Idm selector subcomponent not found; '//& + &'component="GWE"'//& + &', subcomponent="'//trim(subcomponent)//'".', .true.) + end select + return + end function gwe_idm_multi_package + + function gwe_idm_integrated(subcomponent) result(integrated) + character(len=*), intent(in) :: subcomponent + logical :: integrated + integrated = .false. + select case (subcomponent) + case ('DIS') + integrated = .true. + case ('DISU') + integrated = .true. + case ('DISV') + integrated = .true. + case ('DSP') + integrated = .true. + case ('CNT') + integrated = .true. + case ('IC') + integrated = .true. + case ('NAM') + integrated = .true. + case default + end select + return + end function gwe_idm_integrated + +end module IdmGweDfnSelectorModule diff --git a/src/meson.build b/src/meson.build index 51cc3f51d56..26e756290ff 100644 --- a/src/meson.build +++ b/src/meson.build @@ -19,16 +19,20 @@ modflow_sources = files( 'Distributed' / 'VirtualDataLists.f90', 'Distributed' / 'VirtualDataManager.f90', 'Distributed' / 'VirtualExchange.f90', + 'Distributed' / 'VirtualGweExchange.f90', 'Distributed' / 'VirtualGwfExchange.f90', 'Distributed' / 'VirtualGwtExchange.f90', 'Distributed' / 'VirtualModel.f90', + 'Distributed' / 'VirtualGweModel.f90', 'Distributed' / 'VirtualGwfModel.f90', 'Distributed' / 'VirtualGwtModel.f90', 'Distributed' / 'VirtualSolution.f90', 'Exchange' / 'BaseExchange.f90', 'Exchange' / 'DisConnExchange.f90', 'Exchange' / 'GhostNode.f90', + 'Exchange' / 'GweGweExchange.f90', 'Exchange' / 'GwfExchangeMover.f90', + 'Exchange' / 'GwfGweExchange.f90', 'Exchange' / 'GwfGwfExchange.f90', 'Exchange' / 'GwfGwtExchange.f90', 'Exchange' / 'GwtGwtExchange.f90', @@ -41,6 +45,8 @@ modflow_sources = files( 'Model' / 'Connection' / 'CsrUtils.f90', 'Model' / 'Connection' / 'GridConnection.f90', 'Model' / 'Connection' / 'GridSorting.f90', + 'Model' / 'Connection' / 'GweGweConnection.f90', + 'Model' / 'Connection' / 'GweInterfaceModel.f90', 'Model' / 'Connection' / 'GwfGwfConnection.f90', 'Model' / 'Connection' / 'GwtGwtConnection.f90', 'Model' / 'Connection' / 'GwfInterfaceModel.f90', @@ -50,6 +56,17 @@ modflow_sources = files( 'Model' / 'Geometry' / 'BaseGeometry.f90', 'Model' / 'Geometry' / 'CircularGeometry.f90', 'Model' / 'Geometry' / 'RectangularGeometry.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1cnt1.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1cnt1idm.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1dis1idm.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1disu1idm.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1disv1idm.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1dsp1.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1dsp1idm.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1ecidm.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1idm.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1mst1.f90', 'Model' / 'GroundWaterFlow' / 'gwf3.f90', 'Model' / 'GroundWaterFlow' / 'gwf3api8.f90', 'Model' / 'GroundWaterFlow' / 'gwf3buy8.f90', @@ -117,6 +134,8 @@ modflow_sources = files( 'Model' / 'ModelUtilities' / 'DiscretizationBase.f90', 'Model' / 'ModelUtilities' / 'DisvGeom.f90', 'Model' / 'ModelUtilities' / 'FlowModelInterface.f90', + 'Model' / 'ModelUtilities' / 'GweDspOptions.f90', + 'Model' / 'ModelUtilities' / 'GweInputData.f90', 'Model' / 'ModelUtilities' / 'GwfBuyInputData.f90', 'Model' / 'ModelUtilities' / 'GwfMvrPeriodData.f90', 'Model' / 'ModelUtilities' / 'GwfNpfOptions.f90', @@ -188,6 +207,7 @@ modflow_sources = files( 'Utilities' / 'Idm' / 'mf6blockfile' / 'StructVector.f90', 'Utilities' / 'Idm' / 'selector' / 'IdmDfnSelector.f90', 'Utilities' / 'Idm' / 'selector' / 'IdmExgDfnSelector.f90', + 'Utilities' / 'Idm' / 'selector' / 'IdmGweDfnSelector.f90', 'Utilities' / 'Idm' / 'selector' / 'IdmGwfDfnSelector.f90', 'Utilities' / 'Idm' / 'selector' / 'IdmGwtDfnSelector.f90', 'Utilities' / 'Idm' / 'selector' / 'IdmSimDfnSelector.f90', diff --git a/utils/idmloader/scripts/dfn2f90.py b/utils/idmloader/scripts/dfn2f90.py index de1ab63a976..c74a1151829 100644 --- a/utils/idmloader/scripts/dfn2f90.py +++ b/utils/idmloader/scripts/dfn2f90.py @@ -29,7 +29,9 @@ def __init__( self._warnings = [] self._multi_package = False - self.component, self.subcomponent = self._dfnfspec.stem.upper().split("-") + self.component, self.subcomponent = self._dfnfspec.stem.upper().split( + "-" + ) print(f"\nprocessing dfn => {self._dfnfspec}") self._set_var_d() @@ -47,7 +49,9 @@ def add_dfn_entry(self, dfn_d=None): def write_f90(self, ofspec=None): with open(ofspec, "w") as f: # file header - f.write(self._source_file_header(self.component, self.subcomponent)) + f.write( + self._source_file_header(self.component, self.subcomponent) + ) # found type f.write( @@ -76,44 +80,73 @@ def write_f90(self, ofspec=None): # params if len(self._param_varnames): f.write(self._param_str) - f.write(self._source_params_header(self.component, self.subcomponent)) - f.write(" " + ", &\n ".join(self._param_varnames) + " &\n") f.write( - self._source_list_footer(self.component, self.subcomponent) + "\n" + self._source_params_header( + self.component, self.subcomponent + ) + ) + f.write( + " " + ", &\n ".join(self._param_varnames) + " &\n" + ) + f.write( + self._source_list_footer(self.component, self.subcomponent) + + "\n" ) else: - f.write(self._source_params_header(self.component, self.subcomponent)) + f.write( + self._source_params_header( + self.component, self.subcomponent + ) + ) f.write(self._param_str.rsplit(",", 1)[0] + " &\n") f.write( - self._source_list_footer(self.component, self.subcomponent) + "\n" + self._source_list_footer(self.component, self.subcomponent) + + "\n" ) # aggregate types if len(self._aggregate_varnames): f.write(self._aggregate_str) f.write( - self._source_aggregates_header(self.component, self.subcomponent) + self._source_aggregates_header( + self.component, self.subcomponent + ) + ) + f.write( + " " + + ", &\n ".join(self._aggregate_varnames) + + " &\n" ) - f.write(" " + ", &\n ".join(self._aggregate_varnames) + " &\n") f.write( - self._source_list_footer(self.component, self.subcomponent) + "\n" + self._source_list_footer(self.component, self.subcomponent) + + "\n" ) else: f.write( - self._source_aggregates_header(self.component, self.subcomponent) + self._source_aggregates_header( + self.component, self.subcomponent + ) ) f.write(self._aggregate_str.rsplit(",", 1)[0] + " &\n") f.write( - self._source_list_footer(self.component, self.subcomponent) + "\n" + self._source_list_footer(self.component, self.subcomponent) + + "\n" ) # blocks - f.write(self._source_blocks_header(self.component, self.subcomponent)) + f.write( + self._source_blocks_header(self.component, self.subcomponent) + ) f.write(self._block_str.rsplit(",", 1)[0] + " &\n") - f.write(self._source_list_footer(self.component, self.subcomponent) + "\n") + f.write( + self._source_list_footer(self.component, self.subcomponent) + + "\n" + ) # file footer - f.write(self._source_file_footer(self.component, self.subcomponent)) + f.write( + self._source_file_footer(self.component, self.subcomponent) + ) def get_blocknames(self): blocknames = [] @@ -167,7 +200,9 @@ def _set_var_d(self): istart = line.index(" ") v = line[istart:].strip() if k in vd: - raise Exception("Attribute already exists in dictionary: " + k) + raise Exception( + "Attribute already exists in dictionary: " + k + ) vd[k] = v if len(vd) > 0: @@ -178,7 +213,9 @@ def _set_var_d(self): else: key = name if name in vardict: - raise Exception("Variable already exists in dictionary: " + name) + raise Exception( + "Variable already exists in dictionary: " + name + ) vardict[key] = vd self._var_d = vardict @@ -354,7 +391,11 @@ def _set_blk_param_strs(self, blockname, component, subcomponent): if t == "DOUBLE PRECISION": t = "DOUBLE" - if shape != "" and not aggregate_t and (t == "DOUBLE" or t == "INTEGER"): + if ( + shape != "" + and not aggregate_t + and (t == "DOUBLE" or t == "INTEGER") + ): t = f"{t}{ndim}D" inrec = ".false." @@ -535,7 +576,9 @@ def write(self): self._write_master() def _write_master(self): - ofspec = SRC_PATH / "Utilities" / "Idm" / "selector" / "IdmDfnSelector.f90" + ofspec = ( + SRC_PATH / "Utilities" / "Idm" / "selector" / "IdmDfnSelector.f90" + ) with open(ofspec, "w") as fh: self._write_master_decl(fh) self._write_master_defn(fh, defn="param", dtype="param") @@ -559,16 +602,30 @@ def _write_selectors(self): self._write_selector_decl(fh, component=c, sc_list=self._d[c]) self._write_selector_helpers(fh) self._write_selector_defn( - fh, component=c, sc_list=self._d[c], defn="param", dtype="param" + fh, + component=c, + sc_list=self._d[c], + defn="param", + dtype="param", ) self._write_selector_defn( - fh, component=c, sc_list=self._d[c], defn="aggregate", dtype="param" + fh, + component=c, + sc_list=self._d[c], + defn="aggregate", + dtype="param", ) self._write_selector_defn( - fh, component=c, sc_list=self._d[c], defn="block", dtype="block" + fh, + component=c, + sc_list=self._d[c], + defn="block", + dtype="block", ) self._write_selector_multi(fh, component=c, sc_list=self._d[c]) - self._write_selector_integration(fh, component=c, sc_list=self._d[c]) + self._write_selector_integration( + fh, component=c, sc_list=self._d[c] + ) fh.write(f"end module Idm{c.title()}DfnSelectorModule\n") def _write_selector_decl(self, fh=None, component=None, sc_list=None): @@ -690,7 +747,9 @@ def _write_selector_multi(self, fh=None, component=None, sc_list=None): fh.write(s) - def _write_selector_integration(self, fh=None, component=None, sc_list=None): + def _write_selector_integration( + self, fh=None, component=None, sc_list=None + ): c = component s = ( @@ -938,6 +997,30 @@ def _write_master_component(self, fh=None): DFN_PATH / "gwt-ic.dfn", SRC_PATH / "Model" / "GroundWaterTransport" / "gwt1ic1idm.f90", ], + [ + DFN_PATH / "gwe-dis.dfn", + SRC_PATH / "Model" / "GroundWaterEnergy" / "gwe1dis1idm.f90", + ], + [ + DFN_PATH / "gwe-disu.dfn", + SRC_PATH / "Model" / "GroundWaterEnergy" / "gwe1disu1idm.f90", + ], + [ + DFN_PATH / "gwe-disv.dfn", + SRC_PATH / "Model" / "GroundWaterEnergy" / "gwe1disv1idm.f90", + ], + [ + DFN_PATH / "gwe-dsp.dfn", + SRC_PATH / "Model" / "GroundWaterEnergy" / "gwe1dsp1idm.f90", + ], + [ + DFN_PATH / "gwe-cnt.dfn", + SRC_PATH / "Model" / "GroundWaterEnergy" / "gwe1cnt1idm.f90", + ], + [ + DFN_PATH / "gwe-ic.dfn", + SRC_PATH / "Model" / "GroundWaterEnergy" / "gwe1ic1idm.f90", + ], [ DFN_PATH / "gwf-nam.dfn", SRC_PATH / "Model" / "GroundWaterFlow" / "gwf3idm.f90", @@ -946,6 +1029,10 @@ def _write_master_component(self, fh=None): DFN_PATH / "gwt-nam.dfn", SRC_PATH / "Model" / "GroundWaterTransport" / "gwt1idm.f90", ], + [ + DFN_PATH / "gwe-nam.dfn", + SRC_PATH / "Model" / "GroundWaterEnergy" / "gwe1idm.f90", + ], [ DFN_PATH / "exg-gwfgwf.dfn", SRC_PATH / "Exchange" / "gwfgwfidm.f90", From 0ac2f4807a6cea366834daed3857623f537d4a16 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Sat, 9 Dec 2023 06:20:09 -0800 Subject: [PATCH 02/46] fix typo in meson file --- src/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/meson.build b/src/meson.build index 26e756290ff..29d79b66ba0 100644 --- a/src/meson.build +++ b/src/meson.build @@ -64,7 +64,7 @@ modflow_sources = files( 'Model' / 'GroundWaterEnergy' / 'gwe1disv1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1dsp1.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1dsp1idm.f90', - 'Model' / 'GroundWaterEnergy' / 'gwe1ecidm.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1ic1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1mst1.f90', 'Model' / 'GroundWaterFlow' / 'gwf3.f90', From 80333a7f4eef3758e8e38e23c991ac849647f4df Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Mon, 18 Dec 2023 11:00:55 -0800 Subject: [PATCH 03/46] fix a formating issue that was popping up in an MST autotest --- src/Model/TransportModel/tsp1fmi1.f90 | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/Model/TransportModel/tsp1fmi1.f90 b/src/Model/TransportModel/tsp1fmi1.f90 index d2725cc5609..8f1b8412c65 100644 --- a/src/Model/TransportModel/tsp1fmi1.f90 +++ b/src/Model/TransportModel/tsp1fmi1.f90 @@ -514,11 +514,10 @@ subroutine set_active_status(this, cnew) integer(I4B) :: ipos real(DP) :: crewet, tflow, flownm character(len=15) :: nodestr - character(len=LINELENGTH) :: cstr ! -- formats character(len=*), parameter :: fmtoutmsg1 = & - &"(1x,'WARNING: DRY CELL ENCOUNTERED AT', a,'; RESET AS INACTIVE WITH & - &DRY', a, '=', G13.5)" + "(1x,'WARNING: DRY CELL ENCOUNTERED AT ', a,'; RESET AS INACTIVE WITH & + &DRY ', a, '=', G13.5)" character(len=*), parameter :: fmtoutmsg2 = & &"(1x,'DRY CELL REACTIVATED AT', a, 'WITH STARTING', a, '=', G13.5)" ! @@ -538,9 +537,8 @@ subroutine set_active_status(this, cnew) this%ibound(n) = 0 cnew(n) = DHDRY call this%dis%noder_to_string(n, nodestr) - write (cstr, fmtoutmsg1) trim(nodestr), & - trim(adjustl(this%depvartype)), DHDRY - write (this%iout, cstr) + write (this%iout, fmtoutmsg1) & + trim(nodestr), trim(adjustl(this%depvartype)), DHDRY end if end if end do @@ -575,9 +573,8 @@ subroutine set_active_status(this, cnew) this%ibound(n) = 1 cnew(n) = crewet call this%dis%noder_to_string(n, nodestr) - write (cstr, fmtoutmsg2) trim(nodestr), & - trim(adjustl(this%depvartype)), crewet - write (this%iout, cstr) + write (this%iout, fmtoutmsg2) & + trim(nodestr), trim(adjustl(this%depvartype)), crewet end if end if end do From 641d2384f303540884c7f3fdb77b52f10eccbd13 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Mon, 18 Dec 2023 11:11:59 -0800 Subject: [PATCH 04/46] some legacy line leftover from a botched rebase, possibly --- msvs/mf6core.vfproj | 1 - 1 file changed, 1 deletion(-) diff --git a/msvs/mf6core.vfproj b/msvs/mf6core.vfproj index c14b0150492..b2780afe92b 100644 --- a/msvs/mf6core.vfproj +++ b/msvs/mf6core.vfproj @@ -422,7 +422,6 @@ - From 00a6e826134cc6bff14ce9f88cb2b9ddf9c08d2d Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Mon, 18 Dec 2023 14:45:09 -0800 Subject: [PATCH 05/46] Need update initial autotest to conform to new autotest standards adopted with #1464 --- autotest/test_gwe_dsp.py | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/autotest/test_gwe_dsp.py b/autotest/test_gwe_dsp.py index 36a6f91b420..4f3407d8e04 100644 --- a/autotest/test_gwe_dsp.py +++ b/autotest/test_gwe_dsp.py @@ -12,8 +12,6 @@ # Imports import os -import sys - import numpy as np import pytest @@ -35,7 +33,6 @@ from framework import TestFramework -from simulation import TestSimulation # Base simulation and model name and workspace @@ -124,9 +121,9 @@ ctpspd = [[(0, 0, 0), c0]] -def build_model(idx, dir): +def build_models(idx, test): # Base MF6 GWE model type - ws = dir + ws = test.workspace name = ex[idx] print("Building MF6 model...()".format(name)) @@ -357,14 +354,14 @@ def build_model(idx, dir): return sim, None -def eval_transport(sim): +def check_output(idx, test): print("evaluating results...") # read transport results from GWE model - name = ex[sim.idxsim] + name = ex[idx] gwename = "gwe-" + name - fpth = os.path.join(sim.simpath, f"{gwename}.ucn") + fpth = os.path.join(test.workspace, f"{gwename}.ucn") try: # load temperatures cobj = flopy.utils.HeadFile( @@ -489,12 +486,11 @@ def eval_transport(sim): list(enumerate(ex)), ) def test_mf6model(idx, name, function_tmpdir, targets): - ws = str(function_tmpdir) - test = TestFramework() - test.build(build_model, idx, ws) - test.run( - TestSimulation( - name=name, exe_dict=targets, exfunc=eval_transport, idxsim=idx - ), - ws, + test = TestFramework( + name=name, + workspace=function_tmpdir, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t), + targets=targets, ) + test.run() From 059cd4358564d9ee5642e241c9cf1a2ee03bbe52 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Wed, 20 Dec 2023 07:47:25 -0800 Subject: [PATCH 06/46] Start looking for post-rebase breakages --- src/Utilities/Idm/selector/IdmDfnSelector.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utilities/Idm/selector/IdmDfnSelector.f90 b/src/Utilities/Idm/selector/IdmDfnSelector.f90 index 4e304b707f8..57c272f4c31 100644 --- a/src/Utilities/Idm/selector/IdmDfnSelector.f90 +++ b/src/Utilities/Idm/selector/IdmDfnSelector.f90 @@ -7,8 +7,8 @@ module IdmDfnSelectorModule InputBlockDefinitionType use IdmGwfDfnSelectorModule use IdmGwtDfnSelectorModule - use IdmExgDfnSelectorModule use IdmGweDfnSelectorModule + use IdmExgDfnSelectorModule use IdmSimDfnSelectorModule implicit none From 0f185accb7e2d4bbfccad701e9ca1d3c8fdc4f7b Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Wed, 20 Dec 2023 13:13:46 -0800 Subject: [PATCH 07/46] Get gwfgwe and gwegwe exchanges up-to-date based on #1505 --- doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn | 5 + make/makefile | 2 + msvs/mf6core.vfproj | 2 + src/Exchange/GweGweExchange.f90 | 299 +++------ src/Exchange/gwegweidm.f90 | 582 ++++++++++++++++++ src/Exchange/gwfgweidm.f90 | 70 +++ src/SimulationCreate.f90 | 3 +- .../Idm/selector/IdmExgDfnSelector.f90 | 22 + src/meson.build | 2 + utils/idmloader/scripts/dfn2f90.py | 8 + 10 files changed, 784 insertions(+), 211 deletions(-) create mode 100644 src/Exchange/gwegweidm.f90 create mode 100644 src/Exchange/gwfgweidm.f90 diff --git a/doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn b/doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn index f65627640ac..72dcd437bff 100644 --- a/doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn +++ b/doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn @@ -42,6 +42,7 @@ reader urword optional true longname keyword to print input to list file description keyword to indicate that the list of exchange entries will be echoed to the listing file immediately after it is read. +mf6internal iprpak block options name print_flows @@ -50,6 +51,7 @@ reader urword optional true longname keyword to print gwfgwf flows to list file description keyword to indicate that the list of exchange flow rates will be printed to the listing file for every stress period in which ``SAVE BUDGET'' is specified in Output Control. +mf6internal iprflow block options name save_flows @@ -58,6 +60,7 @@ reader urword optional true longname keyword to save GWFGWF flows description keyword to indicate that cell-by-cell flow terms will be written to the budget file for each model provided that the Output Control for the models are set up with the ``BUDGET SAVE FILE'' option. +mf6internal ipakcb block options name adv_scheme @@ -168,6 +171,7 @@ reader urword optional true longname activate interface model on exchange description activates the interface model mechanism for calculating the coefficients at (and possibly near) the exchange. This keyword should only be used for development purposes. +mf6internal dev_ifmod_on # --------------------- exg gwegwe dimensions --------------------- @@ -185,6 +189,7 @@ description keyword and integer value specifying the number of GWE-GWE exchanges block exchangedata name exchangedata type recarray cellidm1 cellidm2 ihc cl1 cl2 hwva aux boundname +shape (nexg) reader urword optional false longname exchange data diff --git a/make/makefile b/make/makefile index 45a7b832d4c..f6a79d09567 100644 --- a/make/makefile +++ b/make/makefile @@ -127,6 +127,8 @@ $(OBJDIR)/gwe1cnt1idm.o \ $(OBJDIR)/gwtgwtidm.o \ $(OBJDIR)/gwfgwtidm.o \ $(OBJDIR)/gwfgwfidm.o \ +$(OBJDIR)/gwfgweidm.o \ +$(OBJDIR)/gwegweidm.o \ $(OBJDIR)/LongLineReader.o \ $(OBJDIR)/DevFeature.o \ $(OBJDIR)/MemoryList.o \ diff --git a/msvs/mf6core.vfproj b/msvs/mf6core.vfproj index b2780afe92b..1fb9c23e4f9 100644 --- a/msvs/mf6core.vfproj +++ b/msvs/mf6core.vfproj @@ -108,8 +108,10 @@ + + diff --git a/src/Exchange/GweGweExchange.f90 b/src/Exchange/GweGweExchange.f90 index c2c127d1a3e..e60e76f5099 100644 --- a/src/Exchange/GweGweExchange.f90 +++ b/src/Exchange/GweGweExchange.f90 @@ -11,7 +11,8 @@ module GweGweExchangeModule use KindModule, only: DP, I4B, LGP use SimVariablesModule, only: errmsg, model_loc_idx - use SimModule, only: store_error + use SimModule, only: store_error, store_error_filename, & + count_errors, ustop use BaseModelModule, only: BaseModelType, GetBaseModelFromList use BaseExchangeModule, only: BaseExchangeType, AddBaseExchangeToList use ConstantsModule, only: LENBOUNDNAME, NAMEDBOUNDFLAG, LINELENGTH, & @@ -26,10 +27,6 @@ module GweGweExchangeModule use VirtualModelModule, only: VirtualModelType use ObserveModule, only: ObserveType use ObsModule, only: ObsType - use SimModule, only: count_errors, store_error, & - store_error_unit, ustop - use SimVariablesModule, only: errmsg - use BlockParserModule, only: BlockParserType use TableModule, only: TableType, table_cr use MatrixBaseModule @@ -60,8 +57,6 @@ module GweGweExchangeModule ! ! -- GWT specific option block: integer(I4B), pointer :: inewton => null() !< unneeded newton flag allows for mvt to be used here - integer(I4B), pointer :: iprflow => null() !< print flag for cell by cell flows - integer(I4B), pointer :: ipakcb => null() !< save flag for cell by cell flows integer(I4B), pointer :: iAdvScheme !< the advection scheme at the interface: !! 0 = upstream, 1 = central, 2 = TVD ! @@ -96,8 +91,7 @@ module GweGweExchangeModule procedure :: use_interface_model procedure :: allocate_scalars procedure :: allocate_arrays - procedure :: read_options - procedure :: parse_option + procedure :: source_options procedure :: read_mvt procedure :: gwe_gwe_bdsav procedure, private :: gwe_gwe_bdsav_model @@ -113,9 +107,8 @@ module GweGweExchangeModule !! !! Create a new GWT to GWT exchange object. !< - subroutine gweexchange_create(filename, name, id, m1_id, m2_id) + subroutine gweexchange_create(filename, name, id, m1_id, m2_id, input_mempath) ! -- modules - use ConstantsModule, only: LINELENGTH use BaseModelModule, only: BaseModelType use ListsModule, only: baseexchangelist use ObsModule, only: obs_cr @@ -126,6 +119,7 @@ subroutine gweexchange_create(filename, name, id, m1_id, m2_id) character(len=*) :: name !< the exchange name integer(I4B), intent(in) :: m1_id !< id for model 1 integer(I4B), intent(in) :: m2_id !< id for model 2 + character(len=*), intent(in) :: input_mempath ! -- local type(GweExchangeType), pointer :: exchange class(BaseModelType), pointer :: mb @@ -141,6 +135,7 @@ subroutine gweexchange_create(filename, name, id, m1_id, m2_id) exchange%id = id exchange%name = name exchange%memoryPath = create_mem_path(exchange%name) + exchange%input_mempath = input_mempath ! ! -- allocate scalars and set defaults call exchange%allocate_scalars() @@ -207,15 +202,9 @@ subroutine gwe_gwe_df(this) use GhostNodeModule, only: gnc_cr ! -- dummy class(GweExchangeType) :: this !< GwtExchangeType - ! -- local - integer(I4B) :: inunit ! - ! -- open the file - inunit = getunit() + ! -- log the exchange write (iout, '(/a,a)') ' Creating exchange: ', this%name - call openfile(inunit, iout, this%filename, 'GWE-GWE') - ! - call this%parser%Initialize(inunit, iout) ! ! -- Ensure models are in same solution if (associated(this%gwemodel1) .and. associated(this%gwemodel2)) then @@ -225,21 +214,21 @@ subroutine gwe_gwe_df(this) 'GWE models must be in same solution: '// & trim(this%gwemodel1%name)//' '// & trim(this%gwemodel2%name)) - call this%parser%StoreErrorUnit() + call store_error_filename(this%filename) end if end if ! - ! -- read options - call this%read_options(iout) + ! -- source options + call this%source_options(iout) ! - ! -- read dimensions - call this%read_dimensions(iout) + ! -- source dimensions + call this%source_dimensions(iout) ! ! -- allocate arrays call this%allocate_arrays() ! - ! -- read exchange data - call this%read_data(iout) + ! -- source exchange data + call this%source_data(iout) ! ! -- Read mover information if (this%inmvt > 0) then @@ -247,9 +236,6 @@ subroutine gwe_gwe_df(this) call this%mvt%mvt_df(this%gwemodel1%dis) end if ! - ! -- close the file - close (inunit) - ! ! -- Store obs call this%gwe_gwe_df_obs() if (associated(this%gwemodel1)) then @@ -658,7 +644,7 @@ end subroutine gwe_gwe_bdsav_model subroutine gwe_gwe_ot(this) ! -- modules use SimVariablesModule, only: iout - use ConstantsModule, only: DZERO, LINELENGTH + use ConstantsModule, only: DZERO ! -- dummy class(GweExchangeType) :: this !< GweExchangeType ! -- local @@ -708,195 +694,96 @@ subroutine gwe_gwe_ot(this) return end subroutine gwe_gwe_ot - !> @ brief Read options + !> @ brief Source options !! - !! Read the options block + !! Source the options block !< - subroutine read_options(this, iout) + subroutine source_options(this, iout) ! -- modules - use ConstantsModule, only: LINELENGTH, LENAUXNAME, DEM6 - use MemoryManagerModule, only: mem_allocate - use SimModule, only: store_error, store_error_unit + use ConstantsModule, only: LENVARNAME + use InputOutputModule, only: getunit, openfile + use MemoryManagerExtModule, only: mem_set_value + use CharacterStringModule, only: CharacterStringType + use ExgGwegweInputModule, only: ExgGwegweParamFoundType + use SourceCommonModule, only: filein_fname ! -- dummy class(GweExchangeType) :: this !< GweExchangeType integer(I4B), intent(in) :: iout ! -- local - character(len=LINELENGTH) :: keyword - logical :: isfound - logical :: endOfBlock - integer(I4B) :: ierr - ! - ! -- get options block - call this%parser%GetBlock('OPTIONS', isfound, ierr, & - supportOpenClose=.true., blockRequired=.false.) - ! - ! -- parse options block if detected - if (isfound) then - write (iout, '(1x,a)') 'PROCESSING GWE-GWE EXCHANGE OPTIONS' - do - call this%parser%GetNextLine(endOfBlock) - if (endOfBlock) then - exit - end if - call this%parser%GetStringCaps(keyword) - ! - ! first parse option in base - if (this%DisConnExchangeType%parse_option(keyword, iout)) then - cycle - end if - ! - ! it's probably ours - if (this%parse_option(keyword, iout)) then - cycle - end if - ! - ! unknown option - errmsg = "Unknown GWE-GWE exchange option '"//trim(keyword)//"'." - call store_error(errmsg) - call this%parser%StoreErrorUnit() - end do - ! - write (iout, '(1x,a)') 'END OF GWE-GWE EXCHANGE OPTIONS' - end if - ! - ! -- Return - return - end subroutine read_options - - !> @brief parse option from exchange file - !< - function parse_option(this, keyword, iout) result(parsed) - ! -- modules - use InputOutputModule, only: getunit, openfile - ! -- dummy - class(GweExchangeType) :: this !< GweExchangeType - character(len=LINELENGTH), intent(in) :: keyword !< the option name - integer(I4B), intent(in) :: iout !< for logging - logical(LGP) :: parsed !< true when parsed - ! -- local - character(len=LINELENGTH) :: fname - integer(I4B) :: inobs, ilen - character(len=LINELENGTH) :: subkey - ! - parsed = .true. - ! - select case (keyword) - case ('GWFMODELNAME1') - call this%parser%GetStringCaps(subkey) - ilen = len_trim(subkey) - if (ilen > LENMODELNAME) then - write (errmsg, '(a,a)') & - 'INVALID MODEL NAME: ', trim(subkey) - call store_error(errmsg) - call this%parser%StoreErrorUnit() - end if - if (this%gwfmodelname1 /= '') then - call store_error('GWFMODELNAME1 has already been set to ' & - //trim(this%gwfmodelname1)// & - '. Cannot set more than once.') - call this%parser%StoreErrorUnit() - end if - this%gwfmodelname1 = subkey(1:LENMODELNAME) + type(ExgGwegweParamFoundType) :: found + character(len=LENVARNAME), dimension(3) :: adv_scheme = & + &[character(len=LENVARNAME) :: 'UPSTREAM', 'CENTRAL', 'TVD'] + character(len=LINELENGTH) :: mvt_fname + ! + ! -- update defaults with values sourced from input context + call mem_set_value(this%gwfmodelname1, 'GWFMODELNAME1', this%input_mempath, & + found%gwfmodelname1) + call mem_set_value(this%gwfmodelname2, 'GWFMODELNAME2', this%input_mempath, & + found%gwfmodelname2) + call mem_set_value(this%iAdvScheme, 'ADV_SCHEME', this%input_mempath, & + adv_scheme, found%adv_scheme) + call mem_set_value(this%ixt3d, 'DSP_XT3D_OFF', this%input_mempath, & + found%dsp_xt3d_off) + call mem_set_value(this%ixt3d, 'DSP_XT3D_RHS', this%input_mempath, & + found%dsp_xt3d_rhs) + ! + write (iout, '(1x,a)') 'PROCESSING GWE-GWE EXCHANGE OPTIONS' + ! + ! -- source base class options + call this%DisConnExchangeType%source_options(iout) + ! + if (found%gwfmodelname1) then write (iout, '(4x,a,a)') & 'GWFMODELNAME1 IS SET TO: ', trim(this%gwfmodelname1) - case ('GWFMODELNAME2') - call this%parser%GetStringCaps(subkey) - ilen = len_trim(subkey) - if (ilen > LENMODELNAME) then - write (errmsg, '(a,a)') & - 'INVALID MODEL NAME: ', trim(subkey) - call store_error(errmsg) - call this%parser%StoreErrorUnit() - end if - if (this%gwfmodelname2 /= '') then - call store_error('GWFMODELNAME2 has already been set to ' & - //trim(this%gwfmodelname2)// & - '. Cannot set more than once.') - call this%parser%StoreErrorUnit() - end if - this%gwfmodelname2 = subkey(1:LENMODELNAME) + end if + ! + if (found%gwfmodelname2) then write (iout, '(4x,a,a)') & 'GWFMODELNAME2 IS SET TO: ', trim(this%gwfmodelname2) - case ('PRINT_FLOWS') - this%iprflow = 1 - write (iout, '(4x,a)') & - 'EXCHANGE FLOWS WILL BE PRINTED TO LIST FILES.' - case ('SAVE_FLOWS') - this%ipakcb = -1 - write (iout, '(4x,a)') & - 'EXCHANGE FLOWS WILL BE SAVED TO BINARY BUDGET FILES.' - case ('MVT6') - call this%parser%GetStringCaps(subkey) - if (subkey /= 'FILEIN') then - call store_error('MVT6 KEYWORD MUST BE FOLLOWED BY '// & - '"FILEIN" then by filename.') - call this%parser%StoreErrorUnit() - end if - call this%parser%GetString(fname) - if (fname == '') then - call store_error('NO MVT6 FILE SPECIFIED.') - call this%parser%StoreErrorUnit() - end if - this%inmvt = getunit() - call openfile(this%inmvt, iout, fname, 'MVT') - write (iout, '(4x,a)') & - 'WATER MOVER TRANSPORT INFORMATION WILL BE READ FROM ', trim(fname) - case ('OBS6') - call this%parser%GetStringCaps(subkey) - if (subkey /= 'FILEIN') then - call store_error('OBS8 KEYWORD MUST BE FOLLOWED BY '// & - '"FILEIN" then by filename.') - call this%parser%StoreErrorUnit() - end if - this%obs%active = .true. - call this%parser%GetString(this%obs%inputFilename) - inobs = GetUnit() - call openfile(inobs, iout, this%obs%inputFilename, 'OBS') - this%obs%inUnitObs = inobs - case ('ADV_SCHEME') - call this%parser%GetStringCaps(subkey) - select case (subkey) - case ('UPSTREAM') - this%iAdvScheme = 0 - case ('CENTRAL') - this%iAdvScheme = 1 - case ('TVD') - this%iAdvScheme = 2 - case default - errmsg = "Unknown weighting method for advection: '"//trim(subkey)//"'." - call store_error(errmsg) - call this%parser%StoreErrorUnit() - end select + end if + ! + if (found%adv_scheme) then + ! -- count from 0 + this%iAdvScheme = this%iAdvScheme - 1 write (iout, '(4x,a,a)') & - 'CELL AVERAGING METHOD HAS BEEN SET TO: ', trim(subkey) - case ('DSP_XT3D_OFF') + 'ADVECTION SCHEME METHOD HAS BEEN SET TO: ', & + trim(adv_scheme(this%iAdvScheme + 1)) + end if + ! + if (found%dsp_xt3d_off .and. found%dsp_xt3d_rhs) then + errmsg = 'DSP_XT3D_OFF and DSP_XT3D_RHS cannot both be set as options.' + call store_error(errmsg) + call store_error_filename(this%filename) + else if (found%dsp_xt3d_off) then this%ixt3d = 0 write (iout, '(4x,a)') 'XT3D FORMULATION HAS BEEN SHUT OFF.' - case ('DSP_XT3D_RHS') + else if (found%dsp_xt3d_rhs) then this%ixt3d = 2 write (iout, '(4x,a)') 'XT3D RIGHT-HAND SIDE FORMULATION IS SELECTED.' - case ('ADVSCHEME') - errmsg = 'ADVSCHEME is no longer a valid keyword. Use ADV_SCHEME & - &instead.' - call store_error(errmsg) - call this%parser%StoreErrorUnit() - case ('XT3D_OFF') - errmsg = 'XT3D_OFF is no longer a valid keyword. Use DSP_XT3D_OFF & - &instead.' - call store_error(errmsg) - call this%parser%StoreErrorUnit() - case ('XT3D_RHS') - errmsg = 'XT3D_RHS is no longer a valid keyword. Use DSP_XT3D_RHS & - &instead.' - call store_error(errmsg) - call this%parser%StoreErrorUnit() - case default - parsed = .false. - end select + end if ! - ! -- Return + ! -- enforce 0 or 1 MVR6_FILENAME entries in option block + if (filein_fname(mvt_fname, 'MVE6_FILENAME', this%input_mempath, & + this%filename)) then + this%inmvt = getunit() + call openfile(this%inmvt, iout, mvt_fname, 'MVT') + write (iout, '(4x,a)') 'WATER MOVER ENERGY TRANSPORT & + &INFORMATION WILL BE READ FROM ', trim(mvt_fname) + end if + ! + ! -- enforce 0 or 1 OBS6_FILENAME entries in option block + if (filein_fname(this%obs%inputFilename, 'OBS6_FILENAME', & + this%input_mempath, this%filename)) then + this%obs%active = .true. + this%obs%inUnitObs = GetUnit() + call openfile(this%obs%inUnitObs, iout, this%obs%inputFilename, 'OBS') + end if + ! + write (iout, '(1x,a)') 'END OF GWE-GWE EXCHANGE OPTIONS' + ! + ! -- return return - end function parse_option + end subroutine source_options !> @ brief Read mover !! @@ -936,14 +823,9 @@ subroutine allocate_scalars(this) call this%DisConnExchangeType%allocate_scalars() ! call mem_allocate(this%inewton, 'INEWTON', this%memoryPath) - call mem_allocate(this%iprflow, 'IPRFLOW', this%memoryPath) - call mem_allocate(this%ipakcb, 'IPAKCB', this%memoryPath) call mem_allocate(this%inobs, 'INOBS', this%memoryPath) call mem_allocate(this%iAdvScheme, 'IADVSCHEME', this%memoryPath) this%inewton = 0 - this%iprpak = 0 - this%iprflow = 0 - this%ipakcb = 0 this%inobs = 0 this%iAdvScheme = 0 ! @@ -992,8 +874,6 @@ subroutine gwe_gwe_da(this) ! -- scalars deallocate (this%filename) call mem_deallocate(this%inewton) - call mem_deallocate(this%iprflow) - call mem_deallocate(this%ipakcb) call mem_deallocate(this%inobs) call mem_deallocate(this%iAdvScheme) call mem_deallocate(this%inmvt) @@ -1162,7 +1042,7 @@ subroutine gwe_gwe_rp_obs(this) ! ! -- write summary of error messages if (count_errors() > 0) then - call store_error_unit(this%inobs) + call store_error_filename(this%obs%inputFilename) end if ! ! -- Return @@ -1235,7 +1115,6 @@ function use_interface_model(this) result(use_im) !< subroutine gwe_gwe_save_simvals(this) ! -- dummy - use SimModule, only: store_error, store_error_unit use SimVariablesModule, only: errmsg use ConstantsModule, only: DZERO use ObserveModule, only: ObserveType @@ -1266,7 +1145,7 @@ subroutine gwe_gwe_save_simvals(this) errmsg = 'Unrecognized observation type: '// & trim(obsrv%ObsTypeId) call store_error(errmsg) - call store_error_unit(this%inobs) + call store_error_filename(this%obs%inputFilename) end select call this%obs%SaveOneSimval(obsrv, v) end do diff --git a/src/Exchange/gwegweidm.f90 b/src/Exchange/gwegweidm.f90 new file mode 100644 index 00000000000..d495d7206e5 --- /dev/null +++ b/src/Exchange/gwegweidm.f90 @@ -0,0 +1,582 @@ +! ** Do Not Modify! MODFLOW 6 system generated file. ** +module ExgGwegweInputModule + use ConstantsModule, only: LENVARNAME + use InputDefinitionModule, only: InputParamDefinitionType, & + InputBlockDefinitionType + private + public exg_gwegwe_param_definitions + public exg_gwegwe_aggregate_definitions + public exg_gwegwe_block_definitions + public ExgGwegweParamFoundType + public exg_gwegwe_multi_package + + type ExgGwegweParamFoundType + logical :: gwfmodelname1 = .false. + logical :: gwfmodelname2 = .false. + logical :: auxiliary = .false. + logical :: boundnames = .false. + logical :: iprpak = .false. + logical :: iprflow = .false. + logical :: ipakcb = .false. + logical :: adv_scheme = .false. + logical :: dsp_xt3d_off = .false. + logical :: dsp_xt3d_rhs = .false. + logical :: filein = .false. + logical :: mve_filerecord = .false. + logical :: mve6 = .false. + logical :: mve6_filename = .false. + logical :: obs_filerecord = .false. + logical :: obs6 = .false. + logical :: obs6_filename = .false. + logical :: dev_ifmod_on = .false. + logical :: nexg = .false. + logical :: cellidm1 = .false. + logical :: cellidm2 = .false. + logical :: ihc = .false. + logical :: cl1 = .false. + logical :: cl2 = .false. + logical :: hwva = .false. + logical :: aux = .false. + logical :: boundname = .false. + end type ExgGwegweParamFoundType + + logical :: exg_gwegwe_multi_package = .true. + + type(InputParamDefinitionType), parameter :: & + exggwegwe_gwfmodelname1 = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'GWFMODELNAME1', & ! tag name + 'GWFMODELNAME1', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_gwfmodelname2 = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'GWFMODELNAME2', & ! tag name + 'GWFMODELNAME2', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_auxiliary = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'AUXILIARY', & ! tag name + 'AUXILIARY', & ! fortran variable + 'STRING', & ! type + 'NAUX', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_boundnames = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'BOUNDNAMES', & ! tag name + 'BOUNDNAMES', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_iprpak = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'PRINT_INPUT', & ! tag name + 'IPRPAK', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_iprflow = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'PRINT_FLOWS', & ! tag name + 'IPRFLOW', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_ipakcb = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'SAVE_FLOWS', & ! tag name + 'IPAKCB', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_adv_scheme = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'ADV_SCHEME', & ! tag name + 'ADV_SCHEME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_dsp_xt3d_off = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'DSP_XT3D_OFF', & ! tag name + 'DSP_XT3D_OFF', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_dsp_xt3d_rhs = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'DSP_XT3D_RHS', & ! tag name + 'DSP_XT3D_RHS', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_filein = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'FILEIN', & ! tag name + 'FILEIN', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_mve_filerecord = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'MVE_FILERECORD', & ! tag name + 'MVE_FILERECORD', & ! fortran variable + 'RECORD MVE6 FILEIN MVE6_FILENAME', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_mve6 = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'MVE6', & ! tag name + 'MVE6', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_mve6_filename = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'MVE6_FILENAME', & ! tag name + 'MVE6_FILENAME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .true., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_obs_filerecord = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'OBS_FILERECORD', & ! tag name + 'OBS_FILERECORD', & ! fortran variable + 'RECORD OBS6 FILEIN OBS6_FILENAME', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_obs6 = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'OBS6', & ! tag name + 'OBS6', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_obs6_filename = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'OBS6_FILENAME', & ! tag name + 'OBS6_FILENAME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .true., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_dev_ifmod_on = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'OPTIONS', & ! block + 'DEV_INTERFACEMODEL_ON', & ! tag name + 'DEV_IFMOD_ON', & ! fortran variable + 'KEYWORD', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_nexg = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'DIMENSIONS', & ! block + 'NEXG', & ! tag name + 'NEXG', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_cellidm1 = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'EXCHANGEDATA', & ! block + 'CELLIDM1', & ! tag name + 'CELLIDM1', & ! fortran variable + 'INTEGER1D', & ! type + 'NCELLDIM', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_cellidm2 = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'EXCHANGEDATA', & ! block + 'CELLIDM2', & ! tag name + 'CELLIDM2', & ! fortran variable + 'INTEGER1D', & ! type + 'NCELLDIM', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_ihc = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'EXCHANGEDATA', & ! block + 'IHC', & ! tag name + 'IHC', & ! fortran variable + 'INTEGER', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_cl1 = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'EXCHANGEDATA', & ! block + 'CL1', & ! tag name + 'CL1', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_cl2 = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'EXCHANGEDATA', & ! block + 'CL2', & ! tag name + 'CL2', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_hwva = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'EXCHANGEDATA', & ! block + 'HWVA', & ! tag name + 'HWVA', & ! fortran variable + 'DOUBLE', & ! type + '', & ! shape + .true., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_aux = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'EXCHANGEDATA', & ! block + 'AUX', & ! tag name + 'AUX', & ! fortran variable + 'DOUBLE1D', & ! type + 'NAUX', & ! shape + .false., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exggwegwe_boundname = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'EXCHANGEDATA', & ! block + 'BOUNDNAME', & ! tag name + 'BOUNDNAME', & ! fortran variable + 'STRING', & ! type + '', & ! shape + .false., & ! required + .true., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exg_gwegwe_param_definitions(*) = & + [ & + exggwegwe_gwfmodelname1, & + exggwegwe_gwfmodelname2, & + exggwegwe_auxiliary, & + exggwegwe_boundnames, & + exggwegwe_iprpak, & + exggwegwe_iprflow, & + exggwegwe_ipakcb, & + exggwegwe_adv_scheme, & + exggwegwe_dsp_xt3d_off, & + exggwegwe_dsp_xt3d_rhs, & + exggwegwe_filein, & + exggwegwe_mve_filerecord, & + exggwegwe_mve6, & + exggwegwe_mve6_filename, & + exggwegwe_obs_filerecord, & + exggwegwe_obs6, & + exggwegwe_obs6_filename, & + exggwegwe_dev_ifmod_on, & + exggwegwe_nexg, & + exggwegwe_cellidm1, & + exggwegwe_cellidm2, & + exggwegwe_ihc, & + exggwegwe_cl1, & + exggwegwe_cl2, & + exggwegwe_hwva, & + exggwegwe_aux, & + exggwegwe_boundname & + ] + + type(InputParamDefinitionType), parameter :: & + exggwegwe_exchangedata = InputParamDefinitionType & + ( & + 'EXG', & ! component + 'GWEGWE', & ! subcomponent + 'EXCHANGEDATA', & ! block + 'EXCHANGEDATA', & ! tag name + 'EXCHANGEDATA', & ! fortran variable + 'RECARRAY CELLIDM1 CELLIDM2 IHC CL1 CL2 HWVA AUX BOUNDNAME', & ! type + 'NEXG', & ! shape + .true., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) + + type(InputParamDefinitionType), parameter :: & + exg_gwegwe_aggregate_definitions(*) = & + [ & + exggwegwe_exchangedata & + ] + + type(InputBlockDefinitionType), parameter :: & + exg_gwegwe_block_definitions(*) = & + [ & + InputBlockDefinitionType( & + 'OPTIONS', & ! blockname + .true., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'DIMENSIONS', & ! blockname + .true., & ! required + .false., & ! aggregate + .false. & ! block_variable + ), & + InputBlockDefinitionType( & + 'EXCHANGEDATA', & ! blockname + .true., & ! required + .true., & ! aggregate + .false. & ! block_variable + ) & + ] + +end module ExgGwegweInputModule diff --git a/src/Exchange/gwfgweidm.f90 b/src/Exchange/gwfgweidm.f90 new file mode 100644 index 00000000000..bc69319b14c --- /dev/null +++ b/src/Exchange/gwfgweidm.f90 @@ -0,0 +1,70 @@ +! ** Do Not Modify! MODFLOW 6 system generated file. ** +module ExgGwfgweInputModule + use ConstantsModule, only: LENVARNAME + use InputDefinitionModule, only: InputParamDefinitionType, & + InputBlockDefinitionType + private + public exg_gwfgwe_param_definitions + public exg_gwfgwe_aggregate_definitions + public exg_gwfgwe_block_definitions + public ExgGwfgweParamFoundType + public exg_gwfgwe_multi_package + + type ExgGwfgweParamFoundType + end type ExgGwfgweParamFoundType + + logical :: exg_gwfgwe_multi_package = .false. + + type(InputParamDefinitionType), parameter :: & + exg_gwfgwe_param_definitions(*) = & + [ & + InputParamDefinitionType & + ( & + '', & ! component + '', & ! subcomponent + '', & ! block + '', & ! tag name + '', & ! fortran variable + '', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) & + ] + + type(InputParamDefinitionType), parameter :: & + exg_gwfgwe_aggregate_definitions(*) = & + [ & + InputParamDefinitionType & + ( & + '', & ! component + '', & ! subcomponent + '', & ! block + '', & ! tag name + '', & ! fortran variable + '', & ! type + '', & ! shape + .false., & ! required + .false., & ! multi-record + .false., & ! preserve case + .false., & ! layered + .false. & ! timeseries + ) & + ] + + type(InputBlockDefinitionType), parameter :: & + exg_gwfgwe_block_definitions(*) = & + [ & + InputBlockDefinitionType & + ( & + '', & ! blockname + .false., & ! required + .false., & ! aggregate + .false. & ! block_varaible + ) & + ] + +end module ExgGwfgweInputModule diff --git a/src/SimulationCreate.f90 b/src/SimulationCreate.f90 index 427aba8ed61..fbf37202459 100644 --- a/src/SimulationCreate.f90 +++ b/src/SimulationCreate.f90 @@ -444,7 +444,8 @@ subroutine exchanges_create() case ('GWE6-GWE6') write (exg_name, '(a,i0)') 'GWE-GWE_', exg_id if (.not. both_remote) then - call gweexchange_create(fname, exg_name, exg_id, m1_id, m2_id) + call gweexchange_create(fname, exg_name, exg_id, m1_id, m2_id, & + exg_mempath) end if call add_virtual_gwe_exchange(exg_name, exg_id, m1_id, m2_id) case default diff --git a/src/Utilities/Idm/selector/IdmExgDfnSelector.f90 b/src/Utilities/Idm/selector/IdmExgDfnSelector.f90 index fa6aea90bc6..558a9decc27 100644 --- a/src/Utilities/Idm/selector/IdmExgDfnSelector.f90 +++ b/src/Utilities/Idm/selector/IdmExgDfnSelector.f90 @@ -7,7 +7,9 @@ module IdmExgDfnSelectorModule InputBlockDefinitionType use ExgGwfgwfInputModule use ExgGwfgwtInputModule + use ExgGwfgweInputModule use ExgGwtgwtInputModule + use ExgGwegweInputModule implicit none private @@ -40,8 +42,12 @@ function exg_param_definitions(subcomponent) result(input_definition) call set_param_pointer(input_definition, exg_gwfgwf_param_definitions) case ('GWFGWT') call set_param_pointer(input_definition, exg_gwfgwt_param_definitions) + case ('GWFGWE') + call set_param_pointer(input_definition, exg_gwfgwe_param_definitions) case ('GWTGWT') call set_param_pointer(input_definition, exg_gwtgwt_param_definitions) + case ('GWEGWE') + call set_param_pointer(input_definition, exg_gwegwe_param_definitions) case default end select return @@ -56,8 +62,12 @@ function exg_aggregate_definitions(subcomponent) result(input_definition) call set_param_pointer(input_definition, exg_gwfgwf_aggregate_definitions) case ('GWFGWT') call set_param_pointer(input_definition, exg_gwfgwt_aggregate_definitions) + case ('GWFGWE') + call set_param_pointer(input_definition, exg_gwfgwe_aggregate_definitions) case ('GWTGWT') call set_param_pointer(input_definition, exg_gwtgwt_aggregate_definitions) + case ('GWEGWE') + call set_param_pointer(input_definition, exg_gwegwe_aggregate_definitions) case default end select return @@ -72,8 +82,12 @@ function exg_block_definitions(subcomponent) result(input_definition) call set_block_pointer(input_definition, exg_gwfgwf_block_definitions) case ('GWFGWT') call set_block_pointer(input_definition, exg_gwfgwt_block_definitions) + case ('GWFGWE') + call set_block_pointer(input_definition, exg_gwfgwe_block_definitions) case ('GWTGWT') call set_block_pointer(input_definition, exg_gwtgwt_block_definitions) + case ('GWEGWE') + call set_block_pointer(input_definition, exg_gwegwe_block_definitions) case default end select return @@ -87,8 +101,12 @@ function exg_idm_multi_package(subcomponent) result(multi_package) multi_package = exg_gwfgwf_multi_package case ('GWFGWT') multi_package = exg_gwfgwt_multi_package + case ('GWFGWE') + multi_package = exg_gwfgwe_multi_package case ('GWTGWT') multi_package = exg_gwtgwt_multi_package + case ('GWEGWE') + multi_package = exg_gwegwe_multi_package case default call store_error('Idm selector subcomponent not found; '//& &'component="EXG"'//& @@ -106,8 +124,12 @@ function exg_idm_integrated(subcomponent) result(integrated) integrated = .true. case ('GWFGWT') integrated = .true. + case ('GWFGWE') + integrated = .true. case ('GWTGWT') integrated = .true. + case ('GWEGWE') + integrated = .true. case default end select return diff --git a/src/meson.build b/src/meson.build index 29d79b66ba0..05a5bf98e5c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -39,7 +39,9 @@ modflow_sources = files( 'Exchange' / 'NumericalExchange.f90', 'Exchange' / 'gwfgwfidm.f90', 'Exchange' / 'gwfgwtidm.f90', + 'Exchange' / 'gwfgweidm.f90', 'Exchange' / 'gwtgwtidm.f90', + 'Exchange' / 'gwegweidm.f90', 'Model' / 'Connection' / 'ConnectionBuilder.f90', 'Model' / 'Connection' / 'CellWithNbrs.f90', 'Model' / 'Connection' / 'CsrUtils.f90', diff --git a/utils/idmloader/scripts/dfn2f90.py b/utils/idmloader/scripts/dfn2f90.py index c74a1151829..c8a4145e3e7 100644 --- a/utils/idmloader/scripts/dfn2f90.py +++ b/utils/idmloader/scripts/dfn2f90.py @@ -1041,10 +1041,18 @@ def _write_master_component(self, fh=None): DFN_PATH / "exg-gwfgwt.dfn", SRC_PATH / "Exchange" / "gwfgwtidm.f90", ], + [ + DFN_PATH / "exg-gwfgwe.dfn", + SRC_PATH / "Exchange" / "gwfgweidm.f90", + ], [ DFN_PATH / "exg-gwtgwt.dfn", SRC_PATH / "Exchange" / "gwtgwtidm.f90", ], + [ + DFN_PATH / "exg-gwegwe.dfn", + SRC_PATH / "Exchange" / "gwegweidm.f90", + ], [ DFN_PATH / "sim-nam.dfn", SRC_PATH / "simnamidm.f90", From 7772953e4bbe2f2fecaaee0d38b2ba8b046ab2bb Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Thu, 21 Dec 2023 09:42:21 -0800 Subject: [PATCH 08/46] Code that had been moved to set_active_status in FMI was still present in fmi_fc(). Removing. --- src/Model/TransportModel/tsp1fmi1.f90 | 59 ++------------------------- 1 file changed, 4 insertions(+), 55 deletions(-) diff --git a/src/Model/TransportModel/tsp1fmi1.f90 b/src/Model/TransportModel/tsp1fmi1.f90 index 8f1b8412c65..c1ca1772272 100644 --- a/src/Model/TransportModel/tsp1fmi1.f90 +++ b/src/Model/TransportModel/tsp1fmi1.f90 @@ -192,60 +192,6 @@ subroutine fmi_ad(this, cnew) call this%set_active_status(cnew) end if ! - ! -- if flow cell is dry, then set gwt%ibound = 0 and conc to dry - do n = 1, this%dis%nodes - ! - ! -- Calculate the ibound-like array that has 0 if saturation - ! is zero and 1 otherwise - if (this%gwfsat(n) > DZERO) then - this%ibdgwfsat0(n) = 1 - else - this%ibdgwfsat0(n) = 0 - end if - ! - ! -- Check if active transport cell is inactive for flow - if (this%ibound(n) > 0) then - if (this%gwfhead(n) == DHDRY) then - ! -- transport cell should be made inactive - this%ibound(n) = 0 - cnew(n) = DHDRY - call this%dis%noder_to_string(n, nodestr) - write (this%iout, fmtdry) trim(nodestr), DHDRY - end if - end if - ! - ! -- Convert dry transport cell to active if flow has rewet - if (cnew(n) == DHDRY) then - if (this%gwfhead(n) /= DHDRY) then - ! - ! -- obtain weighted concentration - crewet = DZERO - tflow = DZERO - do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1 - m = this%dis%con%ja(ipos) - flownm = this%gwfflowja(ipos) - if (flownm > 0) then - if (this%ibound(m) /= 0) then - crewet = crewet + cnew(m) * flownm - tflow = tflow + this%gwfflowja(ipos) - end if - end if - end do - if (tflow > DZERO) then - crewet = crewet / tflow - else - crewet = DZERO - end if - ! - ! -- cell is now wet - this%ibound(n) = 1 - cnew(n) = crewet - call this%dis%noder_to_string(n, nodestr) - write (this%iout, fmtrewet) trim(nodestr), crewet - end if - end if - end do - ! ! -- Return return end subroutine fmi_ad @@ -264,6 +210,7 @@ subroutine fmi_fc(this, nodes, cold, nja, matrix_sln, idxglo, rhs) real(DP), intent(inout), dimension(nodes) :: rhs ! -- local integer(I4B) :: n, idiag, idiag_sln + real(DP) :: qcorr ! ! -- Calculate the flow imbalance error and make a correction for it if (this%iflowerr /= 0) then @@ -273,7 +220,9 @@ subroutine fmi_fc(this, nodes, cold, nja, matrix_sln, idxglo, rhs) do n = 1, nodes idiag = this%dis%con%ia(n) idiag_sln = idxglo(idiag) - call matrix_sln%add_value_pos(idiag_sln, -this%gwfflowja(idiag)) + !call matrix_sln%add_value_pos(idiag_sln, -this%gwfflowja(idiag)) + qcorr = -this%gwfflowja(idiag) * this%eqnsclfac + call matrix_sln%add_value_pos(idiag_sln, qcorr) end do end if ! From 18e4e6df74412ad62fa742e0cc9b2e166529d8ca Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Thu, 21 Dec 2023 09:52:02 -0800 Subject: [PATCH 09/46] Forgot to remove unused variables after making changes in 4d76729 --- src/Model/TransportModel/tsp1fmi1.f90 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Model/TransportModel/tsp1fmi1.f90 b/src/Model/TransportModel/tsp1fmi1.f90 index c1ca1772272..3a282bc501d 100644 --- a/src/Model/TransportModel/tsp1fmi1.f90 +++ b/src/Model/TransportModel/tsp1fmi1.f90 @@ -149,10 +149,6 @@ subroutine fmi_ad(this, cnew) real(DP), intent(inout), dimension(:) :: cnew ! -- local integer(I4B) :: n - integer(I4B) :: m - integer(I4B) :: ipos - real(DP) :: crewet, tflow, flownm - character(len=15) :: nodestr character(len=*), parameter :: fmtdry = & &"(/1X,'WARNING: DRY CELL ENCOUNTERED AT ',a,'; RESET AS INACTIVE & &WITH DRY CONCENTRATION = ', G13.5)" From 6129d2c968946b6520983a605d78d5af81650ed8 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Thu, 21 Dec 2023 10:25:32 -0800 Subject: [PATCH 10/46] Adding another autotest specific to GWE --- autotest/test_gwe_drycell_conduction0.py | 424 +++++++++++++++++++++++ 1 file changed, 424 insertions(+) create mode 100644 autotest/test_gwe_drycell_conduction0.py diff --git a/autotest/test_gwe_drycell_conduction0.py b/autotest/test_gwe_drycell_conduction0.py new file mode 100644 index 00000000000..059b8ea4bb7 --- /dev/null +++ b/autotest/test_gwe_drycell_conduction0.py @@ -0,0 +1,424 @@ +# ## Test problem for GWE +# +# Test the energy "flowing" through a dry cell. The test checks for +# some of the flow-through energy being left behind and warming the +# cell it passes through. Based on the model appearing in the +# MT3D-USGS documention, pages 13-14. Dry cell is in layer 1, row 1 +# column 4. +# +# +-------+-------+-------+-------+-------+-------+ +# -> | -> | | | DRY | | | +# | | -> | | CELL| | | +# | | | -> -+-> | | | | +# +-------+-------+-------+---+---+-------+-------+ +# | | | | v | | | +# -> | -> | -> | -> | -> | -> | -> | -> +# | | | | | | | +# +-------+-------+-------+-------+-------+-------+ +# +# ---> Direction of flow ---> + +# Imports + +import os + +import numpy as np +import pytest +import flopy + +from framework import TestFramework + +# Base simulation and model name and workspace + +scheme = "UPSTREAM" +# scheme = "TVD" + +ex = ["drycell0"] +exdirs = [] +for s in ex: + exdirs.append(os.path.join("temp", s)) + +# Model units +length_units = "meters" +time_units = "days" + +# Table MODFLOW 6 GWE comparison to MT3DMS + +nrow = 1 +ncol = 6 +nlay = 2 +delr = 10.0 # Column width ($m$) +delc = 10.0 # Row width ($m$) +top = 20.0 # Top of model +k11 = 100.0 # Horizontal hydraulic conductivity ($m/d$) +ss = 1e-6 # Specific storage +sy = 0.20 # Specific Yield +prsity = 0.20 # Porosity +nper = 2 # Number of periods +perlen = [1, 100] # Simulation time ($days$) +nstp = [1, 10] # 10 day transient time steps +steady = {0: True, 1: False} +transient = {0: False, 1: True} + +# Set some static model parameter values + +k33 = k11 # Vertical hydraulic conductivity ($m/d$) +idomain = 1 # All cells included in the simulation +iconvert = 1 # All cells are convertible + +icelltype = 1 # Cell conversion type (>1: unconfined) + +# Set some static transport related model parameter values +botm = [] +botm.append(np.ones((nrow, ncol), dtype=float) * 10) +botm.append(np.zeros((nrow, ncol), dtype=float)) +botm = np.array(botm) + +# GWE related parameters +rhow = 1000.0 +cpw = 4183.0 +lhv = 2454.0 + +# Head input +left_hd = 15.0 +right_hd = 2.0 +strt_hd1 = np.ones((nrow, ncol), dtype=float) * 11.0 +strt_hd2 = np.ones((nrow, ncol), dtype=float) * 11.0 +strt_hd1[0] = strt_hd2[0] = left_hd +strt_hd1[-1] = strt_hd2[-1] = right_hd +strt_hd = np.array([strt_hd1, strt_hd2]) +strt_temp = 10.0 + +chd_data = {} +chd_data[0] = [ + [(0, 0, 0), left_hd], + [(1, 0, 0), left_hd], + [(1, 0, ncol - 1), right_hd], +] +chd_mf6 = chd_data + +dispersivity = 0.0 # dispersion (remember, 1D model) + +# Set solver parameter values (and related) +nouter, ninner = 100, 300 +hclose, rclose, relax = 1e-10, 1e-10, 1.0 +ttsmult = 1.0 + +# Set up temporal data used by TDIS file +tdis_rc = [] +for i in np.arange(nper): + tdis_rc.append((perlen[i], nstp[i], ttsmult)) + +# ### Generate MODFLOW 6 Example test model +# + + +def build_models(idx, test): + # Base MF6 GWF model type + ws = test.workspace + name = ex[idx] + + print("Building MF6 model...()".format(name)) + + # generate names for each model + gwfname = "gwf-" + name + gwename1 = "gwe-" + name + + sim = flopy.mf6.MFSimulation( + sim_name=name, sim_ws=ws, exe_name="mf6", version="mf6" + ) + + # Instantiating MODFLOW 6 time discretization + flopy.mf6.ModflowTdis( + sim, nper=nper, perioddata=tdis_rc, time_units=time_units + ) + + # Instantiating MODFLOW 6 groundwater flow model + gwf = flopy.mf6.ModflowGwf( + sim, + newtonoptions="UNDER_RELAXATION", + modelname=gwfname, + save_flows=True, + model_nam_file="{}.nam".format(gwfname), + ) + + # Instantiating MODFLOW 6 solver for flow model + imsgwf = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwfname), + ) + sim.register_ims_package(imsgwf, [gwfname]) + + # Instantiating MODFLOW 6 discretization package + flopy.mf6.ModflowGwfdis( + gwf, + length_units=length_units, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=np.ones((nlay, nrow, ncol)), + pname="DIS-1", + filename="{}.dis".format(gwfname), + ) + + # Instantiating MODFLOW 6 storage package + flopy.mf6.ModflowGwfsto( + gwf, + ss=ss, + sy=sy, + iconvert=iconvert, + steady_state=steady, + transient=transient, + pname="STO", + filename="{}.sto".format(gwfname), + ) + + # Instantiating MODFLOW 6 node-property flow package + flopy.mf6.ModflowGwfnpf( + gwf, + save_flows=True, + icelltype=icelltype, + k=k11, + k33=k33, + alternative_cell_averaging="AMT-HMK", + save_specific_discharge=True, + pname="NPF-1", + filename="{}.npf".format(gwfname), + ) + + # Instantiating MODFLOW 6 constant head package + flopy.mf6.ModflowGwfchd( + gwf, + stress_period_data=chd_mf6, + filename="{}.chd".format(gwfname), + ) + + # Instantiating MODFLOW 6 initial conditions package for flow model + flopy.mf6.ModflowGwfic(gwf, strt=strt_hd, filename="{}.ic".format(gwfname)) + + # Instantiating MODFLOW 6 output control package for flow model + flopy.mf6.ModflowGwfoc( + gwf, + pname="OC-1", + head_filerecord="{}.hds".format(gwfname), + budget_filerecord="{}.cbc".format(gwfname), + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + printrecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + ) + + # ---------------------------------------------------- + # Instantiating MODFLOW 6 GWE model + # ---------------------------------------------------- + gwe1 = flopy.mf6.ModflowGwe( + sim, modelname=gwename1, model_nam_file="{}.nam".format(gwename1) + ) + gwe1.name_file.save_flows = True + imsgwe1 = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwename1), + ) + sim.register_ims_package(imsgwe1, [gwe1.name]) + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwedis( + gwe1, + nogrb=True, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=1, + pname="DIS-2", + filename="{}.dis".format(gwename1), + ) + + # Instantiating MODFLOW 6 transport initial concentrations + flopy.mf6.ModflowGweic( + gwe1, strt=strt_temp, pname="IC-2", filename="{}.ic".format(gwename1) + ) + + # Instantiating MODFLOW 6 transport advection package + flopy.mf6.ModflowGweadv( + gwe1, scheme=scheme, pname="ADV-2", filename="{}.adv".format(gwename1) + ) + + # Instantiating MODFLOW 6 transport dispersion package + flopy.mf6.ModflowGwedsp( + gwe1, + xt3d_off=False, + alh=dispersivity, + ath1=dispersivity, + ktw=0.5918 * 86400, + # ktw=0.0, + kts=0.2700 * 86400, + # kts=0.0, + pname="DSP-2", + filename="{}.dsp".format(gwename1), + ) + + # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) + flopy.mf6.ModflowGwemst( + gwe1, + save_flows=True, + porosity=prsity, + cps=760.0, + rhos=1500.0, + packagedata=[cpw, rhow, lhv], + pname="MST-2", + filename="{}.mst".format(gwename1), + ) + + # Instantiating MODFLOW 6 heat transport source-sink mixing package + flopy.mf6.ModflowGwessm( + gwe1, sources=[[]], pname="SSM-2", filename="{}.ssm".format(gwename1) + ) + + # Instantiate MODFLOW 6 heat transport output control package + flopy.mf6.ModflowGweoc( + gwe1, + pname="OC-2", + budget_filerecord="{}.cbc".format(gwename1), + temperature_filerecord="{}.ucn".format(gwename1), + temperatureprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + printrecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + ) + + # Instantiate a constant temperature in 1 of the dry cells + ctmpspd = { + 0: [[(0, 0, 0), strt_temp], [(1, 0, 0), strt_temp]], + 1: [[(0, 0, 0), strt_temp + 10], [(1, 0, 0), strt_temp + 10]], + } + flopy.mf6.ModflowGwecnt( + gwe1, + stress_period_data=ctmpspd, + pname="CNT-2", + filename="{}.ctmp".format(gwename1), + ) + + # Instantiating MODFLOW 6 flow-transport exchange mechanism + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename1, + pname="GWFGWE1", + filename="{}.gwfgwe1".format(gwename1), + ) + + return sim, None + + +def check_output(idx, test): + print("evaluating results...") + + # read transport results from GWE model + name = ex[idx] + gwename = "gwe-" + name + + fpth = os.path.join(test.workspace, f"{gwename}.ucn") + try: + # load temperatures + cobj = flopy.utils.HeadFile( + fpth, precision="double", text="TEMPERATURE" + ) + conc1 = cobj.get_alldata() + except: + assert False, f'could not load temperature data from "{fpth}"' + + # Check that the two perpetually dry cells: + # 1) after warming begins (2nd stress period onward), should be greater + # than their initial condition + msg0 = "There should be warming in a dry cell via conduction" + assert np.all(conc1[1:, 0, 0, 4] > 10.0), msg0 + assert np.all(conc1[1:, 0, 0, 5] > 10.0), msg0 + + msg1 = ( + "Cell at 1, 1, 5 should be warmer than the cell at 1, 1, 6 " + "throughout the simulation by virtue of it being physically " + "upstream" + ) + assert np.all(conc1[1:, 0, 0, 4] > conc1[1:, 0, 0, 5]), msg1 + + # 2) monotonically increase from being in contact with the warmer + # water passing by the cells below + msg2 = ( + "Perpetually dry cell should be steadily warming as a result of it " + "being in contact with warming cell below it." + ) + assert np.all(np.diff(conc1[:, 0, 0, 5]) > 0), msg2 + assert np.all(np.diff(conc1[:, 0, 0, 4]) > 0), msg2 + + # Because this is a steady flow problem, the largest incremental warming + # increments happen in the first two stress periods. After that, the amount + # of warming from time step to time step decreases. + msg3 = ( + "After the first two stress periods, the relative amount of " + "warming in layer 1, row 1, and column 4 should slow, but isn't" + ) + assert np.all(np.diff(np.diff(conc1[2:, 0, 0, 4])) < 0), msg3 + + # The 'pass-through' cell (layer 1, row 1, column 4 - see diagram at top + # of script) should be warming more than its two neighbors to the right. + msg4 = ( + "Pass through cell should be warming up at a higher rate than " + "the dry cells." + ) + assert np.all(conc1[:, 0, 0, 3] > conc1[:, 0, 0, 4]), msg4 + + # Pass through cell should not be as warm as the cell from which it + # receives water, since that cell will have already robbed the water + # passing through of some of its heat + msg5 = ( + "Pass through cell should not be as warm as its neighbor to " + "the left" + ) + assert np.all(conc1[:, 0, 0, 2] > conc1[:, 0, 0, 3]), msg5 + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(ex)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t), + ) + test.run() From b24a919d60c750d1e188c7deb6461b43124b56b1 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Thu, 21 Dec 2023 10:37:44 -0800 Subject: [PATCH 11/46] Adding another autotest after getting it #1464 compliant --- autotest/test_gwe_drycell_conduction1.py | 481 +++++++++++++++++++++++ 1 file changed, 481 insertions(+) create mode 100644 autotest/test_gwe_drycell_conduction1.py diff --git a/autotest/test_gwe_drycell_conduction1.py b/autotest/test_gwe_drycell_conduction1.py new file mode 100644 index 00000000000..2f53fa0b7bf --- /dev/null +++ b/autotest/test_gwe_drycell_conduction1.py @@ -0,0 +1,481 @@ +# ## Test problem for GWE +# +# Test the energy "flowing" between two dry cells via conduction +# only using a temperature gradient +# +# ~: Represents conduction +# +# A) 1st model configuration +# +# +---------+---------+ +# | |~ | +# | |~ | +# +---------+---------+ +# +# B) 2nd model configuration +# +# +---------+ +# | | +# | ~ ~ | +# +---------+ +# | | +# | | +# +---------+ +# +# C) 3rd model configuration +# +# +---------+ +# +---------+ | +# | |~ | +# | +---------+ +# +---------+ +# +# Imports + +import os +import numpy as np +import pytest +import flopy + +from framework import TestFramework + +# Monotonicity function +def isMonotonic(A): + x, y = [], [] + x.extend(A) + y.extend(A) + x.sort() + y.sort(reverse=True) + if np.all(x == A) or np.all(y == A): + return True + return False + + +# Base simulation and model name and workspace + +scheme = "UPSTREAM" +# scheme = "TVD" + +ex = [ + "drycell2-a", # 2-cell model, horizontally connected with tops and bots aligned + "drycell2-b", # 2-cell model, vertically connected + "drycell2-c", # 2-cell model, horizontally connected with staggered alignment (reduced shared cell face area) +] + +conn_types = ( + "horizontal", + "vertical", + "staggered", +) + +dis_data = { + conn_types[0]: { + "nrow": 1, + "ncol": 2, + "nlay": 1, + "top": np.ones(2, dtype=float), + "bot": np.zeros(2, dtype=float), + "strthd": np.zeros(2, dtype=float), + }, + conn_types[1]: { + "nrow": 1, + "ncol": 1, + "nlay": 2, + "top": 2, + "bot": np.array([[[1.0]], [[0.0]]], dtype=float), + "strthd": np.zeros(2, dtype=float), + }, + conn_types[2]: { + "nrow": 2, + "ncol": 1, + "nlay": 1, + "top": np.array([[[1.0], [1.5]]], dtype=float), + "bot": np.array([[[0.0], [0.5]]], dtype=float), + "strthd": -1 * np.ones(2, dtype=float), + }, +} + +# Model units +length_units = "meters" +time_units = "days" + +# Table MODFLOW 6 GWE comparison to MT3DMS + +delr = 1.0 # Column width ($m$) +delc = 1.0 # Row width ($m$) +k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$) +ss = 1e-6 # Specific storage +sy = 0.20 # Specific Yield +prsity = 0.20 # Porosity +nper = 4 # Number of periods +perlen = [1, 1000, 1, 1000] # Simulation time ($days$) +nstp = [1, 10, 1, 10] # 10 day transient time steps +steady = {0: False} +transient = {0: True} + +# Set some static model parameter values + +k33 = k11 # Vertical hydraulic conductivity ($m/d$) +idomain = 1 # All cells included in the simulation +iconvert = 1 # All cells are convertible + +icelltype = 1 # Cell conversion type (>1: unconfined) + +# Set some static transport related model parameter values +strt_temp1 = 4.0 +strt_temp2 = 34.0 +dispersivity = 0.0 # dispersion (remember, 1D model) + +# GWE related parameters +rhow = 1000.0 +cpw = 4183.0 +lhv = 2454.0 + +# Set solver parameter values (and related) +nouter, ninner = 100, 300 +hclose, rclose, relax = 1e-10, 1e-10, 1.0 +ttsmult = 1.0 + +# Set up temporal data used by TDIS file +tdis_rc = [] +for i in np.arange(nper): + tdis_rc.append((perlen[i], nstp[i], ttsmult)) + +# ### Create MODFLOW 6 GWE MT3DMS Example 1 Boundary Conditions +# +# No GWF, only Heat conduction simulated + + +def build_models(idx, test): + conn_type = conn_types[idx] + + # Base MF6 GWF model type + ws = test.workspace + name = ex[idx] + + print("Building MF6 model...()".format(name)) + + # generate names for each model + gwfname = "gwf-" + name + gwename1 = "gwe-" + name + + sim = flopy.mf6.MFSimulation( + sim_name=name, sim_ws=ws, exe_name="mf6", version="mf6" + ) + + # Instantiating MODFLOW 6 time discretization + flopy.mf6.ModflowTdis( + sim, nper=nper, perioddata=tdis_rc, time_units=time_units + ) + + # Instantiating MODFLOW 6 groundwater flow model + gwf = flopy.mf6.ModflowGwf( + sim, + modelname=gwfname, + save_flows=True, + model_nam_file="{}.nam".format(gwfname), + ) + + # Instantiating MODFLOW 6 solver for flow model + imsgwf = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="CG", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwfname), + ) + sim.register_ims_package(imsgwf, [gwfname]) + + # Instantiating MODFLOW 6 discretization package + flopy.mf6.ModflowGwfdis( + gwf, + length_units=length_units, + nlay=dis_data[conn_type]["nlay"], + nrow=dis_data[conn_type]["nrow"], + ncol=dis_data[conn_type]["ncol"], + delr=delr, + delc=delc, + top=dis_data[conn_type]["top"], + botm=dis_data[conn_type]["bot"], + idomain=np.ones( + ( + dis_data[conn_type]["nlay"], + dis_data[conn_type]["nrow"], + dis_data[conn_type]["ncol"], + ), + dtype=int, + ), + pname="DIS-1", + filename="{}.dis".format(gwfname), + ) + + # Instantiating MODFLOW 6 storage package + flopy.mf6.ModflowGwfsto( + gwf, + ss=ss, + sy=sy, + iconvert=iconvert, + steady_state=steady, + transient=transient, + pname="STO", + filename="{}.sto".format(gwfname), + ) + + # Instantiating MODFLOW 6 node-property flow package + flopy.mf6.ModflowGwfnpf( + gwf, + save_flows=True, + icelltype=icelltype, + k=k11, + k33=k33, + save_specific_discharge=True, + pname="NPF-1", + filename="{}.npf".format(gwfname), + ) + + # Instantiating MODFLOW 6 initial conditions package for flow model + flopy.mf6.ModflowGwfic( + gwf, + strt=dis_data[conn_type]["strthd"], + filename="{}.ic".format(gwfname), + ) + + # Instantiating MODFLOW 6 output control package for flow model + flopy.mf6.ModflowGwfoc( + gwf, + pname="OC-1", + head_filerecord="{}.hds".format(gwfname), + budget_filerecord="{}.cbc".format(gwfname), + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + printrecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + ) + + # ---------------------------------------------------- + # Instantiating MODFLOW 6 GWE model + # ---------------------------------------------------- + gwe1 = flopy.mf6.ModflowGwe( + sim, modelname=gwename1, model_nam_file="{}.nam".format(gwename1) + ) + gwe1.name_file.save_flows = True + imsgwe1 = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwename1), + ) + sim.register_ims_package(imsgwe1, [gwe1.name]) + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwedis( + gwe1, + nogrb=True, + nlay=dis_data[conn_type]["nlay"], + nrow=dis_data[conn_type]["nrow"], + ncol=dis_data[conn_type]["ncol"], + delr=delr, + delc=delc, + top=dis_data[conn_type]["top"], + botm=dis_data[conn_type]["bot"], + idomain=1, + pname="DIS-2", + filename="{}.dis".format(gwename1), + ) + + # Instantiating MODFLOW 6 transport initial concentrations + flopy.mf6.ModflowGweic( + gwe1, strt=strt_temp1, pname="IC-2", filename="{}.ic".format(gwename1) + ) + + # Instantiating MODFLOW 6 transport advection package + flopy.mf6.ModflowGweadv( + gwe1, scheme=scheme, pname="ADV-2", filename="{}.adv".format(gwename1) + ) + + # Instantiating MODFLOW 6 transport dispersion package + flopy.mf6.ModflowGwedsp( + gwe1, + xt3d_off=True, + alh=dispersivity, + ath1=dispersivity, + ktw=0.5918 * 86400, + kts=0.2700 * 86400, + pname="DSP-2", + filename="{}.dsp".format(gwename1), + ) + + # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) + flopy.mf6.ModflowGwemst( + gwe1, + save_flows=True, + porosity=prsity, + cps=760.0, + rhos=1500.0, + packagedata=[cpw, rhow, lhv], + pname="MST-2", + filename="{}.mst".format(gwename1), + ) + + # Instantiate MODFLOW 6 heat transport output control package + flopy.mf6.ModflowGweoc( + gwe1, + pname="OC-2", + budget_filerecord="{}.cbc".format(gwename1), + temperature_filerecord="{}.ucn".format(gwename1), + temperatureprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + printrecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + ) + + # Instantiate a constant temperature in 1 of the dry cells + ctmpspd = { + 0: [ + [(0, 0, 0), strt_temp1], + [ + ( + dis_data[conn_type]["nlay"] - 1, + dis_data[conn_type]["nrow"] - 1, + dis_data[conn_type]["ncol"] - 1, + ), + strt_temp1 + 10, + ], + ], + 1: [], + 2: [ + [(0, 0, 0), strt_temp2], + [ + ( + dis_data[conn_type]["nlay"] - 1, + dis_data[conn_type]["nrow"] - 1, + dis_data[conn_type]["ncol"] - 1, + ), + strt_temp2 - 10, + ], + ], + 3: [], + } + flopy.mf6.ModflowGwecnt( + gwe1, + stress_period_data=ctmpspd, + pname="CNT-2", + filename="{}.ctmp".format(gwename1), + ) + + # Instantiating MODFLOW 6 flow-transport exchange mechanism + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename1, + pname="GWFGWE1", + filename="{}.gwfgwe1".format(gwename1), + ) + + return sim, None + + +def check_output(idx, test): + print("evaluating results...") + + # read transport results from GWE model + name = ex[idx] + gwename = "gwe-" + name + + # All indices are 0 based + # initialize + idxl = 0 + idxr = 0 + idxc = 0 + # override depending on scenario + if idx == 0: + idxc = 1 + + if idx == 1: + idxl = 1 + + if idx == 2: + idxr = 1 + + fpth = os.path.join(test.workspace, f"{gwename}.ucn") + + try: + # load temperatures + cobj = flopy.utils.HeadFile( + fpth, precision="double", text="TEMPERATURE" + ) + conc1 = cobj.get_alldata() + except: + assert False, f'could not load temperature data from "{fpth}"' + + # Ensure constant temperatures are initiated properly in teh 1st and 3rd + # stress periods, which are separated by period of "turning off" the + # constant temperature boundary + msg0 = "Grid cell temperatures do not reflect user-specified difference" + assert conc1[0, 0, 0, 0] + 10.0 == conc1[0, idxl, idxr, idxc], msg0 + assert conc1[11, 0, 0, 0] - 10.0 == conc1[11, idxl, idxr, idxc], msg0 + + # After running transient stress period, temperatures in grid cells + # should equilibrate through the process of conduction only (there + # is no gwf flow) + msg1 = "Grid cell temperatures should have equilabrated via conduction" + assert np.isclose(conc1[10, 0, 0, 0], conc1[10, idxl, idxr, idxc]), msg1 + assert np.isclose(conc1[21, 0, 0, 0], conc1[21, idxl, idxr, idxc]), msg1 + + # Ensure that as the cells equilibrate, they do so in a monotonic manner + msg2 = "There should be a monotonic increase as the 2 cells equilibrate" + msg3 = "There should be a monotonic decrease as the 2 cells equilibrate" + assert isMonotonic(np.diff(conc1[1:11, 0, 0, 0])), msg2 + assert isMonotonic(np.diff(conc1[1:11, idxl, idxr, idxc])), msg3 + assert isMonotonic(np.diff(conc1[12:, 0, 0, 0])), msg3 + assert isMonotonic(np.diff(conc1[12:, idxl, idxr, idxc])), msg2 + + # Ensure that the equilibrated temperature is half the starting difference between the cells + msg4 = ( + "The final equilibrated cell temperature does not split the " + "difference of the starting temperature" + ) + initTdiff1 = abs(conc1[0, 0, 0, 0] - conc1[0, idxl, idxr, idxc]) + initTdiff2 = abs(conc1[11, 0, 0, 0] - conc1[11, idxl, idxr, idxc]) + assert np.isclose( + conc1[10, 0, 0, 0], + conc1[0, 0, 0, 0] + initTdiff1 / 2, + ), msg4 + assert np.isclose( + conc1[21, 0, 0, 0], + conc1[11, 0, 0, 0] - initTdiff2 / 2, + ), msg4 + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(ex)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t) + ) + test.run() From b528234012c3a1c357872038d79a334d4048d175 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Thu, 21 Dec 2023 10:50:28 -0800 Subject: [PATCH 12/46] Compliantizing another new autotest with PR #1464 --- autotest/test_gwe_drycell_conduction2.py | 669 +++++++++++++++++++++++ 1 file changed, 669 insertions(+) create mode 100644 autotest/test_gwe_drycell_conduction2.py diff --git a/autotest/test_gwe_drycell_conduction2.py b/autotest/test_gwe_drycell_conduction2.py new file mode 100644 index 00000000000..34f9ed2e996 --- /dev/null +++ b/autotest/test_gwe_drycell_conduction2.py @@ -0,0 +1,669 @@ +# ## Test problem for GWE +# +# Test conduction from a partially saturated group of cells into their dry +# neighbors. Referring to this test as a flowing trough problem. +# +# +# Profile (side) view w/ approximate water table profile shown +# +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +# |-------|_______|_______| | | | | | | | | | +# | | | |-------|_______| | | | | | | | +# | | | | | |-------|_______| | | | | | +# | | | | | | | |-------| | | | | +# | | | | | | | | |-------| | | | +# | | | | | | | | | |-------| | | +# | | | | | | | | | | |-------| | +# | | | | | | | | | | | |-------| +# | | | | | | | | | | | | | +# | | | | | | | | | | | | | +# | | | | | | | | | | | | | +# | | | | | | | | | | | | | +# +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +# +# ^ +# | +# v +# +# Profile view (all rows) +# +-------+-------+ +# | | | +# | | | <- dry cell that's checked for warming owing to increasing +# | v +-------+ temperature of neighboring cell +# |-------| <- water table +# | | +# | | +# | | +# | | +# | | +# | | +# | | +# | | +# +-------+ +# +# +# Imports + +import os + +import numpy as np +import pytest +import flopy + +from framework import TestFramework + +# Base simulation and model name and workspace + +def my_ceil(a, precision=0): + return np.round(a + 0.5 * 10 ** (-precision), precision) + + +def my_floor(a, precision=0): + return np.round(a - 0.5 * 10 ** (-precision), precision) + + +# Monotonicity function +def isMonotonic(A): + x, y = [], [] + x.extend(A) + y.extend(A) + x.sort() + y.sort(reverse=True) + if np.all(x == A) or np.all(y == A): + return True + return False + + +scheme = "UPSTREAM" +# scheme = "TVD" + +ex = ["drycl-cnduct"] +exdirs = [] +for s in ex: + exdirs.append(os.path.join("temp", s)) + +# Model units +length_units = "meters" +time_units = "days" + +# Table MODFLOW 6 GWE comparison to MT3DMS + +nlay = 1 # Number of layers +ncol = 12 # Number of columns +nrow = 2 # Number of rows +delr = 1.0 # Column width ($m$) +delc = 1.0 # Row width ($m$) +top = 10.0 # Top of the model ($m$) +k11 = 4.61426 # Horizontal hydraulic conductivity ($m/d$) +ss = 1e-6 # Specific storage +sy = 0.20 # Specific Yield +nper = 11 # Number of periods +perlen = 1 # Simulation time ($days$) +nstp = 1 # One day time steps +steady = {0: True, 1: False} +transient = {0: False, 1: True} + + +# Set some static model parameter values +k33 = k11 # Vertical hydraulic conductivity ($m/d$) +idomain = 1 # All cells included in the simulation +iconvert = 1 # All cells are convertible + +bot_r1 = np.zeros(ncol).tolist() +# This is the head solution for row 1, so round up to ensure neighboring cells remain dry +r2 = [ + 6.99850, + 6.78111, + 6.55650, + 6.32391, + 6.08242, + 5.83092, + 5.56805, + 5.29211, + 5.00092, + 4.69161, + 4.36032, + 4.00150, +] +bot_r2 = [my_ceil(val, precision=1) for val in r2] +botm = np.array([bot_r1, bot_r2]) + +strtdry = [my_floor(val, precision=2) for val in r2] +strt = np.array([strtdry, strtdry]) # Starting head ($m$) +icelltype = 1 # Cell conversion type (>1: unconfined) + +# Set some static transport related model parameter values +prsity = 0.20 # Porosity +strt_conc = np.ones((nlay, nrow, ncol), dtype=float) * 4.0 +strt_temp = np.ones((nlay, nrow, ncol), dtype=float) * 4.0 +dispersivity = 0.1 # dispersion (remember, 1D model) +cpw = 4183.0 +cps = 760.0 +rhow = 1000.0 +rhos = 1500.0 +lhv = 2454.0 +ktw = 0.5918 * 86400 +kts = 0.2700 * 86400 + +# Parameter equivalents: +# ---------------------- +# "Distribution Coefficient" +Kd = cps / (cpw * rhow) +# "Bulk Density" +rhob = (1 - prsity) * rhos +# "Molecular Diffusion" +Kt_bulk = prsity * ktw + (1 - prsity) * kts +Dm = Kt_bulk / (prsity * rhow * cpw) + +# Set solver parameter values (and related) +nouter, ninner = 100, 300 +hclose, rclose, relax = 1e-10, 1e-10, 1.0 +ttsmult = 1.0 + +# Set up temporal data used by TDIS file +tdis_rc = [] +for i in np.arange(nper): + tdis_rc.append((perlen, nstp, ttsmult)) + +# ### Create MODFLOW 6 GWE MT3DMS Example 1 Boundary Conditions +# +# Constant head cells are specified on both ends of the model + +# Scenario 1a (GHB to GHB) +ghbcond = 1000.0 +ghb_conc = 4.0 +ghb_temp = 4.0 +ghb_conc_warmup = 30.0 +ghb_temp_warmup = 30.0 +# left boundary: cellid, elv, cond, conc, temp; right bnd: cellid, elv, cond, conc, temp +ghbspd = { + # Steady state stress period + 0: [ + [(0, 0, 0), 7.0, ghbcond, ghb_conc, ghb_temp], + [(0, 0, ncol - 1), 4.0, ghbcond, ghb_conc, ghb_temp], + ], + # First transient stress period + 1: [ + [(0, 0, 0), 7.0, ghbcond, ghb_conc_warmup, ghb_temp_warmup], + [(0, 0, ncol - 1), 4.0, ghbcond, ghb_conc, ghb_temp], + ], +} + + +def build_models(idx, test): + # Base MF6 GWF model type + ws = test.workspace + name = ex[idx] + + print("Building MF6 model...()".format(name)) + + # generate names for each model + gwfname = "gwf-" + name + gwtname = "gwt-" + name + gwename = "gwe-" + name + + sim_ws = os.path.join(ws) + sim = flopy.mf6.MFSimulation( + sim_name=name, sim_ws=ws, exe_name="mf6", version="mf6" + ) + + # Instantiating MODFLOW 6 time discretization + flopy.mf6.ModflowTdis( + sim, nper=nper, perioddata=tdis_rc, time_units=time_units + ) + + # Instantiating MODFLOW 6 groundwater flow model + gwf = flopy.mf6.ModflowGwf( + sim, + modelname=gwfname, + save_flows=True, + model_nam_file="{}.nam".format(gwfname), + ) + + # Instantiating MODFLOW 6 solver for flow model + imsgwf = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="CG", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwfname), + ) + sim.register_ims_package(imsgwf, [gwfname]) + + # Instantiating MODFLOW 6 discretization package + flopy.mf6.ModflowGwfdis( + gwf, + length_units=length_units, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=np.ones((nlay, nrow, ncol), dtype=int), + pname="DIS-1", + filename="{}.dis".format(gwfname), + ) + + # Instantiating MODFLOW 6 storage package + flopy.mf6.ModflowGwfsto( + gwf, + ss=ss, + sy=sy, + iconvert=iconvert, + steady_state=steady, + transient=transient, + pname="STO", + filename="{}.sto".format(gwfname), + ) + + # Instantiating MODFLOW 6 node-property flow package + flopy.mf6.ModflowGwfnpf( + gwf, + save_flows=True, + icelltype=icelltype, + k=k11, + k33=k33, + save_specific_discharge=True, + pname="NPF-1", + filename="{}.npf".format(gwfname), + ) + + # Instantiating MODFLOW 6 initial conditions package for flow model + flopy.mf6.ModflowGwfic(gwf, strt=strt, filename="{}.ic".format(gwfname)) + + # Instatiate left and right general-head boundaries for driving flow + flopy.mf6.ModflowGwfghb( + gwf, + maxbound=len(ghbspd[0]), + stress_period_data=ghbspd, + auxiliary=["CONCENTRATION", "TEMPERATURE"], + save_flows=True, + pname="GHB-1", + filename="{}.ghb".format(gwfname), + ) + + # Instantiating MODFLOW 6 output control package for flow model + flopy.mf6.ModflowGwfoc( + gwf, + pname="OC-1", + head_filerecord="{}.hds".format(gwfname), + budget_filerecord="{}.cbc".format(gwfname), + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + printrecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + ) + + # ---------------------------------------------------- + # Instantiating MODFLOW 6 GWT model + # ---------------------------------------------------- + gwt = flopy.mf6.MFModel( + sim, + model_type="gwt6", + modelname=gwtname, + model_nam_file="{}.nam".format(gwtname), + ) + gwt.name_file.save_flows = True + imsgwt = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwtname), + ) + sim.register_ims_package(imsgwt, [gwt.name]) + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwtdis( + gwt, + nogrb=True, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=1, + pname="DIS-2", + filename="{}.dis".format(gwtname), + ) + + # Instantiating MODFLOW 6 transport initial concentrations + flopy.mf6.ModflowGwtic( + gwt, strt=strt_conc, pname="IC-2", filename="{}.ic".format(gwtname) + ) + + # Instantiating MODFLOW 6 transport advection package + flopy.mf6.ModflowGwtadv( + gwt, scheme=scheme, pname="ADV-2", filename="{}.adv".format(gwtname) + ) + + # Instantiating MODFLOW 6 transport dispersion package + if dispersivity != 0: + flopy.mf6.ModflowGwtdsp( + gwt, + xt3d_off=True, + alh=dispersivity, + ath1=dispersivity, + atv=dispersivity, + diffc=Dm, + pname="DSP-2", + filename="{}.dsp".format(gwtname), + ) + + # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) + flopy.mf6.ModflowGwtmst( + gwt, + porosity=prsity, + first_order_decay=False, + decay=None, + decay_sorbed=None, + sorption="linear", + bulk_density=rhob, + distcoef=Kd, + save_flows=True, + pname="MST-2", + filename="{}.mst".format(gwtname), + ) + + # Instantiating MODFLOW 6 transport source-sink mixing package + global pname + srctype = "AUX" + auxname = "CONCENTRATION" + pname = ["GHB-1"] + # Inpput to SSM is: + sources = [[itm, srctype, auxname] for itm in pname] + + flopy.mf6.ModflowGwtssm( + gwt, sources=sources, pname="SSM-2", filename="{}.ssm".format(gwtname) + ) + + # Instantiate MODFLOW 6 solute transport output control package + flopy.mf6.ModflowGwtoc( + gwt, + pname="OC-2", + budget_filerecord="{}.cbc".format(gwtname), + concentration_filerecord="{}.ucn".format(gwtname), + concentrationprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("CONCENTRATION", "ALL"), ("BUDGET", "ALL")], + printrecord=[("CONCENTRATION", "ALL"), ("BUDGET", "ALL")], + ) + + # Instantiating MODFLOW 6 flow-transport exchange mechanism + flopy.mf6.ModflowGwfgwt( + sim, + exgtype="GWF6-GWT6", + exgmnamea=gwfname, + exgmnameb=gwtname, + pname="GWFGWT", + filename="{}.gwfgwt".format(gwtname), + ) + + # --------------------------------------------------------- + # Instantiating MODFLOW 6 GWE model + # --------------------------------------------------------- + gwe = flopy.mf6.MFModel( + sim, + model_type="gwe6", + modelname=gwename, + model_nam_file="{}.nam".format(gwename), + ) + gwe.name_file.save_flows = True + imsgwe = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwename), + ) + sim.register_ims_package(imsgwe, [gwe.name]) + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwedis( + gwe, + nogrb=True, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=1, + pname="DIS-3", + filename="{}.dis".format(gwename), + ) + + # Instantiating MODFLOW 6 transport initial concentrations + flopy.mf6.ModflowGweic( + gwe, strt=strt_temp, pname="IC-3", filename="{}.ic".format(gwename) + ) + + # Instantiating MODFLOW 6 transport advection package + flopy.mf6.ModflowGweadv( + gwe, scheme=scheme, pname="ADV-3", filename="{}.adv".format(gwename) + ) + + # Instantiating MODFLOW 6 transport dispersion package + if dispersivity != 0: + flopy.mf6.ModflowGwedsp( + gwe, + xt3d_off=False, + alh=dispersivity, + ath1=dispersivity, + ktw=ktw, + kts=kts, + pname="DSP-3", + filename="{}.dsp".format(gwename), + ) + + # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) + flopy.mf6.ModflowGwemst( + gwe, + save_flows=True, + porosity=prsity, + cps=cps, + rhos=rhos, + packagedata=[cpw, rhow, lhv], + pname="MST-3", + filename="{}.mst".format(gwename), + ) + + # Instantiating MODFLOW 6 transport source-sink mixing package + srctype = "AUX" + auxname = "TEMPERATURE" + pname = ["GHB-1"] + # Inpput to SSM is: + sources = [[itm, srctype, auxname] for itm in pname] + + flopy.mf6.ModflowGwessm( + gwe, sources=sources, pname="SSM-3", filename="{}.ssm".format(gwename) + ) + + # Instantiate MODFLOW 6 heat transport output control package + flopy.mf6.ModflowGweoc( + gwe, + pname="OC-3", + budget_filerecord="{}.cbc".format(gwename), + temperature_filerecord="{}.ucn".format(gwename), + temperatureprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + printrecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + ) + + # Instantiating MODFLOW 6 flow-transport exchange mechanism + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename, + pname="GWFGWE", + filename="{}.gwfgwe".format(gwename), + ) + + return sim, None + + +def check_output(idx, test): + print("evaluating results...") + + # read transport results from GWE model + name = ex[idx] + gwfname = "gwf-" + name + gwtname = "gwt-" + name + gwename = "gwe-" + name + + # Pull gw heads from GWF + fpth = os.path.join(test.workspace, f"{gwfname}.hds") + try: + # load temperatures + hobj = flopy.utils.HeadFile(fpth, precision="double", text="HEAD") + hds = hobj.get_alldata() + except: + assert False, f'could not load head data from "{fpth}"' + + # Pull parameter-equivalent calculated temperatures from GWT + fpth = os.path.join(test.workspace, f"{gwtname}.ucn") + try: + # load temperatures + cobj = flopy.utils.HeadFile( + fpth, precision="double", text="CONCENTRATION" + ) + conc1 = cobj.get_alldata() + except: + assert False, f'could not load concentration data from "{fpth}"' + + # Pull natively-calculated temperature output from GWE + fpth = os.path.join(test.workspace, f"{gwename}.ucn") + try: + # load temperatures + tobj = flopy.utils.HeadFile( + fpth, precision="double", text="TEMPERATURE" + ) + temp1 = tobj.get_alldata() + except: + assert False, f'could not load temperature data from "{fpth}"' + + # Check heads satisfy problem set up (i.e., all of row 2 is dry) + hdsr1 = hds[0, 0, 0, :] + assert np.all( + hdsr1 < bot_r2 + ), "heads in row 1 should be below bottom elevation of row 2" + assert np.all(hds[0, 0, 1, :] < 0), "row 2 is not dry" + + # Starting temperatures after steady flow period should be 4.0 degrees + np.all( + np.isclose(temp1[0], strt_temp, atol=1e-10) + ), "Steady state temperatures not as expected" + # Same with concentrations in non-dry cells + assert np.all( + np.isclose(conc1[0, :, 0], strt_conc[:, 0]) + ), "Steady state concentrations not as expected" + # Unlike GWE, GWT will not keep dry cells active and output should reflect this + assert np.all( + conc1[:, :, 1, :] < 0 + ), "Concentrations should be set to 'inactive' (-1.e+30) in row 2" + + # Starting in the transient stress period, the water entering in the + # 'trough' row is warmed to 30.0 C. First check that this is the case + assert np.all( + temp1[-1] > temp1[0] + ), "Transient period temperature increase does not appear to have kicked in" + # Dry cell temperatures are only warmed through conduction with neighboring + # 'trough' cells and shouldn't be as warm as wet cells at the end of the + # warming period + assert np.all( + temp1[-1, :, 0] > temp1[-1, 0, 1] + ), "Cells with water should be warmer than dry cells" + + # None of the cells should reach the temperature of the incoming water + # during the simulation period owing to the thermal bleeding that occurs + # to the adjacent dry cells. + assert np.all( + temp1[-1] < ghb_temp_warmup + ), "Cells should not reach the temperature of the incoming water" + + # An increasing amount of thermal bleeding should occur moving in the + # direction of flow since the thickness of the dry cells increases in the + # downstream direction + assert np.all( + np.diff(temp1[-1, :, 0, :-1]) < 0 + ), "Temperature change in the downstream direction should be negative" + assert isMonotonic( + np.diff(temp1[-1, :, 0, :-1]) + ), "A monotonic increase in the amount of heat lost to neighboring dry " \ + "cells is expected" + + # Check temporal changes in temperature in the most upstream and downstream + # dry cells. Cell bottoms in row 2 were calculated using a rounding function + # to the nearest tenth place and as a result a monotonic tapering-off of + # the temperature increase in the in the interior cells cannot be + # guaranteed because of conduction with not only the wet cell in row 1, but + # also conduction among its two dry neighbors (also with variable thickness + colid = 0 + m_arr = np.diff(temp1[1:, 0, 1, colid]) + assert isMonotonic( + m_arr + ), "Temperatures should be monotonically tapering-off in their " \ + "relative temperature increase with time in the upstream-most" \ + "dry cell" + + colid = 11 + m_arr = np.diff(temp1[1:, 0, 1, colid]) + assert isMonotonic( + m_arr + ), "Temperatures should be monotonically tapering-off in their " \ + "relative temperature increase with time in the downstream-most" \ + "dry cell" + + # Run a few checks between GWE and its GWT counterpart + # In GWT there is no solute interaction with a dry cell, so concentrations + # in the dry cell should remain inactive (i.e., no "molecular diffusion") + # and greater than their GWE counterpart temperatures since there is + # no "retardation" of concentration (temperature) owing to conduction + assert np.all(conc1[:, :, 1, :] < 0), "The dry cells should never have a non-inactive concentration value" + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(ex)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t), + ) + test.run() From 6511c213aa9aa8c37891566b6b135a1ab60621f4 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 22 Dec 2023 07:39:24 -0800 Subject: [PATCH 13/46] Fixes in response to https://github.com/MODFLOW-USGS/modflow6/pull/1493#discussion_r1434957257 --- autotest/test_gwe_drycell_conduction0.py | 11 +++--- autotest/test_gwe_drycell_conduction1.py | 11 +++--- autotest/test_gwe_drycell_conduction2.py | 44 ++++++++++++------------ autotest/test_gwe_dsp.py | 11 +++--- 4 files changed, 36 insertions(+), 41 deletions(-) diff --git a/autotest/test_gwe_drycell_conduction0.py b/autotest/test_gwe_drycell_conduction0.py index 059b8ea4bb7..849f1a81ab5 100644 --- a/autotest/test_gwe_drycell_conduction0.py +++ b/autotest/test_gwe_drycell_conduction0.py @@ -33,10 +33,7 @@ scheme = "UPSTREAM" # scheme = "TVD" -ex = ["drycell0"] -exdirs = [] -for s in ex: - exdirs.append(os.path.join("temp", s)) +cases = ["drycell0"] # Model units length_units = "meters" @@ -116,7 +113,7 @@ def build_models(idx, test): # Base MF6 GWF model type ws = test.workspace - name = ex[idx] + name = cases[idx] print("Building MF6 model...()".format(name)) @@ -345,7 +342,7 @@ def check_output(idx, test): print("evaluating results...") # read transport results from GWE model - name = ex[idx] + name = cases[idx] gwename = "gwe-" + name fpth = os.path.join(test.workspace, f"{gwename}.ucn") @@ -411,7 +408,7 @@ def check_output(idx, test): # - No need to change any code below @pytest.mark.parametrize( "idx, name", - list(enumerate(ex)), + list(enumerate(cases)), ) def test_mf6model(idx, name, function_tmpdir, targets): test = TestFramework( diff --git a/autotest/test_gwe_drycell_conduction1.py b/autotest/test_gwe_drycell_conduction1.py index 2f53fa0b7bf..25f154790b8 100644 --- a/autotest/test_gwe_drycell_conduction1.py +++ b/autotest/test_gwe_drycell_conduction1.py @@ -39,6 +39,7 @@ from framework import TestFramework + # Monotonicity function def isMonotonic(A): x, y = [], [] @@ -56,7 +57,7 @@ def isMonotonic(A): scheme = "UPSTREAM" # scheme = "TVD" -ex = [ +cases = [ "drycell2-a", # 2-cell model, horizontally connected with tops and bots aligned "drycell2-b", # 2-cell model, vertically connected "drycell2-c", # 2-cell model, horizontally connected with staggered alignment (reduced shared cell face area) @@ -151,7 +152,7 @@ def build_models(idx, test): # Base MF6 GWF model type ws = test.workspace - name = ex[idx] + name = cases[idx] print("Building MF6 model...()".format(name)) @@ -397,7 +398,7 @@ def check_output(idx, test): print("evaluating results...") # read transport results from GWE model - name = ex[idx] + name = cases[idx] gwename = "gwe-" + name # All indices are 0 based @@ -468,7 +469,7 @@ def check_output(idx, test): # - No need to change any code below @pytest.mark.parametrize( "idx, name", - list(enumerate(ex)), + list(enumerate(cases)), ) def test_mf6model(idx, name, function_tmpdir, targets): test = TestFramework( @@ -476,6 +477,6 @@ def test_mf6model(idx, name, function_tmpdir, targets): workspace=function_tmpdir, targets=targets, build=lambda t: build_models(idx, t), - check=lambda t: check_output(idx, t) + check=lambda t: check_output(idx, t), ) test.run() diff --git a/autotest/test_gwe_drycell_conduction2.py b/autotest/test_gwe_drycell_conduction2.py index 34f9ed2e996..d5e354b6f7a 100644 --- a/autotest/test_gwe_drycell_conduction2.py +++ b/autotest/test_gwe_drycell_conduction2.py @@ -53,6 +53,7 @@ # Base simulation and model name and workspace + def my_ceil(a, precision=0): return np.round(a + 0.5 * 10 ** (-precision), precision) @@ -76,10 +77,7 @@ def isMonotonic(A): scheme = "UPSTREAM" # scheme = "TVD" -ex = ["drycl-cnduct"] -exdirs = [] -for s in ex: - exdirs.append(os.path.join("temp", s)) +cases = ["drycl-cnduct"] # Model units length_units = "meters" @@ -192,7 +190,7 @@ def isMonotonic(A): def build_models(idx, test): # Base MF6 GWF model type ws = test.workspace - name = ex[idx] + name = cases[idx] print("Building MF6 model...()".format(name)) @@ -537,7 +535,7 @@ def check_output(idx, test): print("evaluating results...") # read transport results from GWE model - name = ex[idx] + name = cases[idx] gwfname = "gwf-" + name gwtname = "gwt-" + name gwename = "gwe-" + name @@ -618,10 +616,10 @@ def check_output(idx, test): assert np.all( np.diff(temp1[-1, :, 0, :-1]) < 0 ), "Temperature change in the downstream direction should be negative" - assert isMonotonic( - np.diff(temp1[-1, :, 0, :-1]) - ), "A monotonic increase in the amount of heat lost to neighboring dry " \ - "cells is expected" + assert isMonotonic(np.diff(temp1[-1, :, 0, :-1])), ( + "A monotonic increase in the amount of heat lost to neighboring dry " + "cells is expected" + ) # Check temporal changes in temperature in the most upstream and downstream # dry cells. Cell bottoms in row 2 were calculated using a rounding function @@ -631,32 +629,34 @@ def check_output(idx, test): # also conduction among its two dry neighbors (also with variable thickness colid = 0 m_arr = np.diff(temp1[1:, 0, 1, colid]) - assert isMonotonic( - m_arr - ), "Temperatures should be monotonically tapering-off in their " \ - "relative temperature increase with time in the upstream-most" \ - "dry cell" + assert isMonotonic(m_arr), ( + "Temperatures should be monotonically tapering-off in their " + "relative temperature increase with time in the upstream-most" + "dry cell" + ) colid = 11 m_arr = np.diff(temp1[1:, 0, 1, colid]) - assert isMonotonic( - m_arr - ), "Temperatures should be monotonically tapering-off in their " \ - "relative temperature increase with time in the downstream-most" \ - "dry cell" + assert isMonotonic(m_arr), ( + "Temperatures should be monotonically tapering-off in their " + "relative temperature increase with time in the downstream-most" + "dry cell" + ) # Run a few checks between GWE and its GWT counterpart # In GWT there is no solute interaction with a dry cell, so concentrations # in the dry cell should remain inactive (i.e., no "molecular diffusion") # and greater than their GWE counterpart temperatures since there is # no "retardation" of concentration (temperature) owing to conduction - assert np.all(conc1[:, :, 1, :] < 0), "The dry cells should never have a non-inactive concentration value" + assert np.all( + conc1[:, :, 1, :] < 0 + ), "The dry cells should never have a non-inactive concentration value" # - No need to change any code below @pytest.mark.parametrize( "idx, name", - list(enumerate(ex)), + list(enumerate(cases)), ) def test_mf6model(idx, name, function_tmpdir, targets): test = TestFramework( diff --git a/autotest/test_gwe_dsp.py b/autotest/test_gwe_dsp.py index 4f3407d8e04..0af08ee25ed 100644 --- a/autotest/test_gwe_dsp.py +++ b/autotest/test_gwe_dsp.py @@ -37,10 +37,7 @@ # Base simulation and model name and workspace viscosity_on = [False] -ex = ["dsp01"] -exdirs = [] -for s in ex: - exdirs.append(os.path.join("temp", s)) +cases = ["dsp01"] # Model units @@ -124,7 +121,7 @@ def build_models(idx, test): # Base MF6 GWE model type ws = test.workspace - name = ex[idx] + name = cases[idx] print("Building MF6 model...()".format(name)) @@ -358,7 +355,7 @@ def check_output(idx, test): print("evaluating results...") # read transport results from GWE model - name = ex[idx] + name = cases[idx] gwename = "gwe-" + name fpth = os.path.join(test.workspace, f"{gwename}.ucn") @@ -483,7 +480,7 @@ def check_output(idx, test): # - No need to change any code below @pytest.mark.parametrize( "idx, name", - list(enumerate(ex)), + list(enumerate(cases)), ) def test_mf6model(idx, name, function_tmpdir, targets): test = TestFramework( From cef5b836fdd0f380c31b87f75e8cd802a57972d9 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 22 Dec 2023 07:47:53 -0800 Subject: [PATCH 14/46] Fix in response to https://github.com/MODFLOW-USGS/modflow6/pull/1493#discussion_r1434959417 --- autotest/test_gwe_drycell_conduction0.py | 40 +++++------ autotest/test_gwe_drycell_conduction1.py | 66 +++++++++--------- autotest/test_gwe_drycell_conduction2.py | 87 ++++++++++++------------ autotest/test_gwe_dsp.py | 22 +++--- 4 files changed, 111 insertions(+), 104 deletions(-) diff --git a/autotest/test_gwe_drycell_conduction0.py b/autotest/test_gwe_drycell_conduction0.py index 849f1a81ab5..e135d72c0d1 100644 --- a/autotest/test_gwe_drycell_conduction0.py +++ b/autotest/test_gwe_drycell_conduction0.py @@ -1,22 +1,24 @@ -# ## Test problem for GWE -# -# Test the energy "flowing" through a dry cell. The test checks for -# some of the flow-through energy being left behind and warming the -# cell it passes through. Based on the model appearing in the -# MT3D-USGS documention, pages 13-14. Dry cell is in layer 1, row 1 -# column 4. -# -# +-------+-------+-------+-------+-------+-------+ -# -> | -> | | | DRY | | | -# | | -> | | CELL| | | -# | | | -> -+-> | | | | -# +-------+-------+-------+---+---+-------+-------+ -# | | | | v | | | -# -> | -> | -> | -> | -> | -> | -> | -> -# | | | | | | | -# +-------+-------+-------+-------+-------+-------+ -# -# ---> Direction of flow ---> +""" +Test problem for GWE + +Test the energy "flowing" through a dry cell. The test checks for +some of the flow-through energy being left behind and warming the +cell it passes through. Based on the model appearing in the +MT3D-USGS documention, pages 13-14. Dry cell is in layer 1, row 1 +column 4. + + +-------+-------+-------+-------+-------+-------+ + -> | -> | | | DRY | | | + | | -> | | CELL| | | + | | | -> -+-> | | | | + +-------+-------+-------+---+---+-------+-------+ + | | | | v | | | + -> | -> | -> | -> | -> | -> | -> | -> + | | | | | | | + +-------+-------+-------+-------+-------+-------+ + + ---> Direction of flow ---> +""" # Imports diff --git a/autotest/test_gwe_drycell_conduction1.py b/autotest/test_gwe_drycell_conduction1.py index 25f154790b8..47857444f1e 100644 --- a/autotest/test_gwe_drycell_conduction1.py +++ b/autotest/test_gwe_drycell_conduction1.py @@ -1,35 +1,37 @@ -# ## Test problem for GWE -# -# Test the energy "flowing" between two dry cells via conduction -# only using a temperature gradient -# -# ~: Represents conduction -# -# A) 1st model configuration -# -# +---------+---------+ -# | |~ | -# | |~ | -# +---------+---------+ -# -# B) 2nd model configuration -# -# +---------+ -# | | -# | ~ ~ | -# +---------+ -# | | -# | | -# +---------+ -# -# C) 3rd model configuration -# -# +---------+ -# +---------+ | -# | |~ | -# | +---------+ -# +---------+ -# +""" +Test problem for GWE + +Test the energy "flowing" between two dry cells via conduction +only using a temperature gradient + + ~: Represents conduction + + A) 1st model configuration + + +---------+---------+ + | |~ | + | |~ | + +---------+---------+ + + B) 2nd model configuration + + +---------+ + | | + | ~ ~ | + +---------+ + | | + | | + +---------+ + + C) 3rd model configuration + + +---------+ + +---------+ | + | |~ | + | +---------+ + +---------+ +""" + # Imports import os diff --git a/autotest/test_gwe_drycell_conduction2.py b/autotest/test_gwe_drycell_conduction2.py index d5e354b6f7a..75439cae5e1 100644 --- a/autotest/test_gwe_drycell_conduction2.py +++ b/autotest/test_gwe_drycell_conduction2.py @@ -1,46 +1,47 @@ -# ## Test problem for GWE -# -# Test conduction from a partially saturated group of cells into their dry -# neighbors. Referring to this test as a flowing trough problem. -# -# -# Profile (side) view w/ approximate water table profile shown -# +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ -# |-------|_______|_______| | | | | | | | | | -# | | | |-------|_______| | | | | | | | -# | | | | | |-------|_______| | | | | | -# | | | | | | | |-------| | | | | -# | | | | | | | | |-------| | | | -# | | | | | | | | | |-------| | | -# | | | | | | | | | | |-------| | -# | | | | | | | | | | | |-------| -# | | | | | | | | | | | | | -# | | | | | | | | | | | | | -# | | | | | | | | | | | | | -# | | | | | | | | | | | | | -# +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ -# -# ^ -# | -# v -# -# Profile view (all rows) -# +-------+-------+ -# | | | -# | | | <- dry cell that's checked for warming owing to increasing -# | v +-------+ temperature of neighboring cell -# |-------| <- water table -# | | -# | | -# | | -# | | -# | | -# | | -# | | -# | | -# +-------+ -# -# +""" +Test problem for GWE + +Test conduction from a partially saturated group of cells into their dry +neighbors. Referring to this test as a flowing trough problem. + + + Profile view of columns w/ approximate water table profile shown + +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ + |-------|_______|_______| | | | | | | | | | + | | | |-------|_______| | | | | | | | + | | | | | |-------|_______| | | | | | + | | | | | | | |-------| | | | | + | | | | | | | | |-------| | | | + | | | | | | | | | |-------| | | + | | | | | | | | | | |-------| | + | | | | | | | | | | | |-------| + | | | | | | | | | | | | | + | | | | | | | | | | | | | + | | | | | | | | | | | | | + | | | | | | | | | | | | | + +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ + + ^ + | + v + + Profile view of rows + +-------+-------+ + | | | + | | | <- dry cell that's checked for warming owing to increasing + | v +-------+ temperature of neighboring cell + |-------| <- water table + | | + | | + | | + | | + | | + | | + | | + | | + +-------+ +""" + # Imports import os diff --git a/autotest/test_gwe_dsp.py b/autotest/test_gwe_dsp.py index 0af08ee25ed..8b3747782d9 100644 --- a/autotest/test_gwe_dsp.py +++ b/autotest/test_gwe_dsp.py @@ -1,13 +1,15 @@ -# ## Test problem for GWE -# -# One-Dimensional Transport in a Uniform Flow Field. -# The purpose of this script is to test the new heat transport model developed -# for MODFLOW 6. To that end, this problem uses the setup of the first MT3DMS -# test problem but adapts it for heat. MODFLOW 6 is setup using the new GWE -# model with input parameters entered in their native units. -# -# It may be possible to find a 1D heat transport analytical solution in the -# future. +""" +Test problem for GWE + +One-Dimensional Transport in a Uniform Flow Field. +The purpose of this script is to test the new heat transport model developed +for MODFLOW 6. To that end, this problem uses the setup of the first MT3DMS +test problem but adapts it for heat. MODFLOW 6 is setup using the new GWE +model with input parameters entered in their native units. + +It may be possible to find a 1D heat transport analytical solution in the +future. +""" # Imports From a8a1df99113289c9f07f44db081a79b9807a0b72 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 22 Dec 2023 08:00:41 -0800 Subject: [PATCH 15/46] Rerunning black in response to https://github.com/MODFLOW-USGS/modflow6/pull/1493#discussion_r1434968145 --- doc/mf6io/mf6ivar/mf6ivar.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/mf6io/mf6ivar/mf6ivar.py b/doc/mf6io/mf6ivar/mf6ivar.py index b0812d05670..a4de0c76b0d 100644 --- a/doc/mf6io/mf6ivar/mf6ivar.py +++ b/doc/mf6io/mf6ivar/mf6ivar.py @@ -153,7 +153,6 @@ def parse_mf6var_file(fname): vd = {} for line in lines: - # skip blank lines if len(line.strip()) == 0: if len(vd) > 0: @@ -682,7 +681,6 @@ def write_appendix(texdir, allblocks): if __name__ == "__main__": - file_order = [ "sim-nam", # dfn completed tex updated "sim-tdis", # dfn completed tex updated From 4f60e29fe1844655280d900143137436796f1efc Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 22 Dec 2023 08:22:24 -0800 Subject: [PATCH 16/46] Fix in response to https://github.com/MODFLOW-USGS/modflow6/pull/1493#discussion_r1434970996 --- doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex index b464804151c..c42592c0fa3 100644 --- a/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex +++ b/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex @@ -3,7 +3,7 @@ \item \textbf{Block: OPTIONS} \begin{description} -\item \texttt{list}---is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the '.lst' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. +\item \texttt{list}---is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the ``.lst'' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. \item \texttt{PRINT\_INPUT}---keyword to indicate that the list of all model stress package information will be written to the listing file immediately after it is read. From 5c774d3c48c8f55b4c92e7be00ce48c6482881cb Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 22 Dec 2023 08:34:08 -0800 Subject: [PATCH 17/46] Made changes to dfn files in response to https://github.com/MODFLOW-USGS/modflow6/pull/1493#discussion_r1434974211 and https://github.com/MODFLOW-USGS/modflow6/pull/1493#discussion_r1434973634 and reran mf6ivar.py, which updated the tex files in this commit --- doc/mf6io/mf6ivar/dfn/gwf-rcha.dfn | 2 +- doc/mf6io/mf6ivar/dfn/utl-spta.dfn | 2 +- doc/mf6io/mf6ivar/md/mf6ivar.md | 4 ++-- doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex | 2 +- doc/mf6io/mf6ivar/tex/utl-spta-desc.tex | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/mf6io/mf6ivar/dfn/gwf-rcha.dfn b/doc/mf6io/mf6ivar/dfn/gwf-rcha.dfn index a0fb9ec0f60..80238e9a48a 100644 --- a/doc/mf6io/mf6ivar/dfn/gwf-rcha.dfn +++ b/doc/mf6io/mf6ivar/dfn/gwf-rcha.dfn @@ -174,7 +174,7 @@ shape (ncol*nrow; ncpl) reader readarray time_series true longname recharge rate -description is the recharge flux rate ($LT^{-1}$). This rate is multiplied inside the program by the surface area of the cell to calculate the volumetric recharge rate. The recharge array may be defined by a time-array series (see the "Using Time-Array Series in a Package" section). +description is the recharge flux rate ($LT^{-1}$). This rate is multiplied inside the program by the surface area of the cell to calculate the volumetric recharge rate. The recharge array may be defined by a time-array series (see the ``Using Time-Array Series in a Package'' section). default_value 1.e-3 block period diff --git a/doc/mf6io/mf6ivar/dfn/utl-spta.dfn b/doc/mf6io/mf6ivar/dfn/utl-spta.dfn index 6f644298ff0..03b3c456f07 100644 --- a/doc/mf6io/mf6ivar/dfn/utl-spta.dfn +++ b/doc/mf6io/mf6ivar/dfn/utl-spta.dfn @@ -84,6 +84,6 @@ type double precision shape (ncol*nrow; ncpl) reader readarray longname temperature -description is the temperature of the associated Recharge or Evapotranspiration stress package. The temperature array may be defined by a time-array series (see the "Using Time-Array Series in a Package" section). +description is the temperature of the associated Recharge or Evapotranspiration stress package. The temperature array may be defined by a time-array series (see the ``Using Time-Array Series in a Package'' section). default_value 0. diff --git a/doc/mf6io/mf6ivar/md/mf6ivar.md b/doc/mf6io/mf6ivar/md/mf6ivar.md index 848ebd0f4ea..137f18f39b1 100644 --- a/doc/mf6io/mf6ivar/md/mf6ivar.md +++ b/doc/mf6io/mf6ivar/md/mf6ivar.md @@ -467,7 +467,7 @@ | GWF | RCHA | OPTIONS | OBS6_FILENAME | STRING | name of input file to define observations for the Recharge package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the Recharge package. | | GWF | RCHA | PERIOD | IPER | INTEGER | integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. | | GWF | RCHA | PERIOD | IRCH | INTEGER (NCOL*NROW; NCPL) | IRCH is the layer number that defines the layer in each vertical column where recharge is applied. If IRCH is omitted, recharge by default is applied to cells in layer 1. IRCH can only be used if READASARRAYS is specified in the OPTIONS block. If IRCH is specified, it must be specified as the first variable in the PERIOD block or MODFLOW will terminate with an error. | -| GWF | RCHA | PERIOD | RECHARGE | DOUBLE PRECISION (NCOL*NROW; NCPL) | is the recharge flux rate ($LT^{-1}$). This rate is multiplied inside the program by the surface area of the cell to calculate the volumetric recharge rate. The recharge array may be defined by a time-array series (see the "Using Time-Array Series in a Package" section). | +| GWF | RCHA | PERIOD | RECHARGE | DOUBLE PRECISION (NCOL*NROW; NCPL) | is the recharge flux rate ($LT^{-1}$). This rate is multiplied inside the program by the surface area of the cell to calculate the volumetric recharge rate. The recharge array may be defined by a time-array series (see the ``Using Time-Array Series in a Package'' section). | | GWF | RCHA | PERIOD | AUX | DOUBLE PRECISION (NCOL*NROW; NCPL) | is an array of values for auxiliary variable aux(iaux), where iaux is a value from 1 to naux, and aux(iaux) must be listed as part of the auxiliary variables. A separate array can be specified for each auxiliary variable. If an array is not specified for an auxiliary variable, then a value of zero is assigned. If the value specified here for the auxiliary variable is the same as auxmultname, then the recharge array will be multiplied by this array. | | GWF | EVT | OPTIONS | FIXED_CELL | KEYWORD | indicates that evapotranspiration will not be reassigned to a cell underlying the cell specified in the list if the specified cell is inactive. | | GWF | EVT | OPTIONS | AUXILIARY | STRING (NAUX) | defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. | @@ -1356,7 +1356,7 @@ | UTL | SPTA | OPTIONS | FILEIN | KEYWORD | keyword to specify that an input filename is expected next. | | UTL | SPTA | OPTIONS | TAS6_FILENAME | STRING | defines a time-array-series file defining a time-array series that can be used to assign time-varying values. See the Time-Variable Input section for instructions on using the time-array series capability. | | UTL | SPTA | PERIOD | IPER | INTEGER | integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. | -| UTL | SPTA | PERIOD | TEMPERATURE | DOUBLE PRECISION (NCOL*NROW; NCPL) | is the temperature of the associated Recharge or Evapotranspiration stress package. The temperature array may be defined by a time-array series (see the "Using Time-Array Series in a Package" section). | +| UTL | SPTA | PERIOD | TEMPERATURE | DOUBLE PRECISION (NCOL*NROW; NCPL) | is the temperature of the associated Recharge or Evapotranspiration stress package. The temperature array may be defined by a time-array series (see the ``Using Time-Array Series in a Package'' section). | | UTL | OBS | OPTIONS | DIGITS | INTEGER | Keyword and an integer digits specifier used for conversion of simulated values to text on output. If not specified, the default is the maximum number of digits stored in the program (as written with the G0 Fortran specifier). When simulated values are written to a comma-separated value text file specified in a CONTINUOUS block below, the digits specifier controls the number of significant digits with which simulated values are written to the output file. The digits specifier has no effect on the number of significant digits with which the simulation time is written for continuous observations. If DIGITS is specified as zero, then observations are written with the default setting, which is the maximum number of digits. | | UTL | OBS | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of observation information will be written to the listing file immediately after it is read. | | UTL | OBS | CONTINUOUS | FILEOUT | KEYWORD | keyword to specify that an output filename is expected next. | diff --git a/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex index c42592c0fa3..b464804151c 100644 --- a/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex +++ b/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex @@ -3,7 +3,7 @@ \item \textbf{Block: OPTIONS} \begin{description} -\item \texttt{list}---is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the ``.lst'' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. +\item \texttt{list}---is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the '.lst' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. \item \texttt{PRINT\_INPUT}---keyword to indicate that the list of all model stress package information will be written to the listing file immediately after it is read. diff --git a/doc/mf6io/mf6ivar/tex/utl-spta-desc.tex b/doc/mf6io/mf6ivar/tex/utl-spta-desc.tex index 819633c49b6..cc610d06868 100644 --- a/doc/mf6io/mf6ivar/tex/utl-spta-desc.tex +++ b/doc/mf6io/mf6ivar/tex/utl-spta-desc.tex @@ -19,7 +19,7 @@ \begin{description} \item \texttt{iper}---integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. -\item \texttt{temperature}---is the temperature of the associated Recharge or Evapotranspiration stress package. The temperature array may be defined by a time-array series (see the "Using Time-Array Series in a Package" section). +\item \texttt{temperature}---is the temperature of the associated Recharge or Evapotranspiration stress package. The temperature array may be defined by a time-array series (see the ``Using Time-Array Series in a Package'' section). \end{description} From e23babc31e9334f8c2d7d557011ea59b3c90ac49 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 22 Dec 2023 08:37:59 -0800 Subject: [PATCH 18/46] Fix in response to https://github.com/MODFLOW-USGS/modflow6/pull/1493#discussion_r1434970996 --- doc/mf6io/mf6ivar/dfn/gwe-nam.dfn | 2 +- doc/mf6io/mf6ivar/md/mf6ivar.md | 2 +- doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/mf6io/mf6ivar/dfn/gwe-nam.dfn b/doc/mf6io/mf6ivar/dfn/gwe-nam.dfn index 9bb5fef92ef..70c89d67135 100644 --- a/doc/mf6io/mf6ivar/dfn/gwe-nam.dfn +++ b/doc/mf6io/mf6ivar/dfn/gwe-nam.dfn @@ -7,7 +7,7 @@ reader urword optional true preserve_case true longname name of listing file -description is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the '.lst' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. +description is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the ``.lst'' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. block options name print_input diff --git a/doc/mf6io/mf6ivar/md/mf6ivar.md b/doc/mf6io/mf6ivar/md/mf6ivar.md index 137f18f39b1..deaa7b59742 100644 --- a/doc/mf6io/mf6ivar/md/mf6ivar.md +++ b/doc/mf6io/mf6ivar/md/mf6ivar.md @@ -1281,7 +1281,7 @@ | GWE | MST | PACKAGEDATA | CPW | DOUBLE PRECISION | is the mass-based heat capacity of the simulated fluid. For example, units of J/kg/C may be used (or equivalent). | | GWE | MST | PACKAGEDATA | RHOW | DOUBLE PRECISION | is a user-specified value of the density of water. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. | | GWE | MST | PACKAGEDATA | LATHEATVAP | DOUBLE PRECISION | is the user-specified value for the latent heat of vaporization. For example, if working in SI units, values may be entered as kJ/kg. | -| GWE | NAM | OPTIONS | LIST | STRING | is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the '.lst' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. | +| GWE | NAM | OPTIONS | LIST | STRING | is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the ``.lst'' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. | | GWE | NAM | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of all model stress package information will be written to the listing file immediately after it is read. | | GWE | NAM | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of all model package flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | | GWE | NAM | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that all model package flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | diff --git a/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex index b464804151c..c42592c0fa3 100644 --- a/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex +++ b/doc/mf6io/mf6ivar/tex/gwe-nam-desc.tex @@ -3,7 +3,7 @@ \item \textbf{Block: OPTIONS} \begin{description} -\item \texttt{list}---is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the '.lst' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. +\item \texttt{list}---is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the ``.lst'' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. \item \texttt{PRINT\_INPUT}---keyword to indicate that the list of all model stress package information will be written to the listing file immediately after it is read. From 6a1c29cfe7ba3a1f64e5638d7e9ddd0fb658b9a5 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 29 Dec 2023 15:19:58 -0800 Subject: [PATCH 19/46] remove unnecessary line of script --- autotest/test_gwe_drycell_conduction2.py | 1 - 1 file changed, 1 deletion(-) diff --git a/autotest/test_gwe_drycell_conduction2.py b/autotest/test_gwe_drycell_conduction2.py index 75439cae5e1..fb53114c180 100644 --- a/autotest/test_gwe_drycell_conduction2.py +++ b/autotest/test_gwe_drycell_conduction2.py @@ -200,7 +200,6 @@ def build_models(idx, test): gwtname = "gwt-" + name gwename = "gwe-" + name - sim_ws = os.path.join(ws) sim = flopy.mf6.MFSimulation( sim_name=name, sim_ws=ws, exe_name="mf6", version="mf6" ) From ca9b549198ebe01440a25e519fb6f7534e1b6de5 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 29 Dec 2023 15:27:31 -0800 Subject: [PATCH 20/46] Add missing lines to ConnectionBuilder.f90 related to GWE --- src/Model/Connection/ConnectionBuilder.f90 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Model/Connection/ConnectionBuilder.f90 b/src/Model/Connection/ConnectionBuilder.f90 index c7b6d28b8d6..d53aa51bedb 100644 --- a/src/Model/Connection/ConnectionBuilder.f90 +++ b/src/Model/Connection/ConnectionBuilder.f90 @@ -147,6 +147,7 @@ function createModelConnection(model, exchange) result(connection) use SimModule, only: ustop use GwfGwfConnectionModule, only: GwfGwfConnectionType use GwtGwtConnectionModule, only: GwtGwtConnectionType + use GweGweConnectionModule, only: GweGweConnectionType use GwfModule, only: GwfModelType class(NumericalModelType), pointer, intent(in) :: model !< the model for which the connection will be created @@ -156,6 +157,7 @@ function createModelConnection(model, exchange) result(connection) ! different concrete connection types: class(GwfGwfConnectionType), pointer :: flowConnection => null() class(GwtGwtConnectionType), pointer :: transportConnection => null() + class(GweGweConnectionType), pointer :: energyTransportConnection => null() connection => null() @@ -171,6 +173,11 @@ function createModelConnection(model, exchange) result(connection) call transportConnection%construct(model, exchange) connection => transportConnection transportConnection => null() + case ('GWE-GWE') + allocate (GweGweConnectionType :: energyTransportConnection) + call energyTransportConnection%construct(model, exchange) + connection => energyTransportConnection + energyTransportConnection => null() case default write (*, *) 'Error (which should never happen): '// & 'undefined exchangetype found' From 83fc63e068b47cafb6d0a543754b17cfe5dad5af Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 12 Jan 2024 08:48:48 -0800 Subject: [PATCH 21/46] Add a GWE vs GWT comparison autotest --- autotest/test_gwe_vs_gwt.py | 564 ++++++++++++++++++++++++++++++++++++ 1 file changed, 564 insertions(+) create mode 100644 autotest/test_gwe_vs_gwt.py diff --git a/autotest/test_gwe_vs_gwt.py b/autotest/test_gwe_vs_gwt.py new file mode 100644 index 00000000000..5fc1a6ac9ed --- /dev/null +++ b/autotest/test_gwe_vs_gwt.py @@ -0,0 +1,564 @@ +""" +Two-Dimensional Transport in a Radial Flow Field Comparison of +MODFLOW 6 GWT with GWE + +The purpose of this script is to test the new heat transport model developed +for MODFLOW 6. To that end, this problem uses the setup of MT3DMS example problem +#5 but adapts it for heat. MODFLOW 6 is setup using GWT and the new GWE +model with input parameters entered in their native units. The equivalent +values are calculated for "tricking" GWT into heat transport for comparison +between the two. +""" + +# Imports +import flopy +import numpy as np +import os +import sys +import pytest + +from framework import TestFramework + +# Base simulation and model name and workspace +cases = ["t_vs_c"] + +# Model units + +length_units = "meters" +time_units = "days" + +# Table + +nlay = 1 # Number of layers +nrow = 31 # Number of rows +ncol = 31 # Number of columns +delr = 10.0 # Column width ($m$) +delc = 10.0 # Row width ($m$) +delz = 1.0 # Layer thickness ($m$) +top = 0.0 # Top of the model ($m$) +prsity = 0.3 # Porosity +perlen = 27 # Simulation time ($days$) +k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$) +qwell = 100.0 # Volumetric injection rate ($m^3/d$) +twell = 100.0 # Concentration of injected water ($mg/L$) +al = 10.0 # Longitudinal dispersivity ($m$) +trpt = 1.0 # Ratio of transverse to longitudinal dispersitivity + +dmcoef = 3.2519e-7 +rhob = 1110.0 +sp2 = 0.0 # read, but not used in this problem +kd = 1.8168e-4 + +cpw = 4183.0 +cps = 760.0 +rhow = 1000.0 +rhos = 1500.0 +lhv = 2454.0 + +# Additional model input + +perlen = [27] +nper = len(perlen) +nstp = [27] +tsmult = [1.0] +strt_temp = 0.0 +c0 = 100.0 +dt0 = 0.3 +ath1 = al * trpt +botm = [top - delz] # Model geometry +k33 = k11 # Vertical hydraulic conductivity ($m/d$) +icelltype = 0 +mixelm = -1 +strt = np.zeros((nlay, nrow, ncol), dtype=float) + +# Active model domain +idomain = np.ones((nlay, nrow, ncol), dtype=int) +icbund = 1 + +# Boundary conditions +# MF2K5 pumping info: + +welspd = {0: [[0, 15, 15, qwell]]} # Well pumping info for MF2K5 +spd = {0: [0, 15, 15, twell, -1]} # Well pumping info for MT3DMS + +# MF6 pumping information + +# (k, i, j), flow, conc +spd_mf6 = {0: [[(0, 15, 15), qwell, c0]]} + +# MF6 constant head boundaries: + +chdspd = [] +# Loop through the left & right sides. +for i in np.arange(nrow): + chdspd.append([(0, i, 0), strt[0, i, 0]]) + chdspd.append([(0, i, ncol - 1), strt[0, i, ncol - 1]]) +# Loop through the top & bottom while omitting the corner cells +for j in np.arange(1, ncol - 1): + chdspd.append([(0, 0, j), strt[0, 0, j]]) + chdspd.append([(0, nrow - 1, j), strt[0, nrow - 1, j]]) + +chdspd = {0: chdspd} + +# Solver settings + +nouter, ninner = 100, 300 +hclose, rclose, relax = 1e-6, 1e-6, 1.0 +percel = 1.0 # HMOC parameters +itrack = 3 +wd = 0.5 +dceps = 1.0e-5 +nplane = 1 +npl = 0 +nph = 16 +npmin = 2 +npmax = 32 +dchmoc = 1.0e-3 +nlsink = nplane +npsink = nph + +# Static temporal data used by TDIS file + +tdis_rc = [] +tdis_rc.append((perlen, nstp, 1.0)) + +# ### Functions to build, write, and run models and plot MT3DMS Example 10 Problem results +# +# MODFLOW 6 flopy simulation object (sim) is returned if building the model + + +def build_models(idx, test): + # MODFLOW 6 + ws = test.workspace + name = cases[idx] + gwfname = "gwf_" + name + gwename = "gwe_" + name + gwtname = "gwt_" + name + + sim = flopy.mf6.MFSimulation( + sim_name=name, + sim_ws=ws, + exe_name="mf6", + ) + + # Instantiating MODFLOW 6 time discretization + tdis_rc = [] + for i in range(nper): + tdis_rc.append((perlen[i], nstp[i], tsmult[i])) + + flopy.mf6.ModflowTdis( + sim, nper=nper, perioddata=tdis_rc, time_units=time_units + ) + + # Instantiating MODFLOW 6 groundwater flow model + gwf = flopy.mf6.ModflowGwf( + sim, + modelname=gwfname, + save_flows=True, + model_nam_file="{}.nam".format(gwfname), + ) + + # Instantiating MODFLOW 6 solver for flow model + imsgwf = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="CG", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwfname), + ) + sim.register_ims_package(imsgwf, [gwf.name]) + + # Instantiating MODFLOW 6 discretization package + flopy.mf6.ModflowGwfdis( + gwf, + length_units=length_units, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=idomain, + pname="DIS-1", + filename="{}.dis".format(gwfname), + ) + + # Instantiating MODFLOW 6 node-property flow package + flopy.mf6.ModflowGwfnpf( + gwf, + save_flows=False, + icelltype=icelltype, + k=k11, + k33=k33, + save_specific_discharge=True, + pname="NPF-1", + filename="{}.npf".format(gwfname), + ) + + # Instantiating MODFLOW 6 storage package (steady flow conditions, so no actual storage, using to print values in .lst file) + flopy.mf6.ModflowGwfsto( + gwf, ss=0, sy=0, pname="STO-1", filename="{}.sto".format(gwfname) + ) + + # Instantiating MODFLOW 6 initial conditions package for flow model + flopy.mf6.ModflowGwfic( + gwf, strt=strt, pname="IC-1", filename="{}.ic".format(gwfname) + ) + + # Instantiating MODFLOW 6 constant head package + flopy.mf6.ModflowGwfchd( + gwf, + maxbound=len(chdspd), + stress_period_data=chdspd, + save_flows=False, + pname="CHD-1", + filename="{}.chd".format(gwfname), + ) + + # Instantiate the wel package + flopy.mf6.ModflowGwfwel( + gwf, + print_input=True, + print_flows=True, + stress_period_data=spd_mf6, + save_flows=False, + auxiliary="TEMPERATURE", + pname="WEL-1", + filename="{}.wel".format(gwfname), + ) + + # Instantiating MODFLOW 6 output control package for flow model + flopy.mf6.ModflowGwfoc( + gwf, + head_filerecord="{}.hds".format(gwfname), + budget_filerecord="{}.bud".format(gwfname), + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "LAST"), ("BUDGET", "LAST")], + printrecord=[("HEAD", "LAST"), ("BUDGET", "LAST")], + ) + + # ---------------------------------------------------- + # Instantiating MODFLOW 6 GWE model + # ---------------------------------------------------- + + # Instantiating MODFLOW 6 groundwater heat transport package + gwe = flopy.mf6.MFModel( + sim, + model_type="gwe6", + modelname=gwename, + model_nam_file="{}.nam".format(gwename), + ) + gwe.name_file.save_flows = True + + # create iterative model solution and register the gwe model with it + imsgwe = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwename), + ) + sim.register_ims_package(imsgwe, [gwe.name]) + + # Instantiating MODFLOW 6 heat transport discretization package + flopy.mf6.ModflowGwedis( + gwe, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=1, + filename="{}.dis".format(gwename), + ) + + # Instantiating MODFLOW 6 heat transport initial temperatures + flopy.mf6.ModflowGweic( + gwe, strt=strt_temp, pname="IC-1", filename="{}.ic".format(gwename) + ) + + # Instantiating MODFLOW 6 heat transport advection package + if mixelm >= 0: + scheme = "UPSTREAM" + elif mixelm == -1: + scheme = "TVD" + else: + raise Exception() + flopy.mf6.ModflowGweadv( + gwe, scheme=scheme, filename="{}.adv".format(gwename) + ) + + # Instantiating MODFLOW 6 heat transport dispersion package + if al != 0: + flopy.mf6.ModflowGwedsp( + gwe, + alh=al, + ath1=ath1, + ktw=0.5918, + kts=0.2700, + filename="{}.dsp".format(gwename), + ) + + # Instantiating MODFLOW 6 heat transport mass storage package (formerly "reaction" package in MT3DMS) + flopy.mf6.ModflowGwemst( + gwe, + porosity=prsity, + cps=760.0, + packagedata=[cpw, rhow, lhv], + rhos=1500.0, + filename="{}.mst".format(gwename), + ) + + # Instantiating MODFLOW 6 heat transport source-sink mixing package + sourcerecarray = [("WEL-1", "AUX", "TEMPERATURE")] + flopy.mf6.ModflowGwessm( + gwe, + sources=sourcerecarray, + pname="SSM-1", + filename="{}.ssm".format(gwename), + ) + + # Instantiating MODFLOW 6 heat transport output control package + flopy.mf6.ModflowGweoc( + gwe, + budget_filerecord="{}.cbc".format(gwename), + temperature_filerecord="{}.ucn".format(gwename), + temperatureprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + printrecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + ) + + # Instantiating MODFLOW 6 flow-transport exchange mechanism + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename, + filename="{}.gwfgwe".format(name), + ) + + # ---------------------------------------------------- + # Instantiating MODFLOW 6 GWT model + # ---------------------------------------------------- + + # Instantiating MODFLOW 6 groundwater transport package to simulate heat + # transport the now "old-fashion way" + gwt = flopy.mf6.MFModel( + sim, + model_type="gwt6", + modelname=gwtname, + model_nam_file=f"{gwtname}.nam", + ) + gwt.name_file.save_flows = True + + # create iterative model solution and register the gwt model with it + imsgwt = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename=f"{gwtname}.ims", + ) + sim.register_ims_package(imsgwt, [gwt.name]) + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwtdis( + gwt, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=1, + filename=f"{gwtname}.dis", + ) + + # Instantiating MODFLOW 6 transport initial concentrations + flopy.mf6.ModflowGwtic( + gwt, strt=strt_temp, pname="IC-1", filename=f"{gwtname}.ic" + ) + + # Instantiating MODFLOW 6 transport advection package + flopy.mf6.ModflowGwtadv( + gwt, scheme=scheme, pname="ADV-1", filename=f"{gwtname}.adv" + ) + + # Instantiating MODFLOW 6 transport dispersion package + if al != 0: + flopy.mf6.ModflowGwtdsp( + gwt, + alh=al, + ath1=ath1, + diffc=dmcoef, + pname="DSP-1", + filename=f"{gwtname}.dsp", + ) + + # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) + flopy.mf6.ModflowGwtmst( + gwt, + porosity=prsity, + first_order_decay=False, + decay=None, + decay_sorbed=None, + sorption="linear", + bulk_density=rhob, + distcoef=kd, + filename=f"{gwtname}.mst", + ) + + # Instantiating MODFLOW 6 transport source-sink mixing package + sourcerecarray = [("WEL-1", "AUX", "TEMPERATURE")] + flopy.mf6.ModflowGwtssm( + gwt, sources=sourcerecarray, pname="SSM-1", filename=f"{gwtname}.ssm" + ) + + # Instantiating MODFLOW 6 transport output control package + flopy.mf6.ModflowGwtoc( + gwt, + budget_filerecord=f"{gwtname}.cbc", + concentration_filerecord=f"{gwtname}.ucn", + concentrationprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("CONCENTRATION", "LAST"), ("BUDGET", "LAST")], + printrecord=[("CONCENTRATION", "LAST"), ("BUDGET", "LAST")], + ) + + # Instantiating MODFLOW 6 flow-transport exchange mechanism + flopy.mf6.ModflowGwfgwt( + sim, + exgtype="GWF6-GWT6", + exgmnamea=gwfname, + exgmnameb=gwtname, + filename=f"{name}.gwfgwt", + ) + + return sim, None + + +def check_output(idx, test): + print("evaluating results...") + + # read transport results from GWE and GWT models + name = cases[idx] + gwename = "gwe_" + name + gwtname = "gwt_" + name + + fpth = os.path.join(test.workspace, f"{gwename}.ucn") + try: + # load temperatures + tobj = flopy.utils.HeadFile( + fpth, precision="double", text="TEMPERATURE" + ) + temps = tobj.get_alldata() + except: + assert False, f'could not load temperature data from "{fpth}"' + + fpth = os.path.join(test.workspace, f"{gwtname}.ucn") + try: + # load temperatures (though stored as "concentrations") + cobj = flopy.utils.HeadFile( + fpth, precision="double", text="CONCENTRATION" + ) + conc = cobj.get_alldata() + except: + assert False, f'could not load concentration data from "{fpth}"' + + # There are some differences between the GWE and GWT solutions. + # For the time being, the solutions are close in that they have + # the same shape; however, as the energy spreads outward in a + # radial flow field simulated by a rectalinear grid, there appears + # to be a halo that forms when differencing the GWE and GWT solutions. + # The maximum of that difference occurs along row 18 (0-based). The + # entire row containing the max difference is stored here for comparison + + diff_ans = np.array( + [ + 1.23070342e-08, + 1.45018687e-07, + 1.58995667e-06, + 1.57489411e-05, + 1.37313132e-04, + 1.02408164e-03, + 6.32680308e-03, + 3.12276340e-02, + 1.18381212e-01, + 3.32011273e-01, + 6.72832216e-01, + 9.91435902e-01, + 1.11198602e00, + 1.02310179e00, + 8.56220661e-01, + 7.61168469e-01, + 8.56220661e-01, + 1.02310179e00, + 1.11198602e00, + 9.91435902e-01, + 6.72832216e-01, + 3.32011273e-01, + 1.18381212e-01, + 3.12276340e-02, + 6.32680308e-03, + 1.02408164e-03, + 1.37313132e-04, + 1.57489411e-05, + 1.58995667e-06, + 1.45018687e-07, + 1.23070339e-08, + ] + ) + + diff = temps[0, 0] - conc[0, 0] + assert diff.max() <= diff_ans.max(), "Max difference should be <= 1.112" + assert np.allclose(diff[18, :], diff_ans), ( + "The difference between a GWE and equivalent GWT solution has " + "changed. Some investigation required." + ) + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(cases)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t), + ) + test.run() From b2886d78283b170953cf13e0641ca49514cfceca Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Mon, 15 Jan 2024 10:33:12 -0800 Subject: [PATCH 22/46] GWE-GWE exchanges now working. Other clean-up for code uniformity --- autotest/test_gwegwe_exchng_with_comp2gwt.py | 1086 ++++++++++++++++++ src/Distributed/VirtualGweModel.f90 | 9 + src/Model/Connection/GweGweConnection.f90 | 198 ++-- src/Model/Connection/GweInterfaceModel.f90 | 39 +- src/Model/GroundWaterEnergy/gwe1.f90 | 2 +- src/Model/GroundWaterEnergy/gwe1dsp1.f90 | 21 +- src/Model/ModelUtilities/GweInputData.f90 | 6 +- src/Model/TransportModel/tsp1.f90 | 99 +- 8 files changed, 1293 insertions(+), 167 deletions(-) create mode 100644 autotest/test_gwegwe_exchng_with_comp2gwt.py diff --git a/autotest/test_gwegwe_exchng_with_comp2gwt.py b/autotest/test_gwegwe_exchng_with_comp2gwt.py new file mode 100644 index 00000000000..3885ee8e6dc --- /dev/null +++ b/autotest/test_gwegwe_exchng_with_comp2gwt.py @@ -0,0 +1,1086 @@ +""" +Two-Dimensional Heat Transport (GWE) in a Radial Flow Field with Comparison to a MODFLOW 6 GWT model + +The purpose of this script is to test the new heat transport model developed +for MODFLOW 6. To that end, this problem uses the setup of the fifth MT3DMS +test problem but adapts it for heat. Moreover, this example also attempts to +adapt the fifth MT3DMS problem to a GWE-GWE example by splitting the model +domain diagonally in half. As such, MODFLOW 6 is setup using the new GWE +model with input parameters entered in their native units. The equivalent +values are calculated for "tricking" MT3DMS into heat transport. + +Cheap depiction of model in plan view follows (not to scale): + + +---------------------------------------------------------------------------+ + | | + +---+ | + | | + +---+ | + | | + +---+ +---+ | + | | | | + | +---+ +---+ | + | | | | + | +---+ +---+ "GWx-ur" | + | | | | + | +---+ +---+ | + | | | | + | +---+ +---+ | + | | | | + | +---+ +---+ | + | | | | + | +---+ +---+ | + | | | * <-- Inj. well with 100 deg C | + | +---+ +---+ water entering simulation> | + | | | Inj. well creates a radial | + | +---+ +---+ (outward) flow field. | + | | | | + | +---+ +---+ | + | | | | + | +---+ +---+ | + | | | | + | +---+ +---+ | + | | | | + | +---+ +---+ | + | | | | + | +---+ +---+ | + | "GWx-ll" | | | + | +---+ +---+ | + | | | | + | +---+ +---+ | + | | | | + | +---+ +---+ + | | + | +---+ + | | + | +---+ + | | + +---------------------------------------------------------------------------+ + +""" + + +import os +import sys + +sys.path.append(os.path.join("..", "common")) + +# Imports + +import matplotlib.pyplot as plt +import flopy +import numpy as np +import pytest + +from framework import TestFramework + +# from figspecs import USGSFigure + + +# Set figure properties specific to this problem +plotModel = plotSave = False +figure_size = (6, 4.5) + +cases = ["gwegwe-gwtgwt"] + +# Model units + +length_units = "meters" +time_units = "days" + +# Table + +nlay = 1 # Number of layers +nrow = 31 # Number of rows +ncol = 31 # Number of columns +delr = 10.0 # Column width ($m$) +delc = 10.0 # Row width ($m$) +delz = 1.0 # Layer thickness ($m$) +top = 0.0 # Top of the model ($m$) +prsity = 0.3 # Porosity +perlen = 27 # Simulation time ($days$) +k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$) +qwell = 100.0 # Volumetric injection rate ($m^3/d$) +twell = 100.0 # Concentration of injected water ($mg/L$) +al = 10.0 # Longitudinal dispersivity ($m$) +trpt = 1.0 # Ratio of transverse to longitudinal dispersitivity + +dmcoef = 3.2519e-7 +rhob = 1110.0 +sp2 = 0.0 # read, but not used in this problem +kd = 1.8168e-4 + +cpw = 4183.0 +cps = 760.0 +rhow = 1000.0 +rhos = 1500.0 +lhv = 2454.0 + +# Additional model input + +perlen = [27] +nper = len(perlen) +nstp = [27] +tsmult = [1.0] +strt_temp = 0.0 +dt0 = 0.3 +ath1 = al * trpt +botm = [top - delz] # Model geometry +k33 = k11 # Vertical hydraulic conductivity ($m/d$) +icelltype = 0 +mixelm = 0 +strt = np.zeros((nlay, nrow, ncol), dtype=float) + +# Active model domain +ibound_mf2k5 = np.ones((nlay, nrow, ncol), dtype=int) * -1 +ibound_mf2k5[:, 1 : nrow - 1, 1 : ncol - 1] = 1 +icbund = 1 +idomain = np.ones((nlay, nrow, ncol), dtype=int) +idomain_ll = idomain.copy() +for rw in np.arange(idomain_ll.shape[1]): # For each row + idomain_ll[0, rw, rw:] = 0 + +idomain_ur = 1 - idomain_ll + +# Work up the exchanges +# Exchange data for GWF-GWF and GWE-GWE +exgdata = [] + +# Stair-step down the shared interface +for i in np.arange(nrow): + for j in np.arange(ncol): + # Checking between rows (i.e., the vertical (y-axis) direction) + if i < (nrow - 1): + # Check to see if two touching cells in adjacent models are both active + # Check + if idomain_ur[0, i, j] > 0 and idomain_ll[0, i + 1, j] > 0: + exgdata.append( + ((0, i, j), (0, i + 1, j), 1, 5, 5, 10, 270.0, 10.0) + ) + if j < (ncol - 1): + if idomain_ur[0, i, j + 1] > 0 and idomain_ll[0, i, j] > 0: + exgdata.append( + ((0, i, j + 1), (0, i, j), 1, 5, 5, 10, 180.0, 10.0) + ) + + +# Boundary conditions +# MF2K5 pumping info: + +welspd = {0: [[0, 15, 15, qwell]]} # Well pumping info for MF2K5 +spd = {0: [0, 15, 15, twell, -1]} # Well pupming info for MT3DMS + +# MF6 pumping information + +# (k, i, j), flow, temperature +spd_mf6 = {0: [[(0, 15, 15), qwell, twell]]} + +# MF6 constant head boundaries: + +chdspd_ur = [] +chdspd_ll = [] +# Loop through the left & right sides. +for i in np.arange(nrow): + if i == 0: + # A special case, this one cell on the left boundary happens to fall in the + # in the "ur" model + chdspd_ur.append([(0, i, 0), strt[0, i, 0]]) + else: + chdspd_ll.append([(0, i, 0), strt[0, i, 0], 0.0]) + + chdspd_ur.append([(0, i, ncol - 1), strt[0, i, ncol - 1]]) + +# Loop through the top & bottom while omitting the corner cells +for j in np.arange(1, ncol - 1): + chdspd_ur.append([(0, 0, j), strt[0, 0, j]]) + chdspd_ll.append([(0, nrow - 1, j), strt[0, nrow - 1, j], 0.0]) + +chdspd_ur = {0: chdspd_ur} +chdspd_ll = {0: chdspd_ll} + +# Solver settings + +nouter, ninner = 100, 300 +hclose, rclose, relax = 1e-8, 1e-8, 1.0 +percel = 1.0 # HMOC parameters +itrack = 3 +wd = 0.5 +dceps = 1.0e-5 +nplane = 1 +npl = 0 +nph = 16 +npmin = 2 +npmax = 32 +dchmoc = 1.0e-3 +nlsink = nplane +npsink = nph + +# Static temporal data used by TDIS file + +tdis_rc = [] +tdis_rc.append((perlen, nstp, 1.0)) + +# Model names +gwfname_up = "gwf-ur" +gwfname_lo = "gwf-ll" +gwename_up = "gwe-ur" +gwename_lo = "gwe-ll" +gwtname_up = "gwt-ur" +gwtname_lo = "gwt-ll" + +# Functions to build, write, and run models +# +# MODFLOW 6 flopy simulation object (sim) is returned if building the model + + +def build_models(idx, test): + + # ----------- + # MODFLOW 6 + # ----------- + + ws = test.workspace + name = cases[idx] + + sim = flopy.mf6.MFSimulation( + sim_name=name, sim_ws=ws, exe_name="mf6", version="mf6" + ) + + # Instantiating MODFLOW 6 time discretization + tdis_rc = [] + for i in range(nper): + tdis_rc.append((perlen[i], nstp[i], tsmult[i])) + + flopy.mf6.ModflowTdis( + sim, nper=nper, perioddata=tdis_rc, time_units=time_units + ) + + # add both solutions to the simulation + add_flow(sim) + add_energy(sim) + add_transport(sim) + + # Instantiating MODFLOW 6 flow-energy transport exchange mechanism + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname_up, + exgmnameb=gwename_up, + filename="{}.gwfgwe".format("upper"), + ) + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname_lo, + exgmnameb=gwename_lo, + filename="{}.gwfgwe".format("lower"), + ) + + # Next, instantiate MODFLOW 6 flow-solute transport exchange mechanism + flopy.mf6.ModflowGwfgwt( + sim, + exgtype="GWF6-GWT6", + exgmnamea=gwfname_up, + exgmnameb=gwtname_up, + filename="{}.gwfgwt".format("upper"), + ) + flopy.mf6.ModflowGwfgwt( + sim, + exgtype="GWF6-GWT6", + exgmnamea=gwfname_lo, + exgmnameb=gwtname_lo, + filename="{}.gwfgwt".format("lower"), + ) + + return sim + + +# Instatiate the upper and lower flow models +def add_flow(sim): + # Instantiating MODFLOW 6 solver for flow model + imsgwf = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="CG", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format("gwfsolver"), + ) + + gwf_upper = add_upper_gwfmodel(sim) + gwf_lower = add_lower_gwfmodel(sim) + + sim.register_ims_package(imsgwf, [gwf_upper.name, gwf_lower.name]) + + # Add the exchange data + gwfgwf = flopy.mf6.ModflowGwfgwf( + sim, + exgtype="GWF6-GWF6", + nexg=len(exgdata), + exgmnamea=gwf_upper.name, + exgmnameb=gwf_lower.name, + exchangedata=exgdata, + xt3d=False, + print_flows=True, + auxiliary=["ANGLDEGX", "CDIST"], + filename="{}.gwfgwf".format("exchng"), + ) + + +# Create the upper GWF model +def add_upper_gwfmodel(sim): + mname = gwfname_up + + # Instantiating MODFLOW 6 groundwater flow model + gwf = flopy.mf6.ModflowGwf( + sim, + modelname=mname, + save_flows=True, + model_nam_file="{}.nam".format(mname), + ) + + # Instantiating MODFLOW 6 discretization package + flopy.mf6.ModflowGwfdis( + gwf, + length_units=length_units, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=idomain_ur, + filename="{}.dis".format(mname), + ) + + # Instantiating MODFLOW 6 node-property flow package + flopy.mf6.ModflowGwfnpf( + gwf, + save_flows=False, + icelltype=icelltype, + k=k11, + k33=k33, + save_specific_discharge=True, + filename="{}.npf".format(mname), + ) + + # Instantiating MODFLOW 6 storage package + # (steady flow conditions, so no actual storage, using to print values in .lst file) + flopy.mf6.ModflowGwfsto(gwf, ss=0, sy=0, filename="{}.sto".format(mname)) + + # Instantiating MODFLOW 6 initial conditions package for flow model + flopy.mf6.ModflowGwfic(gwf, strt=strt, filename="{}.ic".format(mname)) + + # Instantiating MODFLOW 6 constant head package + flopy.mf6.ModflowGwfchd( + gwf, + maxbound=len(chdspd_ur), + stress_period_data=chdspd_ur, + save_flows=False, + pname="CHD-1", + filename="{}.chd".format(mname), + ) + + # Instantiate the wel package + flopy.mf6.ModflowGwfwel( + gwf, + print_input=True, + print_flows=True, + stress_period_data=spd_mf6, + save_flows=False, + auxiliary="TEMPERATURE", + pname="WEL-1", + filename="{}.wel".format(mname), + ) + + # Instantiating MODFLOW 6 output control package for flow model + flopy.mf6.ModflowGwfoc( + gwf, + head_filerecord="{}.hds".format(mname), + budget_filerecord="{}.bud".format(mname), + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "LAST"), ("BUDGET", "LAST")], + printrecord=[("HEAD", "LAST"), ("BUDGET", "LAST")], + ) + + return gwf + + +# Create the lower GWF model +def add_lower_gwfmodel(sim): + mname = gwfname_lo + + # Instantiating MODFLOW 6 groundwater flow model + gwf = flopy.mf6.ModflowGwf( + sim, + modelname=mname, + save_flows=True, + model_nam_file="{}.nam".format(mname), + ) + + # Instantiating MODFLOW 6 discretization package + flopy.mf6.ModflowGwfdis( + gwf, + length_units=length_units, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=idomain_ll, + filename="{}.dis".format(mname), + ) + + # Instantiating MODFLOW 6 initial conditions package for flow model + flopy.mf6.ModflowGwfic(gwf, strt=strt, filename="{}.ic".format(mname)) + + # Instantiating MODFLOW 6 node-property flow package + flopy.mf6.ModflowGwfnpf( + gwf, + save_flows=False, + icelltype=icelltype, + k=k11, + k33=k33, + save_specific_discharge=True, + filename="{}.npf".format(mname), + ) + + # Instantiating MODFLOW 6 storage package + # (steady flow conditions, so no actual storage, using to print values in .lst file) + flopy.mf6.ModflowGwfsto(gwf, ss=0, sy=0, filename="{}.sto".format(mname)) + + # Instantiating MODFLOW 6 constant head package + flopy.mf6.ModflowGwfchd( + gwf, + maxbound=len(chdspd_ll), + stress_period_data=chdspd_ll, + auxiliary="TEMPERATURE", + save_flows=False, + pname="CHD-1", + filename="{}.chd".format(mname), + ) + + # Instantiating MODFLOW 6 output control package for flow model + flopy.mf6.ModflowGwfoc( + gwf, + head_filerecord="{}.hds".format(mname), + budget_filerecord="{}.bud".format(mname), + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "LAST"), ("BUDGET", "LAST")], + printrecord=[("HEAD", "LAST"), ("BUDGET", "LAST")], + ) + + return gwf + + +# Create the upper and lower GWE models +def add_energy(sim): + # create iterative model solution and register the gwt model with it + imsgwe = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format("gwesolver"), + ) + + # Set the advection scheme, it is needed by both gwe model instantiation and gwegwe exchange + if mixelm >= 0: + scheme = "UPSTREAM" + elif mixelm == -1: + scheme = "TVD" + else: + raise Exception() + + # Add transport models + gwe_upper = add_upper_gwemodel(sim, scheme) + gwe_lower = add_lower_gwemodel(sim, scheme) + + sim.register_ims_package(imsgwe, [gwe_upper.name, gwe_lower.name]) + + # Create energy transport to energy transport coupling + assert exgdata is not None + flopy.mf6.ModflowGwegwe( + sim, + exgtype="GWE6-GWE6", + gwfmodelname1=gwfname_up, + gwfmodelname2=gwfname_lo, + adv_scheme=scheme, + nexg=len(exgdata), + exgmnamea=gwe_upper.name, + exgmnameb=gwe_lower.name, + exchangedata=exgdata, + auxiliary=["ANGLDEGX", "CDIST"], + filename="{}.gwegwe".format("exchng"), + ) + + return sim + + +# Create the outer GWT model +def add_upper_gwemodel(sim, scheme): + # Instantiating MODFLOW 6 groundwater heat transport package + mname = gwename_up + + gwe = flopy.mf6.MFModel( + sim, + model_type="gwe6", + modelname=mname, + model_nam_file="{}.nam".format(mname), + ) + gwe.name_file.save_flows = True + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwedis( + gwe, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=idomain_ur, + filename="{}.dis".format(mname), + ) + + # Instantiating MODFLOW 6 heat transport initial temperature + flopy.mf6.ModflowGweic(gwe, strt=strt_temp, filename="{}.ic".format(mname)) + + flopy.mf6.ModflowGweadv( + gwe, scheme=scheme, filename="{}.adv".format(mname) + ) + + # Instantiating MODFLOW 6 heat transport dispersion package + if al != 0: + flopy.mf6.ModflowGwedsp( + gwe, + alh=al, + ath1=ath1, + ktw=0.5918, + kts=0.2700, + filename="{}.dsp".format(mname), + ) + + # Instantiating MODFLOW 6 transport mass storage package + flopy.mf6.ModflowGwemst( + gwe, + porosity=prsity, + cps=cps, + rhos=rhos, + packagedata=[cpw, rhow, lhv], + pname="MST-UP", + filename="{}.mst".format(mname), + ) + + # Instantiating MODFLOW 6 heat transport source-sink mixing package + sourcerecarray = [("WEL-1", "AUX", "TEMPERATURE")] + flopy.mf6.ModflowGwessm( + gwe, sources=sourcerecarray, filename="{}.ssm".format(mname) + ) + + # Instantiating MODFLOW 6 heat transport output control package + flopy.mf6.ModflowGweoc( + gwe, + budget_filerecord="{}.cbc".format(mname), + temperature_filerecord="{}.ucn".format(mname), + temperatureprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + printrecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + ) + + return gwe + + +# Create the lower GWE model +def add_lower_gwemodel(sim, scheme): + # Instantiating MODFLOW 6 groundwater heat transport package + mname = gwename_lo + + gwe = flopy.mf6.MFModel( + sim, + model_type="gwe6", + modelname=mname, + model_nam_file="{}.nam".format(mname), + ) + gwe.name_file.save_flows = True + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwedis( + gwe, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=idomain_ll, + filename="{}.dis".format(mname), + ) + + # Instantiating MODFLOW 6 heat transport initial temperature + flopy.mf6.ModflowGweic(gwe, strt=strt_temp, filename="{}.ic".format(mname)) + + # Instantiating MODFLOW 6 heat transport advection package (lower model) + flopy.mf6.ModflowGweadv( + gwe, scheme=scheme, filename="{}.adv".format(mname) + ) + + # Instantiating MODFLOW 6 heat transport dispersion package + if al != 0: + flopy.mf6.ModflowGwedsp( + gwe, + alh=al, + ath1=ath1, + ktw=0.5918, + kts=0.2700, + filename="{}.dsp".format(mname), + ) + + # Instantiating MODFLOW 6 transport mass storage package + flopy.mf6.ModflowGwemst( + gwe, + porosity=prsity, + cps=cps, + rhos=rhos, + packagedata=[cpw, rhow, lhv], + pname="MST-LO", + filename="{}.mst".format(mname), + ) + + # Instantiating MODFLOW 6 heat transport source-sink mixing package + sourcerecarray = [("CHD-1", "AUX", "TEMPERATURE")] + flopy.mf6.ModflowGwessm( + gwe, sources=sourcerecarray, filename="{}.ssm".format(mname) + ) + + # Instantiating MODFLOW 6 heat transport output control package + # flopy.mf6.ModflowGweoc( + # gwe, + # budget_filerecord="{}.cbc".format(mname), + # temperature_filerecord="{}.ucn".format(mname), + # temperatureprintrecord=[ + # ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + # ], + # saverecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + # printrecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + # ) + flopy.mf6.ModflowGweoc( + gwe, + budget_filerecord="{}.cbc".format(mname), + temperature_filerecord="{}.ucn".format(mname), + temperatureprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + printrecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + ) + + return gwe + + +# Add an equivalent solute transport model for comparing to +def add_transport(sim): + # create iterative model solution and register the gwt model with it + imsgwt = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format("gwtsolver"), + ) + + # Set the advection scheme, it is needed by both gwe model instantiation and gwegwe exchange + if mixelm >= 0: + scheme = "UPSTREAM" + elif mixelm == -1: + scheme = "TVD" + else: + raise Exception() + + # Add transport models + gwt_upper = add_upper_gwtmodel(sim, scheme) + gwt_lower = add_lower_gwtmodel(sim, scheme) + + sim.register_ims_package(imsgwt, [gwt_upper.name, gwt_lower.name]) + + # Create transport-transport coupling + assert exgdata is not None + flopy.mf6.ModflowGwtgwt( + sim, + exgtype="GWT6-GWT6", + gwfmodelname1=gwfname_up, + gwfmodelname2=gwfname_lo, + adv_scheme=scheme, + nexg=len(exgdata), + exgmnamea=gwt_upper.name, + exgmnameb=gwt_lower.name, + exchangedata=exgdata, + auxiliary=["ANGLDEGX", "CDIST"], + filename="{}.gwtgwt".format("exchng"), + ) + + return sim + + +# Create the upper GWT model +def add_upper_gwtmodel(sim, scheme): + # Instantiating MODFLOW 6 groundwater solute transport + # model for comparison with GWE + mname = gwtname_up + + gwt = flopy.mf6.MFModel( + sim, + model_type="gwt6", + modelname=mname, + model_nam_file="{}.nam".format(mname), + ) + gwt.name_file.save_flows = True + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwtdis( + gwt, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=idomain_ur, + filename="{}.dis".format(mname), + ) + + # Instantiating MODFLOW 6 heat transport initial temperature + flopy.mf6.ModflowGwtic(gwt, strt=strt_temp, filename="{}.ic".format(mname)) + + flopy.mf6.ModflowGwtadv( + gwt, scheme=scheme, filename="{}.adv".format(mname) + ) + + # Instantiating MODFLOW 6 heat transport dispersion package + if al != 0: + flopy.mf6.ModflowGwtdsp( + gwt, + alh=al, + ath1=ath1, + diffc=dmcoef, + filename="{}.dsp".format(mname), + ) + + # Instantiating MODFLOW 6 transport mass storage package + flopy.mf6.ModflowGwtmst( + gwt, + sorption="LINEAR", + porosity=prsity, + bulk_density=1110.0, + distcoef=kd, + filename="{}.mst".format(mname), + ) + + # Instantiating MODFLOW 6 source-sink mixing package transport + sourcerecarray = [("WEL-1", "AUX", "TEMPERATURE")] + flopy.mf6.ModflowGwtssm( + gwt, sources=sourcerecarray, filename="{}.ssm".format(mname) + ) + + flopy.mf6.ModflowGwtoc( + gwt, + budget_filerecord="{}.cbc".format(mname), + concentration_filerecord="{}.ucn".format(mname), + concentrationprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("CONCENTRATION", "LAST"), ("BUDGET", "LAST")], + printrecord=[("CONCENTRATION", "LAST"), ("BUDGET", "LAST")], + ) + + return gwt + + +# Create the lower GWT model +def add_lower_gwtmodel(sim, scheme): + # Instantiating MODFLOW 6 groundwater solute transport package + mname = gwtname_lo + + gwt = flopy.mf6.MFModel( + sim, + model_type="gwt6", + modelname=mname, + model_nam_file="{}.nam".format(mname), + ) + gwt.name_file.save_flows = True + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwtdis( + gwt, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=idomain_ll, + filename="{}.dis".format(mname), + ) + + # Instantiating MODFLOW 6 solute transport initial concentration (temperature) + flopy.mf6.ModflowGwtic(gwt, strt=strt_temp, filename="{}.ic".format(mname)) + + # Instantiating MODFLOW 6 solute transport advection package (lower model) + flopy.mf6.ModflowGwtadv( + gwt, scheme=scheme, filename="{}.adv".format(mname) + ) + + # Instantiating MODFLOW 6 heat transport dispersion package + if al != 0: + flopy.mf6.ModflowGwtdsp( + gwt, + alh=al, + ath1=ath1, + diffc=dmcoef, + filename="{}.dsp".format(mname), + ) + + # Instantiating MODFLOW 6 transport mass storage package + flopy.mf6.ModflowGwtmst( + gwt, + sorption="LINEAR", + porosity=prsity, + bulk_density=rhob, + distcoef=kd, + filename="{}.mst".format(mname), + ) + + # Instantiating MODFLOW 6 solute transport source-sink mixing package + sourcerecarray = [("CHD-1", "AUX", "TEMPERATURE")] + flopy.mf6.ModflowGwtssm( + gwt, sources=sourcerecarray, filename="{}.ssm".format(mname) + ) + + # Instantiating MODFLOW 6 solute transport output control package + flopy.mf6.ModflowGwtoc( + gwt, + budget_filerecord="{}.cbc".format(mname), + concentration_filerecord="{}.ucn".format(mname), + concentrationprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("CONCENTRATION", "LAST"), ("BUDGET", "LAST")], + printrecord=[("CONCENTRATION", "LAST"), ("BUDGET", "LAST")], + ) + + return gwt + + +def fict_model(out_pth): + # Instantiate the MODFLOW model + mf = flopy.modflow.Modflow( + modelname="dummy_mod", model_ws=out_pth, exe_name="mfnwt" + ) + + # Instantiate discretization package + # units: itmuni=4 (days), lenuni=2 (m) + flopy.modflow.ModflowDis( + mf, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + nper=nper, + nstp=nstp, + perlen=perlen, + itmuni=4, + lenuni=2, + ) + + return mf + + +# Function to plot the model results +def check_output(idx, test): + print("evaluating results...") + + out_pth = test.workspace + # read transport results from GWE and GWT models + fpth = os.path.join(out_pth, gwename_up + ".ucn") + turobj = flopy.utils.HeadFile(fpth, text="temperature") + temp_ur = turobj.get_alldata() + + fpth = os.path.join(out_pth, gwename_lo + ".ucn") + tllobj = flopy.utils.HeadFile(fpth, text="temperature") + temp_ll = tllobj.get_alldata() + + fpth = os.path.join(out_pth, gwtname_up + ".ucn") + curobj = flopy.utils.HeadFile(fpth, text="concentration") + conc_ur = curobj.get_alldata() + + fpth = os.path.join(out_pth, gwtname_lo + ".ucn") + cllobj = flopy.utils.HeadFile(fpth, text="concentration") + conc_ll = cllobj.get_alldata() + + # Stitch together the temperatures from the upper-right and lower-left models + tm = k = 0 + stitched_temps = np.zeros((nrow, ncol)) + for i in np.arange(nrow): + for j in np.arange(ncol): + if idomain_ur[k, i, j] > 0: + stitched_temps[i, j] = temp_ur[tm, k, i, j] + elif idomain_ll[k, i, j] > 0: + stitched_temps[i, j] = temp_ll[tm, k, i, j] + + # Stitch together the "concentrations" (which represent temperatures) from the upper-right and lower-left models + tm = k = 0 + stitched_conc = np.zeros((nrow, ncol)) + for i in np.arange(nrow): + for j in np.arange(ncol): + if idomain_ur[k, i, j] > 0: + stitched_conc[i, j] = conc_ur[tm, k, i, j] + elif idomain_ll[k, i, j] > 0: + stitched_conc[i, j] = conc_ll[tm, k, i, j] + + diff_ans = np.array( + [ + 1.72851147e-06, + 1.02569324e-05, + 6.03854917e-05, + 3.24474242e-04, + 1.55996452e-03, + 6.58075914e-03, + 2.38852818e-02, + 7.31492711e-02, + 1.85545249e-01, + 3.83629779e-01, + 6.39985972e-01, + 8.62111344e-01, + 9.55210100e-01, + 9.08020311e-01, + 7.95058119e-01, + 7.17466620e-01, + 7.95058119e-01, + 9.08020311e-01, + 9.55210110e-01, + 8.62111344e-01, + 6.39985972e-01, + 3.83629779e-01, + 1.85545249e-01, + 7.31492710e-02, + 2.38852818e-02, + 6.58075913e-03, + 1.55996452e-03, + 3.24474242e-04, + 6.03854915e-05, + 1.02569324e-05, + 1.72851146e-06, + ] + ) + + diff = stitched_temps - stitched_conc + assert diff.max() <= diff_ans.max(), "Max difference should be <= 0.95" + assert np.allclose(diff[18, :], diff_ans), ( + "The difference between a GWE and equivalent GWT solution has " + "changed. Some investigation required." + ) + + # Ensure that all 6 models are present within the simulation + mf6_sim = flopy.mf6.MFSimulation.load(sim_ws=test.workspace) + models = [] + for mname in mf6_sim.model_names: + models.append(mf6_sim.get_model(mname)) + assert ( + len(models) == 6 + ), "Unexpected number of models encountered while loading simulation" + + if plotModel: + # Create figure for scenario + sim_name = cases[idx] + mod = mf6_sim.get_model(mname) + + plt.rcParams["lines.dashed_pattern"] = [5.0, 5.0] + + fig = plt.figure(figsize=figure_size, dpi=300, tight_layout=True) + ax2 = fig.add_subplot(1, 1, 1, aspect="equal") + + # temp1 = stitched_conc[:, :] + # temp2 = stitched_temps[:, :] + + levels = [0.2, 5, 20, 50, 90] + + mod4plot = fict_model(out_pth) + mm = flopy.plot.PlotMapView(model=mod4plot) + mm.plot_grid(color=".5", alpha=0.2) + mm.plot_ibound(ibound=idomain_ur, color_noflow="grey", alpha=0.1) + cs1 = mm.contour_array(stitched_conc, levels=levels, colors="r") + plt.clabel(cs1, inline=1, fontsize=10) + cs2 = mm.contour_array( + stitched_temps, levels=levels, colors="k", linestyles=":" + ) + plt.clabel(cs2, inline=1, fontsize=10) + labels = ["GWT", "GWE"] + lines = [cs1.collections[0], cs2.collections[0]] + + plt.xlabel("Distance Along X-Axis, in meters") + plt.ylabel("Distance Along Y-Axis, in meters") + title = "Comparison of GWT and GWE isoconcentration lines" + ax2.legend(lines, labels, loc="upper right") + + # Add labels to the plot + # style = dict(size=10, color='black') + # ax2.text(235, 140, "Location of x-section \nshown in Fig. x", **style) + + # save figure + if plotSave: + fpth = os.path.join( + out_pth, + "{}".format(sim_name + "-planView.png"), + ) + fig.savefig(fpth) + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(cases)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t), + ) + test.run() diff --git a/src/Distributed/VirtualGweModel.f90 b/src/Distributed/VirtualGweModel.f90 index 6df7a32b666..d93d59c2798 100644 --- a/src/Distributed/VirtualGweModel.f90 +++ b/src/Distributed/VirtualGweModel.f90 @@ -20,6 +20,8 @@ module VirtualGweModelModule type(VirtualDbl1dType), pointer :: dsp_ath1 => null() type(VirtualDbl1dType), pointer :: dsp_ath2 => null() type(VirtualDbl1dType), pointer :: dsp_atv => null() + type(VirtualDbl1dType), pointer :: dsp_ktw => null() + type(VirtualDbl1dType), pointer :: dsp_kts => null() ! FMI type(VirtualDbl1dType), pointer :: fmi_gwfhead => null() type(VirtualDbl1dType), pointer :: fmi_gwfsat => null() @@ -86,6 +88,8 @@ subroutine init_virtual_data(this) call this%set(this%dsp_ath1%base(), 'ATH1', 'DSP', MAP_NODE_TYPE) call this%set(this%dsp_ath2%base(), 'ATH2', 'DSP', MAP_NODE_TYPE) call this%set(this%dsp_atv%base(), 'ATV', 'DSP', MAP_NODE_TYPE) + call this%set(this%dsp_ktw%base(), 'KTW', 'DSP', MAP_NODE_TYPE) + call this%set(this%dsp_kts%base(), 'KTS', 'DSP', MAP_NODE_TYPE) call this%set(this%fmi_gwfhead%base(), 'GWFHEAD', 'FMI', MAP_NODE_TYPE) call this%set(this%fmi_gwfsat%base(), 'GWFSAT', 'FMI', MAP_NODE_TYPE) call this%set(this%fmi_gwfspdis%base(), 'GWFSPDIS', 'FMI', MAP_NODE_TYPE) @@ -134,6 +138,7 @@ subroutine vgwe_prepare_stage(this, stage) call this%map(this%dsp_ath1%base(), nr_nodes, (/STG_BFR_CON_AR/)) call this%map(this%dsp_ath2%base(), nr_nodes, (/STG_BFR_CON_AR/)) call this%map(this%dsp_atv%base(), nr_nodes, (/STG_BFR_CON_AR/)) + call this%map(this%dsp_ktw%base(), nr_nodes, (/STG_BFR_CON_AR/)) end if call this%map(this%fmi_gwfhead%base(), nr_nodes, (/STG_BFR_EXG_AD/)) @@ -160,6 +165,8 @@ subroutine allocate_data(this) allocate (this%dsp_ath1) allocate (this%dsp_ath2) allocate (this%dsp_atv) + allocate (this%dsp_ktw) + allocate (this%dsp_kts) allocate (this%fmi_gwfhead) allocate (this%fmi_gwfsat) allocate (this%fmi_gwfspdis) @@ -181,6 +188,8 @@ subroutine deallocate_data(this) deallocate (this%dsp_ath1) deallocate (this%dsp_ath2) deallocate (this%dsp_atv) + deallocate (this%dsp_ktw) + deallocate (this%dsp_kts) deallocate (this%fmi_gwfhead) deallocate (this%fmi_gwfsat) deallocate (this%fmi_gwfspdis) diff --git a/src/Model/Connection/GweGweConnection.f90 b/src/Model/Connection/GweGweConnection.f90 index 8f4acc8d94d..57b2a6e6c1e 100644 --- a/src/Model/Connection/GweGweConnection.f90 +++ b/src/Model/Connection/GweGweConnection.f90 @@ -80,35 +80,37 @@ module GweGweConnectionModule !> @brief Basic construction of the connection !< subroutine gweGweConnection_ctor(this, model, gweEx) + ! -- modules use InputOutputModule, only: openfile + ! -- dummy class(GweGweConnectionType) :: this !< the connection class(NumericalModelType), pointer :: model !< the model owning this connection, !! this must be a GweModelType class(DisConnExchangeType), pointer :: gweEx !< the GWE-GWE exchange the interface model is created for - ! local + ! -- local character(len=LINELENGTH) :: fname character(len=LENCOMPONENTNAME) :: name class(*), pointer :: objPtr logical(LGP) :: write_ifmodel_listfile = .false. - + ! objPtr => model this%gweModel => CastAsGweModel(objPtr) objPtr => gweEx this%gweExchange => CastAsGweExchange(objPtr) - + ! if (gweEx%v_model1%is_local .and. gweEx%v_model2%is_local) then this%owns_exchange = associated(model, gweEx%model1) else this%owns_exchange = .true. end if - + ! if (gweEx%v_model1 == model) then write (name, '(a,i0)') 'GWECON1_', gweEx%id else write (name, '(a,i0)') 'GWECON2_', gweEx%id end if - - ! .lst file for interface model + ! + ! -- .lst file for interface model if (write_ifmodel_listfile) then fname = trim(name)//'.im.lst' call openfile(this%iout, 0, fname, 'LIST', filstat_opt='REPLACE') @@ -116,61 +118,63 @@ subroutine gweGweConnection_ctor(this, model, gweEx) trim(this%gweModel%name), 'from exchange ', & trim(gweEx%name) end if - - ! first call base constructor + ! + ! -- First call base constructor call this%SpatialModelConnectionType%spatialConnection_ctor(model, & gweEx, & name) - + ! call this%allocate_scalars() this%typename = 'GWE-GWE' this%iIfaceAdvScheme = 0 this%iIfaceXt3d = 0 this%exgflowSign = 1 - + ! allocate (this%gweInterfaceModel) this%interface_model => this%gweInterfaceModel - + ! end subroutine gweGweConnection_ctor !> @brief Allocate scalar variables for this connection !< subroutine allocate_scalars(this) + ! -- dummy class(GweGweConnectionType) :: this !< the connection - + ! call mem_allocate(this%iIfaceAdvScheme, 'IADVSCHEME', this%memoryPath) call mem_allocate(this%iIfaceXt3d, 'IXT3D', this%memoryPath) call mem_allocate(this%exgflowSign, 'EXGFLOWSIGN', this%memoryPath) - + ! end subroutine allocate_scalars !> @brief define the GWE-GWE connection !< subroutine gwegwecon_df(this) + ! -- dummy class(GweGweConnectionType) :: this !< the connection - ! local + ! -- local character(len=LENCOMPONENTNAME) :: imName - ! determine advection scheme (the GWE-GWE exchange - ! has been read at this point) + ! -- Determine advection scheme (the GWE-GWE exchange + ! has been read at this point) this%iIfaceAdvScheme = this%gweExchange%iAdvScheme ! - ! determine xt3d setting on interface + ! -- Determine xt3d setting on interface this%iIfaceXt3d = this%gweExchange%ixt3d - ! turn off when off in the owning model + ! -- Turn off when off in the owning model if (this%gweModel%indsp > 0) then this%iIfaceXt3d = this%gweModel%dsp%ixt3d end if - ! determine the required size of the interface model grid + ! -- Determine the required size of the interface model grid call this%setGridExtent() - ! now set up the GridConnection + ! -- Now set up the GridConnection call this%spatialcon_df() - ! we have to 'catch up' and create the interface model - ! here, then the remainder of this routine will be define + ! -- We have to 'catch up' and create the interface model + ! here, then the remainder of this routine will be define if (this%prim_exchange%v_model1 == this%owner) then write (imName, '(a,i0)') 'GWEIM1_', this%gweExchange%id else @@ -189,14 +193,14 @@ subroutine gwegwecon_df(this) call this%allocate_arrays() call this%gweInterfaceModel%allocate_fmi() - ! connect X, RHS, IBOUND, and flowja + ! -- Connect X, RHS, IBOUND, and flowja call this%spatialcon_setmodelptrs() - ! connect pointers (used by BUY) + ! -- Connect pointers (used by BUY) this%conc => this%gweInterfaceModel%x this%icbound => this%gweInterfaceModel%ibound - ! add connections from the interface model to solution matrix + ! -- Add connections from the interface model to solution matrix call this%spatialcon_connect() end subroutine gwegwecon_df @@ -204,23 +208,24 @@ end subroutine gwegwecon_df !> @brief Configure distributed variables for this interface model !< subroutine cfg_dist_vars(this) + ! -- dummy class(GweGweConnectionType) :: this !< the connection - + ! call this%cfg_dv('X', '', SYNC_NDS, & (/STG_BFR_CON_AR, STG_BFR_EXG_AD, STG_BFR_EXG_CF/)) call this%cfg_dv('IBOUND', '', SYNC_NDS, (/STG_BFR_CON_AR/)) call this%cfg_dv('TOP', 'DIS', SYNC_NDS, (/STG_BFR_CON_AR/)) call this%cfg_dv('BOT', 'DIS', SYNC_NDS, (/STG_BFR_CON_AR/)) call this%cfg_dv('AREA', 'DIS', SYNC_NDS, (/STG_BFR_CON_AR/)) - !if (this%gweInterfaceModel%dsp%idiffc > 0) then - ! call this%cfg_dv('DIFFC', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) - !end if + ! if (this%gweInterfaceModel%dsp%idisp > 0) then call this%cfg_dv('ALH', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) call this%cfg_dv('ALV', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) call this%cfg_dv('ATH1', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) call this%cfg_dv('ATH2', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) call this%cfg_dv('ATV', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('KTW', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('KTS', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) end if call this%cfg_dv('GWFHEAD', 'FMI', SYNC_NDS, (/STG_BFR_EXG_AD/)) call this%cfg_dv('GWFSAT', 'FMI', SYNC_NDS, (/STG_BFR_EXG_AD/)) @@ -228,11 +233,11 @@ subroutine cfg_dist_vars(this) call this%cfg_dv('GWFFLOWJA', 'FMI', SYNC_CON, (/STG_BFR_EXG_AD/)) call this%cfg_dv('GWFFLOWJA', 'FMI', SYNC_EXG, (/STG_BFR_EXG_AD/), & exg_var_name='GWFSIMVALS') - ! fill porosity from mst packages, needed for dsp + ! -- Fill porosity from mst packages, needed for dsp if (this%gweModel%indsp > 0 .and. this%gweModel%inmst > 0) then call this%cfg_dv('POROSITY', 'MST', SYNC_NDS, (/STG_AFT_CON_AR/)) end if - + ! end subroutine cfg_dist_vars !> @brief Allocate array variables for this connection @@ -248,13 +253,14 @@ end subroutine allocate_arrays !> @brief Set required extent of the interface grid from !< the configuration subroutine setGridExtent(this) + ! -- dummy class(GweGweConnectionType) :: this !< the connection - ! local + ! -- local logical(LGP) :: hasAdv, hasDsp - + ! hasAdv = this%gweModel%inadv > 0 hasDsp = this%gweModel%indsp > 0 - + ! if (hasAdv) then if (this%iIfaceAdvScheme == 2) then this%exg_stencil_depth = 2 @@ -263,7 +269,7 @@ subroutine setGridExtent(this) end if end if end if - + ! if (hasDsp) then if (this%iIfaceXt3d > 0) then this%exg_stencil_depth = 2 @@ -272,7 +278,7 @@ subroutine setGridExtent(this) end if end if end if - + ! end subroutine setGridExtent !> @brief allocate and read/set the connection's data structures @@ -285,13 +291,25 @@ subroutine gwegwecon_ar(this) ! called, which is why we do it here call this%validateConnection() - ! allocate and read base + ! -- Allocate and read base call this%spatialcon_ar() ! ... and now the interface model call this%gweInterfaceModel%model_ar() - ! AR the movers and obs through the exchange + ! -- Set a pointer in the interface model to the gwecommon data + if (this%gweModel%inmst > 0) then + this%gweInterfaceModel%gwecommon%gwecpw = this%gweModel%gwecommon%gwecpw + this%gweInterfaceModel%gwecommon%gwerhow = this%gweModel%gwecommon%gwerhow + end if + + !-- Set the equation scaling factor in the interface model to that of + ! underlying GWE model + if (this%gweModel%indsp > 0) then + this%gweInterfaceModel%ieqnsclfac = this%gweModel%dsp%eqnsclfac + end if + + ! -- AR the movers and obs through the exchange if (this%owns_exchange) then !cdl implement this when MVT is ready !cdl if (this%gweExchange%inmvt > 0) then @@ -311,14 +329,14 @@ subroutine validateConnection(this) use SimModule, only: count_errors, store_error class(GweGweConnectionType) :: this !< this connection - ! base validation, the spatial/geometry part + ! -- Base validation, the spatial/geometry part call this%SpatialModelConnectionType%validateConnection() - ! we cannot validate this (yet) in parallel mode + ! -- We cannot validate this (yet) in parallel mode if (.not. this%gweExchange%v_model1%is_local) return if (.not. this%gweExchange%v_model2%is_local) return - ! GWE related matters + ! -- GWE related matters if ((this%gweExchange%gwemodel1%inadv > 0 .and. & this%gweExchange%gwemodel2%inadv == 0) .or. & (this%gweExchange%gwemodel2%inadv > 0 .and. & @@ -328,7 +346,7 @@ subroutine validateConnection(this) &and the other one is not' call store_error(errmsg) end if - + ! if ((this%gweExchange%gwemodel1%indsp > 0 .and. & this%gweExchange%gwemodel2%indsp == 0) .or. & (this%gweExchange%gwemodel2%indsp > 0 .and. & @@ -338,40 +356,43 @@ subroutine validateConnection(this) &and the other one is not' call store_error(errmsg) end if - - ! abort on errors + ! + ! Abort on errors if (count_errors() > 0) then write (errmsg, '(a)') 'Errors occurred while processing exchange(s)' call ustop() end if - + ! end subroutine validateConnection subroutine gwegwecon_rp(this) + ! -- dummy class(GweGweConnectionType) :: this !< the connection - + ! ! Call exchange rp routines if (this%owns_exchange) then call this%gweExchange%exg_rp() end if - + ! end subroutine gwegwecon_rp !> @brief Advance this connection !< subroutine gwegwecon_ad(this) + ! class(GweGweConnectionType) :: this !< this connection - - ! recalculate dispersion ellipse + ! + ! -- Recalculate dispersion ellipse if (this%gweInterfaceModel%indsp > 0) call this%gweInterfaceModel%dsp%dsp_ad() - + ! if (this%owns_exchange) then call this%gweExchange%exg_ad() end if - + ! end subroutine gwegwecon_ad subroutine gwegwecon_fc(this, kiter, matrix_sln, rhs_sln, inwtflag) + ! -- dummy class(GweGweConnectionType) :: this !< the connection integer(I4B), intent(in) :: kiter !< the iteration counter class(MatrixBaseType), pointer :: matrix_sln !< the system matrix @@ -388,118 +409,127 @@ subroutine gwegwecon_fc(this, kiter, matrix_sln, rhs_sln, inwtflag) this%gweExchange%gwemodel2%x) end if end if - + ! end subroutine gwegwecon_fc subroutine gwegwecon_cq(this, icnvg, isuppress_output, isolnid) + ! -- dummy class(GweGweConnectionType) :: this !< the connection integer(I4B), intent(inout) :: icnvg !< convergence flag integer(I4B), intent(in) :: isuppress_output !< suppress output when =1 integer(I4B), intent(in) :: isolnid !< solution id - + ! call this%gweInterfaceModel%model_cq(icnvg, isuppress_output) call this%setFlowToExchange() - + ! end subroutine gwegwecon_cq !> @brief Set the flows (flowja from interface model) to the !< simvals in the exchange, leaving the budget calcution in there subroutine setFlowToExchange(this) + ! -- modules use IndexMapModule + ! -- dummy class(GweGweConnectionType) :: this !< this connection - ! local + ! -- local integer(I4B) :: i class(GweExchangeType), pointer :: gweEx type(IndexMapSgnType), pointer :: map - + ! if (this%owns_exchange) then gweEx => this%gweExchange map => this%interface_map%exchange_maps(this%interface_map%prim_exg_idx) - - ! use (half of) the exchange map in reverse: + ! + ! -- Use (half of) the exchange map in reverse: do i = 1, size(map%src_idx) if (map%sign(i) < 0) cycle ! simvals is defined from exg%m1 => exg%m2 gweEx%simvals(map%src_idx(i)) = & this%gweInterfaceModel%flowja(map%tgt_idx(i)) end do end if - + ! end subroutine setFlowToExchange subroutine gwegwecon_bd(this, icnvg, isuppress_output, isolnid) + ! -- modules use BudgetModule, only: rate_accumulator + ! -- dummy class(GweGweConnectionType) :: this !< the connection integer(I4B), intent(inout) :: icnvg !< convergence flag integer(I4B), intent(in) :: isuppress_output !< suppress output when =1 integer(I4B), intent(in) :: isolnid !< solution id - - ! call exchange budget routine, also calls bd - ! for movers. + ! + ! -- Call exchange budget routine, also calls bd + ! for movers. if (this%owns_exchange) then call this%gweExchange%exg_bd(icnvg, isuppress_output, isolnid) end if - + ! end subroutine gwegwecon_bd subroutine gwegwecon_ot(this) + ! -- dummy class(GweGweConnectionType) :: this !< the connection - - ! Call exg_ot() here as it handles all output processing - ! based on gweExchange%simvals(:), which was correctly - ! filled from gwegwecon + ! + ! -- Call exg_ot() here as it handles all output processing + ! based on gweExchange%simvals(:), which was correctly + ! filled from gwegwecon if (this%owns_exchange) then call this%gweExchange%exg_ot() end if - + ! end subroutine gwegwecon_ot subroutine gwegwecon_da(this) + ! -- dummy class(GweGweConnectionType) :: this !< the connection - ! local + ! -- local logical(LGP) :: isOpen - - ! scalars + ! + ! -- Scalars call mem_deallocate(this%iIfaceAdvScheme) call mem_deallocate(this%iIfaceXt3d) call mem_deallocate(this%exgflowSign) - - ! arrays + ! + ! -- Arrays call mem_deallocate(this%exgflowjaGwe) - - ! interface model + ! + ! -- Interface model call this%gweInterfaceModel%model_da() deallocate (this%gweInterfaceModel) - - ! dealloc base + ! + ! -- Dealloc base call this%spatialcon_da() - + ! inquire (this%iout, opened=isOpen) if (isOpen) then close (this%iout) end if - - ! we need to deallocate the exchange we own: + ! + ! -- We need to deallocate the exchange we own: if (this%owns_exchange) then call this%gweExchange%exg_da() end if - + ! end subroutine gwegwecon_da !> @brief Cast to GweGweConnectionType !< function CastAsGweGweConnection(obj) result(res) implicit none + ! -- dummy class(*), pointer, intent(inout) :: obj !< object to be cast + ! -- return class(GweGweConnectionType), pointer :: res !< the GweGweConnection - + ! res => null() if (.not. associated(obj)) return - + ! select type (obj) class is (GweGweConnectionType) res => obj end select - return + ! end function CastAsGweGweConnection end module diff --git a/src/Model/Connection/GweInterfaceModel.f90 b/src/Model/Connection/GweInterfaceModel.f90 index 5cdb422dc38..5b28b5888c5 100644 --- a/src/Model/Connection/GweInterfaceModel.f90 +++ b/src/Model/Connection/GweInterfaceModel.f90 @@ -14,6 +14,7 @@ module GweInterfaceModelModule use GweMstModule, only: mst_cr use TspObsModule, only: tsp_obs_cr use GridConnectionModule + use GweInputDataModule, only: GweInputDataType implicit none private @@ -50,12 +51,14 @@ module GweInterfaceModelModule !> @brief Create the interface model, analogously to what !< happens in gwe_cr subroutine gweifmod_cr(this, name, iout, gridConn) + ! -- modules + use GweInputDataModule, only: gweshared_dat_cr ! -- dummy class(GweInterfaceModelType) :: this !< the GWE interface model character(len=*), intent(in) :: name !< the interface model's name integer(I4B), intent(in) :: iout !< the output unit class(GridConnectionType), pointer, intent(in) :: gridConn !< the grid connection data for creating a DISU - ! local + ! -- local class(*), pointer :: modelPtr integer(I4B), target :: inobs integer(I4B) :: adv_unit, dsp_unit @@ -63,7 +66,10 @@ subroutine gweifmod_cr(this, name, iout, gridConn) this%memoryPath = create_mem_path(name) call this%allocate_scalars(name) ! - ! defaults + ! -- Instantiate shared data container + call gweshared_dat_cr(this%gwecommon) + ! + ! -- Defaults this%iAdvScheme = 0 this%ixt3d = 0 this%ieqnsclfac = DONE @@ -85,14 +91,14 @@ subroutine gweifmod_cr(this, name, iout, gridConn) dsp_unit = huge(1_I4B) end if ! - ! create dis and packages + ! -- Create dis and packages call disu_cr(this%dis, this%name, '', -1, this%iout) call fmi_cr(this%fmi, this%name, 0, this%iout, this%ieqnsclfac, & this%depvartype) call adv_cr(this%adv, this%name, adv_unit, this%iout, this%fmi, & this%ieqnsclfac) call dsp_cr(this%dsp, this%name, '', -dsp_unit, this%iout, this%fmi, & - this%eqnsclfac, this%gwecommon) + this%ieqnsclfac, this%gwecommon) call tsp_obs_cr(this%obs, inobs) ! ! -- Return @@ -149,7 +155,7 @@ subroutine gweifmod_df(this) adv_options%iAdvScheme = this%iAdvScheme dsp_options%ixt3d = this%ixt3d ! - ! define DISU + ! -- Define DISU disPtr => this%dis call this%gridConnection%getDiscretization(CastAsDisuType(disPtr)) call this%fmi%fmi_df(this%dis, 0) @@ -157,14 +163,11 @@ subroutine gweifmod_df(this) if (this%inadv > 0) then call this%adv%adv_df(adv_options) end if + ! if (this%indsp > 0) then - !this%dsp%idiffc = this%owner%dsp%idiffc this%dsp%idisp = this%owner%dsp%idisp call this%dsp%dsp_df(this%dis, dsp_options) - !if (this%dsp%idiffc > 0) then - ! call mem_reallocate(this%dsp%diffc, this%dis%nodes, 'DIFFC', & - ! trim(this%dsp%memoryPath)) - !end if + ! if (this%dsp%idisp > 0) then call mem_reallocate(this%dsp%alh, this%dis%nodes, 'ALH', & trim(this%dsp%memoryPath)) @@ -186,13 +189,16 @@ subroutine gweifmod_df(this) 'POROSITY', create_mem_path(this%name, 'MST')) end if ! - ! assign or point model members to dis members + ! -- Assign or point model members to dis members this%neq = this%dis%nodes this%nja = this%dis%nja this%ia => this%dis%con%ia this%ja => this%dis%con%ja ! - ! allocate model arrays, now that neq and nja are assigned + ! -- Define shared data (cpw, rhow, latent heat of vaporization) + call this%gwecommon%gweshared_dat_df(this%neq) + ! + ! -- Allocate model arrays, now that neq and nja are assigned call this%allocate_arrays() ! ! -- Return @@ -224,12 +230,13 @@ subroutine gweifmod_da(this) ! -- dummy class(GweInterfaceModelType) :: this !< the GWE interface model ! - ! this + ! -- members specified in the interface model input for use by the + ! interface model call mem_deallocate(this%iAdvScheme) call mem_deallocate(this%ixt3d) call mem_deallocate(this%ieqnsclfac) ! - ! gwe packages + ! -- gwe packages call this%dis%dis_da() call this%fmi%fmi_da() call this%adv%adv_da() @@ -245,7 +252,7 @@ subroutine gweifmod_da(this) deallocate (this%mst) end if ! - ! gwe scalars + ! -- gwe scalars call mem_deallocate(this%inic) call mem_deallocate(this%infmi) call mem_deallocate(this%inadv) @@ -257,7 +264,7 @@ subroutine gweifmod_da(this) call mem_deallocate(this%inobs) call mem_deallocate(this%eqnsclfac) ! - ! base + ! -- base call this%NumericalModelType%model_da() ! ! -- Return diff --git a/src/Model/GroundWaterEnergy/gwe1.f90 b/src/Model/GroundWaterEnergy/gwe1.f90 index 1053a132959..2d7daa882d3 100644 --- a/src/Model/GroundWaterEnergy/gwe1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1.f90 @@ -131,7 +131,7 @@ subroutine gwe_cr(filename, id, modelname) call gweshared_dat_cr(this%gwecommon) ! ! -- Call parent class routine - call this%tsp_cr(filename, id, modelname, 'GWE', indis, this%gwecommon) + call this%tsp_cr(filename, id, modelname, 'GWE', indis) ! ! -- create model packages call this%create_packages(indis) diff --git a/src/Model/GroundWaterEnergy/gwe1dsp1.f90 b/src/Model/GroundWaterEnergy/gwe1dsp1.f90 index 0bc274e5c8f..02b7797c60e 100644 --- a/src/Model/GroundWaterEnergy/gwe1dsp1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1dsp1.f90 @@ -94,8 +94,7 @@ subroutine dsp_cr(dspobj, name_model, input_mempath, inunit, iout, fmi, & integer(I4B), intent(in) :: iout type(TspFmiType), intent(in), target :: fmi real(DP), intent(in), pointer :: eqnsclfac !< governing equation scale factor - type(GweInputDataType), intent(in), target :: gwecommon !< shared data container for use by multiple GWE packages - ! -- locals + type(GweInputDataType), intent(in), target, optional :: gwecommon !< shared data container for use by multiple GWE packages ! -- formats character(len=*), parameter :: fmtdsp = & "(1x,/1x,'DSP-- THERMAL CONDUCTION AND DISPERSION PACKAGE, VERSION 1, ', & @@ -115,7 +114,9 @@ subroutine dsp_cr(dspobj, name_model, input_mempath, inunit, iout, fmi, & dspobj%iout = iout dspobj%fmi => fmi dspobj%eqnsclfac => eqnsclfac - dspobj%gwecommon => gwecommon + if (present(gwecommon)) then + dspobj%gwecommon => gwecommon + end if ! if (dspobj%inunit > 0) then ! @@ -744,13 +745,13 @@ subroutine calcdispellipse(this) this%fmi%gwfsat(n) if (this%ikts > 0) ktbulk = ktbulk + (DONE - this%porosity(n)) * this%kts(n) ! - ! -- The division by rhow*cpw below is done to render dstar in the form - ! of a thermal diffusivity, and not because the governing equation - ! is scaled by rhow*cpw. Because of this conceptual distinction, - ! ktbulk is divided by the explicitly calculated product rhow*cpw, - ! and not by the equivalent scale factor eqnsclfac, even though it - ! should make no practical difference in the result. - dstar = ktbulk / (this%gwecommon%gwecpw * this%gwecommon%gwerhow) ! kluge note eqnsclfac, define product + ! -- The division by rhow*cpw below is undertaken to render dstar in the + ! form of a thermal diffusivity, and not because the governing + ! equation is scaled by rhow*cpw. Because of this conceptual + ! distinction, ktbulk is divided by the explicitly calculated product + ! rhow*cpw, and not by the equivalent scale factor eqnsclfac, even + ! though it should make no practical difference in the result. + dstar = ktbulk / (this%gwecommon%gwecpw * this%gwecommon%gwerhow) ! ! -- Calculate the longitudal and transverse dispersivities al = DZERO diff --git a/src/Model/ModelUtilities/GweInputData.f90 b/src/Model/ModelUtilities/GweInputData.f90 index f7d4f670723..55757560383 100644 --- a/src/Model/ModelUtilities/GweInputData.f90 +++ b/src/Model/ModelUtilities/GweInputData.f90 @@ -45,13 +45,13 @@ module GweInputDataModule !> @brief Allocate the shared data !< - subroutine gweshared_dat_cr(this) + subroutine gweshared_dat_cr(gwe_dat) ! -- modules ! -- dummy - type(GweInputDataType), pointer :: this !< the input data block + type(GweInputDataType), pointer :: gwe_dat !< the input data block ! ! -- Create the object - allocate (this) + allocate (gwe_dat) ! ! -- Return return diff --git a/src/Model/TransportModel/tsp1.f90 b/src/Model/TransportModel/tsp1.f90 index ced3996ff4c..bd7622edebf 100644 --- a/src/Model/TransportModel/tsp1.f90 +++ b/src/Model/TransportModel/tsp1.f90 @@ -92,7 +92,7 @@ module TransportModelModule !! !! Create a new transport model that will be further refined into GWT or GWE !< - subroutine tsp_cr(this, filename, id, modelname, macronym, indis, gwecommon) + subroutine tsp_cr(this, filename, id, modelname, macronym, indis) ! -- modules use MemoryHelperModule, only: create_mem_path use MemoryManagerExtModule, only: mem_set_value @@ -106,7 +106,6 @@ subroutine tsp_cr(this, filename, id, modelname, macronym, indis, gwecommon) integer(I4B), intent(inout) :: indis character(len=*), intent(in) :: modelname character(len=*), intent(in) :: macronym - type(GweInputDataType), intent(in), optional :: gwecommon !< shared data container for use by multiple GWE packages ! -- local character(len=LENMEMPATH) :: input_mempath character(len=LINELENGTH) :: lst_fname @@ -146,11 +145,7 @@ subroutine tsp_cr(this, filename, id, modelname, macronym, indis, gwecommon) call budget_cr(this%budget, this%name) ! ! -- create model packages - if (present(gwecommon)) then - call this%create_tsp_packages(indis, gwecommon) - else - call this%create_tsp_packages(indis) - end if + call this%create_tsp_packages(indis) ! ! -- Return return @@ -163,7 +158,7 @@ end subroutine tsp_cr !! pointers. !< subroutine tsp_df(this) - ! -- dummy variables + ! -- dummy class(TransportModelType) :: this ! ! -- Return @@ -178,10 +173,9 @@ end subroutine tsp_df subroutine tsp_ac(this, sparse) ! -- modules use SparseModule, only: sparsematrix - ! -- dummy variables + ! -- dummy class(TransportModelType) :: this type(sparsematrix), intent(inout) :: sparse - ! -- local ! ! -- Return return @@ -197,7 +191,6 @@ subroutine tsp_mc(this, matrix_sln) ! -- dummy class(TransportModelType) :: this class(MatrixBaseType), pointer :: matrix_sln !< global system matrix - ! -- local ! ! -- Return return @@ -210,7 +203,7 @@ end subroutine tsp_mc !! memory for arrays required by the model object. !< subroutine tsp_ar(this) - ! -- dummy variables + ! -- dummy class(TransportModelType) :: this ! ! -- Return @@ -223,7 +216,7 @@ end subroutine tsp_ar !! the read and prepare (rp) routines of attached packages. !< subroutine tsp_rp(this) - ! -- dummy variables + ! -- dummy class(TransportModelType) :: this ! ! -- Return @@ -236,7 +229,7 @@ end subroutine tsp_rp !! the advance time step (ad) routines of attached packages. !< subroutine tsp_ad(this) - ! -- dummy variables + ! -- dummy class(TransportModelType) :: this ! ! -- Return @@ -249,7 +242,7 @@ end subroutine tsp_ad !! the fill coefficients (fc) routines of attached packages. !< subroutine tsp_fc(this, kiter, matrix_sln, inwtflag) - ! -- dummy variables + ! -- dummy class(TransportModelType) :: this integer(I4B), intent(in) :: kiter class(MatrixBaseType), pointer :: matrix_sln @@ -274,7 +267,6 @@ subroutine tsp_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak) character(len=LENPAKLOC), intent(inout) :: cpak integer(I4B), intent(inout) :: ipak real(DP), intent(inout) :: dpak - ! -- local ! ! -- Return return @@ -286,11 +278,10 @@ end subroutine tsp_cc !! intercell flows (flowja) !< subroutine tsp_cq(this, icnvg, isuppress_output) - ! -- dummy variables + ! -- dummy class(TransportModelType) :: this integer(I4B), intent(in) :: icnvg integer(I4B), intent(in) :: isuppress_output - ! -- local ! ! -- Return return @@ -350,16 +341,16 @@ subroutine tsp_ot(this, inmst) idvprint = this%oc%set_print_flag(trim(this%depvartype), & this%icnvg, endofperiod) ! - ! Calculate and save observations + ! -- Calculate and save observations call this%tsp_ot_obs() ! - ! Save and print flows + ! -- Save and print flows call this%tsp_ot_flow(icbcfl, ibudfl, icbcun, inmst) ! - ! Save and print dependent variables + ! -- Save and print dependent variables call this%tsp_ot_dv(idvsave, idvprint, ipflag) ! - ! Print budget summaries + ! -- Print budget summaries call this%tsp_ot_bdsummary(ibudfl, ipflag) ! ! -- Timing Output; if any dependendent variables or budgets @@ -386,14 +377,14 @@ subroutine tsp_ot_obs(this) ! -- Calculate and save observations call this%obs%obs_bd() call this%obs%obs_ot() - + ! ! -- Calculate and save package obserations do ip = 1, this%bndlist%Count() packobj => GetBndFromList(this%bndlist, ip) call packobj%bnd_bd_obs() call packobj%bnd_ot_obs() end do - + ! end subroutine tsp_ot_obs !> @brief Generalized transport model output routine @@ -417,11 +408,12 @@ subroutine tsp_ot_flow(this, icbcfl, ibudfl, icbcun, inmst) if (this%inssm > 0) then call this%ssm%ssm_ot_flow(icbcfl=icbcfl, ibudfl=0, icbcun=icbcun) end if + ! do ip = 1, this%bndlist%Count() packobj => GetBndFromList(this%bndlist, ip) call packobj%bnd_ot_model_flows(icbcfl=icbcfl, ibudfl=0, icbcun=icbcun) end do - + ! ! -- Save advanced package flows do ip = 1, this%bndlist%Count() packobj => GetBndFromList(this%bndlist, ip) @@ -430,11 +422,11 @@ subroutine tsp_ot_flow(this, icbcfl, ibudfl, icbcun, inmst) if (this%inmvt > 0) then call this%mvt%mvt_ot_saveflow(icbcfl, ibudfl) end if - + ! ! -- Print Model (GWT or GWE) flows - ! no need to print flowja - ! no need to print mst - ! no need to print fmi + ! no need to print flowja + ! no need to print mst + ! no need to print fmi if (this%inssm > 0) then call this%ssm%ssm_ot_flow(icbcfl=icbcfl, ibudfl=ibudfl, icbcun=0) end if @@ -442,16 +434,17 @@ subroutine tsp_ot_flow(this, icbcfl, ibudfl, icbcun, inmst) packobj => GetBndFromList(this%bndlist, ip) call packobj%bnd_ot_model_flows(icbcfl=icbcfl, ibudfl=ibudfl, icbcun=0) end do - + ! ! -- Print advanced package flows do ip = 1, this%bndlist%Count() packobj => GetBndFromList(this%bndlist, ip) call packobj%bnd_ot_package_flows(icbcfl=0, ibudfl=ibudfl) end do + ! if (this%inmvt > 0) then call this%mvt%mvt_ot_printflow(icbcfl, ibudfl) end if - + ! end subroutine tsp_ot_flow !> @brief Generalized transport model output routine @@ -505,8 +498,8 @@ subroutine tsp_ot_dv(this, idvsave, idvprint, ipflag) packobj => GetBndFromList(this%bndlist, ip) call packobj%bnd_ot_dv(idvsave, idvprint) end do - - ! -- save head and print head + ! + ! -- Save head and print head call this%oc%oc_ot(ipflag) ! ! -- Return @@ -530,18 +523,18 @@ subroutine tsp_ot_bdsummary(this, ibudfl, ipflag) packobj => GetBndFromList(this%bndlist, ip) call packobj%bnd_ot_bdsummary(kstp, kper, this%iout, ibudfl) end do - - ! -- mover budget summary + ! + ! -- Mover budget summary if (this%inmvt > 0) then call this%mvt%mvt_ot_bdsummary(ibudfl) end if - - ! -- model budget summary + ! + ! -- Model budget summary if (ibudfl /= 0) then ipflag = 1 call this%budget%budget_ot(kstp, kper, this%iout) end if - + ! ! -- Write to budget csv call this%budget%writecsv(totim) ! @@ -654,7 +647,6 @@ subroutine ftype_check(this, indis, inmst) integer(I4B), intent(in) :: inmst ! -- local character(len=LINELENGTH) :: errmsg -! ------------------------------------------------------------------------------ ! ! -- Check for IC6, DIS(u), and MST. Stop if not present. if (this%inic == 0) then @@ -697,15 +689,15 @@ subroutine create_lstfile(this, lst_fname, model_fname, defined) ! -- local integer(I4B) :: i, istart, istop ! - ! -- set list file name if not provided + ! -- Set list file name if not provided if (.not. defined) then ! - ! -- initialize + ! -- Initialize lst_fname = ' ' istart = 0 istop = len_trim(model_fname) ! - ! -- identify '.' character position from back of string + ! -- Identify '.' character position from back of string do i = istop, 1, -1 if (model_fname(i:i) == '.') then istart = i @@ -713,20 +705,20 @@ subroutine create_lstfile(this, lst_fname, model_fname, defined) end if end do ! - ! -- if not found start from string end + ! -- If not found start from string end if (istart == 0) istart = istop + 1 ! - ! -- set list file name + ! -- Set list file name lst_fname = model_fname(1:istart) istop = istart + 3 lst_fname(istart:istop) = '.lst' end if ! - ! -- create the list file + ! -- Create the list file this%iout = getunit() call openfile(this%iout, 0, lst_fname, 'LIST', filstat_opt='REPLACE') ! - ! -- write list file header + ! -- Write list file header call write_listfile_header(this%iout, 'GROUNDWATER TRANSPORT MODEL (GWT)') ! ! -- Return @@ -736,7 +728,9 @@ end subroutine create_lstfile !> @brief Write model name file options to list file !< subroutine log_namfile_options(this, found) + ! -- modules use GwfNamInputModule, only: GwfNamParamFoundType + ! -- dummy class(TransportModelType) :: this type(GwfNamParamFoundType), intent(in) :: found ! @@ -775,7 +769,7 @@ end subroutine log_namfile_options !> @brief Source package info and begin to process !< - subroutine create_tsp_packages(this, indis, gwecommon) + subroutine create_tsp_packages(this, indis) ! -- modules use ConstantsModule, only: LINELENGTH, LENPACKAGENAME use CharacterStringModule, only: CharacterStringType @@ -796,7 +790,6 @@ subroutine create_tsp_packages(this, indis, gwecommon) ! -- dummy class(TransportModelType) :: this integer(I4B), intent(inout) :: indis ! DIS enabled flag - type(GweInputDataType), intent(in), optional :: gwecommon !< shared data container for use by multiple GWE packages ! -- local type(CharacterStringType), dimension(:), contiguous, & pointer :: pkgtypes => null() @@ -817,10 +810,10 @@ subroutine create_tsp_packages(this, indis, gwecommon) ! -- Initialize indis = 0 ! - ! -- set input memory paths, input/model and input/model/namfile + ! -- Set input memory paths, input/model and input/model/namfile model_mempath = create_mem_path(component=this%name, context=idm_context) ! - ! -- set pointers to model path package info + ! -- Set pointers to model path package info call mem_setptr(pkgtypes, 'PKGTYPES', model_mempath) call mem_setptr(pkgnames, 'PKGNAMES', model_mempath) call mem_setptr(mempaths, 'MEMPATHS', model_mempath) @@ -828,13 +821,13 @@ subroutine create_tsp_packages(this, indis, gwecommon) ! do n = 1, size(pkgtypes) ! - ! attributes for this input package + ! -- Attributes for this input package pkgtype = pkgtypes(n) pkgname = pkgnames(n) mempath = mempaths(n) inunit => inunits(n) ! - ! -- create dis package as it is a prerequisite for other packages + ! -- Create dis package as it is a prerequisite for other packages select case (pkgtype) case ('DIS6') indis = 1 @@ -873,7 +866,7 @@ subroutine create_tsp_packages(this, indis, gwecommon) call adv_cr(this%adv, this%name, this%inadv, this%iout, this%fmi, & this%eqnsclfac) call ssm_cr(this%ssm, this%name, this%inssm, this%iout, this%fmi, & - this%eqnsclfac, this%depvartype, gwecommon) + this%eqnsclfac, this%depvartype) call mvt_cr(this%mvt, this%name, this%inmvt, this%iout, this%fmi, & this%eqnsclfac) call oc_cr(this%oc, this%name, this%inoc, this%iout) From 716fab6f4bfa15672f4ae61a153a637a8afd681b Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Wed, 17 Jan 2024 11:56:43 -0800 Subject: [PATCH 23/46] Rebrand constant temperature package acronym to CTP --- autotest/test_gwe_drycell_conduction0.py | 4 +- autotest/test_gwe_drycell_conduction1.py | 4 +- autotest/test_gwe_dsp.py | 6 +- doc/Common/{gwe-cntobs.tex => gwe-ctpobs.tex} | 2 +- doc/Common/gwe-obstypetable.tex | 2 +- doc/mf6io/gwe/cnt.tex | 47 ----- doc/mf6io/gwe/ctp.tex | 47 +++++ doc/mf6io/gwe/gwe.tex | 4 +- doc/mf6io/gwe/namefile.tex | 2 +- .../mf6ivar/dfn/{gwe-cnt.dfn => gwe-ctp.dfn} | 6 +- ...xample-obs.dat => gwe-ctp-example-obs.dat} | 8 +- ...we-cnt-example.dat => gwe-ctp-example.dat} | 0 .../mf6ivar/examples/gwe-nam-example.dat | 4 +- doc/mf6io/mf6ivar/md/mf6ivar.md | 34 ++-- doc/mf6io/mf6ivar/mf6ivar.py | 2 +- doc/mf6io/mf6ivar/tex/appendixA.tex | 6 +- doc/mf6io/mf6ivar/tex/gwe-ctp-desc.tex | 49 +++++ ...-dimensions.dat => gwe-ctp-dimensions.dat} | 0 ...we-cnt-options.dat => gwe-ctp-options.dat} | 0 ...{gwe-cnt-period.dat => gwe-ctp-period.dat} | 0 make/makefile | 4 +- msvs/mf6core.vfproj | 4 +- src/Model/GroundWaterEnergy/gwe1.f90 | 8 +- .../{gwe1cnt1.f90 => gwe1ctp1.f90} | 168 +++++++++--------- .../{gwe1cnt1idm.f90 => gwe1ctp1idm.f90} | 140 +++++++-------- .../Idm/selector/IdmGweDfnSelector.f90 | 20 +-- src/meson.build | 4 +- utils/idmloader/scripts/dfn2f90.py | 4 +- 28 files changed, 314 insertions(+), 265 deletions(-) rename doc/Common/{gwe-cntobs.tex => gwe-ctpobs.tex} (63%) delete mode 100644 doc/mf6io/gwe/cnt.tex create mode 100644 doc/mf6io/gwe/ctp.tex rename doc/mf6io/mf6ivar/dfn/{gwe-cnt.dfn => gwe-ctp.dfn} (95%) rename doc/mf6io/mf6ivar/examples/{gwe-cnt-example-obs.dat => gwe-ctp-example-obs.dat} (62%) rename doc/mf6io/mf6ivar/examples/{gwe-cnt-example.dat => gwe-ctp-example.dat} (100%) create mode 100644 doc/mf6io/mf6ivar/tex/gwe-ctp-desc.tex rename doc/mf6io/mf6ivar/tex/{gwe-cnt-dimensions.dat => gwe-ctp-dimensions.dat} (100%) rename doc/mf6io/mf6ivar/tex/{gwe-cnt-options.dat => gwe-ctp-options.dat} (100%) rename doc/mf6io/mf6ivar/tex/{gwe-cnt-period.dat => gwe-ctp-period.dat} (100%) rename src/Model/GroundWaterEnergy/{gwe1cnt1.f90 => gwe1ctp1.f90} (79%) rename src/Model/GroundWaterEnergy/{gwe1cnt1idm.f90 => gwe1ctp1idm.f90} (78%) diff --git a/autotest/test_gwe_drycell_conduction0.py b/autotest/test_gwe_drycell_conduction0.py index e135d72c0d1..b2b3c42cf74 100644 --- a/autotest/test_gwe_drycell_conduction0.py +++ b/autotest/test_gwe_drycell_conduction0.py @@ -320,10 +320,10 @@ def build_models(idx, test): 0: [[(0, 0, 0), strt_temp], [(1, 0, 0), strt_temp]], 1: [[(0, 0, 0), strt_temp + 10], [(1, 0, 0), strt_temp + 10]], } - flopy.mf6.ModflowGwecnt( + flopy.mf6.ModflowGwectp( gwe1, stress_period_data=ctmpspd, - pname="CNT-2", + pname="CTP-2", filename="{}.ctmp".format(gwename1), ) diff --git a/autotest/test_gwe_drycell_conduction1.py b/autotest/test_gwe_drycell_conduction1.py index 47857444f1e..6636e19ce3c 100644 --- a/autotest/test_gwe_drycell_conduction1.py +++ b/autotest/test_gwe_drycell_conduction1.py @@ -376,10 +376,10 @@ def build_models(idx, test): ], 3: [], } - flopy.mf6.ModflowGwecnt( + flopy.mf6.ModflowGwectp( gwe1, stress_period_data=ctmpspd, - pname="CNT-2", + pname="CTP-2", filename="{}.ctmp".format(gwename1), ) diff --git a/autotest/test_gwe_dsp.py b/autotest/test_gwe_dsp.py index 8b3747782d9..cae9878d394 100644 --- a/autotest/test_gwe_dsp.py +++ b/autotest/test_gwe_dsp.py @@ -315,13 +315,13 @@ def build_models(idx, test): ) # Instantiating MODFLOW 6 transport constant concentration package - flopy.mf6.ModflowGwecnt( + flopy.mf6.ModflowGwectp( gwe, maxbound=len(ctpspd), stress_period_data=ctpspd, save_flows=False, - pname="CNT-1", - filename="{}.cnt".format(gwename), + pname="CTP-1", + filename="{}.ctp".format(gwename), ) # Instantiating MODFLOW 6 transport source-sink mixing package diff --git a/doc/Common/gwe-cntobs.tex b/doc/Common/gwe-ctpobs.tex similarity index 63% rename from doc/Common/gwe-cntobs.tex rename to doc/Common/gwe-ctpobs.tex index c8e2e87ec4c..8c141d5ae43 100644 --- a/doc/Common/gwe-cntobs.tex +++ b/doc/Common/gwe-ctpobs.tex @@ -1 +1 @@ -CNT & cnt & cellid or boundname & -- & Energy flow between the groundwater system and a constant-temperature boundary or a group of cells with constant-temperature boundaries. +CTP & ctp & cellid or boundname & -- & Energy flow between the groundwater system and a constant-temperature boundary or a group of cells with constant-temperature boundaries. diff --git a/doc/Common/gwe-obstypetable.tex b/doc/Common/gwe-obstypetable.tex index a91fa294b8c..501f5cb63c3 100644 --- a/doc/Common/gwe-obstypetable.tex +++ b/doc/Common/gwe-obstypetable.tex @@ -53,7 +53,7 @@ \hline \endfoot -\input{../Common/gwe-cntobs.tex} \\ +\input{../Common/gwe-ctpobs.tex} \\ \hline % \input{../Common/gwe-esrobs.tex} \\ % \hline diff --git a/doc/mf6io/gwe/cnt.tex b/doc/mf6io/gwe/cnt.tex deleted file mode 100644 index acdfd152f97..00000000000 --- a/doc/mf6io/gwe/cnt.tex +++ /dev/null @@ -1,47 +0,0 @@ -Constant Temperature (CNT) Package information is read from the file that is specified by ``CNT6'' as the file type. Any number of CNT Packages can be specified for a single GWE model, but the same cell cannot be designated as a constant temperature by more than one CNT entry. - -\vspace{5mm} -\subsubsection{Structure of Blocks} -\vspace{5mm} - -\noindent \textit{FOR EACH SIMULATION} -\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-cnt-options.dat} -\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-cnt-dimensions.dat} -\vspace{5mm} -\noindent \textit{FOR ANY STRESS PERIOD} -\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-cnt-period.dat} -\packageperioddescription - -\vspace{5mm} -\subsubsection{Explanation of Variables} -\begin{description} -\input{./mf6ivar/tex/gwe-cnt-desc.tex} -\end{description} - -\vspace{5mm} -\subsubsection{Example Input File} -\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-cnt-example.dat} - -\vspace{5mm} -\subsubsection{Available observation types} -CNT Package observations are limited to the simulated constant temperature energy flow rate (\texttt{cnt}). The data required for the CNT Package observation type is defined in table~\ref{table:gwe-cntobstype}. Negative and positive values for an observation represent a loss from and gain to the GWE model, respectively. - -\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}} -\caption{Available CNT Package observation types} \tabularnewline - -\hline -\hline -\textbf{Model} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ -\hline -\endhead - -\hline -\endfoot - -\input{../Common/gwe-cntobs.tex} -\label{table:gwe-cntobstype} -\end{longtable} - -\vspace{5mm} -\subsubsection{Example Observation Input File} -\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-cnt-example-obs.dat} diff --git a/doc/mf6io/gwe/ctp.tex b/doc/mf6io/gwe/ctp.tex new file mode 100644 index 00000000000..0953d2e3367 --- /dev/null +++ b/doc/mf6io/gwe/ctp.tex @@ -0,0 +1,47 @@ +Constant Temperature (CTP) Package information is read from the file that is specified by ``CTP6'' as the file type. Any number of CTP Packages can be specified for a single GWE model, but the same cell cannot be designated as a constant temperature by more than one CTP entry. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\vspace{5mm} + +\noindent \textit{FOR EACH SIMULATION} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-ctp-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-ctp-dimensions.dat} +\vspace{5mm} +\noindent \textit{FOR ANY STRESS PERIOD} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-ctp-period.dat} +\packageperioddescription + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-ctp-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-ctp-example.dat} + +\vspace{5mm} +\subsubsection{Available observation types} +CTP Package observations are limited to the simulated constant temperature energy flow rate (\texttt{ctp}). The data required for the CTP Package observation type is defined in table~\ref{table:gwe-ctpobstype}. Negative and positive values for an observation represent a loss from and gain to the GWE model, respectively. + +\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}} +\caption{Available CTP Package observation types} \tabularnewline + +\hline +\hline +\textbf{Model} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endhead + +\hline +\endfoot + +\input{../Common/gwe-ctpobs.tex} +\label{table:gwe-ctpobstype} +\end{longtable} + +\vspace{5mm} +\subsubsection{Example Observation Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-ctp-example-obs.dat} diff --git a/doc/mf6io/gwe/gwe.tex b/doc/mf6io/gwe/gwe.tex index 0da6f6208fd..0762434b13d 100644 --- a/doc/mf6io/gwe/gwe.tex +++ b/doc/mf6io/gwe/gwe.tex @@ -118,8 +118,8 @@ \subsection{Mobile Storage and Transfer (MST) Package} \input{gwe/mst} \newpage -\subsection{Constant Temperature (CNT) Package} -\input{gwe/cnt} +\subsection{Constant Temperature (CTP) Package} +\input{gwe/ctp} \newpage \subsection{Flow Model Interface (FMI) Package} diff --git a/doc/mf6io/gwe/namefile.tex b/doc/mf6io/gwe/namefile.tex index 5d27d8b70fc..dfb537a25d3 100644 --- a/doc/mf6io/gwe/namefile.tex +++ b/doc/mf6io/gwe/namefile.tex @@ -32,7 +32,7 @@ \subsubsection{Explanation of Variables} DSP6 & Dispersion Package \\ SSM6 & Source and Sink Mixing Package \\ MST6 & Mobile Storage and Transfer Package \\ -CNT6 & Constant Temperature Package & * \\ +CTP6 & Constant Temperature Package & * \\ OBS6 & Observations Option \\ \hline \end{tabular*} diff --git a/doc/mf6io/mf6ivar/dfn/gwe-cnt.dfn b/doc/mf6io/mf6ivar/dfn/gwe-ctp.dfn similarity index 95% rename from doc/mf6io/mf6ivar/dfn/gwe-cnt.dfn rename to doc/mf6io/mf6ivar/dfn/gwe-ctp.dfn index b636ac1cd00..d8dd2bc68bf 100644 --- a/doc/mf6io/mf6ivar/dfn/gwe-cnt.dfn +++ b/doc/mf6io/mf6ivar/dfn/gwe-ctp.dfn @@ -1,4 +1,4 @@ -# --------------------- gwe cnt options --------------------- +# --------------------- gwe ctp options --------------------- # flopy multi-package block options @@ -131,7 +131,7 @@ longname obs6 input filename description REPLACE obs6_filename {'{#1}': 'Constant Temperature'} -# --------------------- gwe cnt dimensions --------------------- +# --------------------- gwe ctp dimensions --------------------- block dimensions name maxbound @@ -142,7 +142,7 @@ longname maximum number of constant temperatures description REPLACE maxbound {'{#1}': 'constant temperatures'} -# --------------------- gwe cnt period --------------------- +# --------------------- gwe ctp period --------------------- block period name iper diff --git a/doc/mf6io/mf6ivar/examples/gwe-cnt-example-obs.dat b/doc/mf6io/mf6ivar/examples/gwe-ctp-example-obs.dat similarity index 62% rename from doc/mf6io/mf6ivar/examples/gwe-cnt-example-obs.dat rename to doc/mf6io/mf6ivar/examples/gwe-ctp-example-obs.dat index 6b380ac8aa5..db655c076e4 100644 --- a/doc/mf6io/mf6ivar/examples/gwe-cnt-example-obs.dat +++ b/doc/mf6io/mf6ivar/examples/gwe-ctp-example-obs.dat @@ -5,12 +5,12 @@ END OPTIONS BEGIN CONTINUOUS FILEOUT my_model.cnc01.csv # obsname obstype ID - ctemp_3_1 CNC 3 1 1 - ctemp_3_2 CNC 3 2 1 - ctemp_3_3 CNC 3 3 1 + ctemp_3_1 CTP 3 1 1 + ctemp_3_2 CTP 3 2 1 + ctemp_3_3 CTP 3 3 1 END CONTINUOUS BEGIN CONTINUOUS FILEOUT my_model.chd02.csv # obsname obstype ID - ctemp_3_flow CNC CTEMP_3_1 + ctemp_3_flow CTP CTEMP_3_1 END CONTINUOUS \ No newline at end of file diff --git a/doc/mf6io/mf6ivar/examples/gwe-cnt-example.dat b/doc/mf6io/mf6ivar/examples/gwe-ctp-example.dat similarity index 100% rename from doc/mf6io/mf6ivar/examples/gwe-cnt-example.dat rename to doc/mf6io/mf6ivar/examples/gwe-ctp-example.dat diff --git a/doc/mf6io/mf6ivar/examples/gwe-nam-example.dat b/doc/mf6io/mf6ivar/examples/gwe-nam-example.dat index 8ef99d67ed2..c753ed4713e 100644 --- a/doc/mf6io/mf6ivar/examples/gwe-nam-example.dat +++ b/doc/mf6io/mf6ivar/examples/gwe-nam-example.dat @@ -9,8 +9,8 @@ BEGIN PACKAGES ADV6 heat_transport.adv DSP6 heat_transport.dsp SSM6 heat_transport.ssm - CNT6 heat_transport01.cnt LEFT - CNT6 heat_transport02.cnt RIGHT + CTP6 heat_transport01.ctp LEFT + CTP6 heat_transport02.ctp RIGHT OC6 heat_transport.oc END PACKAGES diff --git a/doc/mf6io/mf6ivar/md/mf6ivar.md b/doc/mf6io/mf6ivar/md/mf6ivar.md index deaa7b59742..ab05cd52908 100644 --- a/doc/mf6io/mf6ivar/md/mf6ivar.md +++ b/doc/mf6io/mf6ivar/md/mf6ivar.md @@ -1185,23 +1185,23 @@ | GWT | API | OPTIONS | MOVER | KEYWORD | keyword to indicate that this instance of the api boundary Package can be used with the Water Mover (MVR) Package. When the MOVER option is specified, additional memory is allocated within the package to store the available, provided, and received water. | | GWT | API | DIMENSIONS | MAXBOUND | INTEGER | integer value specifying the maximum number of api boundary cells that will be specified for use during any stress period. | | GWE | ADV | OPTIONS | SCHEME | STRING | scheme used to solve the advection term. Can be upstream, central, or TVD. If not specified, upstream weighting is the default weighting scheme. | -| GWE | CNT | OPTIONS | AUXILIARY | STRING (NAUX) | defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. | -| GWE | CNT | OPTIONS | AUXMULTNAME | STRING | name of auxiliary variable to be used as multiplier of temperature value. | -| GWE | CNT | OPTIONS | BOUNDNAMES | KEYWORD | keyword to indicate that boundary names may be provided with the list of constant temperature cells. | -| GWE | CNT | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of constant temperature information will be written to the listing file immediately after it is read. | -| GWE | CNT | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of constant temperature flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | -| GWE | CNT | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that constant temperature flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | -| GWE | CNT | OPTIONS | TS6 | KEYWORD | keyword to specify that record corresponds to a time-series file. | -| GWE | CNT | OPTIONS | FILEIN | KEYWORD | keyword to specify that an input filename is expected next. | -| GWE | CNT | OPTIONS | TS6_FILENAME | STRING | defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. | -| GWE | CNT | OPTIONS | OBS6 | KEYWORD | keyword to specify that record corresponds to an observations file. | -| GWE | CNT | OPTIONS | OBS6_FILENAME | STRING | name of input file to define observations for the Constant Temperature package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the Constant Temperature package. | -| GWE | CNT | DIMENSIONS | MAXBOUND | INTEGER | integer value specifying the maximum number of constant temperatures cells that will be specified for use during any stress period. | -| GWE | CNT | PERIOD | IPER | INTEGER | integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. | -| GWE | CNT | PERIOD | CELLID | INTEGER (NCELLDIM) | is the cell identifier, and depends on the type of grid that is used for the simulation. For a structured grid that uses the DIS input file, CELLID is the layer, row, and column. For a grid that uses the DISV input file, CELLID is the layer and CELL2D number. If the model uses the unstructured discretization (DISU) input file, CELLID is the node number for the cell. | -| GWE | CNT | PERIOD | TEMP | DOUBLE PRECISION | is the constant temperature value. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | -| GWE | CNT | PERIOD | AUX | DOUBLE PRECISION (NAUX) | represents the values of the auxiliary variables for each constant temperature. The values of auxiliary variables must be present for each constant temperature. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | -| GWE | CNT | PERIOD | BOUNDNAME | STRING | name of the constant temperature cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. | +| GWE | CTP | OPTIONS | AUXILIARY | STRING (NAUX) | defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. | +| GWE | CTP | OPTIONS | AUXMULTNAME | STRING | name of auxiliary variable to be used as multiplier of temperature value. | +| GWE | CTP | OPTIONS | BOUNDNAMES | KEYWORD | keyword to indicate that boundary names may be provided with the list of constant temperature cells. | +| GWE | CTP | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of constant temperature information will be written to the listing file immediately after it is read. | +| GWE | CTP | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of constant temperature flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | +| GWE | CTP | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that constant temperature flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | +| GWE | CTP | OPTIONS | TS6 | KEYWORD | keyword to specify that record corresponds to a time-series file. | +| GWE | CTP | OPTIONS | FILEIN | KEYWORD | keyword to specify that an input filename is expected next. | +| GWE | CTP | OPTIONS | TS6_FILENAME | STRING | defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. | +| GWE | CTP | OPTIONS | OBS6 | KEYWORD | keyword to specify that record corresponds to an observations file. | +| GWE | CTP | OPTIONS | OBS6_FILENAME | STRING | name of input file to define observations for the Constant Temperature package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the Constant Temperature package. | +| GWE | CTP | DIMENSIONS | MAXBOUND | INTEGER | integer value specifying the maximum number of constant temperatures cells that will be specified for use during any stress period. | +| GWE | CTP | PERIOD | IPER | INTEGER | integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. | +| GWE | CTP | PERIOD | CELLID | INTEGER (NCELLDIM) | is the cell identifier, and depends on the type of grid that is used for the simulation. For a structured grid that uses the DIS input file, CELLID is the layer, row, and column. For a grid that uses the DISV input file, CELLID is the layer and CELL2D number. If the model uses the unstructured discretization (DISU) input file, CELLID is the node number for the cell. | +| GWE | CTP | PERIOD | TEMP | DOUBLE PRECISION | is the constant temperature value. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | CTP | PERIOD | AUX | DOUBLE PRECISION (NAUX) | represents the values of the auxiliary variables for each constant temperature. The values of auxiliary variables must be present for each constant temperature. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | CTP | PERIOD | BOUNDNAME | STRING | name of the constant temperature cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. | | GWE | DIS | OPTIONS | LENGTH_UNITS | STRING | is the length units used for this model. Values can be ``FEET'', ``METERS'', or ``CENTIMETERS''. If not specified, the default is ``UNKNOWN''. | | GWE | DIS | OPTIONS | NOGRB | KEYWORD | keyword to deactivate writing of the binary grid file. | | GWE | DIS | OPTIONS | XORIGIN | DOUBLE PRECISION | x-position of the lower-left corner of the model grid. A default value of zero is assigned if not specified. The value for XORIGIN does not affect the model simulation, but it is written to the binary grid file so that postprocessors can locate the grid in space. | diff --git a/doc/mf6io/mf6ivar/mf6ivar.py b/doc/mf6io/mf6ivar/mf6ivar.py index a4de0c76b0d..dd56c9c5a80 100644 --- a/doc/mf6io/mf6ivar/mf6ivar.py +++ b/doc/mf6io/mf6ivar/mf6ivar.py @@ -740,7 +740,7 @@ def write_appendix(texdir, allblocks): "gwt-mvt", "gwt-api", "gwe-adv", - "gwe-cnt", + "gwe-ctp", "gwe-dis", "gwe-disv", "gwe-disu", diff --git a/doc/mf6io/mf6ivar/tex/appendixA.tex b/doc/mf6io/mf6ivar/tex/appendixA.tex index e01d4311182..cd82dfbfcb1 100644 --- a/doc/mf6io/mf6ivar/tex/appendixA.tex +++ b/doc/mf6io/mf6ivar/tex/appendixA.tex @@ -246,9 +246,9 @@ \hline GWE & ADV & OPTIONS & yes \\ \hline -GWE & CNT & OPTIONS & yes \\ -GWE & CNT & DIMENSIONS & yes \\ -GWE & CNT & PERIOD & yes \\ +GWE & CTP & OPTIONS & yes \\ +GWE & CTP & DIMENSIONS & yes \\ +GWE & CTP & PERIOD & yes \\ \hline GWE & DIS & OPTIONS & yes \\ GWE & DIS & DIMENSIONS & yes \\ diff --git a/doc/mf6io/mf6ivar/tex/gwe-ctp-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-ctp-desc.tex new file mode 100644 index 00000000000..5fd2b217104 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-ctp-desc.tex @@ -0,0 +1,49 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{auxiliary}---defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. + +\item \texttt{auxmultname}---name of auxiliary variable to be used as multiplier of temperature value. + +\item \texttt{BOUNDNAMES}---keyword to indicate that boundary names may be provided with the list of constant temperature cells. + +\item \texttt{PRINT\_INPUT}---keyword to indicate that the list of constant temperature information will be written to the listing file immediately after it is read. + +\item \texttt{PRINT\_FLOWS}---keyword to indicate that the list of constant temperature flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. + +\item \texttt{SAVE\_FLOWS}---keyword to indicate that constant temperature flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. + +\item \texttt{TS6}---keyword to specify that record corresponds to a time-series file. + +\item \texttt{FILEIN}---keyword to specify that an input filename is expected next. + +\item \texttt{ts6\_filename}---defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. + +\item \texttt{OBS6}---keyword to specify that record corresponds to an observations file. + +\item \texttt{obs6\_filename}---name of input file to define observations for the Constant Temperature package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the Constant Temperature package. + +\end{description} +\item \textbf{Block: DIMENSIONS} + +\begin{description} +\item \texttt{maxbound}---integer value specifying the maximum number of constant temperatures cells that will be specified for use during any stress period. + +\end{description} +\item \textbf{Block: PERIOD} + +\begin{description} +\item \texttt{iper}---integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. + +\item \texttt{cellid}---is the cell identifier, and depends on the type of grid that is used for the simulation. For a structured grid that uses the DIS input file, CELLID is the layer, row, and column. For a grid that uses the DISV input file, CELLID is the layer and CELL2D number. If the model uses the unstructured discretization (DISU) input file, CELLID is the node number for the cell. + +\item \textcolor{blue}{\texttt{temp}---is the constant temperature value. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{aux}---represents the values of the auxiliary variables for each constant temperature. The values of auxiliary variables must be present for each constant temperature. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \texttt{boundname}---name of the constant temperature cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-cnt-dimensions.dat b/doc/mf6io/mf6ivar/tex/gwe-ctp-dimensions.dat similarity index 100% rename from doc/mf6io/mf6ivar/tex/gwe-cnt-dimensions.dat rename to doc/mf6io/mf6ivar/tex/gwe-ctp-dimensions.dat diff --git a/doc/mf6io/mf6ivar/tex/gwe-cnt-options.dat b/doc/mf6io/mf6ivar/tex/gwe-ctp-options.dat similarity index 100% rename from doc/mf6io/mf6ivar/tex/gwe-cnt-options.dat rename to doc/mf6io/mf6ivar/tex/gwe-ctp-options.dat diff --git a/doc/mf6io/mf6ivar/tex/gwe-cnt-period.dat b/doc/mf6io/mf6ivar/tex/gwe-ctp-period.dat similarity index 100% rename from doc/mf6io/mf6ivar/tex/gwe-cnt-period.dat rename to doc/mf6io/mf6ivar/tex/gwe-ctp-period.dat diff --git a/make/makefile b/make/makefile index f6a79d09567..81d60610183 100644 --- a/make/makefile +++ b/make/makefile @@ -123,7 +123,7 @@ $(OBJDIR)/gwe1dsp1idm.o \ $(OBJDIR)/gwe1disv1idm.o \ $(OBJDIR)/gwe1disu1idm.o \ $(OBJDIR)/gwe1dis1idm.o \ -$(OBJDIR)/gwe1cnt1idm.o \ +$(OBJDIR)/gwe1ctp1idm.o \ $(OBJDIR)/gwtgwtidm.o \ $(OBJDIR)/gwfgwtidm.o \ $(OBJDIR)/gwfgwfidm.o \ @@ -282,7 +282,7 @@ $(OBJDIR)/gwf3evt8.o \ $(OBJDIR)/gwf3chd8.o \ $(OBJDIR)/gwe1mst1.o \ $(OBJDIR)/gwe1dsp1.o \ -$(OBJDIR)/gwe1cnt1.o \ +$(OBJDIR)/gwe1ctp1.o \ $(OBJDIR)/RouterBase.o \ $(OBJDIR)/ImsLinearSolver.o \ $(OBJDIR)/ims8base.o \ diff --git a/msvs/mf6core.vfproj b/msvs/mf6core.vfproj index 1fb9c23e4f9..c56c32586b9 100644 --- a/msvs/mf6core.vfproj +++ b/msvs/mf6core.vfproj @@ -141,8 +141,8 @@ - - + + diff --git a/src/Model/GroundWaterEnergy/gwe1.f90 b/src/Model/GroundWaterEnergy/gwe1.f90 index 2d7daa882d3..1154469e04b 100644 --- a/src/Model/GroundWaterEnergy/gwe1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1.f90 @@ -82,7 +82,7 @@ module GweModule !< integer(I4B), parameter :: GWE_NMULTIPKG = 50 character(len=LENPACKAGETYPE), dimension(GWE_NMULTIPKG) :: GWE_MULTIPKG - data GWE_MULTIPKG/'CNT6 ', 'SRC6 ', 'LKE6 ', 'SFE6 ', ' ', & ! 5 + data GWE_MULTIPKG/'CTP6 ', 'SRC6 ', 'LKE6 ', 'SFE6 ', ' ', & ! 5 &'MWE6 ', 'UZE6 ', 'API6 ', ' ', ' ', & ! 10 &40*' '/ ! 50 @@ -764,7 +764,7 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & ! -- modules use ConstantsModule, only: LINELENGTH use SimModule, only: store_error - use GweCntModule, only: cnt_create + use GweCtpModule, only: ctp_create !use GweSrcModule, only: src_create !use GweLkeModule, only: lke_create !use GweSfeModule, only: sfe_create @@ -788,8 +788,8 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & ! ! -- This part creates the package object select case (filtyp) - case ('CNT6') - call cnt_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + case ('CTP6') + call ctp_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & pakname, this%depvartype, mempath) !case ('SRC6') ! call src_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & diff --git a/src/Model/GroundWaterEnergy/gwe1cnt1.f90 b/src/Model/GroundWaterEnergy/gwe1ctp1.f90 similarity index 79% rename from src/Model/GroundWaterEnergy/gwe1cnt1.f90 rename to src/Model/GroundWaterEnergy/gwe1ctp1.f90 index 0d65110eba3..e8963a50bd2 100644 --- a/src/Model/GroundWaterEnergy/gwe1cnt1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1ctp1.f90 @@ -1,4 +1,4 @@ -module GweCntModule +module GweCtpModule ! use KindModule, only: DP, I4B use ConstantsModule, only: DZERO, DONE, NAMEDBOUNDFLAG, LENFTYPE, & @@ -17,35 +17,35 @@ module GweCntModule implicit none ! private - public :: cnt_create + public :: ctp_create ! - character(len=LENFTYPE) :: ftype = 'CNT' - character(len=LENPACKAGENAME) :: text = ' CNT' + character(len=LENFTYPE) :: ftype = 'CTP' + character(len=LENPACKAGENAME) :: text = ' CTP' ! - type, extends(BndExtType) :: GweCntType + type, extends(BndExtType) :: GweCtpType real(DP), dimension(:), pointer, contiguous :: tspvar => null() !< constant temperature array - real(DP), dimension(:), pointer, contiguous :: ratecntin => null() !< simulated flows into constant temperature (excluding other CNTs) - real(DP), dimension(:), pointer, contiguous :: ratecntout => null() !< simulated flows out of constant temperature (excluding to other CNTs) + real(DP), dimension(:), pointer, contiguous :: ratectpin => null() !< simulated flows into constant temperature (excluding other CNTs) + real(DP), dimension(:), pointer, contiguous :: ratectpout => null() !< simulated flows out of constant temperature (excluding to other CNTs) character(len=LENVARNAME) :: depvartype = '' !< stores string of dependent variable type, depending on model type contains - procedure :: bnd_rp => cnt_rp - procedure :: bnd_ad => cnt_ad - procedure :: bnd_ck => cnt_ck - procedure :: bnd_fc => cnt_fc - procedure :: bnd_cq => cnt_cq - procedure :: bnd_bd => cnt_bd - procedure :: bnd_da => cnt_da - procedure :: allocate_arrays => cnt_allocate_arrays + procedure :: bnd_rp => ctp_rp + procedure :: bnd_ad => ctp_ad + procedure :: bnd_ck => ctp_ck + procedure :: bnd_fc => ctp_fc + procedure :: bnd_cq => ctp_cq + procedure :: bnd_bd => ctp_bd + procedure :: bnd_da => ctp_da + procedure :: allocate_arrays => ctp_allocate_arrays procedure :: define_listlabel - procedure :: bound_value => cnt_bound_value + procedure :: bound_value => ctp_bound_value procedure :: temp_mult ! -- methods for observations - procedure, public :: bnd_obs_supported => cnt_obs_supported - procedure, public :: bnd_df_obs => cnt_df_obs + procedure, public :: bnd_obs_supported => ctp_obs_supported + procedure, public :: bnd_df_obs => ctp_df_obs ! -- method for time series - procedure, public :: bnd_rp_ts => cnt_rp_ts - end type GweCntType + procedure, public :: bnd_rp_ts => ctp_rp_ts + end type GweCtpType contains @@ -53,7 +53,7 @@ module GweCntModule !! !! Routine points packobj to the newly created package !< - subroutine cnt_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, & + subroutine ctp_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, & depvartype, mempath) ! -- dummy class(BndType), pointer :: packobj @@ -66,18 +66,18 @@ subroutine cnt_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, & character(len=LENVARNAME), intent(in) :: depvartype character(len=*), intent(in) :: mempath ! -- local - type(GweCntType), pointer :: cntobj + type(GweCtpType), pointer :: ctpobj ! ! -- allocate the object and assign values to object variables - allocate (cntobj) - packobj => cntobj + allocate (ctpobj) + packobj => ctpobj ! ! -- create name and memory path call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath) packobj%text = text ! ! -- allocate scalars - call cntobj%allocate_scalars() + call ctpobj%allocate_scalars() ! ! -- initialize package call packobj%pack_initialize() @@ -91,19 +91,19 @@ subroutine cnt_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, & packobj%iscloc = 1 ! ! -- Store the appropriate label based on the dependent variable - cntobj%depvartype = depvartype + ctpobj%depvartype = depvartype ! ! -- Return return - end subroutine cnt_create + end subroutine ctp_create !> @brief Allocate arrays specific to the constant temperature package !< - subroutine cnt_allocate_arrays(this, nodelist, auxvar) + subroutine ctp_allocate_arrays(this, nodelist, auxvar) ! -- modules use MemoryManagerModule, only: mem_allocate, mem_setptr, mem_checkin ! -- dummy - class(GweCntType) :: this + class(GweCtpType) :: this integer(I4B), dimension(:), pointer, contiguous, optional :: nodelist real(DP), dimension(:, :), pointer, contiguous, optional :: auxvar ! -- local @@ -112,13 +112,13 @@ subroutine cnt_allocate_arrays(this, nodelist, auxvar) ! -- call standard BndType allocate scalars call this%BndExtType%allocate_arrays(nodelist, auxvar) ! - ! -- allocate ratecntex - call mem_allocate(this%ratecntin, this%maxbound, 'RATECNTIN', this%memoryPath) - call mem_allocate(this%ratecntout, this%maxbound, 'RATECNTOUT', & + ! -- allocate ratectpex + call mem_allocate(this%ratectpin, this%maxbound, 'RATECTPIN', this%memoryPath) + call mem_allocate(this%ratectpout, this%maxbound, 'RATECTPOUT', & this%memoryPath) do i = 1, this%maxbound - this%ratecntin(i) = DZERO - this%ratecntout(i) = DZERO + this%ratectpin(i) = DZERO + this%ratectpout(i) = DZERO end do ! -- set constant head array input context pointer call mem_setptr(this%tspvar, 'TSPVAR', this%input_mempath) @@ -130,23 +130,23 @@ subroutine cnt_allocate_arrays(this, nodelist, auxvar) ! ! -- Return return - end subroutine cnt_allocate_arrays + end subroutine ctp_allocate_arrays !> @brief Constant temperature read and prepare (rp) routine !< - subroutine cnt_rp(this) + subroutine ctp_rp(this) ! -- modules use SimModule, only: store_error use InputOutputModule, only: lowcase implicit none ! -- dummy - class(GweCntType), intent(inout) :: this + class(GweCtpType), intent(inout) :: this ! -- local integer(I4B) :: i, node, ibd, ierr character(len=30) :: nodestr character(len=LENVARNAME) :: dvtype ! - ! -- Reset previous CNTs to active cell + ! -- Reset previous CTPs to active cell do i = 1, this%nbound node = this%nodelist(i) this%ibound(node) = this%ibcnum @@ -184,15 +184,15 @@ subroutine cnt_rp(this) ! ! -- Return return - end subroutine cnt_rp + end subroutine ctp_rp !> @brief Constant temperature package advance routine !! !! Add package connections to matrix !< - subroutine cnt_ad(this) + subroutine ctp_ad(this) ! -- dummy - class(GweCntType) :: this + class(GweCtpType) :: this ! -- local integer(I4B) :: i, node real(DP) :: cb @@ -216,19 +216,19 @@ subroutine cnt_ad(this) ! ! -- Return return - end subroutine cnt_ad + end subroutine ctp_ad !> @brief Check constant temperature boundary condition data !< - subroutine cnt_ck(this) + subroutine ctp_ck(this) ! -- dummy - class(GweCntType), intent(inout) :: this + class(GweCtpType), intent(inout) :: this ! -- local character(len=30) :: nodestr integer(I4B) :: i integer(I4B) :: node ! -- formats - character(len=*), parameter :: fmtcnterr = & + character(len=*), parameter :: fmtctperr = & &"('Specified dependent variable boundary ',i0, & &' temperature (',g0,') is less than zero for cell', a)" ! @@ -238,28 +238,28 @@ subroutine cnt_ck(this) ! -- accumulate errors if (this%temp_mult(i) < DZERO) then call this%dis%noder_to_string(node, nodestr) - write (errmsg, fmt=fmtcnterr) i, this%tspvar(i), trim(nodestr) + write (errmsg, fmt=fmtctperr) i, this%tspvar(i), trim(nodestr) call store_error(errmsg) end if end do ! - ! -- write summary of cnt package error messages + ! -- write summary of ctp package error messages if (count_errors() > 0) then call store_error_filename(this%input_fname) end if ! ! -- Return return - end subroutine cnt_ck + end subroutine ctp_ck !> @brief Override bnd_fc and do nothing !! !! For constant temperature boundary type, the call to bnd_fc needs to be !! overwritten to prevent logic found in bnd from being executed !< - subroutine cnt_fc(this, rhs, ia, idxglo, matrix_sln) + subroutine ctp_fc(this, rhs, ia, idxglo, matrix_sln) ! -- dummy - class(GweCntType) :: this + class(GweCtpType) :: this real(DP), dimension(:), intent(inout) :: rhs integer(I4B), dimension(:), intent(in) :: ia integer(I4B), dimension(:), intent(in) :: idxglo @@ -267,15 +267,15 @@ subroutine cnt_fc(this, rhs, ia, idxglo, matrix_sln) ! ! -- Return return - end subroutine cnt_fc + end subroutine ctp_fc !> @brief Calculate flow associated with constant temperature boundary !! !! This method overrides bnd_cq() !< - subroutine cnt_cq(this, x, flowja, iadv) + subroutine ctp_cq(this, x, flowja, iadv) ! -- dummy - class(GweCntType), intent(inout) :: this + class(GweCtpType), intent(inout) :: this real(DP), dimension(:), intent(in) :: x real(DP), dimension(:), contiguous, intent(inout) :: flowja integer(I4B), optional, intent(in) :: iadv @@ -317,15 +317,15 @@ subroutine cnt_cq(this, x, flowja, iadv) end if end do ! - ! -- For CNT, store total flow in rhs so it is available for other + ! -- For CTP, store total flow in rhs so it is available for other ! calculations this%rhs(i) = -rate this%hcof(i) = DZERO ! ! -- Save simulated value to simvals array. this%simvals(i) = rate - this%ratecntin(i) = ratein - this%ratecntout(i) = rateout + this%ratectpin(i) = ratein + this%ratectpout(i) = rateout flowja(idiag) = flowja(idiag) + rate ! end do @@ -334,16 +334,16 @@ subroutine cnt_cq(this, x, flowja, iadv) ! ! -- Return return - end subroutine cnt_cq + end subroutine ctp_cq !> @brief Add package ratin/ratout to model budget !< - subroutine cnt_bd(this, model_budget) + subroutine ctp_bd(this, model_budget) ! -- modules use TdisModule, only: delt use BudgetModule, only: BudgetType, rate_accumulator ! -- dummy - class(GweCntType) :: this + class(GweCtpType) :: this ! -- local type(BudgetType), intent(inout) :: model_budget real(DP) :: ratin @@ -352,36 +352,36 @@ subroutine cnt_bd(this, model_budget) integer(I4B) :: isuppress_output ! isuppress_output = 0 - call rate_accumulator(this%ratecntin(1:this%nbound), ratin, dum) - call rate_accumulator(this%ratecntout(1:this%nbound), ratout, dum) + call rate_accumulator(this%ratectpin(1:this%nbound), ratin, dum) + call rate_accumulator(this%ratectpout(1:this%nbound), ratout, dum) call model_budget%addentry(ratin, ratout, delt, this%text, & isuppress_output, this%packName) ! ! -- Return return - end subroutine cnt_bd + end subroutine ctp_bd !> @brief Deallocate memory !! !! Method to deallocate memory for the package. !< - subroutine cnt_da(this) + subroutine ctp_da(this) ! -- modules use MemoryManagerModule, only: mem_deallocate ! -- dummy - class(GweCntType) :: this + class(GweCtpType) :: this ! ! -- Deallocate parent package call this%BndExtType%bnd_da() ! ! -- arrays - call mem_deallocate(this%ratecntin) - call mem_deallocate(this%ratecntout) + call mem_deallocate(this%ratectpin) + call mem_deallocate(this%ratectpout) call mem_deallocate(this%tspvar, 'TSPVAR', this%memoryPath) ! ! -- Return return - end subroutine cnt_da + end subroutine ctp_da !> @brief Define labels used in list file !! @@ -390,7 +390,7 @@ end subroutine cnt_da !< subroutine define_listlabel(this) ! -- dummy - class(GweCntType), intent(inout) :: this + class(GweCtpType), intent(inout) :: this ! ! -- create the header list label this%listlabel = trim(this%filtyp)//' NO.' @@ -419,27 +419,27 @@ end subroutine define_listlabel !! This routine: !! - returns true because the SDV package supports observations, !! - overrides packagetype%_obs_supported() - logical function cnt_obs_supported(this) + logical function ctp_obs_supported(this) ! -- dummy - class(GweCntType) :: this + class(GweCtpType) :: this ! - cnt_obs_supported = .true. + ctp_obs_supported = .true. ! ! -- Return return - end function cnt_obs_supported + end function ctp_obs_supported !> @brief Procedure related to observation processing !! !! This routine: !! - defines observations !! - stores observation types supported by either of the SDV packages - !! (CNT or CNT), + !! (CTP or CTP), !! - overrides BndExtType%bnd_df_obs !< - subroutine cnt_df_obs(this) + subroutine ctp_df_obs(this) ! -- dummy - class(GweCntType) :: this + class(GweCtpType) :: this ! -- local integer(I4B) :: indx ! @@ -448,7 +448,7 @@ subroutine cnt_df_obs(this) ! ! -- Return return - end subroutine cnt_df_obs + end subroutine ctp_df_obs ! -- Procedure related to time series @@ -458,9 +458,9 @@ end subroutine cnt_df_obs !! For the constant temperature packages, the dependent variable can also be !! controlled by a time series. !< - subroutine cnt_rp_ts(this) + subroutine ctp_rp_ts(this) ! -- dummy - class(GweCntType), intent(inout) :: this + class(GweCtpType), intent(inout) :: this ! -- local integer(I4B) :: i, nlinks type(TimeSeriesLinkType), pointer :: tslink => null() @@ -478,7 +478,7 @@ subroutine cnt_rp_ts(this) ! ! -- Return return - end subroutine cnt_rp_ts + end subroutine ctp_rp_ts !> @brief Apply auxiliary multiplier to specified temperature if !< appropriate @@ -486,7 +486,7 @@ function temp_mult(this, row) result(temp) ! -- modules use ConstantsModule, only: DZERO ! -- dummy - class(GweCntType), intent(inout) :: this !< BndExtType object + class(GweCtpType), intent(inout) :: this !< BndExtType object integer(I4B), intent(in) :: row ! -- result real(DP) :: temp @@ -505,11 +505,11 @@ end function temp_mult !! !! Return a bound value associated with an ncolbnd index and row. !< - function cnt_bound_value(this, col, row) result(bndval) + function ctp_bound_value(this, col, row) result(bndval) ! -- modules use ConstantsModule, only: DZERO ! -- dummy variables - class(GweCntType), intent(inout) :: this !< BndExtType object + class(GweCtpType), intent(inout) :: this !< BndExtType object integer(I4B), intent(in) :: col integer(I4B), intent(in) :: row ! -- result @@ -528,6 +528,6 @@ function cnt_bound_value(this, col, row) result(bndval) ! ! -- Return return - end function cnt_bound_value + end function ctp_bound_value -end module GweCntModule +end module GweCtpModule diff --git a/src/Model/GroundWaterEnergy/gwe1cnt1idm.f90 b/src/Model/GroundWaterEnergy/gwe1ctp1idm.f90 similarity index 78% rename from src/Model/GroundWaterEnergy/gwe1cnt1idm.f90 rename to src/Model/GroundWaterEnergy/gwe1ctp1idm.f90 index 47f61e1c23d..3b2ca0a2889 100644 --- a/src/Model/GroundWaterEnergy/gwe1cnt1idm.f90 +++ b/src/Model/GroundWaterEnergy/gwe1ctp1idm.f90 @@ -1,16 +1,16 @@ ! ** Do Not Modify! MODFLOW 6 system generated file. ** -module GweCntInputModule +module GweCtpInputModule use ConstantsModule, only: LENVARNAME use InputDefinitionModule, only: InputParamDefinitionType, & InputBlockDefinitionType private - public gwe_cnt_param_definitions - public gwe_cnt_aggregate_definitions - public gwe_cnt_block_definitions - public GweCntParamFoundType - public gwe_cnt_multi_package + public gwe_ctp_param_definitions + public gwe_ctp_aggregate_definitions + public gwe_ctp_block_definitions + public GweCtpParamFoundType + public gwe_ctp_multi_package - type GweCntParamFoundType + type GweCtpParamFoundType logical :: auxiliary = .false. logical :: auxmultname = .false. logical :: boundnames = .false. @@ -29,15 +29,15 @@ module GweCntInputModule logical :: tspvar = .false. logical :: auxvar = .false. logical :: boundname = .false. - end type GweCntParamFoundType + end type GweCtpParamFoundType - logical :: gwe_cnt_multi_package = .true. + logical :: gwe_ctp_multi_package = .true. type(InputParamDefinitionType), parameter :: & - gwecnt_auxiliary = InputParamDefinitionType & + gwectp_auxiliary = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'OPTIONS', & ! block 'AUXILIARY', & ! tag name 'AUXILIARY', & ! fortran variable @@ -51,10 +51,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_auxmultname = InputParamDefinitionType & + gwectp_auxmultname = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'OPTIONS', & ! block 'AUXMULTNAME', & ! tag name 'AUXMULTNAME', & ! fortran variable @@ -68,10 +68,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_boundnames = InputParamDefinitionType & + gwectp_boundnames = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'OPTIONS', & ! block 'BOUNDNAMES', & ! tag name 'BOUNDNAMES', & ! fortran variable @@ -85,10 +85,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_iprflow = InputParamDefinitionType & + gwectp_iprflow = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'OPTIONS', & ! block 'PRINT_INPUT', & ! tag name 'IPRFLOW', & ! fortran variable @@ -102,10 +102,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_ipakcb = InputParamDefinitionType & + gwectp_ipakcb = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'OPTIONS', & ! block 'PRINT_FLOWS', & ! tag name 'IPAKCB', & ! fortran variable @@ -119,10 +119,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_iprpak = InputParamDefinitionType & + gwectp_iprpak = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'OPTIONS', & ! block 'SAVE_FLOWS', & ! tag name 'IPRPAK', & ! fortran variable @@ -136,10 +136,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_ts_filerecord = InputParamDefinitionType & + gwectp_ts_filerecord = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'OPTIONS', & ! block 'TS_FILERECORD', & ! tag name 'TS_FILERECORD', & ! fortran variable @@ -153,10 +153,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_ts6 = InputParamDefinitionType & + gwectp_ts6 = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'OPTIONS', & ! block 'TS6', & ! tag name 'TS6', & ! fortran variable @@ -170,10 +170,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_filein = InputParamDefinitionType & + gwectp_filein = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'OPTIONS', & ! block 'FILEIN', & ! tag name 'FILEIN', & ! fortran variable @@ -187,10 +187,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_ts6_filename = InputParamDefinitionType & + gwectp_ts6_filename = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'OPTIONS', & ! block 'TS6_FILENAME', & ! tag name 'TS6_FILENAME', & ! fortran variable @@ -204,10 +204,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_obs_filerecord = InputParamDefinitionType & + gwectp_obs_filerecord = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'OPTIONS', & ! block 'OBS_FILERECORD', & ! tag name 'OBS_FILERECORD', & ! fortran variable @@ -221,10 +221,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_obs6 = InputParamDefinitionType & + gwectp_obs6 = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'OPTIONS', & ! block 'OBS6', & ! tag name 'OBS6', & ! fortran variable @@ -238,10 +238,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_obs6_filename = InputParamDefinitionType & + gwectp_obs6_filename = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'OPTIONS', & ! block 'OBS6_FILENAME', & ! tag name 'OBS6_FILENAME', & ! fortran variable @@ -255,10 +255,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_maxbound = InputParamDefinitionType & + gwectp_maxbound = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'DIMENSIONS', & ! block 'MAXBOUND', & ! tag name 'MAXBOUND', & ! fortran variable @@ -272,10 +272,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_cellid = InputParamDefinitionType & + gwectp_cellid = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'PERIOD', & ! block 'CELLID', & ! tag name 'CELLID', & ! fortran variable @@ -289,10 +289,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_tspvar = InputParamDefinitionType & + gwectp_tspvar = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'PERIOD', & ! block 'TEMP', & ! tag name 'TSPVAR', & ! fortran variable @@ -306,10 +306,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_auxvar = InputParamDefinitionType & + gwectp_auxvar = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'PERIOD', & ! block 'AUX', & ! tag name 'AUXVAR', & ! fortran variable @@ -323,10 +323,10 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwecnt_boundname = InputParamDefinitionType & + gwectp_boundname = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'PERIOD', & ! block 'BOUNDNAME', & ! tag name 'BOUNDNAME', & ! fortran variable @@ -340,33 +340,33 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwe_cnt_param_definitions(*) = & + gwe_ctp_param_definitions(*) = & [ & - gwecnt_auxiliary, & - gwecnt_auxmultname, & - gwecnt_boundnames, & - gwecnt_iprflow, & - gwecnt_ipakcb, & - gwecnt_iprpak, & - gwecnt_ts_filerecord, & - gwecnt_ts6, & - gwecnt_filein, & - gwecnt_ts6_filename, & - gwecnt_obs_filerecord, & - gwecnt_obs6, & - gwecnt_obs6_filename, & - gwecnt_maxbound, & - gwecnt_cellid, & - gwecnt_tspvar, & - gwecnt_auxvar, & - gwecnt_boundname & + gwectp_auxiliary, & + gwectp_auxmultname, & + gwectp_boundnames, & + gwectp_iprflow, & + gwectp_ipakcb, & + gwectp_iprpak, & + gwectp_ts_filerecord, & + gwectp_ts6, & + gwectp_filein, & + gwectp_ts6_filename, & + gwectp_obs_filerecord, & + gwectp_obs6, & + gwectp_obs6_filename, & + gwectp_maxbound, & + gwectp_cellid, & + gwectp_tspvar, & + gwectp_auxvar, & + gwectp_boundname & ] type(InputParamDefinitionType), parameter :: & - gwecnt_spd = InputParamDefinitionType & + gwectp_spd = InputParamDefinitionType & ( & 'GWE', & ! component - 'CNT', & ! subcomponent + 'CTP', & ! subcomponent 'PERIOD', & ! block 'STRESS_PERIOD_DATA', & ! tag name 'SPD', & ! fortran variable @@ -380,13 +380,13 @@ module GweCntInputModule ) type(InputParamDefinitionType), parameter :: & - gwe_cnt_aggregate_definitions(*) = & + gwe_ctp_aggregate_definitions(*) = & [ & - gwecnt_spd & + gwectp_spd & ] type(InputBlockDefinitionType), parameter :: & - gwe_cnt_block_definitions(*) = & + gwe_ctp_block_definitions(*) = & [ & InputBlockDefinitionType( & 'OPTIONS', & ! blockname @@ -408,4 +408,4 @@ module GweCntInputModule ) & ] -end module GweCntInputModule +end module GweCtpInputModule diff --git a/src/Utilities/Idm/selector/IdmGweDfnSelector.f90 b/src/Utilities/Idm/selector/IdmGweDfnSelector.f90 index 08f2c670780..89714b44a1d 100644 --- a/src/Utilities/Idm/selector/IdmGweDfnSelector.f90 +++ b/src/Utilities/Idm/selector/IdmGweDfnSelector.f90 @@ -9,7 +9,7 @@ module IdmGweDfnSelectorModule use GweDisuInputModule use GweDisvInputModule use GweDspInputModule - use GweCntInputModule + use GweCtpInputModule use GweIcInputModule use GweNamInputModule @@ -48,8 +48,8 @@ function gwe_param_definitions(subcomponent) result(input_definition) call set_param_pointer(input_definition, gwe_disv_param_definitions) case ('DSP') call set_param_pointer(input_definition, gwe_dsp_param_definitions) - case ('CNT') - call set_param_pointer(input_definition, gwe_cnt_param_definitions) + case ('CTP') + call set_param_pointer(input_definition, gwe_ctp_param_definitions) case ('IC') call set_param_pointer(input_definition, gwe_ic_param_definitions) case ('NAM') @@ -72,8 +72,8 @@ function gwe_aggregate_definitions(subcomponent) result(input_definition) call set_param_pointer(input_definition, gwe_disv_aggregate_definitions) case ('DSP') call set_param_pointer(input_definition, gwe_dsp_aggregate_definitions) - case ('CNT') - call set_param_pointer(input_definition, gwe_cnt_aggregate_definitions) + case ('CTP') + call set_param_pointer(input_definition, gwe_ctp_aggregate_definitions) case ('IC') call set_param_pointer(input_definition, gwe_ic_aggregate_definitions) case ('NAM') @@ -96,8 +96,8 @@ function gwe_block_definitions(subcomponent) result(input_definition) call set_block_pointer(input_definition, gwe_disv_block_definitions) case ('DSP') call set_block_pointer(input_definition, gwe_dsp_block_definitions) - case ('CNT') - call set_block_pointer(input_definition, gwe_cnt_block_definitions) + case ('CTP') + call set_block_pointer(input_definition, gwe_ctp_block_definitions) case ('IC') call set_block_pointer(input_definition, gwe_ic_block_definitions) case ('NAM') @@ -119,8 +119,8 @@ function gwe_idm_multi_package(subcomponent) result(multi_package) multi_package = gwe_disv_multi_package case ('DSP') multi_package = gwe_dsp_multi_package - case ('CNT') - multi_package = gwe_cnt_multi_package + case ('CTP') + multi_package = gwe_ctp_multi_package case ('IC') multi_package = gwe_ic_multi_package case ('NAM') @@ -146,7 +146,7 @@ function gwe_idm_integrated(subcomponent) result(integrated) integrated = .true. case ('DSP') integrated = .true. - case ('CNT') + case ('CTP') integrated = .true. case ('IC') integrated = .true. diff --git a/src/meson.build b/src/meson.build index 05a5bf98e5c..1f68d653c95 100644 --- a/src/meson.build +++ b/src/meson.build @@ -59,8 +59,8 @@ modflow_sources = files( 'Model' / 'Geometry' / 'CircularGeometry.f90', 'Model' / 'Geometry' / 'RectangularGeometry.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1.f90', - 'Model' / 'GroundWaterEnergy' / 'gwe1cnt1.f90', - 'Model' / 'GroundWaterEnergy' / 'gwe1cnt1idm.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1ctp1.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1ctp1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1dis1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1disu1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1disv1idm.f90', diff --git a/utils/idmloader/scripts/dfn2f90.py b/utils/idmloader/scripts/dfn2f90.py index c8a4145e3e7..f9b4dc9b360 100644 --- a/utils/idmloader/scripts/dfn2f90.py +++ b/utils/idmloader/scripts/dfn2f90.py @@ -1014,8 +1014,8 @@ def _write_master_component(self, fh=None): SRC_PATH / "Model" / "GroundWaterEnergy" / "gwe1dsp1idm.f90", ], [ - DFN_PATH / "gwe-cnt.dfn", - SRC_PATH / "Model" / "GroundWaterEnergy" / "gwe1cnt1idm.f90", + DFN_PATH / "gwe-ctp.dfn", + SRC_PATH / "Model" / "GroundWaterEnergy" / "gwe1ctp1idm.f90", ], [ DFN_PATH / "gwe-ic.dfn", From a699f822b6908575ec469758204fd128f121faeb Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Wed, 17 Jan 2024 12:20:07 -0800 Subject: [PATCH 24/46] Missed an import renaming update --- src/Model/GroundWaterEnergy/gwe1.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/GroundWaterEnergy/gwe1.f90 b/src/Model/GroundWaterEnergy/gwe1.f90 index 1154469e04b..ffb14be1089 100644 --- a/src/Model/GroundWaterEnergy/gwe1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1.f90 @@ -966,7 +966,7 @@ subroutine create_gwe_packages(this, indis) case ('DSP6') this%indsp = 1 mempathdsp = mempath - case ('CNT6', 'SRC6', 'LKE6', 'SFE6', & + case ('CTP6', 'SRC6', 'LKE6', 'SFE6', & 'MWE6', 'UZE6', 'API6') call expandarray(bndpkgs) bndpkgs(size(bndpkgs)) = n From a0ee6e069e19bdf7ce7c2b6972a3f850769e7351 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Wed, 17 Jan 2024 17:29:41 -0800 Subject: [PATCH 25/46] Forgot to remove a now obsolete file due to renaming. --- doc/mf6io/mf6ivar/tex/gwe-cnt-desc.tex | 49 -------------------------- 1 file changed, 49 deletions(-) delete mode 100644 doc/mf6io/mf6ivar/tex/gwe-cnt-desc.tex diff --git a/doc/mf6io/mf6ivar/tex/gwe-cnt-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-cnt-desc.tex deleted file mode 100644 index 5fd2b217104..00000000000 --- a/doc/mf6io/mf6ivar/tex/gwe-cnt-desc.tex +++ /dev/null @@ -1,49 +0,0 @@ -% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py - -\item \textbf{Block: OPTIONS} - -\begin{description} -\item \texttt{auxiliary}---defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. - -\item \texttt{auxmultname}---name of auxiliary variable to be used as multiplier of temperature value. - -\item \texttt{BOUNDNAMES}---keyword to indicate that boundary names may be provided with the list of constant temperature cells. - -\item \texttt{PRINT\_INPUT}---keyword to indicate that the list of constant temperature information will be written to the listing file immediately after it is read. - -\item \texttt{PRINT\_FLOWS}---keyword to indicate that the list of constant temperature flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. - -\item \texttt{SAVE\_FLOWS}---keyword to indicate that constant temperature flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. - -\item \texttt{TS6}---keyword to specify that record corresponds to a time-series file. - -\item \texttt{FILEIN}---keyword to specify that an input filename is expected next. - -\item \texttt{ts6\_filename}---defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. - -\item \texttt{OBS6}---keyword to specify that record corresponds to an observations file. - -\item \texttt{obs6\_filename}---name of input file to define observations for the Constant Temperature package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the Constant Temperature package. - -\end{description} -\item \textbf{Block: DIMENSIONS} - -\begin{description} -\item \texttt{maxbound}---integer value specifying the maximum number of constant temperatures cells that will be specified for use during any stress period. - -\end{description} -\item \textbf{Block: PERIOD} - -\begin{description} -\item \texttt{iper}---integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. - -\item \texttt{cellid}---is the cell identifier, and depends on the type of grid that is used for the simulation. For a structured grid that uses the DIS input file, CELLID is the layer, row, and column. For a grid that uses the DISV input file, CELLID is the layer and CELL2D number. If the model uses the unstructured discretization (DISU) input file, CELLID is the node number for the cell. - -\item \textcolor{blue}{\texttt{temp}---is the constant temperature value. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} - -\item \textcolor{blue}{\texttt{aux}---represents the values of the auxiliary variables for each constant temperature. The values of auxiliary variables must be present for each constant temperature. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} - -\item \texttt{boundname}---name of the constant temperature cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. - -\end{description} - From b45754bd61c9b2258d08d4ccec5681dd011bfbcc Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Thu, 18 Jan 2024 10:45:08 -0800 Subject: [PATCH 26/46] Rebrand energy storage and transfer package acronym to EST --- autotest/test_gwe_drycell_conduction0.py | 6 +- autotest/test_gwe_drycell_conduction1.py | 6 +- autotest/test_gwe_drycell_conduction2.py | 6 +- autotest/test_gwe_dsp.py | 4 +- autotest/test_gwe_vs_gwt.py | 4 +- autotest/test_gwegwe_exchng_with_comp2gwt.py | 12 +- doc/mf6io/gwe/est.tex | 18 + doc/mf6io/gwe/gwe.tex | 10 +- doc/mf6io/gwe/mst.tex | 17 - doc/mf6io/gwe/namefile.tex | 2 +- .../mf6ivar/dfn/{gwe-mst.dfn => gwe-est.dfn} | 10 +- ...we-mst-example.dat => gwe-est-example.dat} | 1 + .../mf6ivar/examples/gwe-nam-example.dat | 2 +- doc/mf6io/mf6ivar/md/mf6ivar.md | 20 +- doc/mf6io/mf6ivar/md/mf6memvar.md | 1713 ++++++++++------- doc/mf6io/mf6ivar/mf6ivar.py | 2 +- doc/mf6io/mf6ivar/tex/appendixA.tex | 6 +- doc/mf6io/mf6ivar/tex/gwe-est-desc.tex | 35 + ...-mst-griddata.dat => gwe-est-griddata.dat} | 0 ...we-mst-options.dat => gwe-est-options.dat} | 0 ...ackagedata.dat => gwe-est-packagedata.dat} | 0 make/makefile | 2 +- msvs/mf6core.vfproj | 4 +- src/Distributed/VirtualGweModel.f90 | 24 +- src/Exchange/GwfGweExchange.f90 | 2 +- src/Model/Connection/GweGweConnection.f90 | 8 +- src/Model/Connection/GweInterfaceModel.f90 | 20 +- src/Model/GroundWaterEnergy/gwe1.f90 | 46 +- src/Model/GroundWaterEnergy/gwe1dsp1.f90 | 2 +- .../{gwe1mst1.f90 => gwe1est1.f90} | 164 +- src/Model/ModelUtilities/GweInputData.f90 | 22 +- src/Model/TransportModel/tsp1.f90 | 2 +- src/meson.build | 2 +- 33 files changed, 1245 insertions(+), 927 deletions(-) create mode 100644 doc/mf6io/gwe/est.tex delete mode 100644 doc/mf6io/gwe/mst.tex rename doc/mf6io/mf6ivar/dfn/{gwe-mst.dfn => gwe-est.dfn} (91%) rename doc/mf6io/mf6ivar/examples/{gwe-mst-example.dat => gwe-est-example.dat} (88%) create mode 100644 doc/mf6io/mf6ivar/tex/gwe-est-desc.tex rename doc/mf6io/mf6ivar/tex/{gwe-mst-griddata.dat => gwe-est-griddata.dat} (100%) rename doc/mf6io/mf6ivar/tex/{gwe-mst-options.dat => gwe-est-options.dat} (100%) rename doc/mf6io/mf6ivar/tex/{gwe-mst-packagedata.dat => gwe-est-packagedata.dat} (100%) rename src/Model/GroundWaterEnergy/{gwe1mst1.f90 => gwe1est1.f90} (89%) diff --git a/autotest/test_gwe_drycell_conduction0.py b/autotest/test_gwe_drycell_conduction0.py index b2b3c42cf74..083c67dd6ca 100644 --- a/autotest/test_gwe_drycell_conduction0.py +++ b/autotest/test_gwe_drycell_conduction0.py @@ -286,15 +286,15 @@ def build_models(idx, test): ) # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) - flopy.mf6.ModflowGwemst( + flopy.mf6.ModflowGweest( gwe1, save_flows=True, porosity=prsity, cps=760.0, rhos=1500.0, packagedata=[cpw, rhow, lhv], - pname="MST-2", - filename="{}.mst".format(gwename1), + pname="EST-2", + filename="{}.est".format(gwename1), ) # Instantiating MODFLOW 6 heat transport source-sink mixing package diff --git a/autotest/test_gwe_drycell_conduction1.py b/autotest/test_gwe_drycell_conduction1.py index 6636e19ce3c..810e7649782 100644 --- a/autotest/test_gwe_drycell_conduction1.py +++ b/autotest/test_gwe_drycell_conduction1.py @@ -325,15 +325,15 @@ def build_models(idx, test): ) # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) - flopy.mf6.ModflowGwemst( + flopy.mf6.ModflowGweest( gwe1, save_flows=True, porosity=prsity, cps=760.0, rhos=1500.0, packagedata=[cpw, rhow, lhv], - pname="MST-2", - filename="{}.mst".format(gwename1), + pname="EST-2", + filename="{}.est".format(gwename1), ) # Instantiate MODFLOW 6 heat transport output control package diff --git a/autotest/test_gwe_drycell_conduction2.py b/autotest/test_gwe_drycell_conduction2.py index fb53114c180..5fa4909b474 100644 --- a/autotest/test_gwe_drycell_conduction2.py +++ b/autotest/test_gwe_drycell_conduction2.py @@ -483,15 +483,15 @@ def build_models(idx, test): ) # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) - flopy.mf6.ModflowGwemst( + flopy.mf6.ModflowGweest( gwe, save_flows=True, porosity=prsity, cps=cps, rhos=rhos, packagedata=[cpw, rhow, lhv], - pname="MST-3", - filename="{}.mst".format(gwename), + pname="EST-3", + filename="{}.est".format(gwename), ) # Instantiating MODFLOW 6 transport source-sink mixing package diff --git a/autotest/test_gwe_dsp.py b/autotest/test_gwe_dsp.py index cae9878d394..23472c1a1c4 100644 --- a/autotest/test_gwe_dsp.py +++ b/autotest/test_gwe_dsp.py @@ -304,14 +304,14 @@ def build_models(idx, test): ) # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) - flopy.mf6.ModflowGwemst( + flopy.mf6.ModflowGweest( gwe, save_flows=True, porosity=prsity, cps=760.0, rhos=1500.0, packagedata=[cpw, rhow, lhv], - filename="{}.mst".format(gwename), + filename="{}.est".format(gwename), ) # Instantiating MODFLOW 6 transport constant concentration package diff --git a/autotest/test_gwe_vs_gwt.py b/autotest/test_gwe_vs_gwt.py index 5fc1a6ac9ed..ddf4dee1f80 100644 --- a/autotest/test_gwe_vs_gwt.py +++ b/autotest/test_gwe_vs_gwt.py @@ -319,13 +319,13 @@ def build_models(idx, test): ) # Instantiating MODFLOW 6 heat transport mass storage package (formerly "reaction" package in MT3DMS) - flopy.mf6.ModflowGwemst( + flopy.mf6.ModflowGweest( gwe, porosity=prsity, cps=760.0, packagedata=[cpw, rhow, lhv], rhos=1500.0, - filename="{}.mst".format(gwename), + filename="{}.est".format(gwename), ) # Instantiating MODFLOW 6 heat transport source-sink mixing package diff --git a/autotest/test_gwegwe_exchng_with_comp2gwt.py b/autotest/test_gwegwe_exchng_with_comp2gwt.py index 3885ee8e6dc..206d5ac0640 100644 --- a/autotest/test_gwegwe_exchng_with_comp2gwt.py +++ b/autotest/test_gwegwe_exchng_with_comp2gwt.py @@ -581,14 +581,14 @@ def add_upper_gwemodel(sim, scheme): ) # Instantiating MODFLOW 6 transport mass storage package - flopy.mf6.ModflowGwemst( + flopy.mf6.ModflowGweest( gwe, porosity=prsity, cps=cps, rhos=rhos, packagedata=[cpw, rhow, lhv], - pname="MST-UP", - filename="{}.mst".format(mname), + pname="EST-UP", + filename="{}.est".format(mname), ) # Instantiating MODFLOW 6 heat transport source-sink mixing package @@ -659,14 +659,14 @@ def add_lower_gwemodel(sim, scheme): ) # Instantiating MODFLOW 6 transport mass storage package - flopy.mf6.ModflowGwemst( + flopy.mf6.ModflowGweest( gwe, porosity=prsity, cps=cps, rhos=rhos, packagedata=[cpw, rhow, lhv], - pname="MST-LO", - filename="{}.mst".format(mname), + pname="EST-LO", + filename="{}.est".format(mname), ) # Instantiating MODFLOW 6 heat transport source-sink mixing package diff --git a/doc/mf6io/gwe/est.tex b/doc/mf6io/gwe/est.tex new file mode 100644 index 00000000000..4306af74ca3 --- /dev/null +++ b/doc/mf6io/gwe/est.tex @@ -0,0 +1,18 @@ +Energy Storage and Transfer (EST) Package information is read from the file that is specified by ``EST6'' as the file type. Only one EST Package can be specified for a GWE model. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-est-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-est-griddata.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-est-packagedata.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-est-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-est-example.dat} + diff --git a/doc/mf6io/gwe/gwe.tex b/doc/mf6io/gwe/gwe.tex index 0762434b13d..c94381f67dd 100644 --- a/doc/mf6io/gwe/gwe.tex +++ b/doc/mf6io/gwe/gwe.tex @@ -47,7 +47,7 @@ \subsection{Information for Existing Heat Transport Modelers} \item GWE and GWT use the same Source and Sink Mixing (SSM) Package for representing the effects of GWF stress package inflows and outflows on simulated temperatures and concentrations. In a GWE simulation, there are two ways in which users can assign concentrations to the individual features in these stress package. The first way is to activate a temperature auxiliary variable in the corresponding GWF stress package. In the SSM input file, the user provides the name of the auxiliary variable to be used for temperature. The second way is to create a special SPC file, which contains user-assigned time-varying temperatures for stress package features. -\item The GWE model includes an MST Package, but does not include an IST Package. Heat transport-related parameters such as thermal conductivities and heat capacities are specified in the MST Package. +\item The GWE model includes an EST Package, but does not include an IST Package. Heat transport-related parameters such as thermal conductivities and heat capacities are specified in the EST Package. \item A GWE-GWE Exchange (introduced in version 6.5.0) can be used to tightly couple multiple heat transport models, as might be done in a nested grid configuration. @@ -110,12 +110,12 @@ \subsection{Dispersion (DSP) Package} \input{gwe/dsp} \newpage -\subsection{Source and Sink Mixing (SSM) Package} -\input{gwe/ssm} +\subsection{Energy Storage and Transfer (EST) Package} +\input{gwe/est} \newpage -\subsection{Mobile Storage and Transfer (MST) Package} -\input{gwe/mst} +\subsection{Source and Sink Mixing (SSM) Package} +\input{gwe/ssm} \newpage \subsection{Constant Temperature (CTP) Package} diff --git a/doc/mf6io/gwe/mst.tex b/doc/mf6io/gwe/mst.tex deleted file mode 100644 index 283e3febead..00000000000 --- a/doc/mf6io/gwe/mst.tex +++ /dev/null @@ -1,17 +0,0 @@ -Mobile Storage and Transfer (MST) Package information is read from the file that is specified by ``MST6'' as the file type. Only one MST Package can be specified for a GWE model. - -\vspace{5mm} -\subsubsection{Structure of Blocks} -\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-mst-options.dat} -\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-mst-griddata.dat} - -\vspace{5mm} -\subsubsection{Explanation of Variables} -\begin{description} -\input{./mf6ivar/tex/gwe-mst-desc.tex} -\end{description} - -\vspace{5mm} -\subsubsection{Example Input File} -\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-mst-example.dat} - diff --git a/doc/mf6io/gwe/namefile.tex b/doc/mf6io/gwe/namefile.tex index dfb537a25d3..e23b8cb35de 100644 --- a/doc/mf6io/gwe/namefile.tex +++ b/doc/mf6io/gwe/namefile.tex @@ -31,7 +31,7 @@ \subsubsection{Explanation of Variables} ADV6 & Advection Package \\ DSP6 & Dispersion Package \\ SSM6 & Source and Sink Mixing Package \\ -MST6 & Mobile Storage and Transfer Package \\ +EST6 & Energy Storage and Transfer Package \\ CTP6 & Constant Temperature Package & * \\ OBS6 & Observations Option \\ \hline diff --git a/doc/mf6io/mf6ivar/dfn/gwe-mst.dfn b/doc/mf6io/mf6ivar/dfn/gwe-est.dfn similarity index 91% rename from doc/mf6io/mf6ivar/dfn/gwe-mst.dfn rename to doc/mf6io/mf6ivar/dfn/gwe-est.dfn index 75f780ba5df..a31e9a45697 100644 --- a/doc/mf6io/mf6ivar/dfn/gwe-mst.dfn +++ b/doc/mf6io/mf6ivar/dfn/gwe-est.dfn @@ -1,4 +1,4 @@ -# --------------------- gwe mst options --------------------- +# --------------------- gwe est options --------------------- block options name save_flows @@ -6,7 +6,7 @@ type keyword reader urword optional true longname save calculated flows to budget file -description REPLACE save_flows {'{#1}': 'MST'} +description REPLACE save_flows {'{#1}': 'EST'} block options name zero_order_decay @@ -22,9 +22,9 @@ type keyword reader urword optional true longname activate cooling associated with evaporation -description is a text keyword to indicate that cooling associated with evaporation will occur. Use of this keyword requires that LATHEATVAP are specified in the GRIDDATA block. While the MST package does not simulate evaporation, multiple other packages in a GWE simulation may. For example, evaporation may occur from the surface of streams or lakes. Owing to the energy consumed by the change in phase, the latent heat of vaporization is required. +description is a text keyword to indicate that cooling associated with evaporation will occur. Use of this keyword requires that LATHEATVAP are specified in the GRIDDATA block. While the EST package does not simulate evaporation, multiple other packages in a GWE simulation may. For example, evaporation may occur from the surface of streams or lakes. Owing to the energy consumed by the change in phase, the latent heat of vaporization is required. -# --------------------- gwe mst griddata --------------------- +# --------------------- gwe est griddata --------------------- block griddata name porosity @@ -63,7 +63,7 @@ layered true longname density of aquifer material description is a user-specified value of the density of aquifer material not considering the voids. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. -# --------------------- gwe mst packagedata --------------------- +# --------------------- gwe est packagedata --------------------- block packagedata name packagedata diff --git a/doc/mf6io/mf6ivar/examples/gwe-mst-example.dat b/doc/mf6io/mf6ivar/examples/gwe-est-example.dat similarity index 88% rename from doc/mf6io/mf6ivar/examples/gwe-mst-example.dat rename to doc/mf6io/mf6ivar/examples/gwe-est-example.dat index cce31b5124c..8c33d5a9bbc 100644 --- a/doc/mf6io/mf6ivar/examples/gwe-mst-example.dat +++ b/doc/mf6io/mf6ivar/examples/gwe-est-example.dat @@ -1,4 +1,5 @@ BEGIN OPTIONS + LATENT_HEAT_VAPORIZATION END OPTIONS BEGIN GRIDDATA diff --git a/doc/mf6io/mf6ivar/examples/gwe-nam-example.dat b/doc/mf6io/mf6ivar/examples/gwe-nam-example.dat index c753ed4713e..b1b57df5a27 100644 --- a/doc/mf6io/mf6ivar/examples/gwe-nam-example.dat +++ b/doc/mf6io/mf6ivar/examples/gwe-nam-example.dat @@ -5,7 +5,7 @@ END OPTIONS BEGIN PACKAGES DIS6 heat_transport.dis IC6 heat_transport.ic - MST6 heat_transport.mst + EST6 heat_transport.est ADV6 heat_transport.adv DSP6 heat_transport.dsp SSM6 heat_transport.ssm diff --git a/doc/mf6io/mf6ivar/md/mf6ivar.md b/doc/mf6io/mf6ivar/md/mf6ivar.md index ab05cd52908..3862fcb212b 100644 --- a/doc/mf6io/mf6ivar/md/mf6ivar.md +++ b/doc/mf6io/mf6ivar/md/mf6ivar.md @@ -1271,16 +1271,16 @@ | GWE | DSP | GRIDDATA | KTW | DOUBLE PRECISION (NODES) | thermal conductivity of the simulated fluid | | GWE | DSP | GRIDDATA | KTS | DOUBLE PRECISION (NODES) | thermal conductivity of the aquifer material | | GWE | IC | GRIDDATA | STRT | DOUBLE PRECISION (NODES) | is the initial (starting) temperature---that is, the temperature at the beginning of the GWE Model simulation. STRT must be specified for all GWE Model simulations. One value is read for every model cell. | -| GWE | MST | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that MST flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | -| GWE | MST | OPTIONS | ZERO_ORDER_DECAY | KEYWORD | is a text keyword to indicate that zero-order decay will occur. Use of this keyword requires that DECAY and DECAY\_SORBED (if sorption is active) are specified in the GRIDDATA block. | -| GWE | MST | OPTIONS | LATENT_HEAT_VAPORIZATION | KEYWORD | is a text keyword to indicate that cooling associated with evaporation will occur. Use of this keyword requires that LATHEATVAP are specified in the GRIDDATA block. While the MST package does not simulate evaporation, multiple other packages in a GWE simulation may. For example, evaporation may occur from the surface of streams or lakes. Owing to the energy consumed by the change in phase, the latent heat of vaporization is required. | -| GWE | MST | GRIDDATA | POROSITY | DOUBLE PRECISION (NODES) | is the mobile domain porosity, defined as the mobile domain pore volume per mobile domain volume. The GWE model does not support the concept of an immobile domain in the context of heat transport. | -| GWE | MST | GRIDDATA | DECAY | DOUBLE PRECISION (NODES) | is the rate coefficient for zero-order decay for the aqueous phase of the mobile domain. A negative value indicates heat (energy) production. The dimensions of decay for zero-order decay is energy per length cubed per time. Zero-order decay will have no effect on simulation results unless zero-order decay is specified in the options block. | -| GWE | MST | GRIDDATA | CPS | DOUBLE PRECISION (NODES) | is the mass-based heat capacity of dry solids (aquifer material). For example, units of J/kg/C may be used (or equivalent). | -| GWE | MST | GRIDDATA | RHOS | DOUBLE PRECISION (NODES) | is a user-specified value of the density of aquifer material not considering the voids. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. | -| GWE | MST | PACKAGEDATA | CPW | DOUBLE PRECISION | is the mass-based heat capacity of the simulated fluid. For example, units of J/kg/C may be used (or equivalent). | -| GWE | MST | PACKAGEDATA | RHOW | DOUBLE PRECISION | is a user-specified value of the density of water. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. | -| GWE | MST | PACKAGEDATA | LATHEATVAP | DOUBLE PRECISION | is the user-specified value for the latent heat of vaporization. For example, if working in SI units, values may be entered as kJ/kg. | +| GWE | EST | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that EST flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | +| GWE | EST | OPTIONS | ZERO_ORDER_DECAY | KEYWORD | is a text keyword to indicate that zero-order decay will occur. Use of this keyword requires that DECAY and DECAY\_SORBED (if sorption is active) are specified in the GRIDDATA block. | +| GWE | EST | OPTIONS | LATENT_HEAT_VAPORIZATION | KEYWORD | is a text keyword to indicate that cooling associated with evaporation will occur. Use of this keyword requires that LATHEATVAP are specified in the GRIDDATA block. While the EST package does not simulate evaporation, multiple other packages in a GWE simulation may. For example, evaporation may occur from the surface of streams or lakes. Owing to the energy consumed by the change in phase, the latent heat of vaporization is required. | +| GWE | EST | GRIDDATA | POROSITY | DOUBLE PRECISION (NODES) | is the mobile domain porosity, defined as the mobile domain pore volume per mobile domain volume. The GWE model does not support the concept of an immobile domain in the context of heat transport. | +| GWE | EST | GRIDDATA | DECAY | DOUBLE PRECISION (NODES) | is the rate coefficient for zero-order decay for the aqueous phase of the mobile domain. A negative value indicates heat (energy) production. The dimensions of decay for zero-order decay is energy per length cubed per time. Zero-order decay will have no effect on simulation results unless zero-order decay is specified in the options block. | +| GWE | EST | GRIDDATA | CPS | DOUBLE PRECISION (NODES) | is the mass-based heat capacity of dry solids (aquifer material). For example, units of J/kg/C may be used (or equivalent). | +| GWE | EST | GRIDDATA | RHOS | DOUBLE PRECISION (NODES) | is a user-specified value of the density of aquifer material not considering the voids. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. | +| GWE | EST | PACKAGEDATA | CPW | DOUBLE PRECISION | is the mass-based heat capacity of the simulated fluid. For example, units of J/kg/C may be used (or equivalent). | +| GWE | EST | PACKAGEDATA | RHOW | DOUBLE PRECISION | is a user-specified value of the density of water. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. | +| GWE | EST | PACKAGEDATA | LATHEATVAP | DOUBLE PRECISION | is the user-specified value for the latent heat of vaporization. For example, if working in SI units, values may be entered as kJ/kg. | | GWE | NAM | OPTIONS | LIST | STRING | is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the ``.lst'' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. | | GWE | NAM | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of all model stress package information will be written to the listing file immediately after it is read. | | GWE | NAM | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of all model package flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | diff --git a/doc/mf6io/mf6ivar/md/mf6memvar.md b/doc/mf6io/mf6ivar/md/mf6memvar.md index 50fb3e242ed..6343f14769b 100644 --- a/doc/mf6io/mf6ivar/md/mf6memvar.md +++ b/doc/mf6io/mf6ivar/md/mf6memvar.md @@ -2,38 +2,31 @@ | source file | module | type.variable name | variable name | dimensions | | :---: | :---: | :---: | :---: | :---: | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | AUXNAME | 2 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | ICELLAVG | 0 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | IVARCV | 0 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | IDEWATCV | 0 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | INEWTON | 0 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | IANGLEX | 0 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | ICDIST | 0 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | INGNC | 0 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | INMVR | 0 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | INOBS | 0 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | INAMEDBOUND | 0 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | SATOMEGA | 0 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | IHC | 1 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | CL1 | 1 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | CL2 | 1 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | HWVA | 1 | -| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | CONDSAT | 1 | -| NumericalExchange.f90 | NumericalExchangeModule | NumericalExchangeType | IMPLICIT | 0 | -| NumericalExchange.f90 | NumericalExchangeModule | NumericalExchangeType | IPRPAK | 0 | -| NumericalExchange.f90 | NumericalExchangeModule | NumericalExchangeType | IPRFLOW | 0 | -| NumericalExchange.f90 | NumericalExchangeModule | NumericalExchangeType | IPAKCB | 0 | -| NumericalExchange.f90 | NumericalExchangeModule | NumericalExchangeType | NEXG | 0 | -| NumericalExchange.f90 | NumericalExchangeModule | NumericalExchangeType | NAUX | 0 | -| NumericalExchange.f90 | NumericalExchangeModule | NumericalExchangeType | NODEM1 | 1 | -| NumericalExchange.f90 | NumericalExchangeModule | NumericalExchangeType | NODEM2 | 1 | -| NumericalExchange.f90 | NumericalExchangeModule | NumericalExchangeType | COND | 1 | -| NumericalExchange.f90 | NumericalExchangeModule | NumericalExchangeType | IDXGLO | 1 | -| NumericalExchange.f90 | NumericalExchangeModule | NumericalExchangeType | IDXSYMGLO | 1 | -| NumericalExchange.f90 | NumericalExchangeModule | NumericalExchangeType | AUXVAR | 2 | -| NumericalExchange.f90 | NumericalExchangeModule | NumericalExchangeType | AUXNAME | 2 | -| GwfGwtExchange.f90 | GwfGwtExchangeModule | GwfGwtExchangeType | M1ID | 0 | -| GwfGwtExchange.f90 | GwfGwtExchangeModule | GwfGwtExchangeType | M2ID | 0 | +| SimulationCreate.f90 | SimulationCreateModule | None | MRANKS | 1 | +| VirtualBase.f90 | VirtualBaseModule | VirtualIntType | var_name | 0 | +| VirtualBase.f90 | VirtualBaseModule | VirtualInt1dType | var_name | 1 | +| VirtualBase.f90 | VirtualBaseModule | VirtualDblType | var_name | 0 | +| VirtualBase.f90 | VirtualBaseModule | VirtualDbl1dType | var_name | 1 | +| VirtualBase.f90 | VirtualBaseModule | VirtualDbl2dType | var_name | 2 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | NEXG | 0 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | NAUX | 0 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | IANGLEX | 0 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | ICDIST | 0 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | IXT3D | 0 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | IPRPAK | 0 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | IPRFLOW | 0 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | IPAKCB | 0 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | INAMEDBOUND | 0 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | DEV_IFMOD_ON | 0 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | AUXNAME | 2 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | AUXNAME_CST | 2 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | NODEM1 | 1 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | NODEM2 | 1 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | IHC | 1 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | CL1 | 1 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | CL2 | 1 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | HWVA | 1 | +| DisConnExchange.f90 | DisConnExchangeModule | DisConnExchangeType | AUXVAR | 2 | | GhostNode.f90 | GhostNodeModule | GhostNodeType | SMGNC | 0 | | GhostNode.f90 | GhostNodeModule | GhostNodeType | IMPLICIT | 0 | | GhostNode.f90 | GhostNodeModule | GhostNodeType | I2KN | 0 | @@ -50,151 +43,37 @@ | GhostNode.f90 | GhostNodeModule | GhostNodeType | IDXSYMGLO | 1 | | GhostNode.f90 | GhostNodeModule | GhostNodeType | JPOSINROWN | 2 | | GhostNode.f90 | GhostNodeModule | GhostNodeType | JPOSINROWM | 2 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | ID | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IU | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | TTFORM | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | TTSOLN | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | NEQ | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | NJA | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | DVCLOSE | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | HICLOSE | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | BIGCHOLD | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | BIGCH | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | RELAXOLD | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | RES_PREV | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | RES_NEW | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | RES_IN | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IBCOUNT | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | ICNVG | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | ITERTOT_TIMESTEP | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | INNERTOT_SIM | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | MXITER | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | LINMETH | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | NONMETH | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IPRIMS | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | THETA | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | AKAPPA | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | GAMMA | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | AMOMENTUM | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | BREDUC | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | BTOL | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | RES_LIM | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | NUMTRACK | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IBFLAG | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | ICSVOUTEROUT | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | ICSVINNEROUT | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | NITERMAX | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | CONVNMOD | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IALLOWPTC | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IPTCOPT | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IPTCOUT | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | L2NORM0 | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | PTCFACT | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | PTCDEL | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | PTCDEL0 | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | PTCEXP | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | PTCTHRESH | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | PTCRAT | 0 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IA | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | X | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | RHS | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IACTIVE | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | XTEMP | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | DXOLD | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | HNCG | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | LRCH | 2 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | WSAVE | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | HCHOLD | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | DEOLD | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | CONVMODSTART | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | LOCDV | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | LOCDR | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | ITINNER | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | CONVLOCDV | 2 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | CONVLOCDR | 2 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | DVMAX | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | DRMAX | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | CONVDVMAX | 2 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | CONVDRMAX | 2 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | JA | 1 | -| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | AMAT | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | DSCALE | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | DSCALE2 | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IAPC | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | JAPC | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | APC | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IW | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | W | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | JLU | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | JW | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | WLU | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | LORDER | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IORDER | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IARO | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | JARO | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | ARO | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | ID | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | D | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | P | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | Q | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | Z | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | T | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | V | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | DHAT | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | PHAT | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | QHAT | 1 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IOUT | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | ILINMETH | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | ITER1 | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IPC | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | ISCL | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IORD | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NORTH | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | ICNVGOPT | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IACPC | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NITERC | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NIABCGS | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NIAPC | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NJAPC | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | DVCLOSE | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | RCLOSE | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | RELAX | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | EPFACT | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | L2NORM0 | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | DROPTOL | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | LEVEL | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NJLU | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NJW | 0 | -| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NWLU | 0 | -| tdis.f90 | TdisModule | None | NPER | 0 | -| tdis.f90 | TdisModule | None | ITMUNI | 0 | -| tdis.f90 | TdisModule | None | KPER | 0 | -| tdis.f90 | TdisModule | None | KSTP | 0 | -| tdis.f90 | TdisModule | None | READNEWDATA | 0 | -| tdis.f90 | TdisModule | None | ENDOFPERIOD | 0 | -| tdis.f90 | TdisModule | None | ENDOFSIMULATION | 0 | -| tdis.f90 | TdisModule | None | DELT | 0 | -| tdis.f90 | TdisModule | None | PERTIM | 0 | -| tdis.f90 | TdisModule | None | TOTIM | 0 | -| tdis.f90 | TdisModule | None | TOTIMC | 0 | -| tdis.f90 | TdisModule | None | DELTSAV | 0 | -| tdis.f90 | TdisModule | None | TOTIMSAV | 0 | -| tdis.f90 | TdisModule | None | PERTIMSAV | 0 | -| tdis.f90 | TdisModule | None | TOTALSIMTIME | 0 | -| tdis.f90 | TdisModule | None | PERLEN | 1 | -| tdis.f90 | TdisModule | None | NSTP | 1 | -| tdis.f90 | TdisModule | None | TSMULT | 1 | -| OutputControl.f90 | OutputControlModule | OutputControlType | INUNIT | 0 | -| OutputControl.f90 | OutputControlModule | OutputControlType | IOUT | 0 | -| OutputControl.f90 | OutputControlModule | OutputControlType | IPEROC | 0 | -| OutputControl.f90 | OutputControlModule | OutputControlType | IOCREP | 0 | -| NumericalModel.f90 | NumericalModelModule | NumericalModelType | NEQ | 0 | -| NumericalModel.f90 | NumericalModelModule | NumericalModelType | NJA | 0 | -| NumericalModel.f90 | NumericalModelModule | NumericalModelType | ICNVG | 0 | -| NumericalModel.f90 | NumericalModelModule | NumericalModelType | MOFFSET | 0 | -| NumericalModel.f90 | NumericalModelModule | NumericalModelType | XOLD | 1 | -| NumericalModel.f90 | NumericalModelModule | NumericalModelType | FLOWJA | 1 | -| NumericalModel.f90 | NumericalModelModule | NumericalModelType | IDXGLO | 1 | +| GweGweExchange.f90 | GweGweExchangeModule | GweExchangeType | INEWTON | 0 | +| GweGweExchange.f90 | GweGweExchangeModule | GweExchangeType | INOBS | 0 | +| GweGweExchange.f90 | GweGweExchangeModule | GweExchangeType | IADVSCHEME | 0 | +| GweGweExchange.f90 | GweGweExchangeModule | GweExchangeType | INMVT | 0 | +| GweGweExchange.f90 | GweGweExchangeModule | GweExchangeType | COND | 1 | +| GweGweExchange.f90 | GweGweExchangeModule | GweExchangeType | SIMVALS | 1 | +| GwfGweExchange.f90 | GwfGweExchangeModule | GwfGweExchangeType | M1ID | 0 | +| GwfGweExchange.f90 | GwfGweExchangeModule | GwfGweExchangeType | M2ID | 0 | +| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | ICELLAVG | 0 | +| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | IVARCV | 0 | +| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | IDEWATCV | 0 | +| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | INEWTON | 0 | +| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | INGNC | 0 | +| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | INMVR | 0 | +| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | INOBS | 0 | +| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | SATOMEGA | 0 | +| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | COND | 1 | +| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | IDXGLO | 1 | +| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | IDXSYMGLO | 1 | +| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | CONDSAT | 1 | +| GwfGwfExchange.f90 | GwfGwfExchangeModule | GwfExchangeType | SIMVALS | 1 | +| GwfGwtExchange.f90 | GwfGwtExchangeModule | GwfGwtExchangeType | M1ID | 0 | +| GwfGwtExchange.f90 | GwfGwtExchangeModule | GwfGwtExchangeType | M2ID | 0 | +| GwtGwtExchange.f90 | GwtGwtExchangeModule | GwtExchangeType | INEWTON | 0 | +| GwtGwtExchange.f90 | GwtGwtExchangeModule | GwtExchangeType | INOBS | 0 | +| GwtGwtExchange.f90 | GwtGwtExchangeModule | GwtExchangeType | IADVSCHEME | 0 | +| GwtGwtExchange.f90 | GwtGwtExchangeModule | GwtExchangeType | INMVT | 0 | +| GwtGwtExchange.f90 | GwtGwtExchangeModule | GwtExchangeType | COND | 1 | +| GwtGwtExchange.f90 | GwtGwtExchangeModule | GwtExchangeType | SIMVALS | 1 | +| BaseModel.f90 | BaseModelModule | BaseModelType | NAME | 1 | +| BaseModel.f90 | BaseModelModule | BaseModelType | MACRONYM | 1 | | BaseModel.f90 | BaseModelModule | BaseModelType | ID | 0 | | BaseModel.f90 | BaseModelModule | BaseModelType | IOUT | 0 | | BaseModel.f90 | BaseModelModule | BaseModelType | INEWTON | 0 | @@ -202,6 +81,16 @@ | BaseModel.f90 | BaseModelModule | BaseModelType | IPRFLOW | 0 | | BaseModel.f90 | BaseModelModule | BaseModelType | IPAKCB | 0 | | BaseModel.f90 | BaseModelModule | BaseModelType | IDSOLN | 0 | +| ExplicitModel.f90 | ExplicitModelModule | ExplicitModelType | IBOUND | 1 | +| NumericalModel.f90 | NumericalModelModule | NumericalModelType | NEQ | 0 | +| NumericalModel.f90 | NumericalModelModule | NumericalModelType | NJA | 0 | +| NumericalModel.f90 | NumericalModelModule | NumericalModelType | ICNVG | 0 | +| NumericalModel.f90 | NumericalModelModule | NumericalModelType | MOFFSET | 0 | +| NumericalModel.f90 | NumericalModelModule | NumericalModelType | XOLD | 1 | +| NumericalModel.f90 | NumericalModelModule | NumericalModelType | FLOWJA | 1 | +| NumericalModel.f90 | NumericalModelModule | NumericalModelType | IDXGLO | 1 | +| NumericalPackage.f90 | NumericalPackageModule | NumericalPackageType | INPUT_FNAME | 1 | +| NumericalPackage.f90 | NumericalPackageModule | NumericalPackageType | PACKAGE_TYPE | 1 | | NumericalPackage.f90 | NumericalPackageModule | NumericalPackageType | ID | 0 | | NumericalPackage.f90 | NumericalPackageModule | NumericalPackageType | INUNIT | 0 | | NumericalPackage.f90 | NumericalPackageModule | NumericalPackageType | IOUT | 0 | @@ -212,275 +101,296 @@ | NumericalPackage.f90 | NumericalPackageModule | NumericalPackageType | IPAKCB | 0 | | NumericalPackage.f90 | NumericalPackageModule | NumericalPackageType | IONPER | 0 | | NumericalPackage.f90 | NumericalPackageModule | NumericalPackageType | LASTONPER | 0 | -| gwt1.f90 | GwtModule | GwtModelType | INIC | 0 | -| gwt1.f90 | GwtModule | GwtModelType | INFMI | 0 | -| gwt1.f90 | GwtModule | GwtModelType | INMVT | 0 | -| gwt1.f90 | GwtModule | GwtModelType | INMST | 0 | -| gwt1.f90 | GwtModule | GwtModelType | INADV | 0 | -| gwt1.f90 | GwtModule | GwtModelType | INDSP | 0 | -| gwt1.f90 | GwtModule | GwtModelType | INSSM | 0 | -| gwt1.f90 | GwtModule | GwtModelType | INOC | 0 | -| gwt1.f90 | GwtModule | GwtModelType | INOBS | 0 | -| gwt1sft1.f90 | GwtSftModule | GwtSftType | IDXBUDSSM | 1 | -| gwt1sft1.f90 | GwtSftModule | GwtSftType | IDXBUDRAIN | 0 | -| gwt1sft1.f90 | GwtSftModule | GwtSftType | IDXBUDEVAP | 0 | -| gwt1sft1.f90 | GwtSftModule | GwtSftType | IDXBUDROFF | 0 | -| gwt1sft1.f90 | GwtSftModule | GwtSftType | IDXBUDIFLW | 0 | -| gwt1sft1.f90 | GwtSftModule | GwtSftType | IDXBUDOUTF | 0 | -| gwt1sft1.f90 | GwtSftModule | GwtSftType | CONCRAIN | 1 | -| gwt1sft1.f90 | GwtSftModule | GwtSftType | CONCEVAP | 1 | -| gwt1sft1.f90 | GwtSftModule | GwtSftType | CONCROFF | 1 | -| gwt1sft1.f90 | GwtSftModule | GwtSftType | CONCIFLW | 1 | -| gwt1uzt1.f90 | GwtUztModule | GwtUztType | IDXBUDSSM | 1 | -| gwt1uzt1.f90 | GwtUztModule | GwtUztType | IDXBUDINFL | 0 | -| gwt1uzt1.f90 | GwtUztModule | GwtUztType | IDXBUDRINF | 0 | -| gwt1uzt1.f90 | GwtUztModule | GwtUztType | IDXBUDUZET | 0 | -| gwt1uzt1.f90 | GwtUztModule | GwtUztType | IDXBUDRITM | 0 | -| gwt1uzt1.f90 | GwtUztModule | GwtUztType | CONCINFL | 1 | -| gwt1uzt1.f90 | GwtUztModule | GwtUztType | CONCUZET | 1 | -| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDSSM | 1 | -| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDRAIN | 0 | -| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDEVAP | 0 | -| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDROFF | 0 | -| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDIFLW | 0 | -| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDWDRL | 0 | -| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDOUTF | 0 | -| gwt1lkt1.f90 | GwtLktModule | GwtLktType | CONCRAIN | 1 | -| gwt1lkt1.f90 | GwtLktModule | GwtLktType | CONCEVAP | 1 | -| gwt1lkt1.f90 | GwtLktModule | GwtLktType | CONCROFF | 1 | -| gwt1lkt1.f90 | GwtLktModule | GwtLktType | CONCIFLW | 1 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | FLOWS_FROM_FILE | 0 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | IFLOWSUPDATED | 0 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | IFLOWERR | 0 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | IGWFSTRGSS | 0 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | IGWFSTRGSY | 0 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | IUBUD | 0 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | IUHDS | 0 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | IUMVR | 0 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | NFLOWPACK | 0 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | FLOWERR | 1 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | IBDGWFSAT0 | 1 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | GWFFLOWJA | 1 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | GWFSAT | 1 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | GWFHEAD | 1 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | GWFSPDIS | 2 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | GWFSTRGSS | 1 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | GWFSTRGSY | 1 | -| gwt1fmi1.f90 | GwtFmiModule | GwtFmiType | IATP | 1 | -| gwt1adv1.f90 | GwtAdvModule | GwtAdvType | IADVWT | 0 | -| gwt1mwt1.f90 | GwtMwtModule | GwtMwtType | IDXBUDSSM | 1 | -| gwt1mwt1.f90 | GwtMwtModule | GwtMwtType | IDXBUDRATE | 0 | -| gwt1mwt1.f90 | GwtMwtModule | GwtMwtType | IDXBUDFWRT | 0 | -| gwt1mwt1.f90 | GwtMwtModule | GwtMwtType | IDXBUDRTMV | 0 | -| gwt1mwt1.f90 | GwtMwtModule | GwtMwtType | IDXBUDFRTM | 0 | -| gwt1mwt1.f90 | GwtMwtModule | GwtMwtType | CONCRATE | 1 | -| gwt1mst1.f90 | GwtMstModule | GwtMstType | ISRB | 0 | -| gwt1mst1.f90 | GwtMstModule | GwtMstType | IDCY | 0 | -| gwt1mst1.f90 | GwtMstModule | GwtMstType | POROSITY | 1 | -| gwt1mst1.f90 | GwtMstModule | GwtMstType | PRSITY2 | 1 | -| gwt1mst1.f90 | GwtMstModule | GwtMstType | RATESTO | 1 | -| gwt1mst1.f90 | GwtMstModule | GwtMstType | RATEDCY | 1 | -| gwt1mst1.f90 | GwtMstModule | GwtMstType | DECAY | 1 | -| gwt1mst1.f90 | GwtMstModule | GwtMstType | RATEDCYS | 1 | -| gwt1mst1.f90 | GwtMstModule | GwtMstType | DECAY_SORBED | 1 | -| gwt1mst1.f90 | GwtMstModule | GwtMstType | BULK_DENSITY | 1 | -| gwt1mst1.f90 | GwtMstModule | GwtMstType | SP2 | 1 | -| gwt1mst1.f90 | GwtMstModule | GwtMstType | DISTCOEF | 1 | -| gwt1mst1.f90 | GwtMstModule | GwtMstType | RATESRB | 1 | -| gwt1ist1.f90 | GwtIstModule | GwtIstType | ICIMOUT | 0 | -| gwt1ist1.f90 | GwtIstModule | GwtIstType | ISRB | 0 | -| gwt1ist1.f90 | GwtIstModule | GwtIstType | IDCY | 0 | -| gwt1ist1.f90 | GwtIstModule | GwtIstType | STRG | 1 | -| gwt1ist1.f90 | GwtIstModule | GwtIstType | CIM | 1 | -| gwt1ist1.f90 | GwtIstModule | GwtIstType | ZETAIM | 1 | -| gwt1ist1.f90 | GwtIstModule | GwtIstType | THETAIM | 1 | -| gwt1ist1.f90 | GwtIstModule | GwtIstType | BULK_DENSITY | 1 | -| gwt1ist1.f90 | GwtIstModule | GwtIstType | DISTCOEF | 1 | -| gwt1ist1.f90 | GwtIstModule | GwtIstType | DECAY | 1 | -| gwt1ist1.f90 | GwtIstModule | GwtIstType | DECAY_SORBED | 1 | -| gwt1mvt1.f90 | GwtMvtModule | GwtMvtType | MAXPACKAGES | 0 | -| gwt1mvt1.f90 | GwtMvtModule | GwtMvtType | IBUDGETOUT | 0 | -| gwt1ssm1.f90 | GwtSsmModule | GwtSsmType | NBOUND | 0 | -| gwt1ssm1.f90 | GwtSsmModule | GwtSsmType | IAUXPAK | 1 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | IAUXFPCONC | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | IMATROWS | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | IPRCONC | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | ICONCOUT | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | IBUDGETOUT | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | IGWFAPTPAK | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | NCV | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | IDXBUDFJF | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | IDXBUDGWF | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | IDXBUDSTO | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | IDXBUDTMVR | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | IDXBUDFMVR | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | IDXBUDAUX | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | NCONCBUDSSM | 0 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | DBUFF | 1 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | CONCFEAT | 1 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | QSTO | 1 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | CCTERM | 1 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | CONCBUDSSM | 2 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | QMFROMMVR | 1 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | STRT | 1 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | LAUXVAR | 2 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | IBOUND | 1 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | XNEWPAK | 1 | -| gwt1apt1.f90 | GwtAptModule | GwtAptType | XOLDPAK | 1 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | IDIFFC | 0 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | IDISP | 0 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | IXT3D | 0 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | ID22 | 0 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | ID33 | 0 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | IANGLE1 | 0 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | IANGLE2 | 0 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | IANGLE3 | 0 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | ALH | 1 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | ALV | 1 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | ATH1 | 1 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | ATH2 | 1 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | ATV | 1 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | DIFFC | 1 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | D11 | 1 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | D22 | 1 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | D33 | 1 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | ANGLE1 | 1 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | ANGLE2 | 1 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | ANGLE3 | 1 | -| gwt1dsp.f90 | GwtDspModule | GwtDspType | DISPCOEF | 1 | -| BoundaryPackage.f90 | BndModule | BndType | LISTLABEL | 1 | -| BoundaryPackage.f90 | BndModule | BndType | IBCNUM | 0 | -| BoundaryPackage.f90 | BndModule | BndType | MAXBOUND | 0 | -| BoundaryPackage.f90 | BndModule | BndType | NBOUND | 0 | -| BoundaryPackage.f90 | BndModule | BndType | NCOLBND | 0 | -| BoundaryPackage.f90 | BndModule | BndType | ISCLOC | 0 | -| BoundaryPackage.f90 | BndModule | BndType | NAUX | 0 | -| BoundaryPackage.f90 | BndModule | BndType | INAMEDBOUND | 0 | -| BoundaryPackage.f90 | BndModule | BndType | IAUXMULTCOL | 0 | -| BoundaryPackage.f90 | BndModule | BndType | INOBSPKG | 0 | -| BoundaryPackage.f90 | BndModule | BndType | IMOVER | 0 | -| BoundaryPackage.f90 | BndModule | BndType | NPAKEQ | 0 | -| BoundaryPackage.f90 | BndModule | BndType | IOFFSET | 0 | -| BoundaryPackage.f90 | BndModule | BndType | AUXNAME | 2 | -| BoundaryPackage.f90 | BndModule | BndType | NODELIST | 1 | -| BoundaryPackage.f90 | BndModule | BndType | NOUPDATEAUXVAR | 1 | -| BoundaryPackage.f90 | BndModule | BndType | BOUND | 2 | -| BoundaryPackage.f90 | BndModule | BndType | HCOF | 1 | -| BoundaryPackage.f90 | BndModule | BndType | RHS | 1 | -| BoundaryPackage.f90 | BndModule | BndType | SIMVALS | 1 | -| BoundaryPackage.f90 | BndModule | BndType | SIMTOMVR | 1 | -| BoundaryPackage.f90 | BndModule | BndType | AUXVAR | 2 | -| BoundaryPackage.f90 | BndModule | BndType | BOUNDNAME | 2 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | INUNIT | 0 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | IOUT | 0 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | NODES | 0 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | NODESUSER | 0 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | NDIM | 0 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | ICONDIR | 0 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | WRITEGRB | 0 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | XORIGIN | 0 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | YORIGIN | 0 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | ANGROT | 0 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | NJA | 0 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | NJAS | 0 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | LENUNI | 0 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | MSHAPE | 1 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | TOP | 1 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | BOT | 1 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | AREA | 1 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | DBUFF | 1 | -| DiscretizationBase.f90 | BaseDisModule | DisBaseType | IBUFF | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | UZDPST | 2 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | UZTHST | 2 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | UZFLST | 2 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | UZSPST | 2 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | NWAVST | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | UZOLSFLX | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | THTR | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | THTS | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | THTI | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | EPS | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | HA | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | HROOT | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | ROOTACT | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | EXTWC | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | ETACT | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | NWAV | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | NTRAIL | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | UZSTOR | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | DELSTOR | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | TOTFLUX | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | VFLOW | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | SINF | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | FINF | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | FINF_REJ | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | GWET | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | UZFAREA | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | CELLAREA | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | CELTOP | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | CELBOT | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | LANDTOP | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | CVLM1 | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | WATAB | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | WATABOLD | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | SURFDEP | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | VKS | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | SURFLUX | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | SURFLUXBELOW | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | SURFSEEP | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | GWPET | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | PET | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | PETMAX | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | EXTDP | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | EXTDPUZ | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | LANDFLAG | 1 | -| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | IVERTCON | 1 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | IAX | 1 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | JAX | 1 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | IDXGLOX | 1 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | IXT3D | 0 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | NBRMAX | 0 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | INUNIT | 0 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | IOUT | 0 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | INEWTON | 0 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | NUMEXTNBRS | 0 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | NOZEE | 0 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | VCTHRESH | 0 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | LAMATSAVED | 0 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | LDISPERSION | 0 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | QSAT | 1 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | IALLPC | 1 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | AMATPC | 1 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | AMATPCX | 1 | -| Xt3dInterface.f90 | Xt3dModule | Xt3dType | RMATCK | 2 | -| Connections.f90 | ConnectionsModule | ConnectionsType | NODES | 0 | -| Connections.f90 | ConnectionsModule | ConnectionsType | NJA | 0 | -| Connections.f90 | ConnectionsModule | ConnectionsType | NJAS | 0 | -| Connections.f90 | ConnectionsModule | ConnectionsType | IANGLEX | 0 | -| Connections.f90 | ConnectionsModule | ConnectionsType | IA | 1 | -| Connections.f90 | ConnectionsModule | ConnectionsType | JA | 1 | -| Connections.f90 | ConnectionsModule | ConnectionsType | ISYM | 1 | -| Connections.f90 | ConnectionsModule | ConnectionsType | JAS | 1 | -| Connections.f90 | ConnectionsModule | ConnectionsType | HWVA | 1 | -| Connections.f90 | ConnectionsModule | ConnectionsType | ANGLEX | 1 | -| Connections.f90 | ConnectionsModule | ConnectionsType | IHC | 1 | -| Connections.f90 | ConnectionsModule | ConnectionsType | CL1 | 1 | -| Connections.f90 | ConnectionsModule | ConnectionsType | CL2 | 1 | -| Connections.f90 | ConnectionsModule | ConnectionsType | IAUSR | 1 | -| Connections.f90 | ConnectionsModule | ConnectionsType | JAUSR | 1 | -| Connections.f90 | ConnectionsModule | ConnectionsType | MASK | 1 | -| PackageMover.f90 | PackageMoverModule | PackageMoverType | NPROVIDERS | 0 | -| PackageMover.f90 | PackageMoverModule | PackageMoverType | NRECEIVERS | 0 | -| PackageMover.f90 | PackageMoverModule | PackageMoverType | IPRMAP | 1 | -| PackageMover.f90 | PackageMoverModule | PackageMoverType | QTFORMVR | 1 | -| PackageMover.f90 | PackageMoverModule | PackageMoverType | QFORMVR | 1 | -| PackageMover.f90 | PackageMoverModule | PackageMoverType | QTOMVR | 1 | -| PackageMover.f90 | PackageMoverModule | PackageMoverType | QFROMMVR | 1 | +| GridConnection.f90 | GridConnectionModule | GridConnectionType | IDXTOGLOBALIDX | 1 | +| GridConnection.f90 | GridConnectionModule | GridConnectionType | NRBNDCELLS | 0 | +| GridConnection.f90 | GridConnectionModule | GridConnectionType | IDXCOUNT | 0 | +| GridConnection.f90 | GridConnectionModule | GridConnectionType | NRCELLS | 0 | +| GweGweConnection.f90 | GweGweConnectionModule | GweGweConnectionType | IADVSCHEME | 0 | +| GweGweConnection.f90 | GweGweConnectionModule | GweGweConnectionType | IXT3D | 0 | +| GweGweConnection.f90 | GweGweConnectionModule | GweGweConnectionType | EXGFLOWSIGN | 0 | +| GweGweConnection.f90 | GweGweConnectionModule | GweGweConnectionType | EXGFLOWJAGWT | 1 | +| GweInterfaceModel.f90 | GweInterfaceModelModule | GweInterfaceModelType | ADVSCHEME | 0 | +| GweInterfaceModel.f90 | GweInterfaceModelModule | GweInterfaceModelType | IXT3D | 0 | +| GweInterfaceModel.f90 | GweInterfaceModelModule | GweInterfaceModelType | IEQNSCLFAC | 0 | +| GweInterfaceModel.f90 | GweInterfaceModelModule | GweInterfaceModelType | GWFFLOWJA | 1 | +| GweInterfaceModel.f90 | GweInterfaceModelModule | GweInterfaceModelType | GWFHEAD | 1 | +| GweInterfaceModel.f90 | GweInterfaceModelModule | GweInterfaceModelType | GWFSAT | 1 | +| GweInterfaceModel.f90 | GweInterfaceModelModule | GweInterfaceModelType | GWFSPDIS | 2 | +| GweInterfaceModel.f90 | GweInterfaceModelModule | GweInterfaceModelType | create_mem_path(this%name | 2 | +| GwfGwfConnection.f90 | GwfGwfConnectionModule | GwfGwfConnectionType | IXT3DEXG | 0 | +| GwtGwtConnection.f90 | GwtGwtConnectionModule | GwtGwtConnectionType | IADVSCHEME | 0 | +| GwtGwtConnection.f90 | GwtGwtConnectionModule | GwtGwtConnectionType | IXT3D | 0 | +| GwtGwtConnection.f90 | GwtGwtConnectionModule | GwtGwtConnectionType | EXGFLOWSIGN | 0 | +| GwtGwtConnection.f90 | GwtGwtConnectionModule | GwtGwtConnectionType | EXGFLOWJAGWT | 1 | +| GwtInterfaceModel.f90 | GwtInterfaceModelModule | GwtInterfaceModelType | ADVSCHEME | 0 | +| GwtInterfaceModel.f90 | GwtInterfaceModelModule | GwtInterfaceModelType | IXT3D | 0 | +| GwtInterfaceModel.f90 | GwtInterfaceModelModule | GwtInterfaceModelType | IEQNSCLFAC | 0 | +| GwtInterfaceModel.f90 | GwtInterfaceModelModule | GwtInterfaceModelType | GWFFLOWJA | 1 | +| GwtInterfaceModel.f90 | GwtInterfaceModelModule | GwtInterfaceModelType | GWFHEAD | 1 | +| GwtInterfaceModel.f90 | GwtInterfaceModelModule | GwtInterfaceModelType | GWFSAT | 1 | +| GwtInterfaceModel.f90 | GwtInterfaceModelModule | GwtInterfaceModelType | GWFSPDIS | 2 | +| GwtInterfaceModel.f90 | GwtInterfaceModelModule | GwtInterfaceModelType | create_mem_path(this%name | 2 | +| SpatialModelConnection.f90 | SpatialModelConnectionModule | SpatialModelConnectionType | NEQ | 0 | +| SpatialModelConnection.f90 | SpatialModelConnectionModule | SpatialModelConnectionType | INTSTDEPTH | 0 | +| SpatialModelConnection.f90 | SpatialModelConnectionModule | SpatialModelConnectionType | EXGSTDEPTH | 0 | +| SpatialModelConnection.f90 | SpatialModelConnectionModule | SpatialModelConnectionType | NROFCONNS | 0 | +| SpatialModelConnection.f90 | SpatialModelConnectionModule | SpatialModelConnectionType | X | 1 | +| SpatialModelConnection.f90 | SpatialModelConnectionModule | SpatialModelConnectionType | RHS | 1 | +| SpatialModelConnection.f90 | SpatialModelConnectionModule | SpatialModelConnectionType | IACTIVE | 1 | +| gwe1.f90 | GweModule | GweModelType | INEST | 0 | +| gwe1.f90 | GweModule | GweModelType | INDSP | 0 | +| gwe1ctp1.f90 | GweCtpModule | GweCtpType | RATECTPIN | 1 | +| gwe1ctp1.f90 | GweCtpModule | GweCtpType | RATECTPOUT | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IDISP | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IALH | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IALV | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IATH1 | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IATH2 | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IATV | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IXT3DOFF | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IXT3DRHS | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IXT3D | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | ID22 | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | ID33 | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IANGLE1 | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IANGLE2 | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IANGLE3 | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IKTW | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | IKTS | 0 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | ALH | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | ALV | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | ATH1 | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | ATH2 | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | ATV | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | D11 | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | D22 | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | D33 | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | ANGLE1 | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | ANGLE2 | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | ANGLE3 | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | KTW | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | KTS | 1 | +| gwe1dsp1.f90 | GweDspModule | GweDspType | DISPCOEF | 1 | +| gwe1est1.f90 | GweEstModule | GweEstType | CPW | 0 | +| gwe1est1.f90 | GweEstModule | GweEstType | RHOW | 0 | +| gwe1est1.f90 | GweEstModule | GweEstType | LATHEATVAP | 0 | +| gwe1est1.f90 | GweEstModule | GweEstType | IDCY | 0 | +| gwe1est1.f90 | GweEstModule | GweEstType | ILHV | 0 | +| gwe1est1.f90 | GweEstModule | GweEstType | POROSITY | 1 | +| gwe1est1.f90 | GweEstModule | GweEstType | RATESTO | 1 | +| gwe1est1.f90 | GweEstModule | GweEstType | CPS | 1 | +| gwe1est1.f90 | GweEstModule | GweEstType | RHOS | 1 | +| gwe1est1.f90 | GweEstModule | GweEstType | RATEDCY | 1 | +| gwe1est1.f90 | GweEstModule | GweEstType | DECAY | 1 | +| gwe1est1.f90 | GweEstModule | GweEstType | DECAYLAST | 1 | +| gwf3.f90 | GwfModule | GwfModelType | INIC | 0 | +| gwf3.f90 | GwfModule | GwfModelType | INOC | 0 | +| gwf3.f90 | GwfModule | GwfModelType | INNPF | 0 | +| gwf3.f90 | GwfModule | GwfModelType | INBUY | 0 | +| gwf3.f90 | GwfModule | GwfModelType | INVSC | 0 | +| gwf3.f90 | GwfModule | GwfModelType | INSTO | 0 | +| gwf3.f90 | GwfModule | GwfModelType | INCSUB | 0 | +| gwf3.f90 | GwfModule | GwfModelType | INMVR | 0 | +| gwf3.f90 | GwfModule | GwfModelType | INHFB | 0 | +| gwf3.f90 | GwfModule | GwfModelType | INGNC | 0 | +| gwf3.f90 | GwfModule | GwfModelType | INOBS | 0 | +| gwf3.f90 | GwfModule | GwfModelType | ISS | 0 | +| gwf3.f90 | GwfModule | GwfModelType | INEWTONUR | 0 | +| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | IOUTDENSE | 0 | +| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | IFORM | 0 | +| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | IREADELEV | 0 | +| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | IREADCONCBUY | 0 | +| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | ICONCSET | 0 | +| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | DENSEREF | 0 | +| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | NRHOSPECIES | 0 | +| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | DENSE | 1 | +| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | CONCBUY | 1 | +| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | ELEV | 1 | +| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | DRHODC | 1 | +| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | CRHOREF | 1 | +| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | CTEMP | 1 | +| gwf3chd8.f90 | ChdModule | ChdType | RATECHDIN | 1 | +| gwf3chd8.f90 | ChdModule | ChdType | RATECHDOUT | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | LISTLABEL | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | STONAME | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISTOUNIT | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | INOBSPKG | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | NINTERBEDS | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | MAXSIG0 | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | NBOUND | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISCLOC | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IAUXMULTCOL | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | NDELAYCELLS | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | NDELAYBEDS | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | INITIALIZED | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IESLAG | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IPCH | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | LHEAD_BASED | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IUPDATESTRESS | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISPECIFIED_PCS | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISPECIFIED_DBH | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | INAMEDBOUND | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ICONVCHK | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | NAUX | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISTORAGEC | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISTRAINIB | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISTRAINSK | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IOUTCOMP | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IOUTCOMPI | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IOUTCOMPE | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IOUTCOMPIB | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IOUTCOMPS | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IOUTZDISP | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IPAKCSV | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IUPDATEMATPROP | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | EPSILON | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CC_CRIT | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | GAMMAW | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | BETA | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | BRG | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | SATOMEGA | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ICELLF | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | GWFISS0 | 0 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | AUXNAME | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | BUFF | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | BUFFUSR | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | SGM | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | SGS | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_SKE_CR | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_ES | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_ES0 | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_PCS | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_COMP | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_TCOMP | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_STOR | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_SKE | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_SK | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_THICKINI | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_THETAINI | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_THICK | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_THICK0 | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_THETA | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_THETA0 | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CELL_WCSTOR | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CELL_THICK | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | AUXVAR | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | UNODELIST | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | NODELIST | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CG_GS | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | PCS | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | RNB | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | KV | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | H0 | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CI | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | RCI | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IDELAY | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IELASTIC | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ICONVERT | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | COMP | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | TCOMP | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | TCOMPI | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | TCOMPE | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | STORAGEE | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | STORAGEI | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | SKE | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | SK | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | THICKINI | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | THETAINI | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | THICK | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | THICK0 | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | THETA | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | THETA0 | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | BOUNDNAME | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | NODELISTSIG0 | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | SIG0 | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IDB_NCONV_COUNT | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IDBCONVERT | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBDHMAX | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBZ | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBRELZ | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBH | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBH0 | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBGEO | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBES | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBES0 | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBPCS | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBFLOWTOP | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBFLOWBOT | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBDZINI | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBTHETAINI | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBCOMP | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBTCOMP | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBDZ | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBDZ0 | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBTHETA | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBTHETA0 | 2 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBAL | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBAD | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBAU | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBRHS | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBDH | 1 | +| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | DBAW | 1 | +| gwf3dis8.f90 | GwfDisModule | GwfDisType | DELR | 1 | +| gwf3dis8.f90 | GwfDisModule | GwfDisType | DELC | 1 | +| gwf3dis8.f90 | GwfDisModule | GwfDisType | IDOMAIN | 3 | +| gwf3dis8.f90 | GwfDisModule | GwfDisType | TOP2D | 2 | +| gwf3dis8.f90 | GwfDisModule | GwfDisType | BOT3D | 3 | +| gwf3dis8.f90 | GwfDisModule | GwfDisType | CELLX | 1 | +| gwf3dis8.f90 | GwfDisModule | GwfDisType | CELLY | 1 | +| gwf3dis8.f90 | GwfDisModule | GwfDisType | NLAY | 0 | +| gwf3dis8.f90 | GwfDisModule | GwfDisType | NROW | 0 | +| gwf3dis8.f90 | GwfDisModule | GwfDisType | NCOL | 0 | +| gwf3dis8.f90 | GwfDisModule | GwfDisType | NODEUSER | 1 | +| gwf3dis8.f90 | GwfDisModule | GwfDisType | NODEREDUCED | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | TOP1D | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | BOT1D | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | AREA1D | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | IDOMAIN | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | VERTICES | 2 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | IAINP | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | JAINP | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | IHCINP | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | CL12INP | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | HWVAINP | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | ANGLDEGXINP | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | CELLXY | 2 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | IAVERT | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | JAVERT | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | NJAUSR | 0 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | NVERT | 0 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | VOFFSETTOL | 0 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | IANGLEDEGX | 0 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | NODEUSER | 1 | +| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | NODEREDUCED | 1 | +| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | IDOMAIN | 2 | +| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | TOP1D | 1 | +| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | BOT2D | 2 | +| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | VERTICES | 2 | +| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | CELLXY | 2 | +| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | IAVERT | 1 | +| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | JAVERT | 1 | +| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | NLAY | 0 | +| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | NCPL | 0 | +| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | NVERT | 0 | +| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | NODEUSER | 1 | +| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | NODEREDUCED | 1 | | gwf3drn8.f90 | DrnModule | DrnType | IAUXDDRNCOL | 0 | | gwf3drn8.f90 | DrnModule | DrnType | ICUBIC_SCALING | 0 | +| gwf3evt8.f90 | EvtModule | EvtType | NSEG | 0 | +| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | MAXHFB | 0 | +| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | NHFB | 0 | +| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | IVSC | 0 | +| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | NODEN | 1 | +| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | NODEM | 1 | +| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | HYDCHR | 1 | +| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | IDXLOC | 1 | +| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | CSATSAV | 1 | +| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | CONDSAV | 1 | +| gwf3ic8.f90 | GwfIcModule | GwfIcType | STRT | 1 | | gwf3lak8.f90 | LakModule | LakType | IPRHED | 0 | | gwf3lak8.f90 | LakModule | LakType | ISTAGEOUT | 0 | | gwf3lak8.f90 | LakModule | LakType | IBUDGETOUT | 0 | +| gwf3lak8.f90 | LakModule | LakType | IBUDCSV | 0 | | gwf3lak8.f90 | LakModule | LakType | IPAKCSV | 0 | | gwf3lak8.f90 | LakModule | LakType | NLAKES | 0 | | gwf3lak8.f90 | LakModule | LakType | NOUTLETS | 0 | @@ -491,10 +401,12 @@ | gwf3lak8.f90 | LakModule | LakType | IGWHCOPT | 0 | | gwf3lak8.f90 | LakModule | LakType | ICONVCHK | 0 | | gwf3lak8.f90 | LakModule | LakType | ICONVRESIDCHK | 0 | +| gwf3lak8.f90 | LakModule | LakType | MAXLAKIT | 0 | | gwf3lak8.f90 | LakModule | LakType | SURFDEP | 0 | +| gwf3lak8.f90 | LakModule | LakType | DMAXCHG | 0 | | gwf3lak8.f90 | LakModule | LakType | DELH | 0 | | gwf3lak8.f90 | LakModule | LakType | PDMAX | 0 | -| gwf3lak8.f90 | LakModule | LakType | check_attr | 0 | +| gwf3lak8.f90 | LakModule | LakType | CHECK_ATTR | 0 | | gwf3lak8.f90 | LakModule | LakType | BDITEMS | 0 | | gwf3lak8.f90 | LakModule | LakType | CBCAUXITEMS | 0 | | gwf3lak8.f90 | LakModule | LakType | IDENSE | 0 | @@ -503,6 +415,7 @@ | gwf3lak8.f90 | LakModule | LakType | QLEAK | 1 | | gwf3lak8.f90 | LakModule | LakType | QSTO | 1 | | gwf3lak8.f90 | LakModule | LakType | DENSETERMS | 2 | +| gwf3lak8.f90 | LakModule | LakType | VISCRATIOS | 2 | | gwf3lak8.f90 | LakModule | LakType | NLAKECONN | 1 | | gwf3lak8.f90 | LakModule | LakType | IDXLAKECONN | 1 | | gwf3lak8.f90 | LakModule | LakType | NTABROW | 1 | @@ -578,34 +491,19 @@ | gwf3lak8.f90 | LakModule | LakType | OUTROUGH | 1 | | gwf3lak8.f90 | LakModule | LakType | OUTSLOPE | 1 | | gwf3lak8.f90 | LakModule | LakType | SIMOUTRATE | 1 | -| gwf3disv8.f90 | GwfDisvModule | None | IDOMAIN | 3 | -| gwf3disv8.f90 | GwfDisvModule | None | TOP2D | 2 | -| gwf3disv8.f90 | GwfDisvModule | None | BOT3D | 3 | -| gwf3disv8.f90 | GwfDisvModule | None | VERTICES | 2 | -| gwf3disv8.f90 | GwfDisvModule | None | CELLXY | 2 | -| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | IDOMAIN | 3 | -| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | TOP2D | 2 | -| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | BOT3D | 3 | -| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | VERTICES | 2 | -| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | CELLXY | 2 | -| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | IAVERT | 1 | -| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | JAVERT | 1 | -| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | NLAY | 0 | -| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | NCPL | 0 | -| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | NVERT | 0 | -| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | NODEUSER | 1 | -| gwf3disv8.f90 | GwfDisvModule | GwfDisvType | NODEREDUCED | 1 | | gwf3maw8.f90 | MawModule | MawType | CORRECT_FLOW | 0 | | gwf3maw8.f90 | MawModule | MawType | IPRHED | 0 | | gwf3maw8.f90 | MawModule | MawType | IHEADOUT | 0 | | gwf3maw8.f90 | MawModule | MawType | IBUDGETOUT | 0 | +| gwf3maw8.f90 | MawModule | MawType | IBUDCSV | 0 | | gwf3maw8.f90 | MawModule | MawType | IFLOWINGWELLS | 0 | | gwf3maw8.f90 | MawModule | MawType | IMAWISS | 0 | | gwf3maw8.f90 | MawModule | MawType | IMAWISSOPT | 0 | | gwf3maw8.f90 | MawModule | MawType | NMAWWELLS | 0 | -| gwf3maw8.f90 | MawModule | MawType | check_attr | 0 | +| gwf3maw8.f90 | MawModule | MawType | CHECK_ATTR | 0 | | gwf3maw8.f90 | MawModule | MawType | ISHUTOFFCNT | 0 | | gwf3maw8.f90 | MawModule | MawType | IEFFRADOPT | 0 | +| gwf3maw8.f90 | MawModule | MawType | IOUTREDFLOWCSV | 0 | | gwf3maw8.f90 | MawModule | MawType | SATOMEGA | 0 | | gwf3maw8.f90 | MawModule | MawType | BDITEMS | 0 | | gwf3maw8.f90 | MawModule | MawType | THETA | 0 | @@ -659,15 +557,15 @@ | gwf3maw8.f90 | MawModule | MawType | QSTO | 1 | | gwf3maw8.f90 | MawModule | MawType | QCONST | 1 | | gwf3maw8.f90 | MawModule | MawType | DENSETERMS | 2 | +| gwf3maw8.f90 | MawModule | MawType | VISCRATIOS | 2 | | gwf3maw8.f90 | MawModule | MawType | IDXLOCNODE | 1 | | gwf3maw8.f90 | MawModule | MawType | IDXDGLO | 1 | | gwf3maw8.f90 | MawModule | MawType | IDXOFFDGLO | 1 | | gwf3maw8.f90 | MawModule | MawType | IDXSYMDGLO | 1 | | gwf3maw8.f90 | MawModule | MawType | IDXSYMOFFDGLO | 1 | | gwf3maw8.f90 | MawModule | MawType | XOLDPAK | 1 | -| gwf3evt8.f90 | EvtModule | EvtType | INIEVT | 0 | -| gwf3evt8.f90 | EvtModule | EvtType | NSEG | 0 | | gwf3mvr8.f90 | GwfMvrModule | GwfMvrType | IBUDGETOUT | 0 | +| gwf3mvr8.f90 | GwfMvrModule | GwfMvrType | IBUDCSV | 0 | | gwf3mvr8.f90 | GwfMvrModule | GwfMvrType | MAXMVR | 0 | | gwf3mvr8.f90 | GwfMvrModule | GwfMvrType | MAXPACKAGES | 0 | | gwf3mvr8.f90 | GwfMvrModule | GwfMvrType | MAXCOMB | 0 | @@ -675,166 +573,66 @@ | gwf3mvr8.f90 | GwfMvrModule | GwfMvrType | IEXGMVR | 0 | | gwf3mvr8.f90 | GwfMvrModule | GwfMvrType | IMODELNAMES | 0 | | gwf3mvr8.f90 | GwfMvrModule | GwfMvrType | IENTRIES | 1 | -| gwf3.f90 | GwfModule | GwfModelType | INIC | 0 | -| gwf3.f90 | GwfModule | GwfModelType | INOC | 0 | -| gwf3.f90 | GwfModule | GwfModelType | INNPF | 0 | -| gwf3.f90 | GwfModule | GwfModelType | INBUY | 0 | -| gwf3.f90 | GwfModule | GwfModelType | INSTO | 0 | -| gwf3.f90 | GwfModule | GwfModelType | INCSUB | 0 | -| gwf3.f90 | GwfModule | GwfModelType | INMVR | 0 | -| gwf3.f90 | GwfModule | GwfModelType | INHFB | 0 | -| gwf3.f90 | GwfModule | GwfModelType | INGNC | 0 | -| gwf3.f90 | GwfModule | GwfModelType | INOBS | 0 | -| gwf3.f90 | GwfModule | GwfModelType | ISS | 0 | -| gwf3.f90 | GwfModule | GwfModelType | INEWTONUR | 0 | -| gwf3dis8.f90 | GwfDisModule | None | DELR | 1 | -| gwf3dis8.f90 | GwfDisModule | None | DELC | 1 | -| gwf3dis8.f90 | GwfDisModule | None | IDOMAIN | 3 | -| gwf3dis8.f90 | GwfDisModule | None | TOP2D | 2 | -| gwf3dis8.f90 | GwfDisModule | None | BOT3D | 3 | -| gwf3dis8.f90 | GwfDisModule | GwfDisType | DELR | 1 | -| gwf3dis8.f90 | GwfDisModule | GwfDisType | DELC | 1 | -| gwf3dis8.f90 | GwfDisModule | GwfDisType | IDOMAIN | 3 | -| gwf3dis8.f90 | GwfDisModule | GwfDisType | TOP2D | 2 | -| gwf3dis8.f90 | GwfDisModule | GwfDisType | BOT3D | 3 | -| gwf3dis8.f90 | GwfDisModule | GwfDisType | CELLX | 1 | -| gwf3dis8.f90 | GwfDisModule | GwfDisType | CELLY | 1 | -| gwf3dis8.f90 | GwfDisModule | GwfDisType | NLAY | 0 | -| gwf3dis8.f90 | GwfDisModule | GwfDisType | NROW | 0 | -| gwf3dis8.f90 | GwfDisModule | GwfDisType | NCOL | 0 | -| gwf3dis8.f90 | GwfDisModule | GwfDisType | NODEUSER | 1 | -| gwf3dis8.f90 | GwfDisModule | GwfDisType | NODEREDUCED | 1 | -| gwf3ic8.f90 | GwfIcModule | GwfIcType | STRT | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | AUXNAME | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | LISTLABEL | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | STONAME | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISTOUNIT | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | INOBSPKG | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | NINTERBEDS | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | MAXSIG0 | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | NBOUND | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISCLOC | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IAUXMULTCOL | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | NDELAYCELLS | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | NDELAYBEDS | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | INITIALIZED | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IESLAG | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IPCH | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | LHEAD_BASED | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IUPDATESTRESS | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISPECIFIED_PCS | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISPECIFIED_DBH | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | INAMEDBOUND | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ICONVCHK | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | NAUX | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISTORAGEC | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISTRAINIB | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ISTRAINSK | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IOUTCOMP | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IOUTCOMPI | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IOUTCOMPE | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IOUTCOMPIB | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IOUTCOMPS | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IOUTZDISP | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IPAKCSV | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | IUPDATEMATPROP | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | EPSILON | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | CC_CRIT | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | GAMMAW | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | BETA | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | BRG | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | SATOMEGA | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ICELLF | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | GWFISS0 | 0 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | BUFF | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | buffusr | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | sgm | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | sgs | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_ske_cr | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_es | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_es0 | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_pcs | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_comp | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_tcomp | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_stor | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_ske | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_sk | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_thickini | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_thetaini | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_thick | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_thick0 | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_theta | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_theta0 | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cell_wcstor | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cell_thick | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | AUXVAR | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | unodelist | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | nodelist | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | cg_gs | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | pcs | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | rnb | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | kv | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | h0 | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ci | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | rci | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | idelay | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ielastic | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | iconvert | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | comp | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | tcomp | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | tcompi | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | tcompe | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | storagee | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | storagei | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | ske | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | sk | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | thickini | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | thetaini | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | thick | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | thick0 | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | theta | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | theta0 | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | BOUNDNAME | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | NODELISTSIG0 | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | SIG0 | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | idb_nconv_count | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | idbconvert | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbdhmax | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbz | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbrelz | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbh | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbh0 | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbgeo | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbes | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbes0 | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbpcs | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbflowtop | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbflowbot | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbdzini | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbthetaini | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbcomp | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbtcomp | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbdz | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbdz0 | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbtheta | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbtheta0 | 2 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbal | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbad | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbau | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbrhs | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbdh | 1 | -| gwf3csub8.f90 | GwfCsubModule | GwfCsubType | dbaw | 1 | -| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | MAXHFB | 0 | -| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | NHFB | 0 | -| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | NODEN | 1 | -| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | NODEM | 1 | -| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | HYDCHR | 1 | -| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | IDXLOC | 1 | -| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | CSATSAV | 1 | -| gwf3hfb8.f90 | GwfHfbModule | GwfHfbType | CONDSAV | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | INAME | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IXT3D | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IXT3DRHS | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | SATOMEGA | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | HNOFLO | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | HDRY | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ICELLAVG | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IAVGKEFF | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IK22 | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IK33 | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IK22OVERK | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IK33OVERK | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IPERCHED | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IVARCV | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IDEWATCV | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ITHICKSTRT | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IUSGNRHC | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | INWTUPW | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ICALCSPDIS | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ISAVSPDIS | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ISAVSAT | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IREWET | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | WETFCT | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IWETIT | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IHDWET | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | SATMIN | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IANGLE1 | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IANGLE2 | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IANGLE3 | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IWETDRY | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | NEDGES | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | LASTEDGE | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | INTVK | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | INVSC | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | KCHANGEPER | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | KCHANGESTP | 0 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ITHICKSTARTFLAG | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ICELLTYPE | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | K11 | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | SAT | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | CONDSAT | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | K22 | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | K33 | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | WETDRY | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ANGLE1 | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ANGLE2 | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ANGLE3 | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IBOTNODE | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | NODEDGE | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IHCEDGE | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | PROPSEDGE | 2 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | K11INPUT | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | K22INPUT | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | K33INPUT | 1 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | SPDIS | 2 | +| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | NODEKCHANGE | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | IPRHED | 0 | | gwf3sfr8.f90 | SfrModule | SfrType | ISTAGEOUT | 0 | | gwf3sfr8.f90 | SfrModule | SfrType | IBUDGETOUT | 0 | +| gwf3sfr8.f90 | SfrModule | SfrType | IBUDCSV | 0 | | gwf3sfr8.f90 | SfrModule | SfrType | IPAKCSV | 0 | | gwf3sfr8.f90 | SfrModule | SfrType | IDIVERSIONS | 0 | | gwf3sfr8.f90 | SfrModule | SfrType | MAXSFRPICARD | 0 | @@ -842,6 +640,8 @@ | gwf3sfr8.f90 | SfrModule | SfrType | BDITEMS | 0 | | gwf3sfr8.f90 | SfrModule | SfrType | CBCAUXITEMS | 0 | | gwf3sfr8.f90 | SfrModule | SfrType | UNITCONV | 0 | +| gwf3sfr8.f90 | SfrModule | SfrType | LENGTHCONV | 0 | +| gwf3sfr8.f90 | SfrModule | SfrType | TIMECONV | 0 | | gwf3sfr8.f90 | SfrModule | SfrType | DMAXCHG | 0 | | gwf3sfr8.f90 | SfrModule | SfrType | DEPS | 0 | | gwf3sfr8.f90 | SfrModule | SfrType | NCONN | 0 | @@ -849,6 +649,7 @@ | gwf3sfr8.f90 | SfrModule | SfrType | ICONVCHK | 0 | | gwf3sfr8.f90 | SfrModule | SfrType | IDENSE | 0 | | gwf3sfr8.f90 | SfrModule | SfrType | IANYNONE | 0 | +| gwf3sfr8.f90 | SfrModule | SfrType | NCROSSPTSTOT | 0 | | gwf3sfr8.f90 | SfrModule | SfrType | SFRNAME | 2 | | gwf3sfr8.f90 | SfrModule | SfrType | IBOUNDPAK | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | IGWFNODE | 1 | @@ -872,6 +673,7 @@ | gwf3sfr8.f90 | SfrModule | SfrType | SIMRUNOFF | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | STAGE0 | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | USFLOW0 | 1 | +| gwf3sfr8.f90 | SfrModule | SfrType | ISFRORDER | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | IA | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | JA | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | IDIR | 1 | @@ -888,18 +690,37 @@ | gwf3sfr8.f90 | SfrModule | SfrType | DIVREACH | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | DIVFLOW | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | DIVQ | 1 | +| gwf3sfr8.f90 | SfrModule | SfrType | NCROSSPTS | 1 | +| gwf3sfr8.f90 | SfrModule | SfrType | IACROSS | 1 | +| gwf3sfr8.f90 | SfrModule | SfrType | STATION | 1 | +| gwf3sfr8.f90 | SfrModule | SfrType | XSHEIGHT | 1 | +| gwf3sfr8.f90 | SfrModule | SfrType | XSROUGH | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | QOUTFLOW | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | QEXTOUTFLOW | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | DBUFF | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | QAUXCBC | 1 | | gwf3sfr8.f90 | SfrModule | SfrType | DENSETERMS | 2 | +| gwf3sfr8.f90 | SfrModule | SfrType | VISCRATIOS | 2 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | ISTOR_COEF | 0 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | ICONF_SS | 0 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | IORIG_SS | 0 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | IUSESY | 0 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | SATOMEGA | 0 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | INTEGRATECHANGES | 0 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | INTVS | 0 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | ICONVERT | 1 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | SS | 1 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | SY | 1 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | STRGSS | 1 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | STRGSY | 1 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | OLDSS | 1 | +| gwf3sto8.f90 | GwfStoModule | GwfStoType | OLDSY | 1 | | gwf3uzf8.f90 | UzfModule | UzfType | IGWFNODE | 1 | | gwf3uzf8.f90 | UzfModule | UzfType | APPLIEDINF | 1 | | gwf3uzf8.f90 | UzfModule | UzfType | REJINF | 1 | | gwf3uzf8.f90 | UzfModule | UzfType | REJINF0 | 1 | | gwf3uzf8.f90 | UzfModule | UzfType | REJINFTOMVR | 1 | | gwf3uzf8.f90 | UzfModule | UzfType | INFILTRATION | 1 | -| gwf3uzf8.f90 | UzfModule | UzfType | RECHARGE | 1 | | gwf3uzf8.f90 | UzfModule | UzfType | GWET | 1 | | gwf3uzf8.f90 | UzfModule | UzfType | UZET | 1 | | gwf3uzf8.f90 | UzfModule | UzfType | GWD | 1 | @@ -919,26 +740,20 @@ | gwf3uzf8.f90 | UzfModule | UzfType | HROOT | 1 | | gwf3uzf8.f90 | UzfModule | UzfType | ROOTACT | 1 | | gwf3uzf8.f90 | UzfModule | UzfType | UAUXVAR | 2 | +| gwf3uzf8.f90 | UzfModule | UzfType | WCNEW | 1 | +| gwf3uzf8.f90 | UzfModule | UzfType | WCOLD | 1 | | gwf3uzf8.f90 | UzfModule | UzfType | QAUXCBC | 1 | -| gwf3uzf8.f90 | UzfModule | UzfType | OBS_THETA | 1 | -| gwf3uzf8.f90 | UzfModule | UzfType | OBS_DEPTH | 1 | -| gwf3uzf8.f90 | UzfModule | UzfType | OBS_NUM | 1 | | gwf3uzf8.f90 | UzfModule | UzfType | IPRWCONT | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | IWCONTOUT | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | IBUDGETOUT | 0 | +| gwf3uzf8.f90 | UzfModule | UzfType | IBUDCSV | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | IPAKCSV | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | NTRAIL | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | NSETS | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | NODES | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | ISTOCB | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | NWAV | 0 | -| gwf3uzf8.f90 | UzfModule | UzfType | OUTUNITBUD | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | TOTFLUXTOT | 0 | -| gwf3uzf8.f90 | UzfModule | UzfType | INFILSUM | 0 | -| gwf3uzf8.f90 | UzfModule | UzfType | UZETSUM | 0 | -| gwf3uzf8.f90 | UzfModule | UzfType | RECHSUM | 0 | -| gwf3uzf8.f90 | UzfModule | UzfType | VFLUXSUM | 0 | -| gwf3uzf8.f90 | UzfModule | UzfType | DELSTORSUM | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | BDITEMS | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | NBDTXT | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | ISSFLAG | 0 | @@ -951,92 +766,558 @@ | gwf3uzf8.f90 | UzfModule | UzfType | IUZF2UZF | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | CBCAUXITEMS | 0 | | gwf3uzf8.f90 | UzfModule | UzfType | ICONVCHK | 0 | -| gwf3rch8.f90 | RchModule | RchType | INIRCH | 0 | -| gwf3sto8.f90 | GwfStoModule | GwfStoType | IUSESY | 0 | -| gwf3sto8.f90 | GwfStoModule | GwfStoType | ISFAC | 0 | -| gwf3sto8.f90 | GwfStoModule | GwfStoType | ISSEG | 0 | -| gwf3sto8.f90 | GwfStoModule | GwfStoType | SATOMEGA | 0 | -| gwf3sto8.f90 | GwfStoModule | GwfStoType | ICONVERT | 1 | -| gwf3sto8.f90 | GwfStoModule | GwfStoType | SC1 | 1 | -| gwf3sto8.f90 | GwfStoModule | GwfStoType | SC2 | 1 | -| gwf3sto8.f90 | GwfStoModule | GwfStoType | STRGSS | 1 | -| gwf3sto8.f90 | GwfStoModule | GwfStoType | STRGSY | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | INAME | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IXT3D | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | SATOMEGA | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | HNOFLO | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | HDRY | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ICELLAVG | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IAVGKEFF | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IK22 | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IK33 | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IK22OVERK | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IK33OVERK | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IPERCHED | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IVARCV | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IDEWATCV | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ITHICKSTRT | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IUSGNRHC | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | INWTUPW | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ICALCSPDIS | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ISAVSPDIS | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ISAVSAT | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IREWET | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | WETFCT | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IWETIT | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IHDWET | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | SATMIN | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IANGLE1 | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IANGLE2 | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IANGLE3 | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IWETDRY | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | NEDGES | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | LASTEDGE | 0 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ICELLTYPE | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | K11 | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | SAT | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | CONDSAT | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | K22 | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | K33 | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | WETDRY | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ANGLE1 | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ANGLE2 | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | ANGLE3 | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IBOTNODE | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | SPDIS | 2 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | NODEDGE | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | IHCEDGE | 1 | -| gwf3npf8.f90 | GwfNpfModule | GwfNpftype | PROPSEDGE | 2 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | TOP1D | 1 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | BOT1D | 1 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | AREA1D | 1 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | IDOMAIN | 1 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | VERTICES | 2 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | IAINP | 1 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | JAINP | 1 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | IHCINP | 1 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | CL12INP | 1 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | HWVAINP | 1 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | ANGLDEGXINP | 1 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | CELLXY | 2 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | IAVERT | 1 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | JAVERT | 1 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | NJAUSR | 0 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | NVERT | 0 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | NODEUSER | 1 | -| gwf3disu8.f90 | GwfDisuModule | GwfDisuType | NODEREDUCED | 1 | -| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | IOUTDENSE | 0 | -| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | IFORM | 0 | -| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | IREADELEV | 0 | -| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | IREADCONCBUY | 0 | -| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | ICONCSET | 0 | -| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | DENSEREF | 0 | -| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | NRHOSPECIES | 0 | -| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | DENSE | 1 | -| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | CONCBUY | 1 | -| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | ELEV | 1 | -| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | DRHODC | 1 | -| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | CRHOREF | 1 | -| gwf3buy8.f90 | GwfBuyModule | GwfBuyType | CTEMP | 1 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | THERMIVISC | 0 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | IDXTMPR | 0 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | IOUTVISC | 0 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | IREADELEV | 0 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | ICONCSET | 0 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | VISCREF | 0 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | A2 | 0 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | A3 | 0 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | A4 | 0 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | NVISCSPECIES | 0 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | VISC | 1 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | IVISC | 1 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | DRHODC | 1 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | CRHOREF | 1 | +| gwf3vsc8.f90 | GwfVscModule | GwfVscType | CTEMP | 1 | | gwf3wel8.f90 | WelModule | WelType | IFLOWRED | 0 | | gwf3wel8.f90 | WelModule | WelType | FLOWRED | 0 | +| gwf3wel8.f90 | WelModule | WelType | IOUTAFRCSV | 0 | +| gwt1.f90 | GwtModule | GwtModelType | INMST | 0 | +| gwt1.f90 | GwtModule | GwtModelType | INDSP | 0 | +| gwt1cnc1.f90 | GwtCncModule | GwtCncType | RATECNCIN | 1 | +| gwt1cnc1.f90 | GwtCncModule | GwtCncType | RATECNCOUT | 1 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | IDIFFC | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | IDISP | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | IALH | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | IALV | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | IATH1 | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | IATH2 | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | IATV | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | IXT3DOFF | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | IXT3DRHS | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | IXT3D | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | ID22 | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | ID33 | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | IANGLE1 | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | IANGLE2 | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | IANGLE3 | 0 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | ALH | 1 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | ALV | 1 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | ATH1 | 1 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | ATH2 | 1 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | ATV | 1 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | DIFFC | 1 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | D11 | 1 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | D22 | 1 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | D33 | 1 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | ANGLE1 | 1 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | ANGLE2 | 1 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | ANGLE3 | 1 | +| gwt1dsp1.f90 | GwtDspModule | GwtDspType | DISPCOEF | 1 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | ICIMOUT | 0 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | IBUDGETOUT | 0 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | IBUDCSV | 0 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | ISRB | 0 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | IDCY | 0 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | KITER | 0 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | STRG | 1 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | CIM | 1 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | CIMNEW | 1 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | CIMOLD | 1 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | POROSITY | 1 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | ZETAIM | 1 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | VOLFRAC | 1 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | BULK_DENSITY | 1 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | DISTCOEF | 1 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | DECAY | 1 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | DECAYLAST | 1 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | DECAYSLAST | 1 | +| gwt1ist1.f90 | GwtIstModule | GwtIstType | DECAY_SORBED | 1 | +| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDSSM | 1 | +| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDRAIN | 0 | +| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDEVAP | 0 | +| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDROFF | 0 | +| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDIFLW | 0 | +| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDWDRL | 0 | +| gwt1lkt1.f90 | GwtLktModule | GwtLktType | IDXBUDOUTF | 0 | +| gwt1lkt1.f90 | GwtLktModule | GwtLktType | CONCRAIN | 1 | +| gwt1lkt1.f90 | GwtLktModule | GwtLktType | CONCEVAP | 1 | +| gwt1lkt1.f90 | GwtLktModule | GwtLktType | CONCROFF | 1 | +| gwt1lkt1.f90 | GwtLktModule | GwtLktType | CONCIFLW | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | ISRB | 0 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | IDCY | 0 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | POROSITY | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | THETAM | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | VOLFRACIM | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | RATESTO | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | RATEDCY | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | DECAY | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | DECAYLAST | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | RATEDCYS | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | DECAYSLAST | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | DECAY_SORBED | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | BULK_DENSITY | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | SP2 | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | DISTCOEF | 1 | +| gwt1mst1.f90 | GwtMstModule | GwtMstType | RATESRB | 1 | +| gwt1mwt1.f90 | GwtMwtModule | GwtMwtType | IDXBUDSSM | 1 | +| gwt1mwt1.f90 | GwtMwtModule | GwtMwtType | IDXBUDRATE | 0 | +| gwt1mwt1.f90 | GwtMwtModule | GwtMwtType | IDXBUDFWRT | 0 | +| gwt1mwt1.f90 | GwtMwtModule | GwtMwtType | IDXBUDRTMV | 0 | +| gwt1mwt1.f90 | GwtMwtModule | GwtMwtType | IDXBUDFRTM | 0 | +| gwt1mwt1.f90 | GwtMwtModule | GwtMwtType | CONCRATE | 1 | +| gwt1sft1.f90 | GwtSftModule | GwtSftType | IDXBUDSSM | 1 | +| gwt1sft1.f90 | GwtSftModule | GwtSftType | IDXBUDRAIN | 0 | +| gwt1sft1.f90 | GwtSftModule | GwtSftType | IDXBUDEVAP | 0 | +| gwt1sft1.f90 | GwtSftModule | GwtSftType | IDXBUDROFF | 0 | +| gwt1sft1.f90 | GwtSftModule | GwtSftType | IDXBUDIFLW | 0 | +| gwt1sft1.f90 | GwtSftModule | GwtSftType | IDXBUDOUTF | 0 | +| gwt1sft1.f90 | GwtSftModule | GwtSftType | CONCRAIN | 1 | +| gwt1sft1.f90 | GwtSftModule | GwtSftType | CONCEVAP | 1 | +| gwt1sft1.f90 | GwtSftModule | GwtSftType | CONCROFF | 1 | +| gwt1sft1.f90 | GwtSftModule | GwtSftType | CONCIFLW | 1 | +| gwt1uzt1.f90 | GwtUztModule | GwtUztType | IDXBUDSSM | 1 | +| gwt1uzt1.f90 | GwtUztModule | GwtUztType | IDXBUDINFL | 0 | +| gwt1uzt1.f90 | GwtUztModule | GwtUztType | IDXBUDRINF | 0 | +| gwt1uzt1.f90 | GwtUztModule | GwtUztType | IDXBUDUZET | 0 | +| gwt1uzt1.f90 | GwtUztModule | GwtUztType | IDXBUDRITM | 0 | +| gwt1uzt1.f90 | GwtUztModule | GwtUztType | CONCINFL | 1 | +| gwt1uzt1.f90 | GwtUztModule | GwtUztType | CONCUZET | 1 | +| BoundaryPackage.f90 | BndModule | BndType | LISTLABEL | 1 | +| BoundaryPackage.f90 | BndModule | BndType | ISADVPAK | 0 | +| BoundaryPackage.f90 | BndModule | BndType | IBCNUM | 0 | +| BoundaryPackage.f90 | BndModule | BndType | MAXBOUND | 0 | +| BoundaryPackage.f90 | BndModule | BndType | NBOUND | 0 | +| BoundaryPackage.f90 | BndModule | BndType | NCOLBND | 0 | +| BoundaryPackage.f90 | BndModule | BndType | ISCLOC | 0 | +| BoundaryPackage.f90 | BndModule | BndType | NAUX | 0 | +| BoundaryPackage.f90 | BndModule | BndType | INAMEDBOUND | 0 | +| BoundaryPackage.f90 | BndModule | BndType | IAUXMULTCOL | 0 | +| BoundaryPackage.f90 | BndModule | BndType | INOBSPKG | 0 | +| BoundaryPackage.f90 | BndModule | BndType | IMOVER | 0 | +| BoundaryPackage.f90 | BndModule | BndType | IVSC | 0 | +| BoundaryPackage.f90 | BndModule | BndType | NPAKEQ | 0 | +| BoundaryPackage.f90 | BndModule | BndType | IOFFSET | 0 | +| BoundaryPackage.f90 | BndModule | BndType | AUXNAME | 2 | +| BoundaryPackage.f90 | BndModule | BndType | AUXNAME_CST | 2 | +| BoundaryPackage.f90 | BndModule | BndType | NODELIST | 1 | +| BoundaryPackage.f90 | BndModule | BndType | NOUPDATEAUXVAR | 1 | +| BoundaryPackage.f90 | BndModule | BndType | BOUND | 2 | +| BoundaryPackage.f90 | BndModule | BndType | CONDINPUT | 1 | +| BoundaryPackage.f90 | BndModule | BndType | HCOF | 1 | +| BoundaryPackage.f90 | BndModule | BndType | RHS | 1 | +| BoundaryPackage.f90 | BndModule | BndType | SIMVALS | 1 | +| BoundaryPackage.f90 | BndModule | BndType | SIMTOMVR | 1 | +| BoundaryPackage.f90 | BndModule | BndType | AUXVAR | 2 | +| BoundaryPackage.f90 | BndModule | BndType | BOUNDNAME | 2 | +| BoundaryPackage.f90 | BndModule | BndType | BOUNDNAME_CST | 2 | +| Connections.f90 | ConnectionsModule | ConnectionsType | NODES | 0 | +| Connections.f90 | ConnectionsModule | ConnectionsType | NJA | 0 | +| Connections.f90 | ConnectionsModule | ConnectionsType | NJAS | 0 | +| Connections.f90 | ConnectionsModule | ConnectionsType | IANGLEX | 0 | +| Connections.f90 | ConnectionsModule | ConnectionsType | IA | 1 | +| Connections.f90 | ConnectionsModule | ConnectionsType | JA | 1 | +| Connections.f90 | ConnectionsModule | ConnectionsType | ISYM | 1 | +| Connections.f90 | ConnectionsModule | ConnectionsType | JAS | 1 | +| Connections.f90 | ConnectionsModule | ConnectionsType | HWVA | 1 | +| Connections.f90 | ConnectionsModule | ConnectionsType | ANGLEX | 1 | +| Connections.f90 | ConnectionsModule | ConnectionsType | IHC | 1 | +| Connections.f90 | ConnectionsModule | ConnectionsType | CL1 | 1 | +| Connections.f90 | ConnectionsModule | ConnectionsType | CL2 | 1 | +| Connections.f90 | ConnectionsModule | ConnectionsType | IAUSR | 1 | +| Connections.f90 | ConnectionsModule | ConnectionsType | JAUSR | 1 | +| Connections.f90 | ConnectionsModule | ConnectionsType | MASK | 1 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | INUNIT | 0 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | IOUT | 0 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | NODES | 0 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | NODESUSER | 0 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | NDIM | 0 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | ICONDIR | 0 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | NOGRB | 0 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | XORIGIN | 0 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | YORIGIN | 0 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | ANGROT | 0 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | NJA | 0 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | NJAS | 0 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | LENUNI | 0 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | MSHAPE | 1 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | XC | 1 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | YC | 1 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | TOP | 1 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | BOT | 1 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | AREA | 1 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | DBUFF | 1 | +| DiscretizationBase.f90 | BaseDisModule | DisBaseType | IBUFF | 1 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | FLOWS_FROM_FILE | 0 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | IFLOWSUPDATED | 0 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | IGWFSTRGSS | 0 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | IGWFSTRGSY | 0 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | IUBUD | 0 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | IUHDS | 0 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | IUMVR | 0 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | NFLOWPACK | 0 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | IDRYINACTIVE | 0 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | IBDGWFSAT0 | 1 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | GWFFLOWJA | 1 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | GWFSAT | 1 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | GWFHEAD | 1 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | GWFSPDIS | 2 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | GWFSTRGSS | 1 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | GWFSTRGSY | 1 | +| FlowModelInterface.f90 | FlowModelInterfaceModule | FlowModelInterfaceType | IGWFMVRTERM | 1 | +| GwfMvrPeriodData.f90 | GwfMvrPeriodDataModule | GwfMvrPeriodDataType | ID1 | 1 | +| GwfMvrPeriodData.f90 | GwfMvrPeriodDataModule | GwfMvrPeriodDataType | ID2 | 1 | +| GwfMvrPeriodData.f90 | GwfMvrPeriodDataModule | GwfMvrPeriodDataType | IMVRTYPE | 1 | +| GwfMvrPeriodData.f90 | GwfMvrPeriodDataModule | GwfMvrPeriodDataType | VALUE | 1 | +| GwtSpc.f90 | GwtSpcModule | GwtSpcType | ID | 0 | +| GwtSpc.f90 | GwtSpcModule | GwtSpcType | INUNIT | 0 | +| GwtSpc.f90 | GwtSpcModule | GwtSpcType | IOUT | 0 | +| GwtSpc.f90 | GwtSpcModule | GwtSpcType | MAXBOUND | 0 | +| GwtSpc.f90 | GwtSpcModule | GwtSpcType | IONPER | 0 | +| GwtSpc.f90 | GwtSpcModule | GwtSpcType | LASTONPER | 0 | +| GwtSpc.f90 | GwtSpcModule | GwtSpcType | IPRPAK | 0 | +| GwtSpc.f90 | GwtSpcModule | GwtSpcType | READASARRAYS | 0 | +| GwtSpc.f90 | GwtSpcModule | GwtSpcType | DBLVEC | 1 | +| PackageMover.f90 | PackageMoverModule | PackageMoverType | NPROVIDERS | 0 | +| PackageMover.f90 | PackageMoverModule | PackageMoverType | NRECEIVERS | 0 | +| PackageMover.f90 | PackageMoverModule | PackageMoverType | IPRMAP | 1 | +| PackageMover.f90 | PackageMoverModule | PackageMoverType | QTFORMVR | 1 | +| PackageMover.f90 | PackageMoverModule | PackageMoverType | QFORMVR | 1 | +| PackageMover.f90 | PackageMoverModule | PackageMoverType | QTOMVR | 1 | +| PackageMover.f90 | PackageMoverModule | PackageMoverType | QFROMMVR | 1 | +| PackageMover.f90 | PackageMoverModule | PackageMoverType | QFROMMVR0 | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | UZDPST | 2 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | UZTHST | 2 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | UZFLST | 2 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | UZSPST | 2 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | NWAVST | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | THTR | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | THTS | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | THTI | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | EPS | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | HA | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | HROOT | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | ROOTACT | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | EXTWC | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | ETACT | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | NWAV | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | NTRAIL | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | TOTFLUX | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | SINF | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | FINF | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | FINF_REJ | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | GWET | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | UZFAREA | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | CELLAREA | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | CELTOP | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | CELBOT | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | LANDTOP | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | WATAB | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | WATABOLD | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | SURFDEP | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | VKS | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | SURFLUX | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | SURFLUXBELOW | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | SURFSEEP | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | GWPET | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | PET | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | PETMAX | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | EXTDP | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | EXTDPUZ | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | LANDFLAG | 1 | +| UzfCellGroup.f90 | UzfCellGroupModule | UzfCellGroupType | IVERTCON | 1 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | IA_XT3D | 1 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | JA_XT3D | 1 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | IAX | 1 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | JAX | 1 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | IDXGLOX | 1 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | IXT3D | 0 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | NBRMAX | 0 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | INUNIT | 0 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | IOUT | 0 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | INEWTON | 0 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | NUMEXTNBRS | 0 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | NOZEE | 0 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | VCTHRESH | 0 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | LAMATSAVED | 0 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | LDISPERSION | 0 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | QSAT | 1 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | IALLPC | 1 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | AMATPC | 1 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | AMATPCX | 1 | +| Xt3dInterface.f90 | Xt3dModule | Xt3dType | RMATCK | 2 | +| tsp1.f90 | TransportModelModule | TransportModelType | INIC | 0 | +| tsp1.f90 | TransportModelModule | TransportModelType | INFMI | 0 | +| tsp1.f90 | TransportModelModule | TransportModelType | INMVT | 0 | +| tsp1.f90 | TransportModelModule | TransportModelType | INADV | 0 | +| tsp1.f90 | TransportModelModule | TransportModelType | INSSM | 0 | +| tsp1.f90 | TransportModelModule | TransportModelType | INOC | 0 | +| tsp1.f90 | TransportModelModule | TransportModelType | INOBS | 0 | +| tsp1.f90 | TransportModelModule | TransportModelType | EQNSCLFAC | 0 | +| tsp1adv1.f90 | TspAdvModule | TspAdvType | IADVWT | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IAUXFPCONC | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IMATROWS | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IPRCONC | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | ICONCOUT | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IBUDGETOUT | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IBUDCSV | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IGWFAPTPAK | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | NCV | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXBUDFJF | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXBUDGWF | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXBUDSTO | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXBUDTMVR | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXBUDFMVR | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXBUDAUX | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | NCONCBUDSSM | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXPREPAK | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXLASTPAK | 0 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXLOCNODE | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXPAKDIAG | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXGLO | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXOFFDGLO | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXSYMDGLO | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXSYMOFFDGLO | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXFJFDGLO | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IDXFJFOFFDGLO | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | DBUFF | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | CONCFEAT | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | QSTO | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | CCTERM | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | CONCBUDSSM | 2 | +| tsp1apt1.f90 | TspAptModule | TspAptType | QMFROMMVR | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | STRT | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | LAUXVAR | 2 | +| tsp1apt1.f90 | TspAptModule | TspAptType | IBOUND | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | XNEWPAK | 1 | +| tsp1apt1.f90 | TspAptModule | TspAptType | XOLDPAK | 1 | +| tsp1fmi1.f90 | TspFmiModule | TspFmiType | IFLOWERR | 0 | +| tsp1fmi1.f90 | TspFmiModule | TspFmiType | FLOWCORRECT | 1 | +| tsp1fmi1.f90 | TspFmiModule | TspFmiType | IATP | 1 | +| tsp1fmi1.f90 | TspFmiModule | TspFmiType | IGWFMVRTERM | 1 | +| tsp1mvt1.f90 | TspMvtModule | TspMvtType | MAXPACKAGES | 0 | +| tsp1mvt1.f90 | TspMvtModule | TspMvtType | IBUDGETOUT | 0 | +| tsp1mvt1.f90 | TspMvtModule | TspMvtType | IBUDCSV | 0 | +| tsp1ssm1.f90 | TspSsmModule | TspSsmType | NBOUND | 0 | +| tsp1ssm1.f90 | TspSsmModule | TspSsmType | IAUXPAK | 1 | +| tsp1ssm1.f90 | TspSsmModule | TspSsmType | ISRCTYPE | 1 | +| ConvergenceSummary.f90 | ConvergenceSummaryModule | ConvergenceSummaryType | CONVNMOD | 0 | +| ConvergenceSummary.f90 | ConvergenceSummaryModule | ConvergenceSummaryType | NITERMAX | 0 | +| ConvergenceSummary.f90 | ConvergenceSummaryModule | ConvergenceSummaryType | ITINNER | 1 | +| ConvergenceSummary.f90 | ConvergenceSummaryModule | ConvergenceSummaryType | LOCDV | 1 | +| ConvergenceSummary.f90 | ConvergenceSummaryModule | ConvergenceSummaryType | DVMAX | 1 | +| ConvergenceSummary.f90 | ConvergenceSummaryModule | ConvergenceSummaryType | LOCDR | 1 | +| ConvergenceSummary.f90 | ConvergenceSummaryModule | ConvergenceSummaryType | DRMAX | 1 | +| ConvergenceSummary.f90 | ConvergenceSummaryModule | ConvergenceSummaryType | CONVDVMAX | 2 | +| ConvergenceSummary.f90 | ConvergenceSummaryModule | ConvergenceSummaryType | CONVLOCDV | 2 | +| ConvergenceSummary.f90 | ConvergenceSummaryModule | ConvergenceSummaryType | CONVDRMAX | 2 | +| ConvergenceSummary.f90 | ConvergenceSummaryModule | ConvergenceSummaryType | CONVLOCDR | 2 | +| ExplicitSolution.f90 | ExplicitSolutionModule | ExplicitSolutionType | ID | 0 | +| ExplicitSolution.f90 | ExplicitSolutionModule | ExplicitSolutionType | IU | 0 | +| ExplicitSolution.f90 | ExplicitSolutionModule | ExplicitSolutionType | TTSOLN | 0 | +| ExplicitSolution.f90 | ExplicitSolutionModule | ExplicitSolutionType | ICNVG | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | ID | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IU | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | TTFORM | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | TTSOLN | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | ISYMMETRIC | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | NEQ | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | MATRIX_OFFSET | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | DVCLOSE | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | BIGCHOLD | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | BIGCH | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | RELAXOLD | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | RES_PREV | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | RES_NEW | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | ICNVG | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | ITERTOT_TIMESTEP | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IOUTTOT_TIMESTEP | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | INNERTOT_SIM | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | MXITER | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | LINSOLVER | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | NONMETH | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IPRIMS | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | THETA | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | AKAPPA | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | GAMMA | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | AMOMENTUM | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | BREDUC | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | BTOL | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | RES_LIM | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | NUMTRACK | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IBFLAG | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | ICSVOUTEROUT | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | ICSVINNEROUT | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | NITERMAX | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | CONVNMOD | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IALLOWPTC | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IPTCOPT | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IPTCOUT | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | L2NORM0 | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | PTCDEL | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | PTCDEL0 | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | PTCEXP | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | ATSFRAC | 0 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | IACTIVE | 1 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | XTEMP | 1 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | DXOLD | 1 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | HNCG | 1 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | LRCH | 2 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | WSAVE | 1 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | HCHOLD | 1 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | DEOLD | 1 | +| NumericalSolution.f90 | NumericalSolutionModule | NumericalSolutionType | CONVMODSTART | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NJA | 0 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | DSCALE | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | DSCALE2 | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IAPC | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | JAPC | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | APC | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IW | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | W | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | JLU | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | JW | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | WLU | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | LORDER | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IORDER | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IARO | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | JARO | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | ARO | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | ID | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | D | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | P | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | Q | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | Z | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | T | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | V | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | DHAT | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | PHAT | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | QHAT | 1 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IOUT | 0 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IPC | 0 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | IACPC | 0 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NITERC | 0 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NIABCGS | 0 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NIAPC | 0 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NJAPC | 0 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | EPFACT | 0 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | L2NORM0 | 0 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NJLU | 0 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NJW | 0 | +| ims8linear.f90 | IMSLinearModule | ImsLinearDataType | NWLU | 0 | +| ImsLinearSettings.f90 | ImsLinearSettingsModule | ImsLinearSettingsType | DVCLOSE | 0 | +| ImsLinearSettings.f90 | ImsLinearSettingsModule | ImsLinearSettingsType | RCLOSE | 0 | +| ImsLinearSettings.f90 | ImsLinearSettingsModule | ImsLinearSettingsType | ICNVGOPT | 0 | +| ImsLinearSettings.f90 | ImsLinearSettingsModule | ImsLinearSettingsType | ITER1 | 0 | +| ImsLinearSettings.f90 | ImsLinearSettingsModule | ImsLinearSettingsType | ILINMETH | 0 | +| ImsLinearSettings.f90 | ImsLinearSettingsModule | ImsLinearSettingsType | ISCL | 0 | +| ImsLinearSettings.f90 | ImsLinearSettingsModule | ImsLinearSettingsType | IORD | 0 | +| ImsLinearSettings.f90 | ImsLinearSettingsModule | ImsLinearSettingsType | NORTH | 0 | +| ImsLinearSettings.f90 | ImsLinearSettingsModule | ImsLinearSettingsType | RELAX | 0 | +| ImsLinearSettings.f90 | ImsLinearSettingsModule | ImsLinearSettingsType | LEVEL | 0 | +| ImsLinearSettings.f90 | ImsLinearSettingsModule | ImsLinearSettingsType | DROPTOL | 0 | +| ImsLinearSettings.f90 | ImsLinearSettingsModule | ImsLinearSettingsType | IDFPARAM | 0 | +| ats.f90 | AdaptiveTimeStepModule | None | NPER | 0 | +| ats.f90 | AdaptiveTimeStepModule | None | MAXATS | 0 | +| ats.f90 | AdaptiveTimeStepModule | None | DTSTABLE | 0 | +| ats.f90 | AdaptiveTimeStepModule | None | KPERATS | 1 | +| ats.f90 | AdaptiveTimeStepModule | None | IPERATS | 1 | +| ats.f90 | AdaptiveTimeStepModule | None | DT0 | 1 | +| ats.f90 | AdaptiveTimeStepModule | None | DTMIN | 1 | +| ats.f90 | AdaptiveTimeStepModule | None | DTMAX | 1 | +| ats.f90 | AdaptiveTimeStepModule | None | DTADJ | 1 | +| ats.f90 | AdaptiveTimeStepModule | None | DTFAILADJ | 1 | +| tdis.f90 | TdisModule | None | NPER | 0 | +| tdis.f90 | TdisModule | None | ITMUNI | 0 | +| tdis.f90 | TdisModule | None | KPER | 0 | +| tdis.f90 | TdisModule | None | KSTP | 0 | +| tdis.f90 | TdisModule | None | INATS | 0 | +| tdis.f90 | TdisModule | None | READNEWDATA | 0 | +| tdis.f90 | TdisModule | None | ENDOFPERIOD | 0 | +| tdis.f90 | TdisModule | None | ENDOFSIMULATION | 0 | +| tdis.f90 | TdisModule | None | DELT | 0 | +| tdis.f90 | TdisModule | None | PERTIM | 0 | +| tdis.f90 | TdisModule | None | TOPERTIM | 0 | +| tdis.f90 | TdisModule | None | TOTIM | 0 | +| tdis.f90 | TdisModule | None | TOTIMC | 0 | +| tdis.f90 | TdisModule | None | DELTSAV | 0 | +| tdis.f90 | TdisModule | None | TOTIMSAV | 0 | +| tdis.f90 | TdisModule | None | PERTIMSAV | 0 | +| tdis.f90 | TdisModule | None | TOTALSIMTIME | 0 | +| tdis.f90 | TdisModule | None | PERLEN | 1 | +| tdis.f90 | TdisModule | None | NSTP | 1 | +| tdis.f90 | TdisModule | None | TSMULT | 1 | +| PackageBudget.f90 | PackageBudgetModule | PackageBudgetType | NAME | 1 | +| PackageBudget.f90 | PackageBudgetModule | PackageBudgetType | BUDTXT | 1 | +| PackageBudget.f90 | PackageBudgetModule | PackageBudgetType | NAUX | 0 | +| PackageBudget.f90 | PackageBudgetModule | PackageBudgetType | AUXNAME | 2 | +| PackageBudget.f90 | PackageBudgetModule | PackageBudgetType | NBOUND | 0 | +| PackageBudget.f90 | PackageBudgetModule | PackageBudgetType | NODELIST | 1 | +| PackageBudget.f90 | PackageBudgetModule | PackageBudgetType | FLOW | 1 | +| PackageBudget.f90 | PackageBudgetModule | PackageBudgetType | AUXVAR | 2 | +| BoundInputContext.f90 | BoundInputContextModule | BoundInputContextType | NBOUND | 0 | +| BoundInputContext.f90 | BoundInputContextModule | BoundInputContextType | NCPL | 0 | +| BoundInputContext.f90 | BoundInputContextModule | BoundInputContextType | AUXILIARY | 2 | +| BoundInputContext.f90 | BoundInputContextModule | BoundInputContextType | CELLID | 2 | +| BoundInputContext.f90 | BoundInputContextModule | BoundInputContextType | BOUNDNAME | 2 | +| BoundInputContext.f90 | BoundInputContextModule | BoundInputContextType | AUXVAR | 2 | +| BoundInputContext.f90 | BoundInputContextModule | BoundInputContextType | varname | 0 | +| BoundInputContext.f90 | BoundInputContextModule | BoundInputContextType | idt%mf6varname | 1 | +| BoundInputContext.f90 | BoundInputContextModule | BoundInputContextType | idt%mf6varname | 1 | +| BoundInputContext.f90 | BoundInputContextModule | BoundInputContextType | idt%mf6varname | 2 | +| IdmLoad.f90 | IdmLoadModule | None | EXGMEMPATHS | 2 | +| IdmLoad.f90 | IdmLoadModule | None | NCELLDIM | 0 | +| IdmLoad.f90 | IdmLoadModule | None | EXGID | 0 | +| IdmLoad.f90 | IdmLoadModule | None | NUMMODELS | 0 | +| IdmLoad.f90 | IdmLoadModule | None | NUMEXCHANGES | 0 | +| IdmLoad.f90 | IdmLoadModule | None | idt%mf6varname | 0 | +| IdmLoad.f90 | IdmLoadModule | None | idt%mf6varname | 2 | +| IdmLoad.f90 | IdmLoadModule | None | idt%mf6varname | 1 | +| ModelPackageInputs.f90 | ModelPackageInputsModule | LoadablePackageType | INPUT_FNAME | 1 | +| ModelPackageInputs.f90 | ModelPackageInputsModule | ModelPackageInputsType | PKGTYPES | 2 | +| ModelPackageInputs.f90 | ModelPackageInputsModule | ModelPackageInputsType | PKGNAMES | 2 | +| ModelPackageInputs.f90 | ModelPackageInputsModule | ModelPackageInputsType | MEMPATHS | 2 | +| ModelPackageInputs.f90 | ModelPackageInputsModule | ModelPackageInputsType | INUNITS | 1 | +| SourceCommon.f90 | SourceCommonModule | None | MODEL_SHAPE | 1 | +| SourceCommon.f90 | SourceCommonModule | None | NCELLDIM | 0 | +| SourceCommon.f90 | SourceCommonModule | None | NAUX | 0 | +| IdmMf6File.f90 | IdmMf6FileModule | Mf6FileDynamicPkgLoadType | IPER | 0 | +| IdmMf6File.f90 | IdmMf6FileModule | Mf6FileDynamicPkgLoadType | IONPER | 0 | +| LoadMf6File.f90 | LoadMf6FileModule | None | idt%mf6varname | 0 | +| LoadMf6File.f90 | LoadMf6FileModule | None | idt%mf6varname | 1 | +| LoadMf6File.f90 | LoadMf6FileModule | None | idt%mf6varname | 2 | +| LoadMf6File.f90 | LoadMf6FileModule | None | idt%mf6varname | 2 | +| LoadMf6File.f90 | LoadMf6FileModule | None | idt%mf6varname | 1 | +| LoadMf6File.f90 | LoadMf6FileModule | None | idt%mf6varname | 2 | +| LoadMf6File.f90 | LoadMf6FileModule | None | idt%mf6varname | 3 | +| LoadMf6File.f90 | LoadMf6FileModule | None | idt%mf6varname | 0 | +| LoadMf6File.f90 | LoadMf6FileModule | None | idt%mf6varname | 1 | +| LoadMf6File.f90 | LoadMf6FileModule | None | idt%mf6varname | 2 | +| LoadMf6File.f90 | LoadMf6FileModule | None | idt%mf6varname | 3 | +| StressGridInput.f90 | StressGridInputModule | StressGridInputType | AUXTASNAME | 2 | +| StressGridInput.f90 | StressGridInputModule | StressGridInputType | PARAMTASNAME | 2 | +| StructArray.f90 | StructArrayModule | StructArrayType | sv%idt%mf6varname | 1 | +| StructArray.f90 | StructArrayModule | StructArrayType | sv%idt%mf6varname | 1 | +| StructArray.f90 | StructArrayModule | StructArrayType | sv%idt%mf6varname | 2 | +| StructArray.f90 | StructArrayModule | StructArrayType | sv%idt%mf6varname | 2 | +| StructArray.f90 | StructArrayModule | StructArrayType | sv%idt%mf6varname | 2 | +| StructArray.f90 | StructArrayModule | StructArrayType | NSEG_1 | 0 | +| StructArray.f90 | StructArrayModule | StructArrayType | varname | 1 | +| StructArray.f90 | StructArrayModule | StructArrayType | varname | 1 | +| StructArray.f90 | StructArrayModule | StructArrayType | varname | 2 | +| StructArray.f90 | StructArrayModule | StructArrayType | varname | 2 | +| StructArray.f90 | StructArrayModule | StructArrayType | varname | 1 | +| SparseMatrix.f90 | SparseMatrixModule | SparseMatrixType | NROW | 0 | +| SparseMatrix.f90 | SparseMatrixModule | SparseMatrixType | NCOL | 0 | +| SparseMatrix.f90 | SparseMatrixModule | SparseMatrixType | NJA | 0 | +| SparseMatrix.f90 | SparseMatrixModule | SparseMatrixType | IA | 1 | +| SparseMatrix.f90 | SparseMatrixModule | SparseMatrixType | JA | 1 | +| SparseMatrix.f90 | SparseMatrixModule | SparseMatrixType | AMAT | 1 | +| OutputControl.f90 | OutputControlModule | OutputControlType | INUNIT | 0 | +| OutputControl.f90 | OutputControlModule | OutputControlType | IOUT | 0 | +| OutputControl.f90 | OutputControlModule | OutputControlType | IBUDCSV | 0 | +| OutputControl.f90 | OutputControlModule | OutputControlType | IPEROC | 0 | +| OutputControl.f90 | OutputControlModule | OutputControlType | IOCREP | 0 | +| SeqVector.f90 | SeqVectorModule | SeqVectorType | name | 1 | diff --git a/doc/mf6io/mf6ivar/mf6ivar.py b/doc/mf6io/mf6ivar/mf6ivar.py index dd56c9c5a80..0c37229aa5d 100644 --- a/doc/mf6io/mf6ivar/mf6ivar.py +++ b/doc/mf6io/mf6ivar/mf6ivar.py @@ -746,7 +746,7 @@ def write_appendix(texdir, allblocks): "gwe-disu", "gwe-dsp", "gwe-ic", - "gwe-mst", + "gwe-est", "gwe-nam", "gwe-oc", "gwe-ssm", diff --git a/doc/mf6io/mf6ivar/tex/appendixA.tex b/doc/mf6io/mf6ivar/tex/appendixA.tex index cd82dfbfcb1..32e46895c12 100644 --- a/doc/mf6io/mf6ivar/tex/appendixA.tex +++ b/doc/mf6io/mf6ivar/tex/appendixA.tex @@ -272,9 +272,9 @@ \hline GWE & IC & GRIDDATA & no \\ \hline -GWE & MST & OPTIONS & yes \\ -GWE & MST & GRIDDATA & no \\ -GWE & MST & PACKAGEDATA & yes \\ +GWE & EST & OPTIONS & yes \\ +GWE & EST & GRIDDATA & no \\ +GWE & EST & PACKAGEDATA & yes \\ \hline GWE & NAM & OPTIONS & yes \\ GWE & NAM & PACKAGES & yes \\ diff --git a/doc/mf6io/mf6ivar/tex/gwe-est-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-est-desc.tex new file mode 100644 index 00000000000..bf787adc828 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-est-desc.tex @@ -0,0 +1,35 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{SAVE\_FLOWS}---keyword to indicate that EST flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. + +\item \texttt{ZERO\_ORDER\_DECAY}---is a text keyword to indicate that zero-order decay will occur. Use of this keyword requires that DECAY and DECAY\_SORBED (if sorption is active) are specified in the GRIDDATA block. + +\item \texttt{LATENT\_HEAT\_VAPORIZATION}---is a text keyword to indicate that cooling associated with evaporation will occur. Use of this keyword requires that LATHEATVAP are specified in the GRIDDATA block. While the EST package does not simulate evaporation, multiple other packages in a GWE simulation may. For example, evaporation may occur from the surface of streams or lakes. Owing to the energy consumed by the change in phase, the latent heat of vaporization is required. + +\end{description} +\item \textbf{Block: GRIDDATA} + +\begin{description} +\item \texttt{porosity}---is the mobile domain porosity, defined as the mobile domain pore volume per mobile domain volume. The GWE model does not support the concept of an immobile domain in the context of heat transport. + +\item \texttt{decay}---is the rate coefficient for zero-order decay for the aqueous phase of the mobile domain. A negative value indicates heat (energy) production. The dimensions of decay for zero-order decay is energy per length cubed per time. Zero-order decay will have no effect on simulation results unless zero-order decay is specified in the options block. + +\item \texttt{cps}---is the mass-based heat capacity of dry solids (aquifer material). For example, units of J/kg/C may be used (or equivalent). + +\item \texttt{rhos}---is a user-specified value of the density of aquifer material not considering the voids. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. + +\end{description} +\item \textbf{Block: PACKAGEDATA} + +\begin{description} +\item \texttt{cpw}---is the mass-based heat capacity of the simulated fluid. For example, units of J/kg/C may be used (or equivalent). + +\item \texttt{rhow}---is a user-specified value of the density of water. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. + +\item \texttt{latheatvap}---is the user-specified value for the latent heat of vaporization. For example, if working in SI units, values may be entered as kJ/kg. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-mst-griddata.dat b/doc/mf6io/mf6ivar/tex/gwe-est-griddata.dat similarity index 100% rename from doc/mf6io/mf6ivar/tex/gwe-mst-griddata.dat rename to doc/mf6io/mf6ivar/tex/gwe-est-griddata.dat diff --git a/doc/mf6io/mf6ivar/tex/gwe-mst-options.dat b/doc/mf6io/mf6ivar/tex/gwe-est-options.dat similarity index 100% rename from doc/mf6io/mf6ivar/tex/gwe-mst-options.dat rename to doc/mf6io/mf6ivar/tex/gwe-est-options.dat diff --git a/doc/mf6io/mf6ivar/tex/gwe-mst-packagedata.dat b/doc/mf6io/mf6ivar/tex/gwe-est-packagedata.dat similarity index 100% rename from doc/mf6io/mf6ivar/tex/gwe-mst-packagedata.dat rename to doc/mf6io/mf6ivar/tex/gwe-est-packagedata.dat diff --git a/make/makefile b/make/makefile index 81d60610183..5deaf992afd 100644 --- a/make/makefile +++ b/make/makefile @@ -280,7 +280,7 @@ $(OBJDIR)/gwf3buy8.o \ $(OBJDIR)/GhostNode.o \ $(OBJDIR)/gwf3evt8.o \ $(OBJDIR)/gwf3chd8.o \ -$(OBJDIR)/gwe1mst1.o \ +$(OBJDIR)/gwe1est1.o \ $(OBJDIR)/gwe1dsp1.o \ $(OBJDIR)/gwe1ctp1.o \ $(OBJDIR)/RouterBase.o \ diff --git a/msvs/mf6core.vfproj b/msvs/mf6core.vfproj index c56c32586b9..26d97feffc7 100644 --- a/msvs/mf6core.vfproj +++ b/msvs/mf6core.vfproj @@ -148,9 +148,9 @@ + - - + diff --git a/src/Distributed/VirtualGweModel.f90 b/src/Distributed/VirtualGweModel.f90 index d93d59c2798..ea97d448f0f 100644 --- a/src/Distributed/VirtualGweModel.f90 +++ b/src/Distributed/VirtualGweModel.f90 @@ -27,11 +27,11 @@ module VirtualGweModelModule type(VirtualDbl1dType), pointer :: fmi_gwfsat => null() type(VirtualDbl2dType), pointer :: fmi_gwfspdis => null() type(VirtualDbl1dType), pointer :: fmi_gwfflowja => null() - ! MST - type(VirtualDbl1dType), pointer :: mst_porosity => null() + ! EST + type(VirtualDbl1dType), pointer :: est_porosity => null() ! GWE Model fields type(VirtualIntType), pointer :: indsp => null() - type(VirtualIntType), pointer :: inmst => null() + type(VirtualIntType), pointer :: inest => null() contains ! public procedure :: create => vgwe_create @@ -94,9 +94,9 @@ subroutine init_virtual_data(this) call this%set(this%fmi_gwfsat%base(), 'GWFSAT', 'FMI', MAP_NODE_TYPE) call this%set(this%fmi_gwfspdis%base(), 'GWFSPDIS', 'FMI', MAP_NODE_TYPE) call this%set(this%fmi_gwfflowja%base(), 'GWFFLOWJA', 'FMI', MAP_CONN_TYPE) - call this%set(this%mst_porosity%base(), 'POROSITY', 'MST', MAP_NODE_TYPE) + call this%set(this%est_porosity%base(), 'POROSITY', 'EST', MAP_NODE_TYPE) call this%set(this%indsp%base(), 'INDSP', '', MAP_ALL_TYPE) - call this%set(this%inmst%base(), 'INMST', '', MAP_ALL_TYPE) + call this%set(this%inest%base(), 'INEST', '', MAP_ALL_TYPE) end subroutine init_virtual_data @@ -117,7 +117,7 @@ subroutine vgwe_prepare_stage(this, stage) !call this%map(this%dsp_idiffc%base(), (/STG_AFT_MDL_DF/)) call this%map(this%dsp_idisp%base(), (/STG_AFT_MDL_DF/)) call this%map(this%indsp%base(), (/STG_AFT_MDL_DF/)) - call this%map(this%inmst%base(), (/STG_AFT_MDL_DF/)) + call this%map(this%inest%base(), (/STG_AFT_MDL_DF/)) else if (stage == STG_BFR_CON_AR) then @@ -146,8 +146,8 @@ subroutine vgwe_prepare_stage(this, stage) call this%map(this%fmi_gwfspdis%base(), 3, nr_nodes, (/STG_BFR_EXG_AD/)) call this%map(this%fmi_gwfflowja%base(), nr_conns, (/STG_BFR_EXG_AD/)) - if (this%indsp%get() > 0 .and. this%inmst%get() > 0) then - call this%map(this%mst_porosity%base(), nr_nodes, (/STG_AFT_CON_AR/)) + if (this%indsp%get() > 0 .and. this%inest%get() > 0) then + call this%map(this%est_porosity%base(), nr_nodes, (/STG_AFT_CON_AR/)) end if end if @@ -171,9 +171,9 @@ subroutine allocate_data(this) allocate (this%fmi_gwfsat) allocate (this%fmi_gwfspdis) allocate (this%fmi_gwfflowja) - allocate (this%mst_porosity) + allocate (this%est_porosity) allocate (this%indsp) - allocate (this%inmst) + allocate (this%inest) end subroutine allocate_data @@ -194,9 +194,9 @@ subroutine deallocate_data(this) deallocate (this%fmi_gwfsat) deallocate (this%fmi_gwfspdis) deallocate (this%fmi_gwfflowja) - deallocate (this%mst_porosity) + deallocate (this%est_porosity) deallocate (this%indsp) - deallocate (this%inmst) + deallocate (this%inest) end subroutine deallocate_data diff --git a/src/Exchange/GwfGweExchange.f90 b/src/Exchange/GwfGweExchange.f90 index fdb7d180fa4..d60a6be4a6a 100644 --- a/src/Exchange/GwfGweExchange.f90 +++ b/src/Exchange/GwfGweExchange.f90 @@ -245,7 +245,7 @@ subroutine exg_ar(this) ! ! -- setup pointers to the flow storage rates. GWF strg arrays are ! available after the gwf_ar routine is called. - if (gwemodel%inmst > 0) then + if (gwemodel%inest > 0) then if (gwfmodel%insto > 0) then gwemodel%fmi%gwfstrgss => gwfmodel%sto%strgss gwemodel%fmi%igwfstrgss = 1 diff --git a/src/Model/Connection/GweGweConnection.f90 b/src/Model/Connection/GweGweConnection.f90 index 57b2a6e6c1e..5ddb6b70eef 100644 --- a/src/Model/Connection/GweGweConnection.f90 +++ b/src/Model/Connection/GweGweConnection.f90 @@ -233,9 +233,9 @@ subroutine cfg_dist_vars(this) call this%cfg_dv('GWFFLOWJA', 'FMI', SYNC_CON, (/STG_BFR_EXG_AD/)) call this%cfg_dv('GWFFLOWJA', 'FMI', SYNC_EXG, (/STG_BFR_EXG_AD/), & exg_var_name='GWFSIMVALS') - ! -- Fill porosity from mst packages, needed for dsp - if (this%gweModel%indsp > 0 .and. this%gweModel%inmst > 0) then - call this%cfg_dv('POROSITY', 'MST', SYNC_NDS, (/STG_AFT_CON_AR/)) + ! -- Fill porosity from est packages, needed for dsp + if (this%gweModel%indsp > 0 .and. this%gweModel%inest > 0) then + call this%cfg_dv('POROSITY', 'EST', SYNC_NDS, (/STG_AFT_CON_AR/)) end if ! end subroutine cfg_dist_vars @@ -298,7 +298,7 @@ subroutine gwegwecon_ar(this) call this%gweInterfaceModel%model_ar() ! -- Set a pointer in the interface model to the gwecommon data - if (this%gweModel%inmst > 0) then + if (this%gweModel%inest > 0) then this%gweInterfaceModel%gwecommon%gwecpw = this%gweModel%gwecommon%gwecpw this%gweInterfaceModel%gwecommon%gwerhow = this%gweModel%gwecommon%gwerhow end if diff --git a/src/Model/Connection/GweInterfaceModel.f90 b/src/Model/Connection/GweInterfaceModel.f90 index 5b28b5888c5..cbbef1c70fa 100644 --- a/src/Model/Connection/GweInterfaceModel.f90 +++ b/src/Model/Connection/GweInterfaceModel.f90 @@ -11,7 +11,7 @@ module GweInterfaceModelModule use TspAdvOptionsModule, only: TspAdvOptionsType use GweDspModule, only: dsp_cr, GweDspType use GweDspOptionsModule, only: GweDspOptionsType - use GweMstModule, only: mst_cr + use GweEstModule, only: est_cr use TspObsModule, only: tsp_obs_cr use GridConnectionModule use GweInputDataModule, only: GweInputDataType @@ -34,7 +34,7 @@ module GweInterfaceModelModule class(GweModelType), private, pointer :: owner => null() !< the real GWE model for which the exchange coefficients !! are calculated with this interface model - real(DP), dimension(:), pointer, contiguous :: porosity => null() !< to be filled with MST porosity + real(DP), dimension(:), pointer, contiguous :: porosity => null() !< to be filled with EST porosity contains @@ -184,9 +184,9 @@ subroutine gweifmod_df(this) call mem_reallocate(this%dsp%kts, this%dis%nodes, 'KTS', & trim(this%dsp%memoryPath)) end if - allocate (this%mst) - call mem_allocate(this%mst%porosity, this%dis%nodes, & - 'POROSITY', create_mem_path(this%name, 'MST')) + allocate (this%est) + call mem_allocate(this%est%porosity, this%dis%nodes, & + 'POROSITY', create_mem_path(this%name, 'EST')) end if ! ! -- Assign or point model members to dis members @@ -217,7 +217,7 @@ subroutine gweifmod_ar(this) call this%adv%adv_ar(this%dis, this%ibound) end if if (this%indsp > 0) then - call this%dsp%dsp_ar(this%ibound, this%mst%porosity) + call this%dsp%dsp_ar(this%ibound, this%est%porosity) end if ! ! -- Return @@ -247,9 +247,9 @@ subroutine gweifmod_da(this) deallocate (this%adv) deallocate (this%dsp) ! - if (associated(this%mst)) then - call mem_deallocate(this%mst%porosity) - deallocate (this%mst) + if (associated(this%est)) then + call mem_deallocate(this%est%porosity) + deallocate (this%est) end if ! ! -- gwe scalars @@ -258,7 +258,7 @@ subroutine gweifmod_da(this) call mem_deallocate(this%inadv) call mem_deallocate(this%indsp) call mem_deallocate(this%inssm) - call mem_deallocate(this%inmst) + call mem_deallocate(this%inest) call mem_deallocate(this%inmvt) call mem_deallocate(this%inoc) call mem_deallocate(this%inobs) diff --git a/src/Model/GroundWaterEnergy/gwe1.f90 b/src/Model/GroundWaterEnergy/gwe1.f90 index ffb14be1089..45b57ebd9e5 100644 --- a/src/Model/GroundWaterEnergy/gwe1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1.f90 @@ -11,7 +11,7 @@ module GweModule use BaseModelModule, only: BaseModelType use BndModule, only: BndType, AddBndToList, GetBndFromList use GweDspModule, only: GweDspType - use GweMstModule, only: GweMstType + use GweEstModule, only: GweEstType use BudgetModule, only: BudgetType use GweInputDataModule, only: GweInputDataType use TransportModelModule @@ -33,9 +33,9 @@ module GweModule type, extends(TransportModelType) :: GweModelType type(GweInputDataType), pointer :: gwecommon => null() !< container for data shared with multiple packages - type(GweMstType), pointer :: mst => null() !< mass storage and transfer package + type(GweEstType), pointer :: est => null() !< mass storage and transfer package type(GweDspType), pointer :: dsp => null() !< dispersion package - integer(I4B), pointer :: inmst => null() ! unit number MST + integer(I4B), pointer :: inest => null() ! unit number EST integer(I4B), pointer :: indsp => null() ! unit number DSP contains @@ -70,7 +70,7 @@ module GweModule integer(I4B), parameter :: GWE_NBASEPKG = 50 character(len=LENPACKAGETYPE), dimension(GWE_NBASEPKG) :: GWE_BASEPKG data GWE_BASEPKG/'DIS6 ', 'DISV6', 'DISU6', ' ', ' ', & ! 5 - &'IC6 ', 'FMI6 ', 'MST6 ', 'ADV6 ', ' ', & ! 10 + &'IC6 ', 'FMI6 ', 'EST6 ', 'ADV6 ', ' ', & ! 10 &'DSP6 ', 'SSM6 ', 'MVT6 ', 'OC6 ', ' ', & ! 15 &'OBS6 ', ' ', ' ', ' ', ' ', & ! 20 &30*' '/ ! 50 @@ -276,9 +276,9 @@ subroutine gwe_ar(this) call this%fmi%fmi_ar(this%ibound) if (this%inmvt > 0) call this%mvt%mvt_ar() if (this%inic > 0) call this%ic%ic_ar(this%x) - if (this%inmst > 0) call this%mst%mst_ar(this%dis, this%ibound) + if (this%inest > 0) call this%est%est_ar(this%dis, this%ibound) if (this%inadv > 0) call this%adv%adv_ar(this%dis, this%ibound) - if (this%indsp > 0) call this%dsp%dsp_ar(this%ibound, this%mst%porosity) + if (this%indsp > 0) call this%dsp%dsp_ar(this%ibound, this%est%porosity) if (this%inssm > 0) call this%ssm%ssm_ar(this%dis, this%ibound, this%x) if (this%inobs > 0) call this%obs%tsp_obs_ar(this%ic, this%x, this%flowja) ! @@ -440,8 +440,8 @@ subroutine gwe_fc(this, kiter, matrix_sln, inwtflag) if (this%inmvt > 0) then call this%mvt%mvt_fc(this%x, this%x) end if - if (this%inmst > 0) then - call this%mst%mst_fc(this%dis%nodes, this%xold, this%nja, matrix_sln, & + if (this%inest > 0) then + call this%est%est_fc(this%dis%nodes, this%xold, this%nja, matrix_sln, & this%idxglo, this%x, this%rhs, kiter) end if if (this%inadv > 0) then @@ -517,7 +517,7 @@ subroutine gwe_cq(this, icnvg, isuppress_output) end do if (this%inadv > 0) call this%adv%adv_cq(this%x, this%flowja) if (this%indsp > 0) call this%dsp%dsp_cq(this%x, this%flowja) - if (this%inmst > 0) call this%mst%mst_cq(this%dis%nodes, this%x, this%xold, & + if (this%inest > 0) call this%est%est_cq(this%dis%nodes, this%x, this%xold, & this%flowja) if (this%inssm > 0) call this%ssm%ssm_cq(this%flowja) if (this%infmi > 0) call this%fmi%fmi_cq(this%x, this%flowja) @@ -564,7 +564,7 @@ subroutine gwe_bd(this, icnvg, isuppress_output) ! should be added here to this%budget. In a subsequent exchange call, ! exchange flows might also be added. call this%budget%reset() - if (this%inmst > 0) call this%mst%mst_bd(isuppress_output, this%budget) + if (this%inest > 0) call this%est%est_bd(isuppress_output, this%budget) if (this%inssm > 0) call this%ssm%ssm_bd(isuppress_output, this%budget) if (this%infmi > 0) call this%fmi%fmi_bd(isuppress_output, this%budget) if (this%inmvt > 0) call this%mvt%mvt_bd(this%x, this%x) @@ -592,13 +592,13 @@ subroutine gwe_ot(this) ! -- Initialize icbcfl = 0 ! - ! -- Because mst belongs to gwe, call mst_ot_flow directly (and not from parent) + ! -- Because est belongs to gwe, call est_ot_flow directly (and not from parent) if (this%oc%oc_save('BUDGET')) icbcfl = 1 icbcun = this%oc%oc_save_unit('BUDGET') - if (this%inmst > 0) call this%mst%mst_ot_flow(icbcfl, icbcun) + if (this%inest > 0) call this%est%est_ot_flow(icbcfl, icbcun) ! ! -- Call parent class _ot routines. - call this%tsp_ot(this%inmst) + call this%tsp_ot(this%inest) ! ! -- Return return @@ -630,7 +630,7 @@ subroutine gwe_da(this) call this%adv%adv_da() call this%dsp%dsp_da() call this%ssm%ssm_da() - call this%mst%mst_da() + call this%est%est_da() call this%mvt%mvt_da() call this%budget%budget_da() call this%oc%oc_da() @@ -644,7 +644,7 @@ subroutine gwe_da(this) deallocate (this%adv) deallocate (this%dsp) deallocate (this%ssm) - deallocate (this%mst) + deallocate (this%est) deallocate (this%mvt) deallocate (this%budget) deallocate (this%oc) @@ -659,7 +659,7 @@ subroutine gwe_da(this) end do ! ! -- Scalars - call mem_deallocate(this%inmst) + call mem_deallocate(this%inest) call mem_deallocate(this%indsp) ! ! -- Parent class members @@ -744,10 +744,10 @@ subroutine allocate_scalars(this, modelname) call this%allocate_tsp_scalars(modelname) ! ! -- allocate members that are part of model class - call mem_allocate(this%inmst, 'INMST', this%memoryPath) + call mem_allocate(this%inest, 'INEST', this%memoryPath) call mem_allocate(this%indsp, 'INDSP', this%memoryPath) ! - this%inmst = 0 + this%inest = 0 this%indsp = 0 ! ! -- Return @@ -919,7 +919,7 @@ subroutine create_gwe_packages(this, indis) use MemoryManagerModule, only: mem_setptr use MemoryHelperModule, only: create_mem_path use SimVariablesModule, only: idm_context - use GweMstModule, only: mst_cr + use GweEstModule, only: est_cr use GweDspModule, only: dsp_cr ! -- dummy class(GweModelType) :: this @@ -961,8 +961,8 @@ subroutine create_gwe_packages(this, indis) ! ! -- create dis package as it is a prerequisite for other packages select case (pkgtype) - case ('MST6') - this%inmst = inunit + case ('EST6') + this%inest = inunit case ('DSP6') this%indsp = 1 mempathdsp = mempath @@ -976,13 +976,13 @@ subroutine create_gwe_packages(this, indis) end do ! ! -- Create packages that are tied directly to model - call mst_cr(this%mst, this%name, this%inmst, this%iout, this%fmi, & + call est_cr(this%est, this%name, this%inest, this%iout, this%fmi, & this%eqnsclfac, this%gwecommon) call dsp_cr(this%dsp, this%name, mempathdsp, this%indsp, this%iout, & this%fmi, this%eqnsclfac, this%gwecommon) ! ! -- Check to make sure that required ftype's have been specified - call this%ftype_check(indis, this%inmst) + call this%ftype_check(indis, this%inest) ! call this%create_bndpkgs(bndpkgs, pkgtypes, pkgnames, mempaths, inunits) ! diff --git a/src/Model/GroundWaterEnergy/gwe1dsp1.f90 b/src/Model/GroundWaterEnergy/gwe1dsp1.f90 index 02b7797c60e..9e3609a7181 100644 --- a/src/Model/GroundWaterEnergy/gwe1dsp1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1dsp1.f90 @@ -19,7 +19,7 @@ module GweDspModule integer(I4B), dimension(:), pointer, contiguous :: ibound => null() ! pointer to GWE model ibound type(TspFmiType), pointer :: fmi => null() ! pointer to GWE fmi object - type(GweInputDataType), pointer :: gwecommon => null() !< pointer to shared gwe data used by multiple packages but set in mst + type(GweInputDataType), pointer :: gwecommon => null() !< pointer to shared gwe data used by multiple packages but set in est real(DP), dimension(:), pointer, contiguous :: porosity => null() ! pointer to GWE storage porosity real(DP), dimension(:), pointer, contiguous :: alh => null() ! longitudinal horizontal dispersivity real(DP), dimension(:), pointer, contiguous :: alv => null() ! longitudinal vertical dispersivity diff --git a/src/Model/GroundWaterEnergy/gwe1mst1.f90 b/src/Model/GroundWaterEnergy/gwe1est1.f90 similarity index 89% rename from src/Model/GroundWaterEnergy/gwe1mst1.f90 rename to src/Model/GroundWaterEnergy/gwe1est1.f90 index 289417f3ca6..c5a0dba3f65 100644 --- a/src/Model/GroundWaterEnergy/gwe1mst1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1est1.f90 @@ -1,7 +1,7 @@ -!> -- @ brief Mobile Storage and Transfer (MST) Module +!> -- @ brief Energy Storage and Transfer (EST) Module !! -!! The GweMstModule contains the GweMstType, which is related -!! to GwtMstModule; however, there are some important differences +!! The GweEstModule contains the GweEstType, which is related +!! to GwtEstModule; however, there are some important differences !! owing to the fact that a sorbed phase is not considered. !! Instead, a single temperature is simulated for each grid !! cell and is represenative of both the aqueous and solid @@ -10,7 +10,7 @@ !! conductive processes can transport into, through, or !! out of dry cells that are part of the active domain. !< -module GweMstModule +module GweEstModule use KindModule, only: DP, I4B use ConstantsModule, only: DONE, DZERO, DTWO, DHALF, LENBUDTXT @@ -24,18 +24,18 @@ module GweMstModule use GweInputDataModule, only: GweInputDataType implicit none - public :: GweMstType - public :: mst_cr + public :: GweEstType + public :: est_cr ! integer(I4B), parameter :: NBDITEMS = 2 character(len=LENBUDTXT), dimension(NBDITEMS) :: budtxt data budtxt/' STORAGE-CELLBLK', ' DECAY-AQUEOUS'/ - !> @ brief Mobile storage and transfer + !> @ brief Energy storage and transfer !! !! Data and methods for handling changes in temperature !< - type, extends(NumericalPackageType) :: GweMstType + type, extends(NumericalPackageType) :: GweEstType ! ! -- storage real(DP), pointer :: cpw => null() !< heat capacity of water @@ -43,7 +43,7 @@ module GweMstModule real(DP), dimension(:), pointer, contiguous :: cps => null() !< heat capacity of solid real(DP), dimension(:), pointer, contiguous :: rhos => null() !< density of solid real(DP), dimension(:), pointer, contiguous :: porosity => null() !< porosity - real(DP), dimension(:), pointer, contiguous :: ratesto => null() !< rate of mobile storage + real(DP), dimension(:), pointer, contiguous :: ratesto => null() !< rate of energy storage ! ! -- decay integer(I4B), pointer :: idcy => null() !< order of decay rate (0:none, 1:first, 2:zero) @@ -55,39 +55,39 @@ module GweMstModule ! -- misc integer(I4B), dimension(:), pointer, contiguous :: ibound => null() !< pointer to model ibound type(TspFmiType), pointer :: fmi => null() !< pointer to fmi object - type(GweInputDataType), pointer :: gwecommon => null() !< pointer to shared gwe data used by multiple packages but set in mst + type(GweInputDataType), pointer :: gwecommon => null() !< pointer to shared gwe data used by multiple packages but set in est real(DP), pointer :: latheatvap => null() !< latent heat of vaporization real(DP), pointer :: eqnsclfac => null() !< governing equation scale factor; =rhow*cpw for energy contains - procedure :: mst_ar - procedure :: mst_fc - procedure :: mst_fc_sto - procedure :: mst_fc_dcy - procedure :: mst_cq - procedure :: mst_cq_sto - procedure :: mst_cq_dcy - procedure :: mst_bd - procedure :: mst_ot_flow - procedure :: mst_da + procedure :: est_ar + procedure :: est_fc + procedure :: est_fc_sto + procedure :: est_fc_dcy + procedure :: est_cq + procedure :: est_cq_sto + procedure :: est_cq_dcy + procedure :: est_bd + procedure :: est_ot_flow + procedure :: est_da procedure :: allocate_scalars procedure, private :: allocate_arrays procedure, private :: read_options procedure, private :: read_data procedure, private :: read_packagedata - end type GweMstType + end type GweEstType contains - !> @ brief Create a new MST package object + !> @ brief Create a new EST package object !! - !! Create a new MST package + !! Create a new EST package !< - subroutine mst_cr(mstobj, name_model, inunit, iout, fmi, eqnsclfac, gwecommon) + subroutine est_cr(estobj, name_model, inunit, iout, fmi, eqnsclfac, gwecommon) ! -- dummy - type(GweMstType), pointer :: mstobj !< unallocated new mst object to create + type(GweEstType), pointer :: estobj !< unallocated new est object to create character(len=*), intent(in) :: name_model !< name of the model integer(I4B), intent(in) :: inunit !< unit number of WEL package input file integer(I4B), intent(in) :: iout !< unit number of model listing file @@ -96,47 +96,47 @@ subroutine mst_cr(mstobj, name_model, inunit, iout, fmi, eqnsclfac, gwecommon) type(GweInputDataType), intent(in), target :: gwecommon !< shared data container for use by multiple GWE packages ! ! -- Create the object - allocate (mstobj) + allocate (estobj) ! ! -- create name and memory path - call mstobj%set_names(1, name_model, 'MST', 'MST') + call estobj%set_names(1, name_model, 'EST', 'EST') ! ! -- Allocate scalars - call mstobj%allocate_scalars() + call estobj%allocate_scalars() ! ! -- Set variables - mstobj%inunit = inunit - mstobj%iout = iout - mstobj%fmi => fmi - mstobj%eqnsclfac => eqnsclfac - mstobj%gwecommon => gwecommon + estobj%inunit = inunit + estobj%iout = iout + estobj%fmi => fmi + estobj%eqnsclfac => eqnsclfac + estobj%gwecommon => gwecommon ! ! -- Initialize block parser - call mstobj%parser%Initialize(mstobj%inunit, mstobj%iout) + call estobj%parser%Initialize(estobj%inunit, estobj%iout) ! ! -- Return return - end subroutine mst_cr + end subroutine est_cr !> @ brief Allocate and read method for package !! !! Method to allocate and read static data for the package. !< - subroutine mst_ar(this, dis, ibound) + subroutine est_ar(this, dis, ibound) ! -- modules use GweInputDataModule, only: set_gwe_dat_ptrs ! -- dummy - class(GweMstType), intent(inout) :: this !< GweMstType object + class(GweEstType), intent(inout) :: this !< GweEstType object class(DisBaseType), pointer, intent(in) :: dis !< pointer to dis package integer(I4B), dimension(:), pointer, contiguous :: ibound !< pointer to GWE ibound array ! -- local ! -- formats - character(len=*), parameter :: fmtmst = & - "(1x,/1x,'MST -- MOBILE STORAGE AND TRANSFER PACKAGE, VERSION 1, & + character(len=*), parameter :: fmtest = & + "(1x,/1x,'EST -- ENERGY STORAGE AND TRANSFER PACKAGE, VERSION 1, & &7/29/2020 INPUT READ FROM UNIT ', i0, //)" ! - ! --print a message identifying the mobile storage and transfer package. - write (this%iout, fmtmst) this%inunit + ! --print a message identifying the energy storage and transfer package. + write (this%iout, fmtest) this%inunit ! ! -- Read options call this%read_options() @@ -165,17 +165,17 @@ subroutine mst_ar(this, dis, ibound) ! ! -- Return return - end subroutine mst_ar + end subroutine est_ar !> @ brief Fill coefficient method for package !! !! Method to calculate and fill coefficients for the package. !< - subroutine mst_fc(this, nodes, cold, nja, matrix_sln, idxglo, cnew, & + subroutine est_fc(this, nodes, cold, nja, matrix_sln, idxglo, cnew, & rhs, kiter) ! -- modules ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object integer, intent(in) :: nodes !< number of nodes real(DP), intent(in), dimension(nodes) :: cold !< temperature at end of last time step integer(I4B), intent(in) :: nja !< number of GWE connections @@ -187,27 +187,27 @@ subroutine mst_fc(this, nodes, cold, nja, matrix_sln, idxglo, cnew, & ! -- local ! ! -- storage contribution - call this%mst_fc_sto(nodes, cold, nja, matrix_sln, idxglo, rhs) + call this%est_fc_sto(nodes, cold, nja, matrix_sln, idxglo, rhs) ! ! -- decay contribution if (this%idcy /= 0) then - call this%mst_fc_dcy(nodes, cold, cnew, nja, matrix_sln, idxglo, & + call this%est_fc_dcy(nodes, cold, cnew, nja, matrix_sln, idxglo, & rhs, kiter) end if ! ! -- Return return - end subroutine mst_fc + end subroutine est_fc !> @ brief Fill storage coefficient method for package !! !! Method to calculate and fill storage coefficients for the package. !< - subroutine mst_fc_sto(this, nodes, cold, nja, matrix_sln, idxglo, rhs) + subroutine est_fc_sto(this, nodes, cold, nja, matrix_sln, idxglo, rhs) ! -- modules use TdisModule, only: delt ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object integer, intent(in) :: nodes !< number of nodes real(DP), intent(in), dimension(nodes) :: cold !< temperature at end of last time step integer(I4B), intent(in) :: nja !< number of GWE connections @@ -248,18 +248,18 @@ subroutine mst_fc_sto(this, nodes, cold, nja, matrix_sln, idxglo, rhs) ! ! -- Return return - end subroutine mst_fc_sto + end subroutine est_fc_sto !> @ brief Fill decay coefficient method for package !! !! Method to calculate and fill decay coefficients for the package. !< - subroutine mst_fc_dcy(this, nodes, cold, cnew, nja, matrix_sln, & + subroutine est_fc_dcy(this, nodes, cold, cnew, nja, matrix_sln, & idxglo, rhs, kiter) ! -- modules use TdisModule, only: delt ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object integer, intent(in) :: nodes !< number of nodes real(DP), intent(in), dimension(nodes) :: cold !< temperature at end of last time step real(DP), intent(in), dimension(nodes) :: cnew !< temperature at end of this time step @@ -311,16 +311,16 @@ subroutine mst_fc_dcy(this, nodes, cold, cnew, nja, matrix_sln, & ! ! -- Return return - end subroutine mst_fc_dcy + end subroutine est_fc_dcy !> @ brief Calculate flows for package !! !! Method to calculate flows for the package. !< - subroutine mst_cq(this, nodes, cnew, cold, flowja) + subroutine est_cq(this, nodes, cnew, cold, flowja) ! -- modules ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object integer(I4B), intent(in) :: nodes !< number of nodes real(DP), intent(in), dimension(nodes) :: cnew !< temperature at end of this time step real(DP), intent(in), dimension(nodes) :: cold !< temperature at end of last time step @@ -328,26 +328,26 @@ subroutine mst_cq(this, nodes, cnew, cold, flowja) ! -- local ! ! - storage - call this%mst_cq_sto(nodes, cnew, cold, flowja) + call this%est_cq_sto(nodes, cnew, cold, flowja) ! ! -- decay if (this%idcy /= 0) then - call this%mst_cq_dcy(nodes, cnew, cold, flowja) + call this%est_cq_dcy(nodes, cnew, cold, flowja) end if ! ! -- Return return - end subroutine mst_cq + end subroutine est_cq !> @ brief Calculate storage terms for package !! !! Method to calculate storage terms for the package. !< - subroutine mst_cq_sto(this, nodes, cnew, cold, flowja) + subroutine est_cq_sto(this, nodes, cnew, cold, flowja) ! -- modules use TdisModule, only: delt ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object integer(I4B), intent(in) :: nodes !< number of nodes real(DP), intent(in), dimension(nodes) :: cnew !< temperature at end of this time step real(DP), intent(in), dimension(nodes) :: cold !< temperature at end of last time step @@ -392,17 +392,17 @@ subroutine mst_cq_sto(this, nodes, cnew, cold, flowja) ! ! -- Return return - end subroutine mst_cq_sto + end subroutine est_cq_sto !> @ brief Calculate decay terms for package !! !! Method to calculate decay terms for the package. !< - subroutine mst_cq_dcy(this, nodes, cnew, cold, flowja) ! Important note: this handles only decay in water; need to add zero-order (but not first-order?) decay in solid + subroutine est_cq_dcy(this, nodes, cnew, cold, flowja) ! Important note: this handles only decay in water; need to add zero-order (but not first-order?) decay in solid ! -- modules use TdisModule, only: delt ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object integer(I4B), intent(in) :: nodes !< number of nodes real(DP), intent(in), dimension(nodes) :: cnew !< temperature at end of this time step real(DP), intent(in), dimension(nodes) :: cold !< temperature at end of last time step @@ -450,18 +450,18 @@ subroutine mst_cq_dcy(this, nodes, cnew, cold, flowja) ! Important note: this ha ! ! -- Return return - end subroutine mst_cq_dcy + end subroutine est_cq_dcy !> @ brief Calculate budget terms for package !! !! Method to calculate budget terms for the package. !< - subroutine mst_bd(this, isuppress_output, model_budget) + subroutine est_bd(this, isuppress_output, model_budget) ! -- modules use TdisModule, only: delt use BudgetModule, only: BudgetType, rate_accumulator ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object integer(I4B), intent(in) :: isuppress_output !< flag to supress output type(BudgetType), intent(inout) :: model_budget !< model budget object ! -- local @@ -482,15 +482,15 @@ subroutine mst_bd(this, isuppress_output, model_budget) ! ! -- Return return - end subroutine mst_bd + end subroutine est_bd !> @ brief Output flow terms for package !! !! Method to output terms for the package. !< - subroutine mst_ot_flow(this, icbcfl, icbcun) + subroutine est_ot_flow(this, icbcfl, icbcun) ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object integer(I4B), intent(in) :: icbcfl !< flag and unit number for cell-by-cell output integer(I4B), intent(in) :: icbcun !< flag indication if cell-by-cell data should be saved ! -- local @@ -529,17 +529,17 @@ subroutine mst_ot_flow(this, icbcfl, icbcun) ! ! -- Return return - end subroutine mst_ot_flow + end subroutine est_ot_flow !> @brief Deallocate memory !! !! Method to deallocate memory for the package. !< - subroutine mst_da(this) + subroutine est_da(this) ! -- modules use MemoryManagerModule, only: mem_deallocate ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object ! ! -- Deallocate arrays if package was active if (this%inunit > 0) then @@ -566,7 +566,7 @@ subroutine mst_da(this) ! ! -- Return return - end subroutine mst_da + end subroutine est_da !> @ brief Allocate scalar variables for package !! @@ -576,7 +576,7 @@ subroutine allocate_scalars(this) ! -- modules use MemoryManagerModule, only: mem_allocate, mem_setptr ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object ! -- local ! ! -- Allocate scalars in NumericalPackageType @@ -609,7 +609,7 @@ subroutine allocate_arrays(this, nodes) use MemoryManagerModule, only: mem_allocate use ConstantsModule, only: DZERO ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object integer(I4B), intent(in) :: nodes !< number of nodes ! -- local integer(I4B) :: n @@ -657,7 +657,7 @@ subroutine read_options(this) ! -- modules use ConstantsModule, only: LINELENGTH ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object ! -- local character(len=LINELENGTH) :: keyword integer(I4B) :: ierr @@ -680,7 +680,7 @@ subroutine read_options(this) ! ! -- parse options block if detected if (isfound) then - write (this%iout, '(1x,a)') 'PROCESSING MOBILE STORAGE AND TRANSFER OPTIONS' + write (this%iout, '(1x,a)') 'PROCESSING ENERGY STORAGE AND TRANSFER OPTIONS' do call this%parser%GetNextLine(endOfBlock) if (endOfBlock) exit @@ -699,12 +699,12 @@ subroutine read_options(this) this%ilhv = 1 write (this%iout, fmtilhv) case default - write (errmsg, '(a,a)') 'UNKNOWN MST OPTION: ', trim(keyword) + write (errmsg, '(a,a)') 'UNKNOWN EST OPTION: ', trim(keyword) call store_error(errmsg) call this%parser%StoreErrorUnit() end select end do - write (this%iout, '(1x,a)') 'END OF MOBILE STORAGE AND TRANSFER OPTIONS' + write (this%iout, '(1x,a)') 'END OF ENERGY STORAGE AND TRANSFER OPTIONS' end if ! ! -- Return @@ -720,7 +720,7 @@ subroutine read_data(this) use ConstantsModule, only: LINELENGTH use MemoryManagerModule, only: mem_reallocate, mem_reassignptr ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object ! -- local character(len=LINELENGTH) :: keyword character(len=:), allocatable :: line @@ -834,7 +834,7 @@ end subroutine read_data subroutine read_packagedata(this) ! -- modules ! -- dummy - class(GweMstType) :: this !< GweMstType object + class(GweEstType) :: this !< GweEstType object ! -- local logical :: isfound logical :: endOfBlock @@ -909,4 +909,4 @@ function get_zero_order_decay(decay_rate_usr, decay_rate_last, kiter, & return end function get_zero_order_decay -end module GweMstModule +end module GweEstModule diff --git a/src/Model/ModelUtilities/GweInputData.f90 b/src/Model/ModelUtilities/GweInputData.f90 index 55757560383..fb3493f2888 100644 --- a/src/Model/ModelUtilities/GweInputData.f90 +++ b/src/Model/ModelUtilities/GweInputData.f90 @@ -11,7 +11,7 @@ module GweInputDataModule public :: set_gwe_dat_ptrs !> Data for sharing among multiple packages. Originally read in from - !< the MST package + !< the EST package type GweInputDataType @@ -21,7 +21,7 @@ module GweInputDataModule ! strings character(len=LENMEMPATH) :: memoryPath = '' !< the location in the memory manager where the variables are stored - ! mst data to be share across multiple packages + ! est data to be share across multiple packages real(DP), pointer :: gwerhow => null() !< Density of water (for GWE purposes, a constant scalar) real(DP), pointer :: gwecpw => null() !< Heat capacity of water (non-spatially varying) real(DP), pointer :: gwelatheatvap => null() !< latent heat of vaporization @@ -103,9 +103,9 @@ subroutine allocate_shared_vars(this, nodes) return end subroutine allocate_shared_vars - !> @brief Allocate and read data from MST + !> @brief Allocate and read data from EST !! - !! MST data, including heat capacity of water (cpw), density of water + !! EST data, including heat capacity of water (cpw), density of water !! (rhow), latent heat of vaporization (latheatvap), heat capacity of !! the aquifer material (cps), and density of the aquifer material !! (rhow) is used among other packages and is therefore stored in a @@ -114,11 +114,11 @@ subroutine set_gwe_dat_ptrs(this, gwerhow, gwecpw, gwerhos, gwecps, & gwelatheatvap) ! -- dummy class(GweInputDataType) :: this !< the input data block - real(DP), intent(in) :: gwerhow !< ptr to density of water specified in MST - real(DP), intent(in) :: gwecpw !< ptr to heat capacity of water specified in MST - real(DP), intent(in) :: gwerhos !< ptr to sptially-variably density of aquifer material specified in MST - real(DP), intent(in) :: gwecps !< ptr to sptially-variably heat capacity of aquifer material specified in MST - real(DP), intent(in), optional :: gwelatheatvap !< ptr to latent heat of vaporization specified in MST + real(DP), intent(in) :: gwerhow !< ptr to density of water specified in EST + real(DP), intent(in) :: gwecpw !< ptr to heat capacity of water specified in EST + real(DP), intent(in) :: gwerhos !< ptr to sptially-variably density of aquifer material specified in EST + real(DP), intent(in) :: gwecps !< ptr to sptially-variably heat capacity of aquifer material specified in EST + real(DP), intent(in), optional :: gwelatheatvap !< ptr to latent heat of vaporization specified in EST ! ! -- Allocate scalars if (present(gwelatheatvap)) then @@ -134,7 +134,7 @@ subroutine set_gwe_dat_ptrs(this, gwerhow, gwecpw, gwerhos, gwecps, & return end subroutine set_gwe_dat_ptrs - !> @brief Set pointers to scalars read by the MST package + !> @brief Set pointers to scalars read by the EST package !! for use by other packages !! !! Set pointers to GWE-related scalars and arrays for use @@ -164,7 +164,7 @@ subroutine set_gwe_shared_scalars(this, gwerhow, gwecpw, gwelatheatvap) return end subroutine set_gwe_shared_scalars - !> @brief Set pointers to data arrays read by the MST package + !> @brief Set pointers to data arrays read by the EST package !! for use by other packages !! !! Set pointers to GWE-related arrays for use diff --git a/src/Model/TransportModel/tsp1.f90 b/src/Model/TransportModel/tsp1.f90 index bd7622edebf..9e18f720a8b 100644 --- a/src/Model/TransportModel/tsp1.f90 +++ b/src/Model/TransportModel/tsp1.f90 @@ -644,7 +644,7 @@ subroutine ftype_check(this, indis, inmst) ! -- dummy class(TransportModelType) :: this integer(I4B), intent(in) :: indis - integer(I4B), intent(in) :: inmst + integer(I4B), intent(in) :: inmst !< representative of both inmst and inest depending on model type ! -- local character(len=LINELENGTH) :: errmsg ! diff --git a/src/meson.build b/src/meson.build index 1f68d653c95..a2b4bef7667 100644 --- a/src/meson.build +++ b/src/meson.build @@ -68,7 +68,7 @@ modflow_sources = files( 'Model' / 'GroundWaterEnergy' / 'gwe1dsp1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1ic1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1idm.f90', - 'Model' / 'GroundWaterEnergy' / 'gwe1mst1.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1est1.f90', 'Model' / 'GroundWaterFlow' / 'gwf3.f90', 'Model' / 'GroundWaterFlow' / 'gwf3api8.f90', 'Model' / 'GroundWaterFlow' / 'gwf3buy8.f90', From ab699726d19105c1c46cf112cfaae69bb33d0188 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Thu, 18 Jan 2024 11:46:26 -0800 Subject: [PATCH 27/46] Forgot to remove a now obsolete file due to renaming (again) --- doc/mf6io/mf6ivar/tex/gwe-mst-desc.tex | 35 -------------------------- 1 file changed, 35 deletions(-) delete mode 100644 doc/mf6io/mf6ivar/tex/gwe-mst-desc.tex diff --git a/doc/mf6io/mf6ivar/tex/gwe-mst-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-mst-desc.tex deleted file mode 100644 index 4bc66c85094..00000000000 --- a/doc/mf6io/mf6ivar/tex/gwe-mst-desc.tex +++ /dev/null @@ -1,35 +0,0 @@ -% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py - -\item \textbf{Block: OPTIONS} - -\begin{description} -\item \texttt{SAVE\_FLOWS}---keyword to indicate that MST flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. - -\item \texttt{ZERO\_ORDER\_DECAY}---is a text keyword to indicate that zero-order decay will occur. Use of this keyword requires that DECAY and DECAY\_SORBED (if sorption is active) are specified in the GRIDDATA block. - -\item \texttt{LATENT\_HEAT\_VAPORIZATION}---is a text keyword to indicate that cooling associated with evaporation will occur. Use of this keyword requires that LATHEATVAP are specified in the GRIDDATA block. While the MST package does not simulate evaporation, multiple other packages in a GWE simulation may. For example, evaporation may occur from the surface of streams or lakes. Owing to the energy consumed by the change in phase, the latent heat of vaporization is required. - -\end{description} -\item \textbf{Block: GRIDDATA} - -\begin{description} -\item \texttt{porosity}---is the mobile domain porosity, defined as the mobile domain pore volume per mobile domain volume. The GWE model does not support the concept of an immobile domain in the context of heat transport. - -\item \texttt{decay}---is the rate coefficient for zero-order decay for the aqueous phase of the mobile domain. A negative value indicates heat (energy) production. The dimensions of decay for zero-order decay is energy per length cubed per time. Zero-order decay will have no effect on simulation results unless zero-order decay is specified in the options block. - -\item \texttt{cps}---is the mass-based heat capacity of dry solids (aquifer material). For example, units of J/kg/C may be used (or equivalent). - -\item \texttt{rhos}---is a user-specified value of the density of aquifer material not considering the voids. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. - -\end{description} -\item \textbf{Block: PACKAGEDATA} - -\begin{description} -\item \texttt{cpw}---is the mass-based heat capacity of the simulated fluid. For example, units of J/kg/C may be used (or equivalent). - -\item \texttt{rhow}---is a user-specified value of the density of water. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. - -\item \texttt{latheatvap}---is the user-specified value for the latent heat of vaporization. For example, if working in SI units, values may be entered as kJ/kg. - -\end{description} - From 61a6b157fa3f5f20c2ca1b93b872ac9ff1f1c74c Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Thu, 18 Jan 2024 15:23:30 -0800 Subject: [PATCH 28/46] Rebrand gwe dispersion package acronym to CND (conduction) since that is the dominant process in heat transport --- autotest/{test_gwe_dsp.py => test_gwe_cnd.py} | 6 +- ...onduction0.py => test_gwe_drycell_cnd0.py} | 6 +- ...onduction1.py => test_gwe_drycell_cnd1.py} | 6 +- ...onduction2.py => test_gwe_drycell_cnd2.py} | 6 +- autotest/test_gwe_vs_gwt.py | 4 +- autotest/test_gwegwe_exchng_with_comp2gwt.py | 8 +- doc/mf6io/gwe/cnd.tex | 17 ++ doc/mf6io/gwe/dsp.tex | 17 -- doc/mf6io/gwe/gwe.tex | 4 +- doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn | 4 +- .../mf6ivar/dfn/{gwe-dsp.dfn => gwe-cnd.dfn} | 4 +- ...we-dsp-example.dat => gwe-cnd-example.dat} | 0 doc/mf6io/mf6ivar/md/mf6ivar.md | 18 +- doc/mf6io/mf6ivar/mf6ivar.py | 2 +- doc/mf6io/mf6ivar/tex/appendixA.tex | 6 +- .../{gwe-dsp-desc.tex => gwe-cnd-desc.tex} | 0 ...-dsp-griddata.dat => gwe-cnd-griddata.dat} | 0 ...we-dsp-options.dat => gwe-cnd-options.dat} | 0 make/makefile | 6 +- msvs/mf6core.vfproj | 6 +- src/Distributed/VirtualGweModel.f90 | 116 ++++++------ src/Exchange/GweGweExchange.f90 | 18 +- src/Exchange/GwfGweExchange.f90 | 2 +- src/Exchange/gwegweidm.f90 | 20 +- src/Model/Connection/GweGweConnection.f90 | 52 ++--- src/Model/Connection/GweInterfaceModel.f90 | 66 +++---- src/Model/GroundWaterEnergy/gwe1.f90 | 54 +++--- .../{gwe1dsp1.f90 => gwe1cnd1.f90} | 178 +++++++++--------- .../{gwe1dsp1idm.f90 => gwe1cnd1idm.f90} | 80 ++++---- .../{GweDspOptions.f90 => GweCndOptions.f90} | 10 +- .../Idm/selector/IdmGweDfnSelector.f90 | 20 +- src/meson.build | 6 +- utils/idmloader/scripts/dfn2f90.py | 4 +- 33 files changed, 373 insertions(+), 373 deletions(-) rename autotest/{test_gwe_dsp.py => test_gwe_cnd.py} (99%) rename autotest/{test_gwe_drycell_conduction0.py => test_gwe_drycell_cnd0.py} (99%) rename autotest/{test_gwe_drycell_conduction1.py => test_gwe_drycell_cnd1.py} (99%) rename autotest/{test_gwe_drycell_conduction2.py => test_gwe_drycell_cnd2.py} (99%) create mode 100644 doc/mf6io/gwe/cnd.tex delete mode 100644 doc/mf6io/gwe/dsp.tex rename doc/mf6io/mf6ivar/dfn/{gwe-dsp.dfn => gwe-cnd.dfn} (96%) rename doc/mf6io/mf6ivar/examples/{gwe-dsp-example.dat => gwe-cnd-example.dat} (100%) rename doc/mf6io/mf6ivar/tex/{gwe-dsp-desc.tex => gwe-cnd-desc.tex} (100%) rename doc/mf6io/mf6ivar/tex/{gwe-dsp-griddata.dat => gwe-cnd-griddata.dat} (100%) rename doc/mf6io/mf6ivar/tex/{gwe-dsp-options.dat => gwe-cnd-options.dat} (100%) rename src/Model/GroundWaterEnergy/{gwe1dsp1.f90 => gwe1cnd1.f90} (89%) rename src/Model/GroundWaterEnergy/{gwe1dsp1idm.f90 => gwe1cnd1idm.f90} (78%) rename src/Model/ModelUtilities/{GweDspOptions.f90 => GweCndOptions.f90} (51%) diff --git a/autotest/test_gwe_dsp.py b/autotest/test_gwe_cnd.py similarity index 99% rename from autotest/test_gwe_dsp.py rename to autotest/test_gwe_cnd.py index 23472c1a1c4..967e59859d5 100644 --- a/autotest/test_gwe_dsp.py +++ b/autotest/test_gwe_cnd.py @@ -39,7 +39,7 @@ # Base simulation and model name and workspace viscosity_on = [False] -cases = ["dsp01"] +cases = ["cnd01"] # Model units @@ -293,14 +293,14 @@ def build_models(idx, test): # Instantiating MODFLOW 6 transport dispersion package if dispersivity != 0: - flopy.mf6.ModflowGwedsp( + flopy.mf6.ModflowGwecnd( gwe, xt3d_off=True, alh=dispersivity, ath1=dispersivity, ktw=0.5918, kts=0.2700, - filename="{}.dsp".format(gwename), + filename="{}.cnd".format(gwename), ) # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) diff --git a/autotest/test_gwe_drycell_conduction0.py b/autotest/test_gwe_drycell_cnd0.py similarity index 99% rename from autotest/test_gwe_drycell_conduction0.py rename to autotest/test_gwe_drycell_cnd0.py index 083c67dd6ca..8ab3e9ac7e6 100644 --- a/autotest/test_gwe_drycell_conduction0.py +++ b/autotest/test_gwe_drycell_cnd0.py @@ -272,7 +272,7 @@ def build_models(idx, test): ) # Instantiating MODFLOW 6 transport dispersion package - flopy.mf6.ModflowGwedsp( + flopy.mf6.ModflowGwecnd( gwe1, xt3d_off=False, alh=dispersivity, @@ -281,8 +281,8 @@ def build_models(idx, test): # ktw=0.0, kts=0.2700 * 86400, # kts=0.0, - pname="DSP-2", - filename="{}.dsp".format(gwename1), + pname="CND-2", + filename="{}.cnd".format(gwename1), ) # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) diff --git a/autotest/test_gwe_drycell_conduction1.py b/autotest/test_gwe_drycell_cnd1.py similarity index 99% rename from autotest/test_gwe_drycell_conduction1.py rename to autotest/test_gwe_drycell_cnd1.py index 810e7649782..638cb17b884 100644 --- a/autotest/test_gwe_drycell_conduction1.py +++ b/autotest/test_gwe_drycell_cnd1.py @@ -313,15 +313,15 @@ def build_models(idx, test): ) # Instantiating MODFLOW 6 transport dispersion package - flopy.mf6.ModflowGwedsp( + flopy.mf6.ModflowGwecnd( gwe1, xt3d_off=True, alh=dispersivity, ath1=dispersivity, ktw=0.5918 * 86400, kts=0.2700 * 86400, - pname="DSP-2", - filename="{}.dsp".format(gwename1), + pname="CND-2", + filename="{}.cnd".format(gwename1), ) # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) diff --git a/autotest/test_gwe_drycell_conduction2.py b/autotest/test_gwe_drycell_cnd2.py similarity index 99% rename from autotest/test_gwe_drycell_conduction2.py rename to autotest/test_gwe_drycell_cnd2.py index 5fa4909b474..aaa798c29b9 100644 --- a/autotest/test_gwe_drycell_conduction2.py +++ b/autotest/test_gwe_drycell_cnd2.py @@ -471,15 +471,15 @@ def build_models(idx, test): # Instantiating MODFLOW 6 transport dispersion package if dispersivity != 0: - flopy.mf6.ModflowGwedsp( + flopy.mf6.ModflowGwecnd( gwe, xt3d_off=False, alh=dispersivity, ath1=dispersivity, ktw=ktw, kts=kts, - pname="DSP-3", - filename="{}.dsp".format(gwename), + pname="CND-3", + filename="{}.cnd".format(gwename), ) # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) diff --git a/autotest/test_gwe_vs_gwt.py b/autotest/test_gwe_vs_gwt.py index ddf4dee1f80..d204f60f524 100644 --- a/autotest/test_gwe_vs_gwt.py +++ b/autotest/test_gwe_vs_gwt.py @@ -309,13 +309,13 @@ def build_models(idx, test): # Instantiating MODFLOW 6 heat transport dispersion package if al != 0: - flopy.mf6.ModflowGwedsp( + flopy.mf6.ModflowGwecnd( gwe, alh=al, ath1=ath1, ktw=0.5918, kts=0.2700, - filename="{}.dsp".format(gwename), + filename="{}.cnd".format(gwename), ) # Instantiating MODFLOW 6 heat transport mass storage package (formerly "reaction" package in MT3DMS) diff --git a/autotest/test_gwegwe_exchng_with_comp2gwt.py b/autotest/test_gwegwe_exchng_with_comp2gwt.py index 206d5ac0640..ecefa3fb51e 100644 --- a/autotest/test_gwegwe_exchng_with_comp2gwt.py +++ b/autotest/test_gwegwe_exchng_with_comp2gwt.py @@ -571,13 +571,13 @@ def add_upper_gwemodel(sim, scheme): # Instantiating MODFLOW 6 heat transport dispersion package if al != 0: - flopy.mf6.ModflowGwedsp( + flopy.mf6.ModflowGwecnd( gwe, alh=al, ath1=ath1, ktw=0.5918, kts=0.2700, - filename="{}.dsp".format(mname), + filename="{}.cnd".format(mname), ) # Instantiating MODFLOW 6 transport mass storage package @@ -649,13 +649,13 @@ def add_lower_gwemodel(sim, scheme): # Instantiating MODFLOW 6 heat transport dispersion package if al != 0: - flopy.mf6.ModflowGwedsp( + flopy.mf6.ModflowGwecnd( gwe, alh=al, ath1=ath1, ktw=0.5918, kts=0.2700, - filename="{}.dsp".format(mname), + filename="{}.cnd".format(mname), ) # Instantiating MODFLOW 6 transport mass storage package diff --git a/doc/mf6io/gwe/cnd.tex b/doc/mf6io/gwe/cnd.tex new file mode 100644 index 00000000000..aeb317f899e --- /dev/null +++ b/doc/mf6io/gwe/cnd.tex @@ -0,0 +1,17 @@ +Conduction (CND) Package information is read from the file that is specified by ``CND6'' as the file type. Only one CND Package can be specified for a GWE model. The CND Package is based on the mathematical formulation presented for the XT3D option of the NPF Package available to represent full three-dimensional anisotropy in groundwater flow. XT3D can be computationally expensive and can be turned off to use a simplified and approximate form of the dispersion equations that also account for conduction in a heat transport model. For most problems, however, XT3D will be required to accurately represent conduction and dispersion. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-cnd-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-cnd-griddata.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-cnd-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-cnd-example.dat} + diff --git a/doc/mf6io/gwe/dsp.tex b/doc/mf6io/gwe/dsp.tex deleted file mode 100644 index a12f1f3cd0c..00000000000 --- a/doc/mf6io/gwe/dsp.tex +++ /dev/null @@ -1,17 +0,0 @@ -Dispersion (DSP) Package information is read from the file that is specified by ``DSP6'' as the file type. Only one DSP Package can be specified for a GWE model. The DSP Package is based on the mathematical formulation presented for the XT3D option of the NPF Package available to represent full three-dimensional anisotropy in groundwater flow. XT3D can be computationally expensive and can be turned off to use a simplified and approximate form of the dispersion equations. For most problems, however, XT3D will be required to accurately represent dispersion. - -\vspace{5mm} -\subsubsection{Structure of Blocks} -\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-dsp-options.dat} -\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-dsp-griddata.dat} - -\vspace{5mm} -\subsubsection{Explanation of Variables} -\begin{description} -\input{./mf6ivar/tex/gwe-dsp-desc.tex} -\end{description} - -\vspace{5mm} -\subsubsection{Example Input File} -\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-dsp-example.dat} - diff --git a/doc/mf6io/gwe/gwe.tex b/doc/mf6io/gwe/gwe.tex index c94381f67dd..dd1a8c688f8 100644 --- a/doc/mf6io/gwe/gwe.tex +++ b/doc/mf6io/gwe/gwe.tex @@ -106,8 +106,8 @@ \subsection{Advection (ADV) Package} \input{gwe/adv} \newpage -\subsection{Dispersion (DSP) Package} -\input{gwe/dsp} +\subsection{Conduction (CND) Package} +\input{gwe/cnd} \newpage \subsection{Energy Storage and Transfer (EST) Package} diff --git a/doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn b/doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn index 72dcd437bff..315296422bf 100644 --- a/doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn +++ b/doc/mf6io/mf6ivar/dfn/exg-gwegwe.dfn @@ -72,7 +72,7 @@ longname advective scheme description scheme used to solve the advection term. Can be upstream, central, or TVD. If not specified, upstream weighting is the default weighting scheme. block options -name dsp_xt3d_off +name cnd_xt3d_off type keyword shape reader urword @@ -81,7 +81,7 @@ longname deactivate xt3d description deactivate the xt3d method for the dispersive flux and use the faster and less accurate approximation for this exchange. block options -name dsp_xt3d_rhs +name cnd_xt3d_rhs type keyword shape reader urword diff --git a/doc/mf6io/mf6ivar/dfn/gwe-dsp.dfn b/doc/mf6io/mf6ivar/dfn/gwe-cnd.dfn similarity index 96% rename from doc/mf6io/mf6ivar/dfn/gwe-dsp.dfn rename to doc/mf6io/mf6ivar/dfn/gwe-cnd.dfn index 5faa7f1c26b..e49626edf32 100644 --- a/doc/mf6io/mf6ivar/dfn/gwe-dsp.dfn +++ b/doc/mf6io/mf6ivar/dfn/gwe-cnd.dfn @@ -1,4 +1,4 @@ -# --------------------- gwe dsp options --------------------- +# --------------------- gwe cnd options --------------------- block options name xt3d_off @@ -18,7 +18,7 @@ optional true longname xt3d on right-hand side description add xt3d terms to right-hand side, when possible. This option uses less memory, but may require more iterations. -# --------------------- gwe dsp griddata --------------------- +# --------------------- gwe cnd griddata --------------------- block griddata name alh diff --git a/doc/mf6io/mf6ivar/examples/gwe-dsp-example.dat b/doc/mf6io/mf6ivar/examples/gwe-cnd-example.dat similarity index 100% rename from doc/mf6io/mf6ivar/examples/gwe-dsp-example.dat rename to doc/mf6io/mf6ivar/examples/gwe-cnd-example.dat diff --git a/doc/mf6io/mf6ivar/md/mf6ivar.md b/doc/mf6io/mf6ivar/md/mf6ivar.md index 3862fcb212b..f8f0b8f2a96 100644 --- a/doc/mf6io/mf6ivar/md/mf6ivar.md +++ b/doc/mf6io/mf6ivar/md/mf6ivar.md @@ -1185,6 +1185,15 @@ | GWT | API | OPTIONS | MOVER | KEYWORD | keyword to indicate that this instance of the api boundary Package can be used with the Water Mover (MVR) Package. When the MOVER option is specified, additional memory is allocated within the package to store the available, provided, and received water. | | GWT | API | DIMENSIONS | MAXBOUND | INTEGER | integer value specifying the maximum number of api boundary cells that will be specified for use during any stress period. | | GWE | ADV | OPTIONS | SCHEME | STRING | scheme used to solve the advection term. Can be upstream, central, or TVD. If not specified, upstream weighting is the default weighting scheme. | +| GWE | CND | OPTIONS | XT3D_OFF | KEYWORD | deactivate the xt3d method and use the faster and less accurate approximation. This option may provide a fast and accurate solution under some circumstances, such as when flow aligns with the model grid, there is no mechanical dispersion, or when the longitudinal and transverse dispersivities are equal. This option may also be used to assess the computational demand of the XT3D approach by noting the run time differences with and without this option on. | +| GWE | CND | OPTIONS | XT3D_RHS | KEYWORD | add xt3d terms to right-hand side, when possible. This option uses less memory, but may require more iterations. | +| GWE | CND | GRIDDATA | ALH | DOUBLE PRECISION (NODES) | longitudinal dispersivity in horizontal direction. If flow is strictly horizontal, then this is the longitudinal dispersivity that will be used. If flow is not strictly horizontal or strictly vertical, then the longitudinal dispersivity is a function of both ALH and ALV. If mechanical dispersion is represented (by specifying any dispersivity values) then this array is required. | +| GWE | CND | GRIDDATA | ALV | DOUBLE PRECISION (NODES) | longitudinal dispersivity in vertical direction. If flow is strictly vertical, then this is the longitudinal dispsersivity value that will be used. If flow is not strictly horizontal or strictly vertical, then the longitudinal dispersivity is a function of both ALH and ALV. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ALH. | +| GWE | CND | GRIDDATA | ATH1 | DOUBLE PRECISION (NODES) | transverse dispersivity in horizontal direction. This is the transverse dispersivity value for the second ellipsoid axis. If flow is strictly horizontal and directed in the x direction (along a row for a regular grid), then this value controls spreading in the y direction. If mechanical dispersion is represented (by specifying any dispersivity values) then this array is required. | +| GWE | CND | GRIDDATA | ATH2 | DOUBLE PRECISION (NODES) | transverse dispersivity in horizontal direction. This is the transverse dispersivity value for the third ellipsoid axis. If flow is strictly horizontal and directed in the x direction (along a row for a regular grid), then this value controls spreading in the z direction. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ATH1. | +| GWE | CND | GRIDDATA | ATV | DOUBLE PRECISION (NODES) | transverse dispersivity when flow is in vertical direction. If flow is strictly vertical and directed in the z direction, then this value controls spreading in the x and y directions. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ATH2. | +| GWE | CND | GRIDDATA | KTW | DOUBLE PRECISION (NODES) | thermal conductivity of the simulated fluid | +| GWE | CND | GRIDDATA | KTS | DOUBLE PRECISION (NODES) | thermal conductivity of the aquifer material | | GWE | CTP | OPTIONS | AUXILIARY | STRING (NAUX) | defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. | | GWE | CTP | OPTIONS | AUXMULTNAME | STRING | name of auxiliary variable to be used as multiplier of temperature value. | | GWE | CTP | OPTIONS | BOUNDNAMES | KEYWORD | keyword to indicate that boundary names may be provided with the list of constant temperature cells. | @@ -1261,15 +1270,6 @@ | GWE | DISU | CELL2D | YC | DOUBLE PRECISION | is the y-coordinate for the cell center. | | GWE | DISU | CELL2D | NCVERT | INTEGER | is the number of vertices required to define the cell. There may be a different number of vertices for each cell. | | GWE | DISU | CELL2D | ICVERT | INTEGER (NCVERT) | is an array of integer values containing vertex numbers (in the VERTICES block) used to define the cell. Vertices must be listed in clockwise order. | -| GWE | DSP | OPTIONS | XT3D_OFF | KEYWORD | deactivate the xt3d method and use the faster and less accurate approximation. This option may provide a fast and accurate solution under some circumstances, such as when flow aligns with the model grid, there is no mechanical dispersion, or when the longitudinal and transverse dispersivities are equal. This option may also be used to assess the computational demand of the XT3D approach by noting the run time differences with and without this option on. | -| GWE | DSP | OPTIONS | XT3D_RHS | KEYWORD | add xt3d terms to right-hand side, when possible. This option uses less memory, but may require more iterations. | -| GWE | DSP | GRIDDATA | ALH | DOUBLE PRECISION (NODES) | longitudinal dispersivity in horizontal direction. If flow is strictly horizontal, then this is the longitudinal dispersivity that will be used. If flow is not strictly horizontal or strictly vertical, then the longitudinal dispersivity is a function of both ALH and ALV. If mechanical dispersion is represented (by specifying any dispersivity values) then this array is required. | -| GWE | DSP | GRIDDATA | ALV | DOUBLE PRECISION (NODES) | longitudinal dispersivity in vertical direction. If flow is strictly vertical, then this is the longitudinal dispsersivity value that will be used. If flow is not strictly horizontal or strictly vertical, then the longitudinal dispersivity is a function of both ALH and ALV. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ALH. | -| GWE | DSP | GRIDDATA | ATH1 | DOUBLE PRECISION (NODES) | transverse dispersivity in horizontal direction. This is the transverse dispersivity value for the second ellipsoid axis. If flow is strictly horizontal and directed in the x direction (along a row for a regular grid), then this value controls spreading in the y direction. If mechanical dispersion is represented (by specifying any dispersivity values) then this array is required. | -| GWE | DSP | GRIDDATA | ATH2 | DOUBLE PRECISION (NODES) | transverse dispersivity in horizontal direction. This is the transverse dispersivity value for the third ellipsoid axis. If flow is strictly horizontal and directed in the x direction (along a row for a regular grid), then this value controls spreading in the z direction. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ATH1. | -| GWE | DSP | GRIDDATA | ATV | DOUBLE PRECISION (NODES) | transverse dispersivity when flow is in vertical direction. If flow is strictly vertical and directed in the z direction, then this value controls spreading in the x and y directions. If this value is not specified and mechanical dispersion is represented, then this array is set equal to ATH2. | -| GWE | DSP | GRIDDATA | KTW | DOUBLE PRECISION (NODES) | thermal conductivity of the simulated fluid | -| GWE | DSP | GRIDDATA | KTS | DOUBLE PRECISION (NODES) | thermal conductivity of the aquifer material | | GWE | IC | GRIDDATA | STRT | DOUBLE PRECISION (NODES) | is the initial (starting) temperature---that is, the temperature at the beginning of the GWE Model simulation. STRT must be specified for all GWE Model simulations. One value is read for every model cell. | | GWE | EST | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that EST flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | | GWE | EST | OPTIONS | ZERO_ORDER_DECAY | KEYWORD | is a text keyword to indicate that zero-order decay will occur. Use of this keyword requires that DECAY and DECAY\_SORBED (if sorption is active) are specified in the GRIDDATA block. | diff --git a/doc/mf6io/mf6ivar/mf6ivar.py b/doc/mf6io/mf6ivar/mf6ivar.py index 0c37229aa5d..509f48c3cda 100644 --- a/doc/mf6io/mf6ivar/mf6ivar.py +++ b/doc/mf6io/mf6ivar/mf6ivar.py @@ -740,11 +740,11 @@ def write_appendix(texdir, allblocks): "gwt-mvt", "gwt-api", "gwe-adv", + "gwe-cnd", "gwe-ctp", "gwe-dis", "gwe-disv", "gwe-disu", - "gwe-dsp", "gwe-ic", "gwe-est", "gwe-nam", diff --git a/doc/mf6io/mf6ivar/tex/appendixA.tex b/doc/mf6io/mf6ivar/tex/appendixA.tex index 32e46895c12..870df97d6d4 100644 --- a/doc/mf6io/mf6ivar/tex/appendixA.tex +++ b/doc/mf6io/mf6ivar/tex/appendixA.tex @@ -246,6 +246,9 @@ \hline GWE & ADV & OPTIONS & yes \\ \hline +GWE & CND & OPTIONS & yes \\ +GWE & CND & GRIDDATA & no \\ +\hline GWE & CTP & OPTIONS & yes \\ GWE & CTP & DIMENSIONS & yes \\ GWE & CTP & PERIOD & yes \\ @@ -267,9 +270,6 @@ GWE & DISU & VERTICES & yes \\ GWE & DISU & CELL2D & yes \\ \hline -GWE & DSP & OPTIONS & yes \\ -GWE & DSP & GRIDDATA & no \\ -\hline GWE & IC & GRIDDATA & no \\ \hline GWE & EST & OPTIONS & yes \\ diff --git a/doc/mf6io/mf6ivar/tex/gwe-dsp-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-cnd-desc.tex similarity index 100% rename from doc/mf6io/mf6ivar/tex/gwe-dsp-desc.tex rename to doc/mf6io/mf6ivar/tex/gwe-cnd-desc.tex diff --git a/doc/mf6io/mf6ivar/tex/gwe-dsp-griddata.dat b/doc/mf6io/mf6ivar/tex/gwe-cnd-griddata.dat similarity index 100% rename from doc/mf6io/mf6ivar/tex/gwe-dsp-griddata.dat rename to doc/mf6io/mf6ivar/tex/gwe-cnd-griddata.dat diff --git a/doc/mf6io/mf6ivar/tex/gwe-dsp-options.dat b/doc/mf6io/mf6ivar/tex/gwe-cnd-options.dat similarity index 100% rename from doc/mf6io/mf6ivar/tex/gwe-dsp-options.dat rename to doc/mf6io/mf6ivar/tex/gwe-cnd-options.dat diff --git a/make/makefile b/make/makefile index 5deaf992afd..812ce14a500 100644 --- a/make/makefile +++ b/make/makefile @@ -119,11 +119,11 @@ $(OBJDIR)/gwf3dis8idm.o \ $(OBJDIR)/gwf3chd8idm.o \ $(OBJDIR)/gwe1idm.o \ $(OBJDIR)/gwe1ic1idm.o \ -$(OBJDIR)/gwe1dsp1idm.o \ $(OBJDIR)/gwe1disv1idm.o \ $(OBJDIR)/gwe1disu1idm.o \ $(OBJDIR)/gwe1dis1idm.o \ $(OBJDIR)/gwe1ctp1idm.o \ +$(OBJDIR)/gwe1cnd1idm.o \ $(OBJDIR)/gwtgwtidm.o \ $(OBJDIR)/gwfgwtidm.o \ $(OBJDIR)/gwfgwfidm.o \ @@ -246,7 +246,7 @@ $(OBJDIR)/Mover.o \ $(OBJDIR)/GwfMvrPeriodData.o \ $(OBJDIR)/ims8misc.o \ $(OBJDIR)/GwfBuyInputData.o \ -$(OBJDIR)/GweDspOptions.o \ +$(OBJDIR)/GweCndOptions.o \ $(OBJDIR)/VirtualSolution.o \ $(OBJDIR)/SparseMatrix.o \ $(OBJDIR)/LinearSolverBase.o \ @@ -281,8 +281,8 @@ $(OBJDIR)/GhostNode.o \ $(OBJDIR)/gwf3evt8.o \ $(OBJDIR)/gwf3chd8.o \ $(OBJDIR)/gwe1est1.o \ -$(OBJDIR)/gwe1dsp1.o \ $(OBJDIR)/gwe1ctp1.o \ +$(OBJDIR)/gwe1cnd1.o \ $(OBJDIR)/RouterBase.o \ $(OBJDIR)/ImsLinearSolver.o \ $(OBJDIR)/ims8base.o \ diff --git a/msvs/mf6core.vfproj b/msvs/mf6core.vfproj index 26d97feffc7..6bada52f499 100644 --- a/msvs/mf6core.vfproj +++ b/msvs/mf6core.vfproj @@ -141,13 +141,13 @@ + + - - @@ -221,7 +221,7 @@ - + diff --git a/src/Distributed/VirtualGweModel.f90 b/src/Distributed/VirtualGweModel.f90 index ea97d448f0f..ef9c93cf696 100644 --- a/src/Distributed/VirtualGweModel.f90 +++ b/src/Distributed/VirtualGweModel.f90 @@ -11,17 +11,17 @@ module VirtualGweModelModule public :: add_virtual_gwe_model type, extends(VirtualModelType) :: VirtualGweModelType - ! DSP - !type(VirtualIntType), pointer :: dsp_idiffc => null() - type(VirtualIntType), pointer :: dsp_idisp => null() - !type(VirtualDbl1dType), pointer :: dsp_diffc => null() - type(VirtualDbl1dType), pointer :: dsp_alh => null() - type(VirtualDbl1dType), pointer :: dsp_alv => null() - type(VirtualDbl1dType), pointer :: dsp_ath1 => null() - type(VirtualDbl1dType), pointer :: dsp_ath2 => null() - type(VirtualDbl1dType), pointer :: dsp_atv => null() - type(VirtualDbl1dType), pointer :: dsp_ktw => null() - type(VirtualDbl1dType), pointer :: dsp_kts => null() + ! CND + !type(VirtualIntType), pointer :: cnd_idiffc => null() + type(VirtualIntType), pointer :: cnd_idisp => null() + !type(VirtualDbl1dType), pointer :: cnd_diffc => null() + type(VirtualDbl1dType), pointer :: cnd_alh => null() + type(VirtualDbl1dType), pointer :: cnd_alv => null() + type(VirtualDbl1dType), pointer :: cnd_ath1 => null() + type(VirtualDbl1dType), pointer :: cnd_ath2 => null() + type(VirtualDbl1dType), pointer :: cnd_atv => null() + type(VirtualDbl1dType), pointer :: cnd_ktw => null() + type(VirtualDbl1dType), pointer :: cnd_kts => null() ! FMI type(VirtualDbl1dType), pointer :: fmi_gwfhead => null() type(VirtualDbl1dType), pointer :: fmi_gwfsat => null() @@ -30,7 +30,7 @@ module VirtualGweModelModule ! EST type(VirtualDbl1dType), pointer :: est_porosity => null() ! GWE Model fields - type(VirtualIntType), pointer :: indsp => null() + type(VirtualIntType), pointer :: incnd => null() type(VirtualIntType), pointer :: inest => null() contains ! public @@ -80,22 +80,22 @@ end subroutine vgwe_create subroutine init_virtual_data(this) class(VirtualGweModelType) :: this - !call this%set(this%dsp_idiffc%base(), 'IDIFFC', 'DSP', MAP_ALL_TYPE) - call this%set(this%dsp_idisp%base(), 'IDISP', 'DSP', MAP_ALL_TYPE) - !call this%set(this%dsp_diffc%base(), 'DIFFC', 'DSP', MAP_NODE_TYPE) - call this%set(this%dsp_alh%base(), 'ALH', 'DSP', MAP_NODE_TYPE) - call this%set(this%dsp_alv%base(), 'ALV', 'DSP', MAP_NODE_TYPE) - call this%set(this%dsp_ath1%base(), 'ATH1', 'DSP', MAP_NODE_TYPE) - call this%set(this%dsp_ath2%base(), 'ATH2', 'DSP', MAP_NODE_TYPE) - call this%set(this%dsp_atv%base(), 'ATV', 'DSP', MAP_NODE_TYPE) - call this%set(this%dsp_ktw%base(), 'KTW', 'DSP', MAP_NODE_TYPE) - call this%set(this%dsp_kts%base(), 'KTS', 'DSP', MAP_NODE_TYPE) + !call this%set(this%cnd_idiffc%base(), 'IDIFFC', 'CND', MAP_ALL_TYPE) + call this%set(this%cnd_idisp%base(), 'IDISP', 'CND', MAP_ALL_TYPE) + !call this%set(this%cnd_diffc%base(), 'DIFFC', 'CND', MAP_NODE_TYPE) + call this%set(this%cnd_alh%base(), 'ALH', 'CND', MAP_NODE_TYPE) + call this%set(this%cnd_alv%base(), 'ALV', 'CND', MAP_NODE_TYPE) + call this%set(this%cnd_ath1%base(), 'ATH1', 'CND', MAP_NODE_TYPE) + call this%set(this%cnd_ath2%base(), 'ATH2', 'CND', MAP_NODE_TYPE) + call this%set(this%cnd_atv%base(), 'ATV', 'CND', MAP_NODE_TYPE) + call this%set(this%cnd_ktw%base(), 'KTW', 'CND', MAP_NODE_TYPE) + call this%set(this%cnd_kts%base(), 'KTS', 'CND', MAP_NODE_TYPE) call this%set(this%fmi_gwfhead%base(), 'GWFHEAD', 'FMI', MAP_NODE_TYPE) call this%set(this%fmi_gwfsat%base(), 'GWFSAT', 'FMI', MAP_NODE_TYPE) call this%set(this%fmi_gwfspdis%base(), 'GWFSPDIS', 'FMI', MAP_NODE_TYPE) call this%set(this%fmi_gwfflowja%base(), 'GWFFLOWJA', 'FMI', MAP_CONN_TYPE) call this%set(this%est_porosity%base(), 'POROSITY', 'EST', MAP_NODE_TYPE) - call this%set(this%indsp%base(), 'INDSP', '', MAP_ALL_TYPE) + call this%set(this%incnd%base(), 'INCND', '', MAP_ALL_TYPE) call this%set(this%inest%base(), 'INEST', '', MAP_ALL_TYPE) end subroutine init_virtual_data @@ -114,9 +114,9 @@ subroutine vgwe_prepare_stage(this, stage) if (stage == STG_AFT_MDL_DF) then - !call this%map(this%dsp_idiffc%base(), (/STG_AFT_MDL_DF/)) - call this%map(this%dsp_idisp%base(), (/STG_AFT_MDL_DF/)) - call this%map(this%indsp%base(), (/STG_AFT_MDL_DF/)) + !call this%map(this%cnd_idiffc%base(), (/STG_AFT_MDL_DF/)) + call this%map(this%cnd_idisp%base(), (/STG_AFT_MDL_DF/)) + call this%map(this%incnd%base(), (/STG_AFT_MDL_DF/)) call this%map(this%inest%base(), (/STG_AFT_MDL_DF/)) else if (stage == STG_BFR_CON_AR) then @@ -128,17 +128,17 @@ subroutine vgwe_prepare_stage(this, stage) (/STG_BFR_CON_AR, STG_BFR_EXG_AD, STG_BFR_EXG_CF/)) call this%map(this%ibound%base(), nr_nodes, (/STG_BFR_CON_AR/)) - !if (this%dsp_idiffc%get() > 0) then - ! call this%map(this%dsp_diffc%base(), nr_nodes, (/STG_BFR_CON_AR/)) + !if (this%cnd_idiffc%get() > 0) then + ! call this%map(this%cnd_diffc%base(), nr_nodes, (/STG_BFR_CON_AR/)) !end if - if (this%dsp_idisp%get() > 0) then - call this%map(this%dsp_alh%base(), nr_nodes, (/STG_BFR_CON_AR/)) - call this%map(this%dsp_alv%base(), nr_nodes, (/STG_BFR_CON_AR/)) - call this%map(this%dsp_ath1%base(), nr_nodes, (/STG_BFR_CON_AR/)) - call this%map(this%dsp_ath2%base(), nr_nodes, (/STG_BFR_CON_AR/)) - call this%map(this%dsp_atv%base(), nr_nodes, (/STG_BFR_CON_AR/)) - call this%map(this%dsp_ktw%base(), nr_nodes, (/STG_BFR_CON_AR/)) + if (this%cnd_idisp%get() > 0) then + call this%map(this%cnd_alh%base(), nr_nodes, (/STG_BFR_CON_AR/)) + call this%map(this%cnd_alv%base(), nr_nodes, (/STG_BFR_CON_AR/)) + call this%map(this%cnd_ath1%base(), nr_nodes, (/STG_BFR_CON_AR/)) + call this%map(this%cnd_ath2%base(), nr_nodes, (/STG_BFR_CON_AR/)) + call this%map(this%cnd_atv%base(), nr_nodes, (/STG_BFR_CON_AR/)) + call this%map(this%cnd_ktw%base(), nr_nodes, (/STG_BFR_CON_AR/)) end if call this%map(this%fmi_gwfhead%base(), nr_nodes, (/STG_BFR_EXG_AD/)) @@ -146,7 +146,7 @@ subroutine vgwe_prepare_stage(this, stage) call this%map(this%fmi_gwfspdis%base(), 3, nr_nodes, (/STG_BFR_EXG_AD/)) call this%map(this%fmi_gwfflowja%base(), nr_conns, (/STG_BFR_EXG_AD/)) - if (this%indsp%get() > 0 .and. this%inest%get() > 0) then + if (this%incnd%get() > 0 .and. this%inest%get() > 0) then call this%map(this%est_porosity%base(), nr_nodes, (/STG_AFT_CON_AR/)) end if @@ -157,22 +157,22 @@ end subroutine vgwe_prepare_stage subroutine allocate_data(this) class(VirtualGweModelType) :: this - !allocate (this%dsp_idiffc) - allocate (this%dsp_idisp) - !allocate (this%dsp_diffc) - allocate (this%dsp_alh) - allocate (this%dsp_alv) - allocate (this%dsp_ath1) - allocate (this%dsp_ath2) - allocate (this%dsp_atv) - allocate (this%dsp_ktw) - allocate (this%dsp_kts) + !allocate (this%cnd_idiffc) + allocate (this%cnd_idisp) + !allocate (this%cnd_diffc) + allocate (this%cnd_alh) + allocate (this%cnd_alv) + allocate (this%cnd_ath1) + allocate (this%cnd_ath2) + allocate (this%cnd_atv) + allocate (this%cnd_ktw) + allocate (this%cnd_kts) allocate (this%fmi_gwfhead) allocate (this%fmi_gwfsat) allocate (this%fmi_gwfspdis) allocate (this%fmi_gwfflowja) allocate (this%est_porosity) - allocate (this%indsp) + allocate (this%incnd) allocate (this%inest) end subroutine allocate_data @@ -180,22 +180,22 @@ end subroutine allocate_data subroutine deallocate_data(this) class(VirtualGweModelType) :: this - !deallocate (this%dsp_idiffc) - deallocate (this%dsp_idisp) - !deallocate (this%dsp_diffc) - deallocate (this%dsp_alh) - deallocate (this%dsp_alv) - deallocate (this%dsp_ath1) - deallocate (this%dsp_ath2) - deallocate (this%dsp_atv) - deallocate (this%dsp_ktw) - deallocate (this%dsp_kts) + !deallocate (this%cnd_idiffc) + deallocate (this%cnd_idisp) + !deallocate (this%cnd_diffc) + deallocate (this%cnd_alh) + deallocate (this%cnd_alv) + deallocate (this%cnd_ath1) + deallocate (this%cnd_ath2) + deallocate (this%cnd_atv) + deallocate (this%cnd_ktw) + deallocate (this%cnd_kts) deallocate (this%fmi_gwfhead) deallocate (this%fmi_gwfsat) deallocate (this%fmi_gwfspdis) deallocate (this%fmi_gwfflowja) deallocate (this%est_porosity) - deallocate (this%indsp) + deallocate (this%incnd) deallocate (this%inest) end subroutine deallocate_data diff --git a/src/Exchange/GweGweExchange.f90 b/src/Exchange/GweGweExchange.f90 index e60e76f5099..0593bd15eea 100644 --- a/src/Exchange/GweGweExchange.f90 +++ b/src/Exchange/GweGweExchange.f90 @@ -284,7 +284,7 @@ subroutine validate_exchange(this) ! If so, then ANGLDEGX must be provided as an auxiliary variable for this ! GWE-GWE exchange (this%ianglex > 0). if (associated(this%gwemodel1) .and. associated(this%gwemodel2)) then - if (this%gwemodel1%indsp /= 0 .or. this%gwemodel2%indsp /= 0) then + if (this%gwemodel1%incnd /= 0 .or. this%gwemodel2%incnd /= 0) then if (this%ianglex == 0) then write (errmsg, '(3a)') 'GWE-GWE exchange ', trim(this%name), & ' requires that ANGLDEGX be specified as an'// & @@ -722,10 +722,10 @@ subroutine source_options(this, iout) found%gwfmodelname2) call mem_set_value(this%iAdvScheme, 'ADV_SCHEME', this%input_mempath, & adv_scheme, found%adv_scheme) - call mem_set_value(this%ixt3d, 'DSP_XT3D_OFF', this%input_mempath, & - found%dsp_xt3d_off) - call mem_set_value(this%ixt3d, 'DSP_XT3D_RHS', this%input_mempath, & - found%dsp_xt3d_rhs) + call mem_set_value(this%ixt3d, 'CND_XT3D_OFF', this%input_mempath, & + found%cnd_xt3d_off) + call mem_set_value(this%ixt3d, 'CND_XT3D_RHS', this%input_mempath, & + found%cnd_xt3d_rhs) ! write (iout, '(1x,a)') 'PROCESSING GWE-GWE EXCHANGE OPTIONS' ! @@ -750,14 +750,14 @@ subroutine source_options(this, iout) trim(adv_scheme(this%iAdvScheme + 1)) end if ! - if (found%dsp_xt3d_off .and. found%dsp_xt3d_rhs) then - errmsg = 'DSP_XT3D_OFF and DSP_XT3D_RHS cannot both be set as options.' + if (found%cnd_xt3d_off .and. found%cnd_xt3d_rhs) then + errmsg = 'CND_XT3D_OFF and CND_XT3D_RHS cannot both be set as options.' call store_error(errmsg) call store_error_filename(this%filename) - else if (found%dsp_xt3d_off) then + else if (found%cnd_xt3d_off) then this%ixt3d = 0 write (iout, '(4x,a)') 'XT3D FORMULATION HAS BEEN SHUT OFF.' - else if (found%dsp_xt3d_rhs) then + else if (found%cnd_xt3d_rhs) then this%ixt3d = 2 write (iout, '(4x,a)') 'XT3D RIGHT-HAND SIDE FORMULATION IS SELECTED.' end if diff --git a/src/Exchange/GwfGweExchange.f90 b/src/Exchange/GwfGweExchange.f90 index d60a6be4a6a..3295aadcc8f 100644 --- a/src/Exchange/GwfGweExchange.f90 +++ b/src/Exchange/GwfGweExchange.f90 @@ -177,7 +177,7 @@ subroutine exg_df(this) ! ! -- Set the npf flag so that specific discharge is available for ! transport calculations if dispersion is active - if (gwemodel%indsp > 0) then + if (gwemodel%incnd > 0) then gwfmodel%npf%icalcspdis = 1 end if ! diff --git a/src/Exchange/gwegweidm.f90 b/src/Exchange/gwegweidm.f90 index d495d7206e5..588078857a2 100644 --- a/src/Exchange/gwegweidm.f90 +++ b/src/Exchange/gwegweidm.f90 @@ -19,8 +19,8 @@ module ExgGwegweInputModule logical :: iprflow = .false. logical :: ipakcb = .false. logical :: adv_scheme = .false. - logical :: dsp_xt3d_off = .false. - logical :: dsp_xt3d_rhs = .false. + logical :: cnd_xt3d_off = .false. + logical :: cnd_xt3d_rhs = .false. logical :: filein = .false. logical :: mve_filerecord = .false. logical :: mve6 = .false. @@ -179,13 +179,13 @@ module ExgGwegweInputModule ) type(InputParamDefinitionType), parameter :: & - exggwegwe_dsp_xt3d_off = InputParamDefinitionType & + exggwegwe_cnd_xt3d_off = InputParamDefinitionType & ( & 'EXG', & ! component 'GWEGWE', & ! subcomponent 'OPTIONS', & ! block - 'DSP_XT3D_OFF', & ! tag name - 'DSP_XT3D_OFF', & ! fortran variable + 'CND_XT3D_OFF', & ! tag name + 'CND_XT3D_OFF', & ! fortran variable 'KEYWORD', & ! type '', & ! shape .false., & ! required @@ -196,13 +196,13 @@ module ExgGwegweInputModule ) type(InputParamDefinitionType), parameter :: & - exggwegwe_dsp_xt3d_rhs = InputParamDefinitionType & + exggwegwe_cnd_xt3d_rhs = InputParamDefinitionType & ( & 'EXG', & ! component 'GWEGWE', & ! subcomponent 'OPTIONS', & ! block - 'DSP_XT3D_RHS', & ! tag name - 'DSP_XT3D_RHS', & ! fortran variable + 'CND_XT3D_RHS', & ! tag name + 'CND_XT3D_RHS', & ! fortran variable 'KEYWORD', & ! type '', & ! shape .false., & ! required @@ -512,8 +512,8 @@ module ExgGwegweInputModule exggwegwe_iprflow, & exggwegwe_ipakcb, & exggwegwe_adv_scheme, & - exggwegwe_dsp_xt3d_off, & - exggwegwe_dsp_xt3d_rhs, & + exggwegwe_cnd_xt3d_off, & + exggwegwe_cnd_xt3d_rhs, & exggwegwe_filein, & exggwegwe_mve_filerecord, & exggwegwe_mve6, & diff --git a/src/Model/Connection/GweGweConnection.f90 b/src/Model/Connection/GweGweConnection.f90 index 5ddb6b70eef..2f4464b0d27 100644 --- a/src/Model/Connection/GweGweConnection.f90 +++ b/src/Model/Connection/GweGweConnection.f90 @@ -33,7 +33,7 @@ module GweGweConnectionModule class(GweInterfaceModelType), pointer :: gweInterfaceModel => null() !< the interface model integer(I4B), pointer :: iIfaceAdvScheme => null() !< the advection scheme at the interface: !! 0 = upstream, 1 = central, 2 = TVD - integer(I4B), pointer :: iIfaceXt3d => null() !< XT3D in the interface DSP package: 0 = no, 1 = lhs, 2 = rhs + integer(I4B), pointer :: iIfaceXt3d => null() !< XT3D in the interface CND package: 0 = no, 1 = lhs, 2 = rhs integer(I4B), pointer :: exgflowSign => null() !< indicates the flow direction of exgflowja real(DP), dimension(:), pointer, contiguous :: exgflowjaGwe => null() !< gwe-flowja at the interface (this is a subset of the GWT !! interface model flowja's) @@ -163,8 +163,8 @@ subroutine gwegwecon_df(this) this%iIfaceXt3d = this%gweExchange%ixt3d ! -- Turn off when off in the owning model - if (this%gweModel%indsp > 0) then - this%iIfaceXt3d = this%gweModel%dsp%ixt3d + if (this%gweModel%incnd > 0) then + this%iIfaceXt3d = this%gweModel%cnd%ixt3d end if ! -- Determine the required size of the interface model grid @@ -218,14 +218,14 @@ subroutine cfg_dist_vars(this) call this%cfg_dv('BOT', 'DIS', SYNC_NDS, (/STG_BFR_CON_AR/)) call this%cfg_dv('AREA', 'DIS', SYNC_NDS, (/STG_BFR_CON_AR/)) ! - if (this%gweInterfaceModel%dsp%idisp > 0) then - call this%cfg_dv('ALH', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) - call this%cfg_dv('ALV', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) - call this%cfg_dv('ATH1', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) - call this%cfg_dv('ATH2', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) - call this%cfg_dv('ATV', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) - call this%cfg_dv('KTW', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) - call this%cfg_dv('KTS', 'DSP', SYNC_NDS, (/STG_BFR_CON_AR/)) + if (this%gweInterfaceModel%cnd%idisp > 0) then + call this%cfg_dv('ALH', 'CND', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('ALV', 'CND', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('ATH1', 'CND', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('ATH2', 'CND', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('ATV', 'CND', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('KTW', 'CND', SYNC_NDS, (/STG_BFR_CON_AR/)) + call this%cfg_dv('KTS', 'CND', SYNC_NDS, (/STG_BFR_CON_AR/)) end if call this%cfg_dv('GWFHEAD', 'FMI', SYNC_NDS, (/STG_BFR_EXG_AD/)) call this%cfg_dv('GWFSAT', 'FMI', SYNC_NDS, (/STG_BFR_EXG_AD/)) @@ -233,8 +233,8 @@ subroutine cfg_dist_vars(this) call this%cfg_dv('GWFFLOWJA', 'FMI', SYNC_CON, (/STG_BFR_EXG_AD/)) call this%cfg_dv('GWFFLOWJA', 'FMI', SYNC_EXG, (/STG_BFR_EXG_AD/), & exg_var_name='GWFSIMVALS') - ! -- Fill porosity from est packages, needed for dsp - if (this%gweModel%indsp > 0 .and. this%gweModel%inest > 0) then + ! -- Fill porosity from est packages, needed for cnd + if (this%gweModel%incnd > 0 .and. this%gweModel%inest > 0) then call this%cfg_dv('POROSITY', 'EST', SYNC_NDS, (/STG_AFT_CON_AR/)) end if ! @@ -256,10 +256,10 @@ subroutine setGridExtent(this) ! -- dummy class(GweGweConnectionType) :: this !< the connection ! -- local - logical(LGP) :: hasAdv, hasDsp + logical(LGP) :: hasAdv, hasCnd ! hasAdv = this%gweModel%inadv > 0 - hasDsp = this%gweModel%indsp > 0 + hasCnd = this%gweModel%incnd > 0 ! if (hasAdv) then if (this%iIfaceAdvScheme == 2) then @@ -270,10 +270,10 @@ subroutine setGridExtent(this) end if end if ! - if (hasDsp) then + if (hasCnd) then if (this%iIfaceXt3d > 0) then this%exg_stencil_depth = 2 - if (this%gweModel%dsp%ixt3d > 0) then + if (this%gweModel%cnd%ixt3d > 0) then this%int_stencil_depth = 2 end if end if @@ -305,8 +305,8 @@ subroutine gwegwecon_ar(this) !-- Set the equation scaling factor in the interface model to that of ! underlying GWE model - if (this%gweModel%indsp > 0) then - this%gweInterfaceModel%ieqnsclfac = this%gweModel%dsp%eqnsclfac + if (this%gweModel%incnd > 0) then + this%gweInterfaceModel%ieqnsclfac = this%gweModel%cnd%eqnsclfac end if ! -- AR the movers and obs through the exchange @@ -347,12 +347,12 @@ subroutine validateConnection(this) call store_error(errmsg) end if ! - if ((this%gweExchange%gwemodel1%indsp > 0 .and. & - this%gweExchange%gwemodel2%indsp == 0) .or. & - (this%gweExchange%gwemodel2%indsp > 0 .and. & - this%gweExchange%gwemodel1%indsp == 0)) then + if ((this%gweExchange%gwemodel1%incnd > 0 .and. & + this%gweExchange%gwemodel2%incnd == 0) .or. & + (this%gweExchange%gwemodel2%incnd > 0 .and. & + this%gweExchange%gwemodel1%incnd == 0)) then write (errmsg, '(1x,a,a,a)') 'Cannot connect GWE models in exchange ', & - trim(this%gweExchange%name), ' because one model is configured with DSP & + trim(this%gweExchange%name), ' because one model is configured with CND & &and the other one is not' call store_error(errmsg) end if @@ -382,8 +382,8 @@ subroutine gwegwecon_ad(this) ! class(GweGweConnectionType) :: this !< this connection ! - ! -- Recalculate dispersion ellipse - if (this%gweInterfaceModel%indsp > 0) call this%gweInterfaceModel%dsp%dsp_ad() + ! -- Recalculate conduction ellipse + if (this%gweInterfaceModel%incnd > 0) call this%gweInterfaceModel%cnd%cnd_ad() ! if (this%owns_exchange) then call this%gweExchange%exg_ad() diff --git a/src/Model/Connection/GweInterfaceModel.f90 b/src/Model/Connection/GweInterfaceModel.f90 index cbbef1c70fa..d7f1978f5ff 100644 --- a/src/Model/Connection/GweInterfaceModel.f90 +++ b/src/Model/Connection/GweInterfaceModel.f90 @@ -9,8 +9,8 @@ module GweInterfaceModelModule use TspFmiModule, only: fmi_cr, TspFmiType use TspAdvModule, only: adv_cr, TspAdvType use TspAdvOptionsModule, only: TspAdvOptionsType - use GweDspModule, only: dsp_cr, GweDspType - use GweDspOptionsModule, only: GweDspOptionsType + use GweCndModule, only: cnd_cr, GweCndType + use GweCndOptionsModule, only: GweCndOptionsType use GweEstModule, only: est_cr use TspObsModule, only: tsp_obs_cr use GridConnectionModule @@ -61,7 +61,7 @@ subroutine gweifmod_cr(this, name, iout, gridConn) ! -- local class(*), pointer :: modelPtr integer(I4B), target :: inobs - integer(I4B) :: adv_unit, dsp_unit + integer(I4B) :: adv_unit, cnd_unit ! this%memoryPath = create_mem_path(name) call this%allocate_scalars(name) @@ -81,14 +81,14 @@ subroutine gweifmod_cr(this, name, iout, gridConn) ! inobs = 0 adv_unit = 0 - dsp_unit = 0 + cnd_unit = 0 if (this%owner%inadv > 0) then this%inadv = huge(1_I4B) adv_unit = huge(1_I4B) end if - if (this%owner%indsp > 0) then - this%indsp = huge(1_I4B) - dsp_unit = huge(1_I4B) + if (this%owner%incnd > 0) then + this%incnd = huge(1_I4B) + cnd_unit = huge(1_I4B) end if ! ! -- Create dis and packages @@ -97,7 +97,7 @@ subroutine gweifmod_cr(this, name, iout, gridConn) this%depvartype) call adv_cr(this%adv, this%name, adv_unit, this%iout, this%fmi, & this%ieqnsclfac) - call dsp_cr(this%dsp, this%name, '', -dsp_unit, this%iout, this%fmi, & + call cnd_cr(this%cnd, this%name, '', -cnd_unit, this%iout, this%fmi, & this%ieqnsclfac, this%gwecommon) call tsp_obs_cr(this%obs, inobs) ! @@ -149,11 +149,11 @@ subroutine gweifmod_df(this) ! -- local class(*), pointer :: disPtr type(TspAdvOptionsType) :: adv_options - type(GweDspOptionsType) :: dsp_options + type(GweCndOptionsType) :: cnd_options ! this%moffset = 0 adv_options%iAdvScheme = this%iAdvScheme - dsp_options%ixt3d = this%ixt3d + cnd_options%ixt3d = this%ixt3d ! ! -- Define DISU disPtr => this%dis @@ -164,25 +164,25 @@ subroutine gweifmod_df(this) call this%adv%adv_df(adv_options) end if ! - if (this%indsp > 0) then - this%dsp%idisp = this%owner%dsp%idisp - call this%dsp%dsp_df(this%dis, dsp_options) + if (this%incnd > 0) then + this%cnd%idisp = this%owner%cnd%idisp + call this%cnd%cnd_df(this%dis, cnd_options) ! - if (this%dsp%idisp > 0) then - call mem_reallocate(this%dsp%alh, this%dis%nodes, 'ALH', & - trim(this%dsp%memoryPath)) - call mem_reallocate(this%dsp%alv, this%dis%nodes, 'ALV', & - trim(this%dsp%memoryPath)) - call mem_reallocate(this%dsp%ath1, this%dis%nodes, 'ATH1', & - trim(this%dsp%memoryPath)) - call mem_reallocate(this%dsp%ath2, this%dis%nodes, 'ATH2', & - trim(this%dsp%memoryPath)) - call mem_reallocate(this%dsp%atv, this%dis%nodes, 'ATV', & - trim(this%dsp%memoryPath)) - call mem_reallocate(this%dsp%ktw, this%dis%nodes, 'KTW', & - trim(this%dsp%memoryPath)) - call mem_reallocate(this%dsp%kts, this%dis%nodes, 'KTS', & - trim(this%dsp%memoryPath)) + if (this%cnd%idisp > 0) then + call mem_reallocate(this%cnd%alh, this%dis%nodes, 'ALH', & + trim(this%cnd%memoryPath)) + call mem_reallocate(this%cnd%alv, this%dis%nodes, 'ALV', & + trim(this%cnd%memoryPath)) + call mem_reallocate(this%cnd%ath1, this%dis%nodes, 'ATH1', & + trim(this%cnd%memoryPath)) + call mem_reallocate(this%cnd%ath2, this%dis%nodes, 'ATH2', & + trim(this%cnd%memoryPath)) + call mem_reallocate(this%cnd%atv, this%dis%nodes, 'ATV', & + trim(this%cnd%memoryPath)) + call mem_reallocate(this%cnd%ktw, this%dis%nodes, 'KTW', & + trim(this%cnd%memoryPath)) + call mem_reallocate(this%cnd%kts, this%dis%nodes, 'KTS', & + trim(this%cnd%memoryPath)) end if allocate (this%est) call mem_allocate(this%est%porosity, this%dis%nodes, & @@ -216,8 +216,8 @@ subroutine gweifmod_ar(this) if (this%inadv > 0) then call this%adv%adv_ar(this%dis, this%ibound) end if - if (this%indsp > 0) then - call this%dsp%dsp_ar(this%ibound, this%est%porosity) + if (this%incnd > 0) then + call this%cnd%cnd_ar(this%ibound, this%est%porosity) end if ! ! -- Return @@ -240,12 +240,12 @@ subroutine gweifmod_da(this) call this%dis%dis_da() call this%fmi%fmi_da() call this%adv%adv_da() - call this%dsp%dsp_da() + call this%cnd%cnd_da() ! deallocate (this%dis) deallocate (this%fmi) deallocate (this%adv) - deallocate (this%dsp) + deallocate (this%cnd) ! if (associated(this%est)) then call mem_deallocate(this%est%porosity) @@ -256,7 +256,7 @@ subroutine gweifmod_da(this) call mem_deallocate(this%inic) call mem_deallocate(this%infmi) call mem_deallocate(this%inadv) - call mem_deallocate(this%indsp) + call mem_deallocate(this%incnd) call mem_deallocate(this%inssm) call mem_deallocate(this%inest) call mem_deallocate(this%inmvt) diff --git a/src/Model/GroundWaterEnergy/gwe1.f90 b/src/Model/GroundWaterEnergy/gwe1.f90 index 45b57ebd9e5..f1ba1249226 100644 --- a/src/Model/GroundWaterEnergy/gwe1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1.f90 @@ -10,7 +10,7 @@ module GweModule use NumericalModelModule, only: NumericalModelType use BaseModelModule, only: BaseModelType use BndModule, only: BndType, AddBndToList, GetBndFromList - use GweDspModule, only: GweDspType + use GweCndModule, only: GweCndType use GweEstModule, only: GweEstType use BudgetModule, only: BudgetType use GweInputDataModule, only: GweInputDataType @@ -34,9 +34,9 @@ module GweModule type(GweInputDataType), pointer :: gwecommon => null() !< container for data shared with multiple packages type(GweEstType), pointer :: est => null() !< mass storage and transfer package - type(GweDspType), pointer :: dsp => null() !< dispersion package + type(GweCndType), pointer :: cnd => null() !< dispersion package integer(I4B), pointer :: inest => null() ! unit number EST - integer(I4B), pointer :: indsp => null() ! unit number DSP + integer(I4B), pointer :: incnd => null() ! unit number CND contains @@ -71,7 +71,7 @@ module GweModule character(len=LENPACKAGETYPE), dimension(GWE_NBASEPKG) :: GWE_BASEPKG data GWE_BASEPKG/'DIS6 ', 'DISV6', 'DISU6', ' ', ' ', & ! 5 &'IC6 ', 'FMI6 ', 'EST6 ', 'ADV6 ', ' ', & ! 10 - &'DSP6 ', 'SSM6 ', 'MVT6 ', 'OC6 ', ' ', & ! 15 + &'CND6 ', 'SSM6 ', 'MVT6 ', 'OC6 ', ' ', & ! 15 &'OBS6 ', ' ', ' ', ' ', ' ', & ! 20 &30*' '/ ! 50 @@ -161,7 +161,7 @@ subroutine gwe_df(this) call this%fmi%fmi_df(this%dis, 0) if (this%inmvt > 0) call this%mvt%mvt_df(this%dis) if (this%inadv > 0) call this%adv%adv_df() - if (this%indsp > 0) call this%dsp%dsp_df(this%dis) + if (this%incnd > 0) call this%cnd%cnd_df(this%dis) if (this%inssm > 0) call this%ssm%ssm_df() call this%oc%oc_df() call this%budget%budget_df(NIUNIT_GWE, this%depvarunit, & @@ -217,8 +217,8 @@ subroutine gwe_ac(this, sparse) ! ! -- Add the internal connections of this model to sparse call this%dis%dis_ac(this%moffset, sparse) - if (this%indsp > 0) & - call this%dsp%dsp_ac(this%moffset, sparse) + if (this%incnd > 0) & + call this%cnd%cnd_ac(this%moffset, sparse) ! ! -- Add any package connections do ip = 1, this%bndlist%Count() @@ -245,7 +245,7 @@ subroutine gwe_mc(this, matrix_sln) ! and store them in idxglo. call this%dis%dis_mc(this%moffset, this%idxglo, matrix_sln) ! - if (this%indsp > 0) call this%dsp%dsp_mc(this%moffset, matrix_sln) + if (this%incnd > 0) call this%cnd%cnd_mc(this%moffset, matrix_sln) ! ! -- Map any package connections do ip = 1, this%bndlist%Count() @@ -278,7 +278,7 @@ subroutine gwe_ar(this) if (this%inic > 0) call this%ic%ic_ar(this%x) if (this%inest > 0) call this%est%est_ar(this%dis, this%ibound) if (this%inadv > 0) call this%adv%adv_ar(this%dis, this%ibound) - if (this%indsp > 0) call this%dsp%dsp_ar(this%ibound, this%est%porosity) + if (this%incnd > 0) call this%cnd%cnd_ar(this%ibound, this%est%porosity) if (this%inssm > 0) call this%ssm%ssm_ar(this%dis, this%ibound, this%x) if (this%inobs > 0) call this%obs%tsp_obs_ar(this%ic, this%x, this%flowja) ! @@ -377,7 +377,7 @@ subroutine gwe_ad(this) call this%fmi%fmi_ad(this%x) ! ! -- Advance - if (this%indsp > 0) call this%dsp%dsp_ad() + if (this%incnd > 0) call this%cnd%cnd_ad() if (this%inssm > 0) call this%ssm%ssm_ad() do ip = 1, this%bndlist%Count() packobj => GetBndFromList(this%bndlist, ip) @@ -448,8 +448,8 @@ subroutine gwe_fc(this, kiter, matrix_sln, inwtflag) call this%adv%adv_fc(this%dis%nodes, matrix_sln, this%idxglo, this%x, & this%rhs) end if - if (this%indsp > 0) then - call this%dsp%dsp_fc(kiter, this%dis%nodes, this%nja, matrix_sln, & + if (this%incnd > 0) then + call this%cnd%cnd_fc(kiter, this%dis%nodes, this%nja, matrix_sln, & this%idxglo, this%rhs, this%x) end if if (this%inssm > 0) then @@ -516,7 +516,7 @@ subroutine gwe_cq(this, icnvg, isuppress_output) this%flowja(i) = DZERO end do if (this%inadv > 0) call this%adv%adv_cq(this%x, this%flowja) - if (this%indsp > 0) call this%dsp%dsp_cq(this%x, this%flowja) + if (this%incnd > 0) call this%cnd%cnd_cq(this%x, this%flowja) if (this%inest > 0) call this%est%est_cq(this%dis%nodes, this%x, this%xold, & this%flowja) if (this%inssm > 0) call this%ssm%ssm_cq(this%flowja) @@ -628,7 +628,7 @@ subroutine gwe_da(this) call this%ic%ic_da() call this%fmi%fmi_da() call this%adv%adv_da() - call this%dsp%dsp_da() + call this%cnd%cnd_da() call this%ssm%ssm_da() call this%est%est_da() call this%mvt%mvt_da() @@ -642,7 +642,7 @@ subroutine gwe_da(this) deallocate (this%ic) deallocate (this%fmi) deallocate (this%adv) - deallocate (this%dsp) + deallocate (this%cnd) deallocate (this%ssm) deallocate (this%est) deallocate (this%mvt) @@ -660,7 +660,7 @@ subroutine gwe_da(this) ! ! -- Scalars call mem_deallocate(this%inest) - call mem_deallocate(this%indsp) + call mem_deallocate(this%incnd) ! ! -- Parent class members call this%TransportModelType%tsp_da() @@ -712,9 +712,9 @@ function gwe_get_iasym(this) result(iasym) if (this%adv%iasym /= 0) iasym = 1 end if ! - ! -- DSP - if (this%indsp > 0) then - if (this%dsp%ixt3d /= 0) iasym = 1 + ! -- CND + if (this%incnd > 0) then + if (this%cnd%ixt3d /= 0) iasym = 1 end if ! ! -- Check for any packages that introduce matrix asymmetry @@ -745,10 +745,10 @@ subroutine allocate_scalars(this, modelname) ! ! -- allocate members that are part of model class call mem_allocate(this%inest, 'INEST', this%memoryPath) - call mem_allocate(this%indsp, 'INDSP', this%memoryPath) + call mem_allocate(this%incnd, 'INCND', this%memoryPath) ! this%inest = 0 - this%indsp = 0 + this%incnd = 0 ! ! -- Return return @@ -920,7 +920,7 @@ subroutine create_gwe_packages(this, indis) use MemoryHelperModule, only: create_mem_path use SimVariablesModule, only: idm_context use GweEstModule, only: est_cr - use GweDspModule, only: dsp_cr + use GweCndModule, only: cnd_cr ! -- dummy class(GweModelType) :: this integer(I4B), intent(in) :: indis @@ -940,7 +940,7 @@ subroutine create_gwe_packages(this, indis) integer(I4B), pointer :: inunit integer(I4B), dimension(:), allocatable :: bndpkgs integer(I4B) :: n - character(len=LENMEMPATH) :: mempathdsp = '' + character(len=LENMEMPATH) :: mempathcnd = '' ! ! -- set input memory paths, input/model and input/model/namfile model_mempath = create_mem_path(component=this%name, context=idm_context) @@ -963,9 +963,9 @@ subroutine create_gwe_packages(this, indis) select case (pkgtype) case ('EST6') this%inest = inunit - case ('DSP6') - this%indsp = 1 - mempathdsp = mempath + case ('CND6') + this%incnd = 1 + mempathcnd = mempath case ('CTP6', 'SRC6', 'LKE6', 'SFE6', & 'MWE6', 'UZE6', 'API6') call expandarray(bndpkgs) @@ -978,7 +978,7 @@ subroutine create_gwe_packages(this, indis) ! -- Create packages that are tied directly to model call est_cr(this%est, this%name, this%inest, this%iout, this%fmi, & this%eqnsclfac, this%gwecommon) - call dsp_cr(this%dsp, this%name, mempathdsp, this%indsp, this%iout, & + call cnd_cr(this%cnd, this%name, mempathcnd, this%incnd, this%iout, & this%fmi, this%eqnsclfac, this%gwecommon) ! ! -- Check to make sure that required ftype's have been specified diff --git a/src/Model/GroundWaterEnergy/gwe1dsp1.f90 b/src/Model/GroundWaterEnergy/gwe1cnd1.f90 similarity index 89% rename from src/Model/GroundWaterEnergy/gwe1dsp1.f90 rename to src/Model/GroundWaterEnergy/gwe1cnd1.f90 index 9e3609a7181..f3a1646ef55 100644 --- a/src/Model/GroundWaterEnergy/gwe1dsp1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1cnd1.f90 @@ -1,4 +1,4 @@ -module GweDspModule +module GweCndModule use KindModule, only: DP, I4B use ConstantsModule, only: DONE, DZERO, DHALF, DPI @@ -6,16 +6,16 @@ module GweDspModule use BaseDisModule, only: DisBaseType use TspFmiModule, only: TspFmiType use Xt3dModule, only: Xt3dType, xt3d_cr - use GweDspOptionsModule, only: GweDspOptionsType + use GweCndOptionsModule, only: GweCndOptionsType use GweInputDataModule, only: GweInputDataType use MatrixBaseModule implicit none private - public :: GweDspType - public :: dsp_cr + public :: GweCndType + public :: cnd_cr - type, extends(NumericalPackageType) :: GweDspType + type, extends(NumericalPackageType) :: GweCndType integer(I4B), dimension(:), pointer, contiguous :: ibound => null() ! pointer to GWE model ibound type(TspFmiType), pointer :: fmi => null() ! pointer to GWE fmi object @@ -56,14 +56,14 @@ module GweDspModule contains - procedure :: dsp_df - procedure :: dsp_ac - procedure :: dsp_mc - procedure :: dsp_ar - procedure :: dsp_ad - procedure :: dsp_fc - procedure :: dsp_cq - procedure :: dsp_da + procedure :: cnd_df + procedure :: cnd_ac + procedure :: cnd_mc + procedure :: cnd_ar + procedure :: cnd_ad + procedure :: cnd_fc + procedure :: cnd_cq + procedure :: cnd_da procedure :: allocate_scalars procedure :: allocate_arrays procedure, private :: source_options @@ -73,21 +73,21 @@ module GweDspModule procedure, private :: calcdispellipse procedure, private :: calcdispcoef - end type GweDspType + end type GweCndType contains - !> @brief Create a new DSP object + !> @brief Create a new CND object !! - !! Create a new MST package + !! Create a new CND package !< - subroutine dsp_cr(dspobj, name_model, input_mempath, inunit, iout, fmi, & + subroutine cnd_cr(cndobj, name_model, input_mempath, inunit, iout, fmi, & eqnsclfac, gwecommon) ! -- modules use KindModule, only: LGP use MemoryManagerExtModule, only: mem_set_value ! -- dummy - type(GweDspType), pointer :: dspobj + type(GweCndType), pointer :: cndobj character(len=*), intent(in) :: name_model character(len=*), intent(in) :: input_mempath integer(I4B), intent(in) :: inunit @@ -96,49 +96,49 @@ subroutine dsp_cr(dspobj, name_model, input_mempath, inunit, iout, fmi, & real(DP), intent(in), pointer :: eqnsclfac !< governing equation scale factor type(GweInputDataType), intent(in), target, optional :: gwecommon !< shared data container for use by multiple GWE packages ! -- formats - character(len=*), parameter :: fmtdsp = & - "(1x,/1x,'DSP-- THERMAL CONDUCTION AND DISPERSION PACKAGE, VERSION 1, ', & + character(len=*), parameter :: fmtcnd = & + "(1x,/1x,'CND-- THERMAL CONDUCTION AND DISPERSION PACKAGE, VERSION 1, ', & &'01/01/2024, INPUT READ FROM MEMPATH ', A, //)" ! ! -- Create the object - allocate (dspobj) + allocate (cndobj) ! ! -- create name and memory path - call dspobj%set_names(1, name_model, 'DSP', 'DSP', input_mempath) + call cndobj%set_names(1, name_model, 'CND', 'CND', input_mempath) ! ! -- Allocate scalars - call dspobj%allocate_scalars() + call cndobj%allocate_scalars() ! ! -- Set variables - dspobj%inunit = inunit - dspobj%iout = iout - dspobj%fmi => fmi - dspobj%eqnsclfac => eqnsclfac + cndobj%inunit = inunit + cndobj%iout = iout + cndobj%fmi => fmi + cndobj%eqnsclfac => eqnsclfac if (present(gwecommon)) then - dspobj%gwecommon => gwecommon + cndobj%gwecommon => gwecommon end if ! - if (dspobj%inunit > 0) then + if (cndobj%inunit > 0) then ! ! -- Print a message identifying the dispersion package. - if (dspobj%iout > 0) then - write (dspobj%iout, fmtdsp) input_mempath + if (cndobj%iout > 0) then + write (cndobj%iout, fmtcnd) input_mempath end if end if ! ! -- Return return - end subroutine dsp_cr + end subroutine cnd_cr - !> @brief Define DSP object + !> @brief Define CND object !< - subroutine dsp_df(this, dis, dspOptions) + subroutine cnd_df(this, dis, cndOptions) ! -- modules ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this class(DisBaseType), pointer :: dis - type(GweDspOptionsType), optional, intent(in) :: dspOptions !< the optional DSP options, used when not - !! creating DSP from file + type(GweCndOptionsType), optional, intent(in) :: cndOptions !< the optional CND options, used when not + !! creating CND from file ! ! -- Store pointer to dis this%dis => dis @@ -148,8 +148,8 @@ subroutine dsp_df(this, dis, dspOptions) this%ixt3d = 1 ! ! -- Read dispersion options - if (present(dspOptions)) then - this%ixt3d = dspOptions%ixt3d + if (present(cndOptions)) then + this%ixt3d = cndOptions%ixt3d ! ! -- Allocate only, grid data will not be read from file call this%allocate_arrays(this%dis%nodes) @@ -173,18 +173,18 @@ subroutine dsp_df(this, dis, dspOptions) ! ! -- Return return - end subroutine dsp_df + end subroutine cnd_df - !> @brief Add connections to DSP + !> @brief Add connections to CND !! !! Add connections for extended neighbors to the sparse matrix !< - subroutine dsp_ac(this, moffset, sparse) + subroutine cnd_ac(this, moffset, sparse) ! -- modules use SparseModule, only: sparsematrix use MemoryManagerModule, only: mem_allocate ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this integer(I4B), intent(in) :: moffset type(sparsematrix), intent(inout) :: sparse ! @@ -193,17 +193,17 @@ subroutine dsp_ac(this, moffset, sparse) ! ! -- Return return - end subroutine dsp_ac + end subroutine cnd_ac - !> @brief Map DSP connections + !> @brief Map CND connections !! !! Map connections and construct iax, jax, and idxglox !< - subroutine dsp_mc(this, moffset, matrix_sln) + subroutine cnd_mc(this, moffset, matrix_sln) ! -- modules use MemoryManagerModule, only: mem_allocate ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this integer(I4B), intent(in) :: moffset class(MatrixBaseType), pointer :: matrix_sln ! @@ -212,39 +212,39 @@ subroutine dsp_mc(this, moffset, matrix_sln) ! ! -- Return return - end subroutine dsp_mc + end subroutine cnd_mc !> @brief Allocate and read method for package !! !! Method to allocate and read static data for the package. !< - subroutine dsp_ar(this, ibound, porosity) + subroutine cnd_ar(this, ibound, porosity) ! -- modules ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this integer(I4B), dimension(:), pointer, contiguous :: ibound real(DP), dimension(:), pointer, contiguous :: porosity ! -- local ! -- formats - character(len=*), parameter :: fmtdsp = & - "(1x,/1x,'DSP-- THERMAL CONDUCTION AND DISPERSION PACKAGE, VERSION 1, ', & + character(len=*), parameter :: fmtcnd = & + "(1x,/1x,'CND-- THERMAL CONDUCTION AND DISPERSION PACKAGE, VERSION 1, ', & &'5/01/2023, INPUT READ FROM UNIT ', i0, //)" ! - ! -- dsp pointers to arguments that were passed in + ! -- cnd pointers to arguments that were passed in this%ibound => ibound this%porosity => porosity ! ! -- Return return - end subroutine dsp_ar + end subroutine cnd_ar !> @brief Advance method for the package !< - subroutine dsp_ad(this) + subroutine cnd_ad(this) ! -- modules use TdisModule, only: kstp, kper ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this ! ! -- xt3d ! TODO: might consider adding a new mf6 level set pointers method, and @@ -272,15 +272,15 @@ subroutine dsp_ad(this) ! ! -- Return return - end subroutine dsp_ad + end subroutine cnd_ad !> @brief Fill coefficient method for package !! !! Method to calculate and fill coefficients for the package. !< - subroutine dsp_fc(this, kiter, nodes, nja, matrix_sln, idxglo, rhs, cnew) + subroutine cnd_fc(this, kiter, nodes, nja, matrix_sln, idxglo, rhs, cnew) ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this integer(I4B) :: kiter integer(I4B), intent(in) :: nodes integer(I4B), intent(in) :: nja @@ -321,16 +321,16 @@ subroutine dsp_fc(this, kiter, nodes, nja, matrix_sln, idxglo, rhs, cnew) ! ! -- Return return - end subroutine dsp_fc + end subroutine cnd_fc !> @ brief Calculate flows for package !! !! Method to calculate dispersion contribution to flowja !< - subroutine dsp_cq(this, cnew, flowja) + subroutine cnd_cq(this, cnew, flowja) ! -- modules ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this real(DP), intent(inout), dimension(:) :: cnew real(DP), intent(inout), dimension(:) :: flowja ! -- local @@ -357,7 +357,7 @@ subroutine dsp_cq(this, cnew, flowja) ! ! -- Return return - end subroutine dsp_cq + end subroutine cnd_cq !> @ brief Allocate scalar variables for package !! @@ -368,7 +368,7 @@ subroutine allocate_scalars(this) use MemoryManagerModule, only: mem_allocate use ConstantsModule, only: DZERO ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this ! ! -- allocate scalars in NumericalPackageType call this%NumericalPackageType%allocate_scalars() @@ -422,7 +422,7 @@ subroutine allocate_arrays(this, nodes) use MemoryManagerModule, only: mem_allocate use ConstantsModule, only: DZERO ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this integer(I4B), intent(in) :: nodes ! ! -- Allocate @@ -456,17 +456,17 @@ end subroutine allocate_arrays !! !! Method to deallocate memory for the package. !< - subroutine dsp_da(this) + subroutine cnd_da(this) ! -- modules use MemoryManagerModule, only: mem_deallocate use MemoryManagerExtModule, only: memorylist_remove use SimVariablesModule, only: idm_context ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this ! -- local ! ! -- Deallocate input memory - call memorylist_remove(this%name_model, 'DSP', idm_context) + call memorylist_remove(this%name_model, 'CND', idm_context) ! ! -- deallocate arrays if (this%inunit /= 0) then @@ -514,19 +514,19 @@ subroutine dsp_da(this) ! ! -- Return return - end subroutine dsp_da + end subroutine cnd_da !> @brief Write user options to list file !< subroutine log_options(this, found) - use GweDspInputModule, only: GweDspParamFoundType - class(GweDspType) :: this - type(GweDspParamFoundType), intent(in) :: found + use GweCndInputModule, only: GweCndParamFoundType + class(GweCndType) :: this + type(GweCndParamFoundType), intent(in) :: found ! - write (this%iout, '(1x,a)') 'Setting DSP Options' + write (this%iout, '(1x,a)') 'Setting CND Options' write (this%iout, '(4x,a,i0)') 'XT3D formulation [0=INACTIVE, 1=ACTIVE, & &3=ACTIVE RHS] set to: ', this%ixt3d - write (this%iout, '(1x,a,/)') 'End Setting DSP Options' + write (this%iout, '(1x,a,/)') 'End Setting CND Options' ! -- Return return end subroutine log_options @@ -536,11 +536,11 @@ end subroutine log_options subroutine source_options(this) ! -- modules use MemoryManagerExtModule, only: mem_set_value - use GweDspInputModule, only: GweDspParamFoundType + use GweCndInputModule, only: GweCndParamFoundType ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this ! -- locals - type(GweDspParamFoundType) :: found + type(GweCndParamFoundType) :: found ! ! -- update defaults with idm sourced values call mem_set_value(this%ixt3doff, 'XT3D_OFF', this%input_mempath, & @@ -564,11 +564,11 @@ end subroutine source_options !> @brief Write dimensions to list file !< subroutine log_griddata(this, found) - use GweDspInputModule, only: GweDspParamFoundType - class(GweDspType) :: this - type(GweDspParamFoundType), intent(in) :: found + use GweCndInputModule, only: GweCndParamFoundType + class(GweCndType) :: this + type(GweCndParamFoundType), intent(in) :: found ! - write (this%iout, '(1x,a)') 'Setting DSP Griddata' + write (this%iout, '(1x,a)') 'Setting CND Griddata' ! if (found%alh) then write (this%iout, '(4x,a)') 'ALH set from input file' @@ -598,13 +598,13 @@ subroutine log_griddata(this, found) write (this%iout, '(4x,a)') 'KTS set from input file' end if ! - write (this%iout, '(1x,a,/)') 'End Setting DSP Griddata' + write (this%iout, '(1x,a,/)') 'End Setting CND Griddata' ! ! -- Return return end subroutine log_griddata - !> @brief Update DSP simulation data from input mempath + !> @brief Update CND simulation data from input mempath !< subroutine source_griddata(this) ! -- modules @@ -612,12 +612,12 @@ subroutine source_griddata(this) use MemoryManagerModule, only: mem_reallocate, mem_reassignptr use MemoryManagerExtModule, only: mem_set_value use ConstantsModule, only: LENMEMPATH, LINELENGTH - use GweDspInputModule, only: GweDspParamFoundType + use GweCndInputModule, only: GweCndParamFoundType ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this ! -- locals character(len=LINELENGTH) :: errmsg - type(GweDspParamFoundType) :: found + type(GweCndParamFoundType) :: found integer(I4B), dimension(:), pointer, contiguous :: map ! -- formats ! @@ -690,7 +690,7 @@ end subroutine source_griddata subroutine calcdispellipse(this) ! -- modules ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this ! -- local integer(I4B) :: nodes, n real(DP) :: q, qx, qy, qz @@ -811,7 +811,7 @@ subroutine calcdispcoef(this) ! -- modules use GwfNpfModule, only: hyeff_calc ! -- dummy - class(GweDspType) :: this + class(GweCndType) :: this ! -- local integer(I4B) :: nodes, n, m, idiag, ipos real(DP) :: clnm, clmn, dn, dm @@ -940,4 +940,4 @@ subroutine calcdispcoef(this) return end subroutine calcdispcoef -end module GweDspModule +end module GweCndModule diff --git a/src/Model/GroundWaterEnergy/gwe1dsp1idm.f90 b/src/Model/GroundWaterEnergy/gwe1cnd1idm.f90 similarity index 78% rename from src/Model/GroundWaterEnergy/gwe1dsp1idm.f90 rename to src/Model/GroundWaterEnergy/gwe1cnd1idm.f90 index b98fe8f3307..9757a46bcc1 100644 --- a/src/Model/GroundWaterEnergy/gwe1dsp1idm.f90 +++ b/src/Model/GroundWaterEnergy/gwe1cnd1idm.f90 @@ -1,16 +1,16 @@ ! ** Do Not Modify! MODFLOW 6 system generated file. ** -module GweDspInputModule +module GweCndInputModule use ConstantsModule, only: LENVARNAME use InputDefinitionModule, only: InputParamDefinitionType, & InputBlockDefinitionType private - public gwe_dsp_param_definitions - public gwe_dsp_aggregate_definitions - public gwe_dsp_block_definitions - public GweDspParamFoundType - public gwe_dsp_multi_package + public gwe_cnd_param_definitions + public gwe_cnd_aggregate_definitions + public gwe_cnd_block_definitions + public GweCndParamFoundType + public gwe_cnd_multi_package - type GweDspParamFoundType + type GweCndParamFoundType logical :: xt3d_off = .false. logical :: xt3d_rhs = .false. logical :: alh = .false. @@ -20,15 +20,15 @@ module GweDspInputModule logical :: atv = .false. logical :: ktw = .false. logical :: kts = .false. - end type GweDspParamFoundType + end type GweCndParamFoundType - logical :: gwe_dsp_multi_package = .false. + logical :: gwe_cnd_multi_package = .false. type(InputParamDefinitionType), parameter :: & - gwedsp_xt3d_off = InputParamDefinitionType & + gwecnd_xt3d_off = InputParamDefinitionType & ( & 'GWE', & ! component - 'DSP', & ! subcomponent + 'CND', & ! subcomponent 'OPTIONS', & ! block 'XT3D_OFF', & ! tag name 'XT3D_OFF', & ! fortran variable @@ -42,10 +42,10 @@ module GweDspInputModule ) type(InputParamDefinitionType), parameter :: & - gwedsp_xt3d_rhs = InputParamDefinitionType & + gwecnd_xt3d_rhs = InputParamDefinitionType & ( & 'GWE', & ! component - 'DSP', & ! subcomponent + 'CND', & ! subcomponent 'OPTIONS', & ! block 'XT3D_RHS', & ! tag name 'XT3D_RHS', & ! fortran variable @@ -59,10 +59,10 @@ module GweDspInputModule ) type(InputParamDefinitionType), parameter :: & - gwedsp_alh = InputParamDefinitionType & + gwecnd_alh = InputParamDefinitionType & ( & 'GWE', & ! component - 'DSP', & ! subcomponent + 'CND', & ! subcomponent 'GRIDDATA', & ! block 'ALH', & ! tag name 'ALH', & ! fortran variable @@ -76,10 +76,10 @@ module GweDspInputModule ) type(InputParamDefinitionType), parameter :: & - gwedsp_alv = InputParamDefinitionType & + gwecnd_alv = InputParamDefinitionType & ( & 'GWE', & ! component - 'DSP', & ! subcomponent + 'CND', & ! subcomponent 'GRIDDATA', & ! block 'ALV', & ! tag name 'ALV', & ! fortran variable @@ -93,10 +93,10 @@ module GweDspInputModule ) type(InputParamDefinitionType), parameter :: & - gwedsp_ath1 = InputParamDefinitionType & + gwecnd_ath1 = InputParamDefinitionType & ( & 'GWE', & ! component - 'DSP', & ! subcomponent + 'CND', & ! subcomponent 'GRIDDATA', & ! block 'ATH1', & ! tag name 'ATH1', & ! fortran variable @@ -110,10 +110,10 @@ module GweDspInputModule ) type(InputParamDefinitionType), parameter :: & - gwedsp_ath2 = InputParamDefinitionType & + gwecnd_ath2 = InputParamDefinitionType & ( & 'GWE', & ! component - 'DSP', & ! subcomponent + 'CND', & ! subcomponent 'GRIDDATA', & ! block 'ATH2', & ! tag name 'ATH2', & ! fortran variable @@ -127,10 +127,10 @@ module GweDspInputModule ) type(InputParamDefinitionType), parameter :: & - gwedsp_atv = InputParamDefinitionType & + gwecnd_atv = InputParamDefinitionType & ( & 'GWE', & ! component - 'DSP', & ! subcomponent + 'CND', & ! subcomponent 'GRIDDATA', & ! block 'ATV', & ! tag name 'ATV', & ! fortran variable @@ -144,10 +144,10 @@ module GweDspInputModule ) type(InputParamDefinitionType), parameter :: & - gwedsp_ktw = InputParamDefinitionType & + gwecnd_ktw = InputParamDefinitionType & ( & 'GWE', & ! component - 'DSP', & ! subcomponent + 'CND', & ! subcomponent 'GRIDDATA', & ! block 'KTW', & ! tag name 'KTW', & ! fortran variable @@ -161,10 +161,10 @@ module GweDspInputModule ) type(InputParamDefinitionType), parameter :: & - gwedsp_kts = InputParamDefinitionType & + gwecnd_kts = InputParamDefinitionType & ( & 'GWE', & ! component - 'DSP', & ! subcomponent + 'CND', & ! subcomponent 'GRIDDATA', & ! block 'KTS', & ! tag name 'KTS', & ! fortran variable @@ -178,21 +178,21 @@ module GweDspInputModule ) type(InputParamDefinitionType), parameter :: & - gwe_dsp_param_definitions(*) = & + gwe_cnd_param_definitions(*) = & [ & - gwedsp_xt3d_off, & - gwedsp_xt3d_rhs, & - gwedsp_alh, & - gwedsp_alv, & - gwedsp_ath1, & - gwedsp_ath2, & - gwedsp_atv, & - gwedsp_ktw, & - gwedsp_kts & + gwecnd_xt3d_off, & + gwecnd_xt3d_rhs, & + gwecnd_alh, & + gwecnd_alv, & + gwecnd_ath1, & + gwecnd_ath2, & + gwecnd_atv, & + gwecnd_ktw, & + gwecnd_kts & ] type(InputParamDefinitionType), parameter :: & - gwe_dsp_aggregate_definitions(*) = & + gwe_cnd_aggregate_definitions(*) = & [ & InputParamDefinitionType & ( & @@ -212,7 +212,7 @@ module GweDspInputModule ] type(InputBlockDefinitionType), parameter :: & - gwe_dsp_block_definitions(*) = & + gwe_cnd_block_definitions(*) = & [ & InputBlockDefinitionType( & 'OPTIONS', & ! blockname @@ -228,4 +228,4 @@ module GweDspInputModule ) & ] -end module GweDspInputModule +end module GweCndInputModule diff --git a/src/Model/ModelUtilities/GweDspOptions.f90 b/src/Model/ModelUtilities/GweCndOptions.f90 similarity index 51% rename from src/Model/ModelUtilities/GweDspOptions.f90 rename to src/Model/ModelUtilities/GweCndOptions.f90 index 85e8d52cbc9..86c5f1a7630 100644 --- a/src/Model/ModelUtilities/GweDspOptions.f90 +++ b/src/Model/ModelUtilities/GweCndOptions.f90 @@ -1,12 +1,12 @@ -module GweDspOptionsModule +module GweCndOptionsModule use KindModule, only: I4B implicit none private - !> @brief data structure (and helpers) for passing dsp option data + !> @brief data structure (and helpers) for passing cnd option data !< into the package, as opposed to reading it from file - type, public :: GweDspOptionsType + type, public :: GweCndOptionsType integer(I4B) :: ixt3d !< flag indicating xt3d is active: 1 = enabled, 2 = rhs - end type GweDspOptionsType + end type GweCndOptionsType -end module GweDspOptionsModule +end module GweCndOptionsModule diff --git a/src/Utilities/Idm/selector/IdmGweDfnSelector.f90 b/src/Utilities/Idm/selector/IdmGweDfnSelector.f90 index 89714b44a1d..bbf704b441a 100644 --- a/src/Utilities/Idm/selector/IdmGweDfnSelector.f90 +++ b/src/Utilities/Idm/selector/IdmGweDfnSelector.f90 @@ -8,7 +8,7 @@ module IdmGweDfnSelectorModule use GweDisInputModule use GweDisuInputModule use GweDisvInputModule - use GweDspInputModule + use GweCndInputModule use GweCtpInputModule use GweIcInputModule use GweNamInputModule @@ -46,8 +46,8 @@ function gwe_param_definitions(subcomponent) result(input_definition) call set_param_pointer(input_definition, gwe_disu_param_definitions) case ('DISV') call set_param_pointer(input_definition, gwe_disv_param_definitions) - case ('DSP') - call set_param_pointer(input_definition, gwe_dsp_param_definitions) + case ('CND') + call set_param_pointer(input_definition, gwe_cnd_param_definitions) case ('CTP') call set_param_pointer(input_definition, gwe_ctp_param_definitions) case ('IC') @@ -70,8 +70,8 @@ function gwe_aggregate_definitions(subcomponent) result(input_definition) call set_param_pointer(input_definition, gwe_disu_aggregate_definitions) case ('DISV') call set_param_pointer(input_definition, gwe_disv_aggregate_definitions) - case ('DSP') - call set_param_pointer(input_definition, gwe_dsp_aggregate_definitions) + case ('CND') + call set_param_pointer(input_definition, gwe_cnd_aggregate_definitions) case ('CTP') call set_param_pointer(input_definition, gwe_ctp_aggregate_definitions) case ('IC') @@ -94,8 +94,8 @@ function gwe_block_definitions(subcomponent) result(input_definition) call set_block_pointer(input_definition, gwe_disu_block_definitions) case ('DISV') call set_block_pointer(input_definition, gwe_disv_block_definitions) - case ('DSP') - call set_block_pointer(input_definition, gwe_dsp_block_definitions) + case ('CND') + call set_block_pointer(input_definition, gwe_cnd_block_definitions) case ('CTP') call set_block_pointer(input_definition, gwe_ctp_block_definitions) case ('IC') @@ -117,8 +117,8 @@ function gwe_idm_multi_package(subcomponent) result(multi_package) multi_package = gwe_disu_multi_package case ('DISV') multi_package = gwe_disv_multi_package - case ('DSP') - multi_package = gwe_dsp_multi_package + case ('CND') + multi_package = gwe_cnd_multi_package case ('CTP') multi_package = gwe_ctp_multi_package case ('IC') @@ -144,7 +144,7 @@ function gwe_idm_integrated(subcomponent) result(integrated) integrated = .true. case ('DISV') integrated = .true. - case ('DSP') + case ('CND') integrated = .true. case ('CTP') integrated = .true. diff --git a/src/meson.build b/src/meson.build index a2b4bef7667..124cfefedbc 100644 --- a/src/meson.build +++ b/src/meson.build @@ -59,13 +59,13 @@ modflow_sources = files( 'Model' / 'Geometry' / 'CircularGeometry.f90', 'Model' / 'Geometry' / 'RectangularGeometry.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1cnd1.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1cnd1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1ctp1.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1ctp1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1dis1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1disu1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1disv1idm.f90', - 'Model' / 'GroundWaterEnergy' / 'gwe1dsp1.f90', - 'Model' / 'GroundWaterEnergy' / 'gwe1dsp1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1ic1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1est1.f90', @@ -132,11 +132,11 @@ modflow_sources = files( 'Model' / 'GroundWaterTransport' / 'gwt1uzt1.f90', 'Model' / 'ModelUtilities' / 'BoundaryPackage.f90', 'Model' / 'ModelUtilities' / 'BoundaryPackageExt.f90', + 'Model' / 'ModelUtilities' / 'GweCndOptions.f90', 'Model' / 'ModelUtilities' / 'Connections.f90', 'Model' / 'ModelUtilities' / 'DiscretizationBase.f90', 'Model' / 'ModelUtilities' / 'DisvGeom.f90', 'Model' / 'ModelUtilities' / 'FlowModelInterface.f90', - 'Model' / 'ModelUtilities' / 'GweDspOptions.f90', 'Model' / 'ModelUtilities' / 'GweInputData.f90', 'Model' / 'ModelUtilities' / 'GwfBuyInputData.f90', 'Model' / 'ModelUtilities' / 'GwfMvrPeriodData.f90', diff --git a/utils/idmloader/scripts/dfn2f90.py b/utils/idmloader/scripts/dfn2f90.py index f9b4dc9b360..f53fa3e1150 100644 --- a/utils/idmloader/scripts/dfn2f90.py +++ b/utils/idmloader/scripts/dfn2f90.py @@ -1010,8 +1010,8 @@ def _write_master_component(self, fh=None): SRC_PATH / "Model" / "GroundWaterEnergy" / "gwe1disv1idm.f90", ], [ - DFN_PATH / "gwe-dsp.dfn", - SRC_PATH / "Model" / "GroundWaterEnergy" / "gwe1dsp1idm.f90", + DFN_PATH / "gwe-cnd.dfn", + SRC_PATH / "Model" / "GroundWaterEnergy" / "gwe1cnd1idm.f90", ], [ DFN_PATH / "gwe-ctp.dfn", From 400a4d35980fe17c080bf9c01a9164bcd5ba8b90 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 19 Jan 2024 11:11:37 -0800 Subject: [PATCH 29/46] Remove gwe-related code from generalized transport code (tsp1.f90 & tsp1ssm1.f90) --- src/Model/TransportModel/tsp1.f90 | 1 - src/Model/TransportModel/tsp1ssm1.f90 | 12 +----------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/Model/TransportModel/tsp1.f90 b/src/Model/TransportModel/tsp1.f90 index 9e18f720a8b..31d1f928b64 100644 --- a/src/Model/TransportModel/tsp1.f90 +++ b/src/Model/TransportModel/tsp1.f90 @@ -20,7 +20,6 @@ module TransportModelModule use TspOcModule, only: TspOcType use TspObsModule, only: TspObsType use BudgetModule, only: BudgetType - use GweInputDataModule, only: GweInputDataType use MatrixBaseModule implicit none diff --git a/src/Model/TransportModel/tsp1ssm1.f90 b/src/Model/TransportModel/tsp1ssm1.f90 index 9cddf3e2e2e..d190a7fdc92 100644 --- a/src/Model/TransportModel/tsp1ssm1.f90 +++ b/src/Model/TransportModel/tsp1ssm1.f90 @@ -46,7 +46,6 @@ module TspSsmModule type(GwtSpcType), dimension(:), pointer :: ssmivec => null() !< array of stress package concentration objects real(DP), pointer :: eqnsclfac => null() !< governing equation scale factor; =1. for solute; =rhow*cpw for energy character(len=LENVARNAME) :: depvartype = '' - type(GweInputDataType), pointer :: gwecommon => null() !< pointer to shared gwe data used by multiple packages but set in mst contains @@ -81,7 +80,7 @@ module TspSsmModule !! and initializing the parser. !< subroutine ssm_cr(ssmobj, name_model, inunit, iout, fmi, eqnsclfac, & - depvartype, gwecommon) + depvartype) ! -- dummy type(TspSsmType), pointer :: ssmobj !< TspSsmType object character(len=*), intent(in) :: name_model !< name of the model @@ -90,7 +89,6 @@ subroutine ssm_cr(ssmobj, name_model, inunit, iout, fmi, eqnsclfac, & type(TspFmiType), intent(in), target :: fmi !< Transport FMI package real(DP), intent(in), pointer :: eqnsclfac !< governing equation scale factor character(len=LENVARNAME), intent(in) :: depvartype !< dependent variable type ('concentration' or 'temperature') - type(GweInputDataType), intent(in), target, optional :: gwecommon !< shared data container for use by multiple GWE packages ! ! -- Create the object allocate (ssmobj) @@ -114,11 +112,6 @@ subroutine ssm_cr(ssmobj, name_model, inunit, iout, fmi, eqnsclfac, & ! package has access to the corresponding dependent variable type ssmobj%depvartype = depvartype ! - ! -- Give package access to the shared heat transport variables assigned in MST - if (present(gwecommon)) then - ssmobj%gwecommon => gwecommon - end if - ! ! -- Return return end subroutine ssm_cr @@ -726,9 +719,6 @@ subroutine ssm_da(this) ! -- Scalars call mem_deallocate(this%nbound) ! - ! -- Pointers - nullify (this%gwecommon) - ! ! -- deallocate parent call this%NumericalPackageType%da() ! From 2135ed534859b19f058c1e2bf21e1698d9e5a529 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 26 Jan 2024 14:52:05 -0800 Subject: [PATCH 30/46] add single-cell test for energy source loading (ESL) package --- autotest/test_gwe_esl01.py | 369 +++++++++++++++++++++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 autotest/test_gwe_esl01.py diff --git a/autotest/test_gwe_esl01.py b/autotest/test_gwe_esl01.py new file mode 100644 index 00000000000..4b58c30d001 --- /dev/null +++ b/autotest/test_gwe_esl01.py @@ -0,0 +1,369 @@ +""" +A "bathtub" test problem for GWE - bathtub meaning a single cell model +(and actually, the bathtub is dry in this example) + +Test the energy source loading package by warming a single cell with a known +amount of energy input. + + Model configuration + + ~: Represents energy source loading + + +---------+ + | | + | ~ | + | | + +---------+ + +""" + +# Imports + +import os +import numpy as np +import pytest +import flopy + +from framework import TestFramework + + +# Base simulation and model name and workspace + +scheme = "UPSTREAM" +# scheme = "TVD" + +cases = [ + "warmup", # 2-cell model, horizontally connected with tops and bots aligned +] + +# Model units +length_units = "meters" +time_units = "days" + +# Parameterization + +nrow = ncol = nlay = 1 +top = 1.0 +botm = [0.0] +delr = 1.0 # Column width ($m$) +delc = 1.0 # Row width ($m$) +k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$) +ss = 1e-6 # Specific storage +sy = 0.10 # Specific Yield +prsity = sy # Porosity +nper = 4 # Number of periods +perlen = [1, 1, 1, 1] # Simulation time ($days$) +nstp = [1, 1, 1, 1] # 10 day transient time steps +steady = {0: False} +transient = {0: True} +strthd = 0.0 + +# Set some static model parameter values + +k33 = k11 # Vertical hydraulic conductivity ($m/d$) +idomain = 1 # All cells included in the simulation +iconvert = 1 # All cells are convertible + +icelltype = 1 # Cell conversion type (>1: unconfined) + +# Set some static transport related model parameter values +strt_temp1 = 0.0 +dispersivity = 0.0 # dispersion (remember, 1D model) + +# GWE related parameters +rhow = 1000.0 +cpw = 4183.0 +lhv = 2454.0 +cps = 760.0 +rhos = 1500.0 + +# Set solver parameter values (and related) +nouter, ninner = 100, 300 +hclose, rclose, relax = 1e-10, 1e-10, 1.0 +ttsmult = 1.0 + +# Set up temporal data used by TDIS file +tdis_rc = [] +for i in np.arange(nper): + tdis_rc.append((perlen[i], nstp[i], ttsmult)) + +Joules_added_for_1degC_rise = ( + delr * delc * (top - botm[0]) * (1 - prsity) * cps * rhos +) + +# ### Create MODFLOW 6 GWE MT3DMS Example 1 Boundary Conditions +# +# No GWF, only Heat conduction simulated + + +def build_models(idx, test): + # Base MF6 GWF model type + ws = test.workspace + name = cases[idx] + + print("Building MF6 model...()".format(name)) + + # generate names for each model + gwfname = "gwf-" + name + gwename = "gwe-" + name + + sim = flopy.mf6.MFSimulation( + sim_name=name, sim_ws=ws, exe_name="mf6", version="mf6" + ) + + # Instantiating MODFLOW 6 time discretization + flopy.mf6.ModflowTdis( + sim, nper=nper, perioddata=tdis_rc, time_units=time_units + ) + + # Instantiating MODFLOW 6 groundwater flow model + gwf = flopy.mf6.ModflowGwf( + sim, + modelname=gwfname, + save_flows=True, + model_nam_file="{}.nam".format(gwfname), + ) + + # Instantiating MODFLOW 6 solver for flow model + imsgwf = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="CG", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwfname), + ) + sim.register_ims_package(imsgwf, [gwfname]) + + # Instantiating MODFLOW 6 discretization package + flopy.mf6.ModflowGwfdis( + gwf, + length_units=length_units, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=1, + pname="DIS-1", + filename="{}.dis".format(gwfname), + ) + + # Instantiating MODFLOW 6 storage package + flopy.mf6.ModflowGwfsto( + gwf, + ss=ss, + sy=sy, + iconvert=iconvert, + steady_state=steady, + transient=transient, + pname="STO", + filename="{}.sto".format(gwfname), + ) + + # Instantiating MODFLOW 6 node-property flow package + flopy.mf6.ModflowGwfnpf( + gwf, + save_flows=True, + icelltype=icelltype, + k=k11, + k33=k33, + save_specific_discharge=True, + pname="NPF-1", + filename="{}.npf".format(gwfname), + ) + + # Instantiating MODFLOW 6 initial conditions package for flow model + flopy.mf6.ModflowGwfic( + gwf, + strt=strthd, + pname="IC-HD", + filename="{}.ic".format(gwfname), + ) + + # Instantiating MODFLOW 6 output control package for flow model + flopy.mf6.ModflowGwfoc( + gwf, + pname="OC-1", + head_filerecord="{}.hds".format(gwfname), + budget_filerecord="{}.cbc".format(gwfname), + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + printrecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + ) + + # ---------------------------------- + # Instantiating MODFLOW 6 GWE model + # ---------------------------------- + gwe = flopy.mf6.ModflowGwe( + sim, modelname=gwename, model_nam_file="{}.nam".format(gwename) + ) + gwe.name_file.save_flows = True + + imsgwe = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwename), + ) + sim.register_ims_package(imsgwe, [gwe.name]) + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwedis( + gwe, + nogrb=True, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=1, + pname="DIS-GWE", + filename="{}.dis".format(gwename), + ) + + # Instantiating MODFLOW 6 transport initial concentrations + flopy.mf6.ModflowGweic( + gwe, strt=strt_temp1, pname="IC-2", filename="{}.ic".format(gwename) + ) + + # Instantiating MODFLOW 6 transport advection package + flopy.mf6.ModflowGweadv( + gwe, scheme=scheme, pname="ADV-2", filename="{}.adv".format(gwename) + ) + + # Instantiating MODFLOW 6 transport dispersion package + flopy.mf6.ModflowGwecnd( + gwe, + xt3d_off=True, + alh=dispersivity, + ath1=dispersivity, + ktw=0.5918 * 86400, + kts=0.2700 * 86400, + pname="CND-2", + filename="{}.cnd".format(gwename), + ) + + # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) + flopy.mf6.ModflowGweest( + gwe, + save_flows=True, + porosity=prsity, + cps=cps, + rhos=rhos, + packagedata=[cpw, rhow, lhv], + pname="EST-2", + filename="{}.est".format(gwename), + ) + + # Instantiate MODFLOW 6 heat transport output control package + flopy.mf6.ModflowGweoc( + gwe, + pname="OC-1", + budget_filerecord="{}.cbc".format(gwename), + temperature_filerecord="{}.ucn".format(gwename), + temperatureprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + printrecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + ) + + # Instantiate energy source loading (ESL) package + # Energy is added such that the temperature change in the cell will be + # +1.0, +2.0, -1.0, and 0.0 degrees Celcius from stress period to stress + # period + esl_spd = { + 0: [ + [(0, 0, 0), Joules_added_for_1degC_rise], + ], + 1: [[(0, 0, 0), 2 * Joules_added_for_1degC_rise]], + 2: [[(0, 0, 0), -1 * Joules_added_for_1degC_rise]], + 3: [], + } + flopy.mf6.ModflowGweesl( + gwe, + stress_period_data=esl_spd, + pname="ESL-1", + filename="{}.esl".format(gwename), + ) + + # Instantiating MODFLOW 6 flow-transport exchange mechanism + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename, + pname="GWFGWE1", + filename="{}.gwfgwe1".format(gwename), + ) + + return sim, None + + +def check_output(idx, test): + print("evaluating results...") + + # read transport results from GWE model + name = cases[idx] + gwename = "gwe-" + name + + fpth = os.path.join(test.workspace, f"{gwename}.ucn") + + try: + # load temperatures + tobj = flopy.utils.HeadFile( + fpth, precision="double", text="TEMPERATURE" + ) + temps = tobj.get_alldata() + except: + assert False, f'could not load temperature data from "{fpth}"' + + # Energy source loading was carefully chosen to result in a +1, + # +2 (for an absolute value of 3 deg C), -1, and 0.0 degree C + # change between stress periods. + known_ans = [1.0, 3.0, 2.0, 2.0] + msg0 = ( + "Grid cell temperatures do not reflect the expected difference " + "in stress period " + ) + for index in np.arange(4): + assert np.isclose(temps[index, 0, 0, 0], known_ans[index]), msg0 + str( + index + ) + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(cases)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t), + ) + test.run() From 5f7f0a445bfeea94defd76489e74115a04a433b6 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 26 Jan 2024 15:15:06 -0800 Subject: [PATCH 31/46] Adding energy source loading (ESL) package --- autotest/test_gwe_vs_gwt.py | 2 +- doc/Common/gwe-eslobs.tex | 1 + doc/Common/gwe-obs.tex | 2 +- doc/mf6io/gwe/esl.tex | 47 +++ doc/mf6io/gwe/gwe.tex | 4 + doc/mf6io/mf6ivar/dfn/gwe-esl.dfn | 205 ++++++++++++ .../mf6ivar/examples/gwe-esl-example-obs.dat | 11 + .../mf6ivar/examples/gwe-esl-example.dat | 13 + doc/mf6io/mf6ivar/md/mf6ivar.md | 23 +- doc/mf6io/mf6ivar/mf6ivar.py | 3 +- doc/mf6io/mf6ivar/tex/appendixA.tex | 6 +- doc/mf6io/mf6ivar/tex/exg-gwegwe-desc.tex | 4 +- doc/mf6io/mf6ivar/tex/exg-gwegwe-options.dat | 4 +- doc/mf6io/mf6ivar/tex/gwe-esl-desc.tex | 49 +++ doc/mf6io/mf6ivar/tex/gwe-esl-dimensions.dat | 3 + doc/mf6io/mf6ivar/tex/gwe-esl-options.dat | 10 + doc/mf6io/mf6ivar/tex/gwe-esl-period.dat | 5 + make/makefile | 1 + msvs/mf6core.vfproj | 1 + src/Model/GroundWaterEnergy/gwe1.f90 | 30 +- src/Model/GroundWaterEnergy/gwe1esl1.f90 | 297 ++++++++++++++++++ src/meson.build | 3 +- 22 files changed, 697 insertions(+), 27 deletions(-) create mode 100644 doc/Common/gwe-eslobs.tex create mode 100644 doc/mf6io/gwe/esl.tex create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-esl.dfn create mode 100644 doc/mf6io/mf6ivar/examples/gwe-esl-example-obs.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-esl-example.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-esl-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-esl-dimensions.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-esl-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-esl-period.dat create mode 100644 src/Model/GroundWaterEnergy/gwe1esl1.f90 diff --git a/autotest/test_gwe_vs_gwt.py b/autotest/test_gwe_vs_gwt.py index d204f60f524..422ce9a65f3 100644 --- a/autotest/test_gwe_vs_gwt.py +++ b/autotest/test_gwe_vs_gwt.py @@ -307,7 +307,7 @@ def build_models(idx, test): gwe, scheme=scheme, filename="{}.adv".format(gwename) ) - # Instantiating MODFLOW 6 heat transport dispersion package + # Instantiating MODFLOW 6 heat transport conduction package if al != 0: flopy.mf6.ModflowGwecnd( gwe, diff --git a/doc/Common/gwe-eslobs.tex b/doc/Common/gwe-eslobs.tex new file mode 100644 index 00000000000..c25662d1dd8 --- /dev/null +++ b/doc/Common/gwe-eslobs.tex @@ -0,0 +1 @@ +ESL & esl & cellid or boundname & -- & Energy source loading rate between the groundwater system and a energy source loading boundary or a group of boundaries. \ No newline at end of file diff --git a/doc/Common/gwe-obs.tex b/doc/Common/gwe-obs.tex index 9113ede12f3..4d3913438b0 100644 --- a/doc/Common/gwe-obs.tex +++ b/doc/Common/gwe-obs.tex @@ -1,2 +1,2 @@ GWE & temperature & cellid & -- & Temperature at a specified cell. \\ -GWE & flow-ja-face & cellid & cellid & Energy flow in dimensions of watts between two adjacent cells. The energy flow rate includes the contributions from both advection (convection) and dispersion (conduction) if those packages are active \ No newline at end of file +GWE & flow-ja-face & cellid & cellid & Energy flow in dimensions of watts between two adjacent cells. The energy flow rate includes the contributions from both advection and conduction (including mechanical dispersion) if those packages are active \ No newline at end of file diff --git a/doc/mf6io/gwe/esl.tex b/doc/mf6io/gwe/esl.tex new file mode 100644 index 00000000000..a32c4b3c497 --- /dev/null +++ b/doc/mf6io/gwe/esl.tex @@ -0,0 +1,47 @@ +Input to the Energy Source Loading (ESL) Package is read from the file that has type ``ESL6'' in the Name File. Any number of SRC Packages can be specified for a single groundwater energy transport model. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\vspace{5mm} + +\noindent \textit{FOR EACH SIMULATION} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-esl-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-esl-dimensions.dat} +\vspace{5mm} +\noindent \textit{FOR ANY STRESS PERIOD} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-esl-period.dat} +\packageperioddescription + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-esl-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-esl-example.dat} + +\vspace{5mm} +\subsubsection{Available observation types} +Energy Source Loading Package observations include the simulated energy source loading rates (\texttt{esl}). The data required for each ESL Package observation type is defined in table~\ref{table:gwe-eslobstype}. The \texttt{esl} observation is equal to the simulated energy source loading rate. Negative and positive values for an observation represent a loss from and gain to the GWE model, respectively. + +\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}} +\caption{Available ESL Package observation types} \tabularnewline + +\hline +\hline +\textbf{Stress Package} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endhead + +\hline +\endfoot + +\input{../Common/gwe-eslobs.tex} +\label{table:gwe-eslobstype} +\end{longtable} + +\vspace{5mm} +\subsubsection{Example Observation Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-esl-example-obs.dat} diff --git a/doc/mf6io/gwe/gwe.tex b/doc/mf6io/gwe/gwe.tex index dd1a8c688f8..7e49294e095 100644 --- a/doc/mf6io/gwe/gwe.tex +++ b/doc/mf6io/gwe/gwe.tex @@ -121,6 +121,10 @@ \subsection{Source and Sink Mixing (SSM) Package} \subsection{Constant Temperature (CTP) Package} \input{gwe/ctp} +\newpage +\subsection{Energy Source Loading (ESL) Package} +\input{gwe/esl} + \newpage \subsection{Flow Model Interface (FMI) Package} \input{gwe/fmi} diff --git a/doc/mf6io/mf6ivar/dfn/gwe-esl.dfn b/doc/mf6io/mf6ivar/dfn/gwe-esl.dfn new file mode 100644 index 00000000000..534db1b0278 --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-esl.dfn @@ -0,0 +1,205 @@ +# --------------------- gwe esl options --------------------- + +block options +name auxiliary +type string +shape (naux) +reader urword +optional true +longname keyword to specify aux variables +description REPLACE auxnames {'{#1}': 'Groundwater Energy Transport'} + +block options +name auxmultname +type string +shape +reader urword +optional true +longname name of auxiliary variable for multiplier +description REPLACE auxmultname {'{#1}': 'energy loading rate'} + +block options +name boundnames +type keyword +shape +reader urword +optional true +longname +description REPLACE boundnames {'{#1}': 'energy source loading'} + +block options +name print_input +type keyword +reader urword +optional true +longname print input to listing file +description REPLACE print_input {'{#1}': 'energy source loading'} + +block options +name print_flows +type keyword +reader urword +optional true +longname print calculated flows to listing file +description REPLACE print_flows {'{#1}': 'energy source loading'} + +block options +name save_flows +type keyword +reader urword +optional true +longname save well flows to budget file +description REPLACE save_flows {'{#1}': 'energy source loading'} + +block options +name ts_filerecord +type record ts6 filein ts6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name ts6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname head keyword +description keyword to specify that record corresponds to a time-series file. + +block options +name filein +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname file keyword +description keyword to specify that an input filename is expected next. + +block options +name ts6_filename +type string +preserve_case true +in_record true +reader urword +optional false +tagged false +longname file name of time series information +description REPLACE timeseriesfile {} + +block options +name obs_filerecord +type record obs6 filein obs6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name obs6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname obs keyword +description keyword to specify that record corresponds to an observations file. + +block options +name obs6_filename +type string +preserve_case true +in_record true +tagged false +reader urword +optional false +longname obs6 input filename +description REPLACE obs6_filename {'{#1}': 'Energy Source Loading'} + +# --------------------- gwe esl dimensions --------------------- + +block dimensions +name maxbound +type integer +reader urword +optional false +longname maximum number of sources +description REPLACE maxbound {'{#1}': 'sources'} + + +# --------------------- gwe esl period --------------------- + +block period +name iper +type integer +block_variable True +in_record true +tagged false +shape +valid +reader urword +optional false +longname stress period number +description REPLACE iper {} + +block period +name stress_period_data +type recarray cellid senerrate aux boundname +shape (maxbound) +reader urword +longname +description + +block period +name cellid +type integer +shape (ncelldim) +tagged false +in_record true +reader urword +longname cell identifier +description REPLACE cellid {} + +block period +name senerrate +type double precision +shape +tagged false +in_record true +reader urword +time_series true +longname energy source loading rate +description is the energy source loading rate. A positive value indicates addition of energy and a negative value indicates removal of energy. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name aux +type double precision +in_record true +tagged false +shape (naux) +reader urword +optional true +time_series true +longname auxiliary variables +description REPLACE aux {'{#1}': 'energy source'} + +block period +name boundname +type string +shape +tagged false +in_record true +reader urword +optional true +longname well name +description REPLACE boundname {'{#1}': 'energy source'} diff --git a/doc/mf6io/mf6ivar/examples/gwe-esl-example-obs.dat b/doc/mf6io/mf6ivar/examples/gwe-esl-example-obs.dat new file mode 100644 index 00000000000..e88ff1991a5 --- /dev/null +++ b/doc/mf6io/mf6ivar/examples/gwe-esl-example-obs.dat @@ -0,0 +1,11 @@ +BEGIN OPTIONS + DIGITS 7 + PRINT_INPUT +END OPTIONS + +BEGIN CONTINUOUS FILEOUT my_model.esl.obs.csv +# obsname obstype ID + esl_7_102_17 ESL 7 102 17 + esl_7_102_17 ESL CW_1 + esources ESL esources +END CONTINUOUS diff --git a/doc/mf6io/mf6ivar/examples/gwe-esl-example.dat b/doc/mf6io/mf6ivar/examples/gwe-esl-example.dat new file mode 100644 index 00000000000..72f42e5d4e8 --- /dev/null +++ b/doc/mf6io/mf6ivar/examples/gwe-esl-example.dat @@ -0,0 +1,13 @@ +BEGIN OPTIONS + PRINT_FLOWS + PRINT_INPUT + SAVE_FLOWS +END OPTIONS + +BEGIN DIMENSIONS + MAXBOUND 1 +END DIMENSIONS + +BEGIN PERIOD 1 + 1 1 1 1500000.0 +END PERIOD diff --git a/doc/mf6io/mf6ivar/md/mf6ivar.md b/doc/mf6io/mf6ivar/md/mf6ivar.md index f8f0b8f2a96..ab412395945 100644 --- a/doc/mf6io/mf6ivar/md/mf6ivar.md +++ b/doc/mf6io/mf6ivar/md/mf6ivar.md @@ -89,8 +89,8 @@ | EXG | GWEGWE | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of exchange flow rates will be printed to the listing file for every stress period in which ``SAVE BUDGET'' is specified in Output Control. | | EXG | GWEGWE | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that cell-by-cell flow terms will be written to the budget file for each model provided that the Output Control for the models are set up with the ``BUDGET SAVE FILE'' option. | | EXG | GWEGWE | OPTIONS | ADV_SCHEME | STRING | scheme used to solve the advection term. Can be upstream, central, or TVD. If not specified, upstream weighting is the default weighting scheme. | -| EXG | GWEGWE | OPTIONS | DSP_XT3D_OFF | KEYWORD | deactivate the xt3d method for the dispersive flux and use the faster and less accurate approximation for this exchange. | -| EXG | GWEGWE | OPTIONS | DSP_XT3D_RHS | KEYWORD | add xt3d dispersion terms to right-hand side, when possible, for this exchange. | +| EXG | GWEGWE | OPTIONS | CND_XT3D_OFF | KEYWORD | deactivate the xt3d method for the dispersive flux and use the faster and less accurate approximation for this exchange. | +| EXG | GWEGWE | OPTIONS | CND_XT3D_RHS | KEYWORD | add xt3d dispersion terms to right-hand side, when possible, for this exchange. | | EXG | GWEGWE | OPTIONS | FILEIN | KEYWORD | keyword to specify that an input filename is expected next. | | EXG | GWEGWE | OPTIONS | MVE6 | KEYWORD | keyword to specify that record corresponds to an energy transport mover file. | | EXG | GWEGWE | OPTIONS | MVE6_FILENAME | STRING | is the file name of the transport mover input file to apply to this exchange. Information for the transport mover are provided in the file provided with these keywords. | @@ -1270,7 +1270,23 @@ | GWE | DISU | CELL2D | YC | DOUBLE PRECISION | is the y-coordinate for the cell center. | | GWE | DISU | CELL2D | NCVERT | INTEGER | is the number of vertices required to define the cell. There may be a different number of vertices for each cell. | | GWE | DISU | CELL2D | ICVERT | INTEGER (NCVERT) | is an array of integer values containing vertex numbers (in the VERTICES block) used to define the cell. Vertices must be listed in clockwise order. | -| GWE | IC | GRIDDATA | STRT | DOUBLE PRECISION (NODES) | is the initial (starting) temperature---that is, the temperature at the beginning of the GWE Model simulation. STRT must be specified for all GWE Model simulations. One value is read for every model cell. | +| GWE | ESL | OPTIONS | AUXILIARY | STRING (NAUX) | defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. | +| GWE | ESL | OPTIONS | AUXMULTNAME | STRING | name of auxiliary variable to be used as multiplier of energy loading rate. | +| GWE | ESL | OPTIONS | BOUNDNAMES | KEYWORD | keyword to indicate that boundary names may be provided with the list of energy source loading cells. | +| GWE | ESL | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of energy source loading information will be written to the listing file immediately after it is read. | +| GWE | ESL | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of energy source loading flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | +| GWE | ESL | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that energy source loading flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | +| GWE | ESL | OPTIONS | TS6 | KEYWORD | keyword to specify that record corresponds to a time-series file. | +| GWE | ESL | OPTIONS | FILEIN | KEYWORD | keyword to specify that an input filename is expected next. | +| GWE | ESL | OPTIONS | TS6_FILENAME | STRING | defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. | +| GWE | ESL | OPTIONS | OBS6 | KEYWORD | keyword to specify that record corresponds to an observations file. | +| GWE | ESL | OPTIONS | OBS6_FILENAME | STRING | name of input file to define observations for the Energy Source Loading package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the Energy Source Loading package. | +| GWE | ESL | DIMENSIONS | MAXBOUND | INTEGER | integer value specifying the maximum number of sources cells that will be specified for use during any stress period. | +| GWE | ESL | PERIOD | IPER | INTEGER | integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. | +| GWE | ESL | PERIOD | CELLID | INTEGER (NCELLDIM) | is the cell identifier, and depends on the type of grid that is used for the simulation. For a structured grid that uses the DIS input file, CELLID is the layer, row, and column. For a grid that uses the DISV input file, CELLID is the layer and CELL2D number. If the model uses the unstructured discretization (DISU) input file, CELLID is the node number for the cell. | +| GWE | ESL | PERIOD | SENERRATE | DOUBLE PRECISION | is the energy source loading rate. A positive value indicates addition of energy and a negative value indicates removal of energy. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | ESL | PERIOD | AUX | DOUBLE PRECISION (NAUX) | represents the values of the auxiliary variables for each energy source. The values of auxiliary variables must be present for each energy source. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | ESL | PERIOD | BOUNDNAME | STRING | name of the energy source cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. | | GWE | EST | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that EST flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | | GWE | EST | OPTIONS | ZERO_ORDER_DECAY | KEYWORD | is a text keyword to indicate that zero-order decay will occur. Use of this keyword requires that DECAY and DECAY\_SORBED (if sorption is active) are specified in the GRIDDATA block. | | GWE | EST | OPTIONS | LATENT_HEAT_VAPORIZATION | KEYWORD | is a text keyword to indicate that cooling associated with evaporation will occur. Use of this keyword requires that LATHEATVAP are specified in the GRIDDATA block. While the EST package does not simulate evaporation, multiple other packages in a GWE simulation may. For example, evaporation may occur from the surface of streams or lakes. Owing to the energy consumed by the change in phase, the latent heat of vaporization is required. | @@ -1281,6 +1297,7 @@ | GWE | EST | PACKAGEDATA | CPW | DOUBLE PRECISION | is the mass-based heat capacity of the simulated fluid. For example, units of J/kg/C may be used (or equivalent). | | GWE | EST | PACKAGEDATA | RHOW | DOUBLE PRECISION | is a user-specified value of the density of water. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. | | GWE | EST | PACKAGEDATA | LATHEATVAP | DOUBLE PRECISION | is the user-specified value for the latent heat of vaporization. For example, if working in SI units, values may be entered as kJ/kg. | +| GWE | IC | GRIDDATA | STRT | DOUBLE PRECISION (NODES) | is the initial (starting) temperature---that is, the temperature at the beginning of the GWE Model simulation. STRT must be specified for all GWE Model simulations. One value is read for every model cell. | | GWE | NAM | OPTIONS | LIST | STRING | is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the ``.lst'' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. | | GWE | NAM | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of all model stress package information will be written to the listing file immediately after it is read. | | GWE | NAM | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of all model package flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | diff --git a/doc/mf6io/mf6ivar/mf6ivar.py b/doc/mf6io/mf6ivar/mf6ivar.py index 509f48c3cda..e8c204d80df 100644 --- a/doc/mf6io/mf6ivar/mf6ivar.py +++ b/doc/mf6io/mf6ivar/mf6ivar.py @@ -745,8 +745,9 @@ def write_appendix(texdir, allblocks): "gwe-dis", "gwe-disv", "gwe-disu", - "gwe-ic", + "gwe-esl", "gwe-est", + "gwe-ic", "gwe-nam", "gwe-oc", "gwe-ssm", diff --git a/doc/mf6io/mf6ivar/tex/appendixA.tex b/doc/mf6io/mf6ivar/tex/appendixA.tex index 870df97d6d4..dc136dd01d5 100644 --- a/doc/mf6io/mf6ivar/tex/appendixA.tex +++ b/doc/mf6io/mf6ivar/tex/appendixA.tex @@ -270,12 +270,16 @@ GWE & DISU & VERTICES & yes \\ GWE & DISU & CELL2D & yes \\ \hline -GWE & IC & GRIDDATA & no \\ +GWE & ESL & OPTIONS & yes \\ +GWE & ESL & DIMENSIONS & yes \\ +GWE & ESL & PERIOD & yes \\ \hline GWE & EST & OPTIONS & yes \\ GWE & EST & GRIDDATA & no \\ GWE & EST & PACKAGEDATA & yes \\ \hline +GWE & IC & GRIDDATA & no \\ +\hline GWE & NAM & OPTIONS & yes \\ GWE & NAM & PACKAGES & yes \\ \hline diff --git a/doc/mf6io/mf6ivar/tex/exg-gwegwe-desc.tex b/doc/mf6io/mf6ivar/tex/exg-gwegwe-desc.tex index 9fb1bf5b633..1aac574010d 100644 --- a/doc/mf6io/mf6ivar/tex/exg-gwegwe-desc.tex +++ b/doc/mf6io/mf6ivar/tex/exg-gwegwe-desc.tex @@ -19,9 +19,9 @@ \item \texttt{adv\_scheme}---scheme used to solve the advection term. Can be upstream, central, or TVD. If not specified, upstream weighting is the default weighting scheme. -\item \texttt{DSP\_XT3D\_OFF}---deactivate the xt3d method for the dispersive flux and use the faster and less accurate approximation for this exchange. +\item \texttt{CND\_XT3D\_OFF}---deactivate the xt3d method for the dispersive flux and use the faster and less accurate approximation for this exchange. -\item \texttt{DSP\_XT3D\_RHS}---add xt3d dispersion terms to right-hand side, when possible, for this exchange. +\item \texttt{CND\_XT3D\_RHS}---add xt3d dispersion terms to right-hand side, when possible, for this exchange. \item \texttt{FILEIN}---keyword to specify that an input filename is expected next. diff --git a/doc/mf6io/mf6ivar/tex/exg-gwegwe-options.dat b/doc/mf6io/mf6ivar/tex/exg-gwegwe-options.dat index 54e7e9d3695..bb69493d8ea 100644 --- a/doc/mf6io/mf6ivar/tex/exg-gwegwe-options.dat +++ b/doc/mf6io/mf6ivar/tex/exg-gwegwe-options.dat @@ -7,8 +7,8 @@ BEGIN OPTIONS [PRINT_FLOWS] [SAVE_FLOWS] [ADV_SCHEME ] - [DSP_XT3D_OFF] - [DSP_XT3D_RHS] + [CND_XT3D_OFF] + [CND_XT3D_RHS] [MVE6 FILEIN ] [OBS6 FILEIN ] END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-esl-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-esl-desc.tex new file mode 100644 index 00000000000..b330d892aaa --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-esl-desc.tex @@ -0,0 +1,49 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{auxiliary}---defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. + +\item \texttt{auxmultname}---name of auxiliary variable to be used as multiplier of energy loading rate. + +\item \texttt{BOUNDNAMES}---keyword to indicate that boundary names may be provided with the list of energy source loading cells. + +\item \texttt{PRINT\_INPUT}---keyword to indicate that the list of energy source loading information will be written to the listing file immediately after it is read. + +\item \texttt{PRINT\_FLOWS}---keyword to indicate that the list of energy source loading flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. + +\item \texttt{SAVE\_FLOWS}---keyword to indicate that energy source loading flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. + +\item \texttt{TS6}---keyword to specify that record corresponds to a time-series file. + +\item \texttt{FILEIN}---keyword to specify that an input filename is expected next. + +\item \texttt{ts6\_filename}---defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. + +\item \texttt{OBS6}---keyword to specify that record corresponds to an observations file. + +\item \texttt{obs6\_filename}---name of input file to define observations for the Energy Source Loading package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the Energy Source Loading package. + +\end{description} +\item \textbf{Block: DIMENSIONS} + +\begin{description} +\item \texttt{maxbound}---integer value specifying the maximum number of sources cells that will be specified for use during any stress period. + +\end{description} +\item \textbf{Block: PERIOD} + +\begin{description} +\item \texttt{iper}---integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. + +\item \texttt{cellid}---is the cell identifier, and depends on the type of grid that is used for the simulation. For a structured grid that uses the DIS input file, CELLID is the layer, row, and column. For a grid that uses the DISV input file, CELLID is the layer and CELL2D number. If the model uses the unstructured discretization (DISU) input file, CELLID is the node number for the cell. + +\item \textcolor{blue}{\texttt{senerrate}---is the energy source loading rate. A positive value indicates addition of energy and a negative value indicates removal of energy. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{aux}---represents the values of the auxiliary variables for each energy source. The values of auxiliary variables must be present for each energy source. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \texttt{boundname}---name of the energy source cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-esl-dimensions.dat b/doc/mf6io/mf6ivar/tex/gwe-esl-dimensions.dat new file mode 100644 index 00000000000..7b4c7bf6ec7 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-esl-dimensions.dat @@ -0,0 +1,3 @@ +BEGIN DIMENSIONS + MAXBOUND +END DIMENSIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-esl-options.dat b/doc/mf6io/mf6ivar/tex/gwe-esl-options.dat new file mode 100644 index 00000000000..0985bd51e40 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-esl-options.dat @@ -0,0 +1,10 @@ +BEGIN OPTIONS + [AUXILIARY ] + [AUXMULTNAME ] + [BOUNDNAMES] + [PRINT_INPUT] + [PRINT_FLOWS] + [SAVE_FLOWS] + [TS6 FILEIN ] + [OBS6 FILEIN ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-esl-period.dat b/doc/mf6io/mf6ivar/tex/gwe-esl-period.dat new file mode 100644 index 00000000000..1d90784538b --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-esl-period.dat @@ -0,0 +1,5 @@ +BEGIN PERIOD + <@senerrate@> [<@aux(naux)@>] [] + <@senerrate@> [<@aux(naux)@>] [] + ... +END PERIOD diff --git a/make/makefile b/make/makefile index 812ce14a500..c94b0e8a471 100644 --- a/make/makefile +++ b/make/makefile @@ -281,6 +281,7 @@ $(OBJDIR)/GhostNode.o \ $(OBJDIR)/gwf3evt8.o \ $(OBJDIR)/gwf3chd8.o \ $(OBJDIR)/gwe1est1.o \ +$(OBJDIR)/gwe1esl1.o \ $(OBJDIR)/gwe1ctp1.o \ $(OBJDIR)/gwe1cnd1.o \ $(OBJDIR)/RouterBase.o \ diff --git a/msvs/mf6core.vfproj b/msvs/mf6core.vfproj index 6bada52f499..f630573d138 100644 --- a/msvs/mf6core.vfproj +++ b/msvs/mf6core.vfproj @@ -148,6 +148,7 @@ + diff --git a/src/Model/GroundWaterEnergy/gwe1.f90 b/src/Model/GroundWaterEnergy/gwe1.f90 index f1ba1249226..9de9bc1a76d 100644 --- a/src/Model/GroundWaterEnergy/gwe1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1.f90 @@ -82,7 +82,7 @@ module GweModule !< integer(I4B), parameter :: GWE_NMULTIPKG = 50 character(len=LENPACKAGETYPE), dimension(GWE_NMULTIPKG) :: GWE_MULTIPKG - data GWE_MULTIPKG/'CTP6 ', 'SRC6 ', 'LKE6 ', 'SFE6 ', ' ', & ! 5 + data GWE_MULTIPKG/'CTP6 ', 'ESL6 ', 'LKE6 ', 'SFE6 ', ' ', & ! 5 &'MWE6 ', 'UZE6 ', 'API6 ', ' ', ' ', & ! 10 &40*' '/ ! 50 @@ -765,7 +765,7 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & use ConstantsModule, only: LINELENGTH use SimModule, only: store_error use GweCtpModule, only: ctp_create - !use GweSrcModule, only: src_create + use GweEslModule, only: esl_create !use GweLkeModule, only: lke_create !use GweSfeModule, only: sfe_create !use GweMweModule, only: mwe_create @@ -788,12 +788,12 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & ! ! -- This part creates the package object select case (filtyp) - case ('CTP6') - call ctp_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & - pakname, this%depvartype, mempath) - !case ('SRC6') - ! call src_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & - ! pakname, this%tsplab, this%gwecommon) + case ('CTP6') + call ctp_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + pakname, this%depvartype, mempath) + case ('ESL6') + call esl_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + pakname, this%gwecommon) !case ('LKE6') ! call lke_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & ! pakname, this%fmi, this%tsplab, this%eqnsclfac, & @@ -961,13 +961,13 @@ subroutine create_gwe_packages(this, indis) ! ! -- create dis package as it is a prerequisite for other packages select case (pkgtype) - case ('EST6') - this%inest = inunit - case ('CND6') - this%incnd = 1 - mempathcnd = mempath - case ('CTP6', 'SRC6', 'LKE6', 'SFE6', & - 'MWE6', 'UZE6', 'API6') + case ('EST6') + this%inest = inunit + case ('CND6') + this%incnd = 1 + mempathcnd = mempath + case ('CTP6', 'ESL6', 'LKE6', 'SFE6', & + 'MWE6', 'UZE6', 'API6') call expandarray(bndpkgs) bndpkgs(size(bndpkgs)) = n case default diff --git a/src/Model/GroundWaterEnergy/gwe1esl1.f90 b/src/Model/GroundWaterEnergy/gwe1esl1.f90 new file mode 100644 index 00000000000..fd5742387ce --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1esl1.f90 @@ -0,0 +1,297 @@ +module GweEslModule + ! + use KindModule, only: DP, I4B + use ConstantsModule, only: DZERO, DEM1, DONE, LENFTYPE + use BndModule, only: BndType + use ObsModule, only: DefaultObsIdProcessor + use TimeSeriesLinkModule, only: TimeSeriesLinkType, & + GetTimeSeriesLinkFromList + use BlockParserModule, only: BlockParserType + use GweInputDataModule, only: GweInputDataType + use MatrixBaseModule + ! + implicit none + ! + private + public :: esl_create + ! + character(len=LENFTYPE) :: ftype = 'ESL' + character(len=16) :: text = ' ESL' + ! + type, extends(BndType) :: GweEslType + + type(GweInputDataType), pointer :: gwecommon => null() !< pointer to shared gwe data used by multiple packages but set in mst + + contains + + procedure :: allocate_scalars => esl_allocate_scalars + procedure :: bnd_cf => esl_cf + procedure :: bnd_fc => esl_fc + procedure :: bnd_da => esl_da + procedure :: define_listlabel + ! -- methods for observations + procedure, public :: bnd_obs_supported => esl_obs_supported + procedure, public :: bnd_df_obs => esl_df_obs + ! -- methods for time series + procedure, public :: bnd_rp_ts => esl_rp_ts + + end type GweEslType + +contains + + !> @brief Create an energy source loading package + !! + !! This subroutine points bndobj to the newly created package + !< + subroutine esl_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, & + gwecommon) + ! -- dummy + class(BndType), pointer :: packobj + integer(I4B), intent(in) :: id + integer(I4B), intent(in) :: ibcnum + integer(I4B), intent(in) :: inunit + integer(I4B), intent(in) :: iout + character(len=*), intent(in) :: namemodel + character(len=*), intent(in) :: pakname + type(GweInputDataType), intent(in), target :: gwecommon !< shared data container for use by multiple GWE packages + ! -- local + type(GweEslType), pointer :: eslobj + ! + ! -- Allocate the object and assign values to object variables + allocate (eslobj) + packobj => eslobj + ! + ! -- Create name and memory path + call packobj%set_names(ibcnum, namemodel, pakname, ftype) + packobj%text = text + ! + ! -- Allocate scalars + call eslobj%allocate_scalars() + ! + ! -- Initialize package + call packobj%pack_initialize() + ! + packobj%inunit = inunit + packobj%iout = iout + packobj%id = id + packobj%ibcnum = ibcnum + packobj%ncolbnd = 1 + packobj%iscloc = 1 + ! + ! -- Store pointer to shared data module for accessing cpw, rhow + ! for the budget calculations, and for accessing the latent heat of + ! vaporization for evaporative cooling. + eslobj%gwecommon => gwecommon + ! + ! -- Return + return + end subroutine esl_create + + !> @brief Deallocate memory + !< + subroutine esl_da(this) + ! -- modules + use MemoryManagerModule, only: mem_deallocate + ! -- dummy + class(GweEslType) :: this + ! + ! -- Deallocate parent package + call this%BndType%bnd_da() + ! + ! -- Return + return + end subroutine esl_da + + !> @brief Allocate scalars + !! + !! Allocate scalars specific to this energy source loading package + !< + subroutine esl_allocate_scalars(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweEslType) :: this + ! + ! -- call standard BndType allocate scalars + call this%BndType%allocate_scalars() + ! + ! -- allocate the object and assign values to object variables + ! + ! -- Set values + ! + ! -- Return + return + end subroutine esl_allocate_scalars + + !> @brief Formulate the HCOF and RHS terms + !! + !! This subroutine: + !! - calculates hcof and rhs terms + !! - skip if no sources + !< + subroutine esl_cf(this) + ! -- dummy + class(GweEslType) :: this + ! -- local + integer(I4B) :: i, node + real(DP) :: q + logical :: lrm + ! + ! -- Return if no sources + if (this%nbound == 0) return + ! + ! -- Calculate hcof and rhs for each source entry + do i = 1, this%nbound + node = this%nodelist(i) + this%hcof(i) = DZERO + if (this%ibound(node) <= 0) then + this%rhs(i) = DZERO + cycle + end if + q = this%bound(1, i) + this%rhs(i) = -q + end do + ! + ! -- Return + return + end subroutine esl_cf + + !> @brief Add matrix terms related to specified energy source loading + !! + !! Copy rhs and hcof into solution rhs and amat + !< + subroutine esl_fc(this, rhs, ia, idxglo, matrix_sln) + ! -- dummy + class(GweEslType) :: this + real(DP), dimension(:), intent(inout) :: rhs + integer(I4B), dimension(:), intent(in) :: ia + integer(I4B), dimension(:), intent(in) :: idxglo + class(MatrixBaseType), pointer :: matrix_sln + ! -- local + integer(I4B) :: i, n, ipos + ! + ! -- pakmvrobj fc + if (this%imover == 1) then + call this%pakmvrobj%fc() + end if + ! + ! -- Copy package rhs and hcof into solution rhs and amat + do i = 1, this%nbound + n = this%nodelist(i) + rhs(n) = rhs(n) + this%rhs(i) + ipos = ia(n) + call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(i)) + ! + ! -- If mover is active and mass is being withdrawn, + ! store available mass (as positive value). + if (this%imover == 1 .and. this%rhs(i) > DZERO) then + call this%pakmvrobj%accumulate_qformvr(i, this%rhs(i)) + end if + end do + ! + ! -- Return + return + end subroutine esl_fc + + !> @brief Define list labels + !! + !! Define the list heading that is written to iout when + !! PRINT_INPUT option is used. + !< + subroutine define_listlabel(this) + ! -- dummy + class(GweEslType), intent(inout) :: this + ! + ! -- Create the header list label + this%listlabel = trim(this%filtyp)//' NO.' + if (this%dis%ndim == 3) then + write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER' + write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW' + write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL' + elseif (this%dis%ndim == 2) then + write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER' + write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D' + else + write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE' + end if + write (this%listlabel, '(a, a16)') trim(this%listlabel), 'STRESS RATE' + if (this%inamedbound == 1) then + write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME' + end if + ! + ! -- Return + return + end subroutine define_listlabel + + ! -- Procedures related to observations + + !> @brief Support function for specified energy source loading observations + !! + !! This function: + !! - returns true because ESL package supports observations. + !! - overrides BndType%bnd_obs_supported() + !< + logical function esl_obs_supported(this) + implicit none + ! -- dummy + class(GweEslType) :: this + ! + esl_obs_supported = .true. + ! + ! -- Return + return + end function esl_obs_supported + + !> @brief Define observations + !! + !! This subroutine: + !! - stores observation types supported by ESL package. + !! - overrides BndType%bnd_df_obs + !< + subroutine esl_df_obs(this) + implicit none + ! -- dummy + class(GweEslType) :: this + ! -- local + integer(I4B) :: indx + ! + call this%obs%StoreObsType('esl', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => DefaultObsIdProcessor + ! + ! -- Store obs type and assign procedure pointer + ! for to-mvr observation type. + call this%obs%StoreObsType('to-mvr', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => DefaultObsIdProcessor + ! + ! -- Return + return + end subroutine esl_df_obs + + !> @brief Procedure related to time series + !! + !! Assign tsLink%Text appropriately for all time series in use by package. + !! In the ESL package only the SENERRATE variable can be controlled by time + !! series. + !< + subroutine esl_rp_ts(this) + ! -- dummy + class(GweEslType), intent(inout) :: this + ! -- local + integer(I4B) :: i, nlinks + type(TimeSeriesLinkType), pointer :: tslink => null() + ! + nlinks = this%TsManager%boundtslinks%Count() + do i = 1, nlinks + tslink => GetTimeSeriesLinkFromList(this%TsManager%boundtslinks, i) + if (associated(tslink)) then + if (tslink%JCol == 1) then + tslink%Text = 'SMASSRATE' + end if + end if + end do + ! + ! -- Return + return + end subroutine esl_rp_ts + +end module GweEslModule diff --git a/src/meson.build b/src/meson.build index 124cfefedbc..2227eb67345 100644 --- a/src/meson.build +++ b/src/meson.build @@ -66,9 +66,10 @@ modflow_sources = files( 'Model' / 'GroundWaterEnergy' / 'gwe1dis1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1disu1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1disv1idm.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1esl1.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1est1.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1ic1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1idm.f90', - 'Model' / 'GroundWaterEnergy' / 'gwe1est1.f90', 'Model' / 'GroundWaterFlow' / 'gwf3.f90', 'Model' / 'GroundWaterFlow' / 'gwf3api8.f90', 'Model' / 'GroundWaterFlow' / 'gwf3buy8.f90', From d0c0056b00db5c97c3b42a94865467edc374330a Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 26 Jan 2024 15:50:23 -0800 Subject: [PATCH 32/46] remove unused variable --- src/Model/GroundWaterEnergy/gwe1esl1.f90 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Model/GroundWaterEnergy/gwe1esl1.f90 b/src/Model/GroundWaterEnergy/gwe1esl1.f90 index fd5742387ce..6efb5db51d6 100644 --- a/src/Model/GroundWaterEnergy/gwe1esl1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1esl1.f90 @@ -135,7 +135,6 @@ subroutine esl_cf(this) ! -- local integer(I4B) :: i, node real(DP) :: q - logical :: lrm ! ! -- Return if no sources if (this%nbound == 0) return From cf51996a118c464ce313262b72a4f8e2e11a12ff Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 26 Jan 2024 15:58:59 -0800 Subject: [PATCH 33/46] fprettify --- src/Model/GroundWaterEnergy/gwe1.f90 | 26 ++++++++++++------------ src/Model/GroundWaterEnergy/gwe1esl1.f90 | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Model/GroundWaterEnergy/gwe1.f90 b/src/Model/GroundWaterEnergy/gwe1.f90 index 9de9bc1a76d..11d2e8a25a2 100644 --- a/src/Model/GroundWaterEnergy/gwe1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1.f90 @@ -788,12 +788,12 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & ! ! -- This part creates the package object select case (filtyp) - case ('CTP6') - call ctp_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & - pakname, this%depvartype, mempath) - case ('ESL6') - call esl_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & - pakname, this%gwecommon) + case ('CTP6') + call ctp_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + pakname, this%depvartype, mempath) + case ('ESL6') + call esl_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + pakname, this%gwecommon) !case ('LKE6') ! call lke_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & ! pakname, this%fmi, this%tsplab, this%eqnsclfac, & @@ -961,13 +961,13 @@ subroutine create_gwe_packages(this, indis) ! ! -- create dis package as it is a prerequisite for other packages select case (pkgtype) - case ('EST6') - this%inest = inunit - case ('CND6') - this%incnd = 1 - mempathcnd = mempath - case ('CTP6', 'ESL6', 'LKE6', 'SFE6', & - 'MWE6', 'UZE6', 'API6') + case ('EST6') + this%inest = inunit + case ('CND6') + this%incnd = 1 + mempathcnd = mempath + case ('CTP6', 'ESL6', 'LKE6', 'SFE6', & + 'MWE6', 'UZE6', 'API6') call expandarray(bndpkgs) bndpkgs(size(bndpkgs)) = n case default diff --git a/src/Model/GroundWaterEnergy/gwe1esl1.f90 b/src/Model/GroundWaterEnergy/gwe1esl1.f90 index 6efb5db51d6..dd18988ca72 100644 --- a/src/Model/GroundWaterEnergy/gwe1esl1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1esl1.f90 @@ -34,7 +34,7 @@ module GweEslModule procedure, public :: bnd_df_obs => esl_df_obs ! -- methods for time series procedure, public :: bnd_rp_ts => esl_rp_ts - + end type GweEslType contains @@ -223,7 +223,7 @@ subroutine define_listlabel(this) end subroutine define_listlabel ! -- Procedures related to observations - + !> @brief Support function for specified energy source loading observations !! !! This function: From b981a4f8f990945b9feb9fbf14a5b463727c6422 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Mon, 29 Jan 2024 09:43:23 -0800 Subject: [PATCH 34/46] Add another ESL autotest --- autotest/test_gwe_esl01.py | 4 +- autotest/test_gwe_esl02.py | 366 +++++++++++++++++++++++++++++++++++++ 2 files changed, 368 insertions(+), 2 deletions(-) create mode 100644 autotest/test_gwe_esl02.py diff --git a/autotest/test_gwe_esl01.py b/autotest/test_gwe_esl01.py index 4b58c30d001..56370d8f627 100644 --- a/autotest/test_gwe_esl01.py +++ b/autotest/test_gwe_esl01.py @@ -33,7 +33,7 @@ # scheme = "TVD" cases = [ - "warmup", # 2-cell model, horizontally connected with tops and bots aligned + "warmup", # 1-cell "bathtub" model with easily calculate-able answers ] # Model units @@ -91,7 +91,7 @@ delr * delc * (top - botm[0]) * (1 - prsity) * cps * rhos ) -# ### Create MODFLOW 6 GWE MT3DMS Example 1 Boundary Conditions +# ### Create MODFLOW 6 GWE # # No GWF, only Heat conduction simulated diff --git a/autotest/test_gwe_esl02.py b/autotest/test_gwe_esl02.py new file mode 100644 index 00000000000..05ded2783cc --- /dev/null +++ b/autotest/test_gwe_esl02.py @@ -0,0 +1,366 @@ +""" +A "bathtub" test problem for GWE - bathtub meaning a single cell model +(and actually, the bathtub is dry in this example) + +Test the energy source loading package by warming a single cell with a known +amount of energy input. + + Model configuration + + *: Represents energy source loading + ~: Represents conduction into neighboring cell + + +---------+---------+ + | |~ | + | * |~ | + | |~ | + +---------+---------+ + +""" + +# Imports + +import os +import numpy as np +import pytest +import flopy + +from framework import TestFramework + + +# Base simulation and model name and workspace + +scheme = "UPSTREAM" +# scheme = "TVD" + +cases = [ + "2cell_cnd", # 2-cell model, horizontally connected with tops and bottoms aligned + "3cell_cnd", +] +ncol = [2, 3] + +# Model units +length_units = "meters" +time_units = "days" + +# Parameterization + +nrow = nlay = 1 +top = 1.0 +botm = [0.0] +delr = 1.0 # Column width ($m$) +delc = 1.0 # Row width ($m$) +k11 = 1.0 # Horizontal hydraulic conductivity ($m/d$) +ss = 1e-6 # Specific storage +sy = 0.10 # Specific Yield +prsity = sy # Porosity +steady = {0: False} +transient = {0: True} +strthd = strt_temp1 = 0.0 + +# Set some static model parameter values + +k33 = k11 # Vertical hydraulic conductivity ($m/d$) +idomain = 1 # All cells included in the simulation +iconvert = 1 # All cells are convertible +icelltype = 1 # Cell conversion type (>0: unconfined) + +# Set some static transport related model parameter values +dispersivity = 0.0 # dispersion (remember, 1D model) + +# GWE related parameters +rhow = 1000.0 +cpw = 4183.0 +lhv = 2454.0 +cps = 760.0 +rhos = 1500.0 + +# Set solver parameter values (and related) +nouter, ninner = 100, 300 +hclose, rclose, relax = 1e-10, 1e-10, 1.0 +ttsmult = 1.0 + +# Set up temporal data used by TDIS file +perlen = [1, 1e5] # Simulation time ($days$) +nstp = [1, 100] # 10 day transient time steps +ttsmult = 1.0 +tdis_rc = [] +for i in np.arange(len(perlen)): + tdis_rc.append((perlen[i], nstp[i], ttsmult)) + + +# ### Create MODFLOW 6 GWE model +# +# No GWF, only heat conduction simulated between two cells with energy supplied +# by energy source loading package + + +def build_models(idx, test): + # Base MF6 GWF model type + ws = test.workspace + name = cases[idx] + + print("Building MF6 model...()".format(name)) + + # generate names for each model + gwfname = "gwf-" + name + gwename = "gwe-" + name + + sim = flopy.mf6.MFSimulation( + sim_name=name, sim_ws=ws, exe_name="mf6", version="mf6" + ) + + # Instantiating MODFLOW 6 time discretization + flopy.mf6.ModflowTdis( + sim, nper=len(perlen), perioddata=tdis_rc, time_units=time_units + ) + + # Instantiating MODFLOW 6 groundwater flow model + gwf = flopy.mf6.ModflowGwf( + sim, + modelname=gwfname, + save_flows=True, + model_nam_file="{}.nam".format(gwfname), + ) + + # Instantiating MODFLOW 6 solver for flow model + imsgwf = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="CG", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwfname), + ) + sim.register_ims_package(imsgwf, [gwfname]) + + # Instantiating MODFLOW 6 discretization package + flopy.mf6.ModflowGwfdis( + gwf, + length_units=length_units, + nlay=nlay, + nrow=nrow, + ncol=ncol[idx], + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=1, + pname="DIS-1", + filename="{}.dis".format(gwfname), + ) + + # Instantiating MODFLOW 6 storage package + flopy.mf6.ModflowGwfsto( + gwf, + ss=ss, + sy=sy, + iconvert=iconvert, + steady_state=steady, + transient=transient, + pname="STO", + filename="{}.sto".format(gwfname), + ) + + # Instantiating MODFLOW 6 node-property flow package + flopy.mf6.ModflowGwfnpf( + gwf, + save_flows=True, + icelltype=icelltype, + k=k11, + k33=k33, + save_specific_discharge=True, + pname="NPF-1", + filename="{}.npf".format(gwfname), + ) + + # Instantiating MODFLOW 6 initial conditions package for flow model + flopy.mf6.ModflowGwfic( + gwf, + strt=strthd, + pname="IC-HD", + filename="{}.ic".format(gwfname), + ) + + # Instantiating MODFLOW 6 output control package for flow model + flopy.mf6.ModflowGwfoc( + gwf, + pname="OC-1", + head_filerecord="{}.hds".format(gwfname), + budget_filerecord="{}.cbc".format(gwfname), + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "LAST"), ("BUDGET", "LAST")], + printrecord=[("HEAD", "LAST"), ("BUDGET", "LAST")], + ) + + # ---------------------------------- + # Instantiating MODFLOW 6 GWE model + # ---------------------------------- + gwe = flopy.mf6.ModflowGwe( + sim, modelname=gwename, model_nam_file="{}.nam".format(gwename) + ) + gwe.name_file.save_flows = True + + imsgwe = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwename), + ) + sim.register_ims_package(imsgwe, [gwe.name]) + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwedis( + gwe, + nogrb=True, + nlay=nlay, + nrow=nrow, + ncol=ncol[idx], + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=1, + pname="DIS-1", + filename="{}.dis".format(gwename), + ) + + # Instantiating MODFLOW 6 transport initial concentrations + flopy.mf6.ModflowGweic( + gwe, strt=strt_temp1, pname="IC-1", filename="{}.ic".format(gwename) + ) + + # Instantiating MODFLOW 6 transport advection package + flopy.mf6.ModflowGweadv( + gwe, scheme=scheme, pname="ADV-1", filename="{}.adv".format(gwename) + ) + + # Instantiating MODFLOW 6 transport dispersion package + flopy.mf6.ModflowGwecnd( + gwe, + xt3d_off=True, + alh=dispersivity, + ath1=dispersivity, + ktw=0.5918 * 86400, + kts=0.2700 * 86400, + pname="CND-1", + filename="{}.cnd".format(gwename), + ) + + # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) + flopy.mf6.ModflowGweest( + gwe, + save_flows=True, + porosity=prsity, + cps=cps, + rhos=rhos, + packagedata=[cpw, rhow, lhv], + pname="EST-1", + filename="{}.est".format(gwename), + ) + + # Instantiate MODFLOW 6 heat transport output control package + flopy.mf6.ModflowGweoc( + gwe, + pname="OC-1", + budget_filerecord="{}.cbc".format(gwename), + temperature_filerecord="{}.ucn".format(gwename), + temperatureprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + printrecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + ) + + # Instantiate energy source loading (ESL) package + # Energy is added such that the temperature change in the cell will be + # +1.0, +2.0, -1.0, and 0.0 degrees Celcius from stress period to stress + # period + factor = ncol[idx] + Specified_joules_added = ( + factor * delr * delc * (top - botm[0]) * (1 - prsity) * cps * rhos + ) + esl_spd = { + 0: [ + [(0, 0, 0), Specified_joules_added], + ], + 1: [], + } + flopy.mf6.ModflowGweesl( + gwe, + stress_period_data=esl_spd, + pname="ESL-1", + filename="{}.esl".format(gwename), + ) + + # Instantiating MODFLOW 6 flow-transport exchange mechanism + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename, + pname="GWFGWE1", + filename="{}.gwfgwe1".format(gwename), + ) + + return sim, None + + +def check_output(idx, test): + print("evaluating results...") + + # read transport results from GWE model + name = cases[idx] + gwename = "gwe-" + name + + fpth = os.path.join(test.workspace, f"{gwename}.ucn") + + try: + # load temperatures + tobj = flopy.utils.HeadFile( + fpth, precision="double", text="TEMPERATURE" + ) + temps = tobj.get_alldata() + except: + assert False, f'could not load temperature data from "{fpth}"' + + # Energy source loading was crafted such that each cell in + # the simulation would rise by 1 degree at the end of the simulation. + msg0 = ( + "Grid cell temperatures do not reflect the expected difference" + "in stress period " + ) + ans = ncol[idx] + assert np.isclose(np.sum(temps[-1]), ans), msg0 + str(index) + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(cases)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t), + ) + test.run() From 0612af8bbd78526d5d741ddc5728ed930e29c93e Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Tue, 30 Jan 2024 14:34:11 -0800 Subject: [PATCH 35/46] Adding another autotest that compares gwe to three different analytical solutions from Carslaw & Jaeger (1947) --- autotest/test_gwe_esl_analyt_sln.py | 561 ++++++++++++++++++++++++++++ 1 file changed, 561 insertions(+) create mode 100644 autotest/test_gwe_esl_analyt_sln.py diff --git a/autotest/test_gwe_esl_analyt_sln.py b/autotest/test_gwe_esl_analyt_sln.py new file mode 100644 index 00000000000..8d39c6416a3 --- /dev/null +++ b/autotest/test_gwe_esl_analyt_sln.py @@ -0,0 +1,561 @@ +""" + An analytical solution provided by Carslaw & Jaeger (1947) and discussed in + accompanying Techniques & Methods report. + + Energy is added to the right hand side boundary using the energy source loading + (ESL) package. Basic model set up is below, with a slab of unit thickness + (1.0 m) that is 100 m "deep" with energy being loaded on right side. + Temperature will begin to rise on the right and propagate to the left. There are + no sinks in this first example. + + Section 43, case i: + ------------------- + + | <-------------------------- 10 m --------------------------> | + + +------------------------------------------------------------------+ + | Initial temperature = T_0 | <-- *ESL + +------------------------------------------------------------------+ + ^ * ESL: Energy Source Loading Boundary + | + No heat-flow boundary + + + Section 43, case ii: + -------------------- + + +------------------------------------------------------------------+ + | Initial temperature = 0.0 | <-- *ESL + +------------------------------------------------------------------+ + ^ + | + Specified temperature boundary, T_0 + + + Section 43, case iii: + --------------------- + + +------------------------------------------------------------------+ +CTP -> | | <- CTP = T_0 + = T_0 +------------------------------------------------------------------+ + \-------------------------------------------------------------/ + | + Uniform, constant heat production throughout the slab + + + Specified temperature boundary, T_0 + +""" + +import os +import math +import pytest +import flopy +import numpy as np +import matplotlib.pyplot as plt + +from framework import TestFramework + +# Parameters that vary by scenario +cases = ["esl_casei", "esl_caseii", "esl_caseiii"] +perlen = {0: [100, 900], 1: [100, 9900], 2: [100, 900]} +nstp = [100, 900] +tsmult = [ + [1.0, 1.0], + [1.0, 1.0], + [1.0, 1.0], +] + +T_0 = 0.0 # Initial temperature in all scenarios. +# Additionally serves as the CTP bnd temperature in scenarios ii and iii + +xt3d = [True] + +# Parameters for tdis package + +# Model parameters + +# Slab thickness +el = 10.0 # meters + +# Cell dimensions +nlay, nrow, ncol = 1, 1, 1000 +delc = delz = 1.0 +delr = el / ncol + +top = 1.0 +laytyp = 1 +strt = 0.0 +ss = 0.0 +sy = 0.1 +botm = [0.0] +strt = 0.0 +hnoflo = 1e30 +hdry = -1e30 +hk = 1.0 +alh = 0.0 +alv = 0.0 +ath1 = 0.0 +atv = 0.0 +lhv = 2454.0 + +# Solver parameters +nouter, ninner = 100, 300 +hclose, rclose, relax = 1e-6, 1e-6, 1.0 + +# Boundary condition (same for all scenarios +chd_perdat = {0: [[(0, 0, 0), 0.0000000], [(0, 0, ncol - 1), 0.0000000]]} + +# The following lists the parameter used in generating an analytical solution +# for comparing the MF6 solution to. + +# Density of the solids +rhos = 2700.0 # kg/m^3 + +# Density of water +rhow = 1000.0 # kg/m^3 + +# Heat capacity of the solids +Cps = 703.7 # J / (kg * C) + +# Heat capacity of water +Cpw = 4183.0 # J / (kg * C) + +# "Bulk" thermal conductivity +# For this problem, K_t_bulk represents the thermal conductivity of the +# solid material only since the problem represents a dry slab +Kts = 0.2700 * 86400 # * 1e8 # J / (day * m * C) +Ktw = 0.5918 * 86400 # J / (day * m * C) + +# Amount of saturation in a cell (cells are dry in this example) +Sw = 0.0 # dimensionless + +# Define porosity +theta = 0.1 # dimensionless + +# Equation 4-6 (for now anyway) +K_t_bulk = Sw * theta * Ktw + (1 - theta) * Kts + +# Eqn 7-4: Bulk specific heat on a per volume basis +rho_C_bulk = Sw * theta * rhow * Cpw + (1 - theta) * rhos * Cps + +# Eqn 7-3: Bulk thermal diffusivity +D = K_t_bulk / rho_C_bulk + +# Energy input to boundary (q_x term in the documentation) +def calc_ener_input(primer_val): + ener_add_rate = delr * delc * delz * rho_C_bulk * primer_val + return ener_add_rate + + +# Define function to solve analytical solution +# Function names derive from equation numbers in Techniques and Methdos + + +def build_models(idx, test, ener_input): + + name = cases[idx] + + # Build MODFLOW 6 files + ws = test.workspace + sim = flopy.mf6.MFSimulation( + sim_name=name, version="mf6", exe_name="mf6", sim_ws=ws + ) + + # Create tdis package + tdis_rc = [] + for i in range(len(perlen[idx])): + tdis_rc.append((perlen[idx][i], nstp[i], tsmult[idx][i])) + + flopy.mf6.ModflowTdis( + sim, time_units="DAYS", nper=len(perlen[idx]), perioddata=tdis_rc + ) + + # Create GWF model + gwfname = "gwf_" + name + gwf = flopy.mf6.MFModel( + sim, + model_type="gwf6", + modelname=gwfname, + model_nam_file=f"{gwfname}.nam", + ) + gwf.name_file.save_flows = True + + # Create iterative model solution and register the gwf model with it + imsgwf = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="CG", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename=f"{gwfname}.ims", + ) + sim.register_ims_package(imsgwf, [gwf.name]) + + # Discretization package + flopy.mf6.ModflowGwfdis( + gwf, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=np.ones((nlay, nrow, ncol), dtype=int), + pname="DIS-GWF", + filename=f"{gwfname}.dis", + ) + + # Initial conditions + flopy.mf6.ModflowGwfic( + gwf, strt=strt, pname="IC-HD", filename=f"{gwfname}.ic" + ) + + # Node property flow + flopy.mf6.ModflowGwfnpf( + gwf, + save_specific_discharge=True, + icelltype=laytyp, + k=hk, + k33=hk, + filename=f"{gwfname}.npf", + ) + + # Instantiating MODFLOW 6 storage package + flopy.mf6.ModflowGwfsto( + gwf, + ss=ss, + sy=sy, + iconvert=1, + steady_state=False, + transient=True, + pname="STO", + filename="{}.sto".format(gwfname), + ) + + # Constant head files + chd = None + # chd = flopy.mf6.ModflowGwfchd( + # gwf, + # maxbound=len(chd_perdat[0]), + # stress_period_data=chd_perdat, + # save_flows=False, + # pname="CHD-1", + # filename=f"{gwfname}.chd" + # ) + + # Output control + flopy.mf6.ModflowGwfoc( + gwf, + budget_filerecord=f"{gwfname}.cbc", + head_filerecord=f"{gwfname}.hds", + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "LAST"), ("BUDGET", "LAST")], + printrecord=[("HEAD", "LAST"), ("BUDGET", "LAST")], + ) + + # ----------------- + # Create GWE model + # ----------------- + + gwename = "gwe_" + name + gwe = flopy.mf6.MFModel( + sim, + model_type="gwe6", + modelname=gwename, + model_nam_file=f"{gwename}.nam", + ) + gwe.name_file.save_flows = True + + # Create iterative model solution and register the gwt model with it + imsgwe = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename=f"{gwename}.ims", + ) + sim.register_ims_package(imsgwe, [gwe.name]) + + flopy.mf6.ModflowGwedis( + gwe, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=1, + filename=f"{gwename}.dis", + ) + + # Initial conditions + flopy.mf6.ModflowGweic( + gwe, strt=T_0, pname="IC-1", filename=f"{gwename}.ic" + ) + + # Advection + flopy.mf6.ModflowGweadv( + gwe, scheme="UPSTREAM", pname="ADV-E", filename=f"{gwename}.adv" + ) + + # Heat conduction + flopy.mf6.ModflowGwecnd( + gwe, + alh=alh, + alv=alv, + ath1=ath1, + atv=atv, + ktw=Ktw, + kts=Kts, + pname="CND-1", + filename="{}.cnd".format(gwename), + ) + + flopy.mf6.ModflowGweest( + gwe, + porosity=theta, + cps=Cps, + rhos=rhos, + packagedata=[Cpw, rhow, lhv], + pname="EST-1", + filename="{}.est".format(gwename), + ) + + # Constant temperature + # Note: Implementation of the CTP boundary depends on which analytical sln is in view + # See notes at top of script regarding scenarios + if idx > 0: + if idx == 1: + ctp = {0: [[(0, 0, 0), T_0]]} + elif idx == 2: + ctp = {0: [[(0, 0, 0), T_0], [(0, 0, ncol - 1), T_0]]} + flopy.mf6.ModflowGwectp( + gwe, + maxbound=len(ctp), + stress_period_data=ctp, + save_flows=True, + pname="CTP-1", + filename=f"{gwename}.ctp", + ) + + # Instantiate energy source loading (ESL) package + if idx < 2: + esrc = {0: [[(0, 0, ncol - 1), ener_input]]} + + elif idx == 2: + esrcs = [] + for j in np.arange(ncol): + esrcs.append([(0, 0, j), ener_input]) + esrc = {0: esrcs} + + flopy.mf6.ModflowGweesl( + gwe, + maxbound=len(esrc[0]), + stress_period_data=esrc, + save_flows=False, + pname="ESL-1", + filename=f"{gwename}.esl", + ) + + # Sources + if chd is not None: + flopy.mf6.ModflowGwessm( + gwe, sources=[[]], pname="SSM-E", filename=f"{gwename}.ssm" + ) + + # Output control + flopy.mf6.ModflowGweoc( + gwe, + budget_filerecord=f"{gwename}.cbc", + temperature_filerecord=f"{gwename}.ucn", + temperatureprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + printrecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + ) + + # GWF GWE exchange + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename, + filename=f"{name}.gwfgwe", + ) + + return sim, None + + +def eq7_24(x, t, l, D, T_0, ener_add_rate): + # Compute corresponding x_hat term + x_hat = x / l # Dimensionless distance + + # Compute corresponding t_hat term + t_hat = D * t / l ** 2 # Dimensionless time + + # Solve equation 7-24 + term1 = (1 / 2) * (x_hat ** 2 - 1 / 3) + summation_terms = [ + ((-1) ** n) + / n ** 2 + * math.exp(-1 * n ** 2 * math.pi ** 2 * t_hat) + * math.cos(n * math.pi * x_hat) + for n in np.arange(1, 1000) + ] + term2 = 2 / (math.pi ** 2) * np.sum(summation_terms) + T = T_0 + ener_add_rate * l / K_t_bulk * (t_hat + term1 - term2) + + return T + + +def eq7_25(x, t, l, D, T_0, ener_add_rate): + # Compute corresponding x_hat term + x_hat = x / l # Dimensionless distance + + # Compute corresponding t_hat term + t_hat = D * t / l ** 2 # Dimensionless time + + # Solve equation 7-25 + summation_terms = [ + ((-1) ** n) + / (2 * n + 1) ** 2 + * math.exp(-1 * (2 * n + 1) ** 2 * math.pi ** 2 * t_hat / 4) + * math.sin((2 * n + 1) * math.pi * x_hat / 2) + for n in np.arange(0, 1000) + ] + term1 = (8 / math.pi ** 2) * np.sum(summation_terms) + + T = T_0 + ener_add_rate * l / K_t_bulk * (x_hat - term1) + + return T + + +def eq7_26(x, t, el, D, T_0, ener_add_rate): + # Compute corresponding x_hat term + x_hat = x / el # Dimensionless distance + + # Compute corresponding t_hat term + t_hat = D * t / el ** 2 # Dimensionless time + + # Solve equation 7-26 + term1 = x_hat * (1 - x_hat) + summation_terms = [ + 1 + / (2 * n + 1) ** 3 + * math.exp(-1 * (2 * n + 1) ** 2 * math.pi ** 2 * t_hat) + * math.sin((2 * n + 1) * math.pi * x_hat) + for n in np.arange(0, 1000) + ] + term2 = (8 / math.pi ** 3) * np.sum(summation_terms) + T = T_0 + 0.5 * ener_add_rate * el ** 2 / K_t_bulk * (term1 - term2) + + return T + + +def check_output(idx, test, ener_input): + name = test.name + gwename = "gwe_" + name + + fpth = os.path.join(test.workspace, f"{gwename}.ucn") + tobj = flopy.utils.HeadFile(fpth, precision="double", text="TEMPERATURE") + sim_temps = tobj.get_alldata() + + # Compare simulated output to analytical solutions (scenario dependent) + if idx < 2: + t_accumulate = 0.0 + area_input = delc * delz + ener_flux = ener_input / area_input + + for sp, t in enumerate(perlen[idx]): + # Time to solution + t_accumulate += t # days + + # Iterate over x which represents the cell centroid locations for which + # analytical solution is desired (cell centroid locations) + cell_centroids = [] + analytical_temps = [] + for x in np.arange(delr / 2, el + (delr / 2), delr): + cell_centroids.append(x) + if idx == 0: + T = eq7_24(x, t_accumulate, el, D, T_0, ener_flux) + elif idx == 1: + T = eq7_25(x, t_accumulate, el, D, T_0, ener_flux) + analytical_temps.append(T) + + analytical_temps = np.array(analytical_temps) + assert np.allclose( + analytical_temps, sim_temps[sp, 0, 0, :], atol=0.005 + ), "simulated solution is whacked" + # plt.plot(cell_centroids, analytical_temps, "r-", label="Analytical Solution") + # plt.plot(cell_centroids, sim_temps[sp, 0, 0, :], "b--", label="GWE") + # plt.axhline(0.0, color='black') + # plt.legend() + # plt.show() + + elif idx == 2: + + t_accumulate = 0.0 + ener_src = ener_input / (delr * delc * delz) + + for sp, t in enumerate(perlen[idx]): + # Time to solution + t_accumulate += t # days + + analytical_temps = [] + cell_centroids = [] + for x in np.arange(delr / 2, el + (delr / 2), delr): + cell_centroids.append(x) + T = eq7_26(x, t_accumulate, el - (delr * 2), D, T_0, ener_src) + analytical_temps.append(T) + + analytical_temps = np.array(analytical_temps) + if sp == 0: + atol = 0.16 + else: + atol = 0.47 + + assert np.allclose( + analytical_temps, sim_temps[sp, 0, 0, :], atol=atol + ), "simulated solution is whacked" + + # plt.plot(cell_centroids, analytical_temps, "r-", label="Analytical Solution") + # plt.plot(cell_centroids, sim_temps[sp, 0, 0, :], "b--", label="GWE") + # plt.axhline(0.0, color='black') + # plt.legend() + # plt.show() + + +# - No need to change any code below +@pytest.mark.parametrize("idx, name", enumerate(cases)) +def test_mf6model(idx, name, function_tmpdir, targets): + if idx < 2: + ener_input = calc_ener_input(1.0) + elif idx == 2: + ener_input = calc_ener_input(0.1) + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t, ener_input), + check=lambda t: check_output(idx, t, ener_input), + ) + test.run() From 2ee0a1b3dac9fdb2b892837a7eded374bf8ba2f2 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Wed, 31 Jan 2024 10:27:38 -0800 Subject: [PATCH 36/46] Bringing over Stallman autotest from previous GWE PR (#1237) --- autotest/test_gwe_stallman.py | 404 ++++++++++++++++++++++++++++++++++ 1 file changed, 404 insertions(+) create mode 100644 autotest/test_gwe_stallman.py diff --git a/autotest/test_gwe_stallman.py b/autotest/test_gwe_stallman.py new file mode 100644 index 00000000000..ddbf90a8252 --- /dev/null +++ b/autotest/test_gwe_stallman.py @@ -0,0 +1,404 @@ +# ## Test problem for GWE +# +# One-Dimensional Stallman Problem +# Compare MF6-GWE simulation results with analytical solution + + +# Imports +import os +import numpy as np +import pytest +import matplotlib.pyplot as plt +import flopy + +from framework import TestFramework + +# Base simulation and model name and workspace + +viscosity_on = [False] +cases = ["stallman"] + +# Model units + +length_units = "meters" +time_units = "seconds" + +# Table MODFLOW 6 GWE parameters + +nper = 600 # Number of periods +nstp = 6 # Number of time steps +perlen = 525600 # Simulation time length ($s$) +nlay = 120 # Number of layers +nrow = 1 # Number of rows +ncol = 1 # Number of columns +system_length = 60.0 # Length of system ($m$) +delr = 1.0 # Column width ($m$) +delc = 1.0 # Row width ($m$) +delv_str = "ranges from 0.1 to 1" # Layer thickness +top = 60.0 # Top of the model ($m$) +hydraulic_conductivity = 1.0e-4 # Hydraulic conductivity ($m s^{-1}$) +porosity = 0.35 # Porosity (unitless) +alphal = 0.0 # Longitudinal dispersivity ($m$) +alphat = 0.0 # Transverse dispersivity ($m$) +diffc = 1.02882e-06 # Diffusion coefficient ($m s^{-1}$) +T_az = 10 # Ambient temperature ($^o C$) +dT = 5 # Temperature variation ($^o C$) +bulk_dens = 2630 # Bulk density ($kg/m^3$) +kd = 0.000191663 # Distribution coefficient (unitless) +ktw = 0.58 +kts = 2 +cpw = 4174.0 +cps = 800.0 +rhow = 1000.0 +rhos = bulk_dens +lhv = 2454000.0 # Latent heat of vaporization ($J/kg$) + +# Stress period input +per_data = [] +for k in range(nper): + per_data.append((perlen, nstp, 1.0)) +per_mf6 = per_data + +# Geometry input +tp = top +botm = [] +for i in range(nlay): + if i == 0: + botm.append(59.9) + elif i == 119: + botm.append(0.0) + else: + botm.append(60 - i * 0.5) + +# Head input +chd_data = {} +# for k in range(nper): +chd_data[0] = [[(0, 0, 0), 60.000000], [(119, 0, 0), 59.701801]] +chd_mf6 = chd_data + +# Initial temperature input +strt_temp = T_az * np.ones((nlay, 1, 1), dtype=np.float32) + +# Boundary temperature input +cnc_data = {} +for k in range(nper): + cnc_temp = T_az + dT * np.sin(2 * np.pi * k * perlen / 365 / 86400) + cnc_data[k] = [[(0, 0, 0), cnc_temp]] +cnc_mf6 = cnc_data + +nouter, ninner = 100, 300 +hclose, rclose, relax = 1e-8, 1e-8, 0.97 + + +# Analytical solution for Stallman analysis (Stallman 1965, JGR) +def Stallman(T_az, dT, tau, t, c_rho, darcy_flux, ko, c_w, rho_w, zbotm, nlay): + zstallman = np.zeros((nlay, 2)) + K = np.pi * c_rho / ko / tau + V = darcy_flux * c_w * rho_w / 2 / ko + a = ((K ** 2 + V ** 4 / 4) ** 0.5 + V ** 2 / 2) ** 0.5 - V + b = ((K ** 2 + V ** 4 / 4) ** 0.5 - V ** 2 / 2) ** 0.5 + for i in range(len(zstallman)): + zstallman[i, 0] = zbotm[i] + zstallman[i, 1] = ( + dT + * np.exp(-a * (-zstallman[i, 0])) + * np.sin(2 * np.pi * t / tau - b * (-zstallman[i, 0])) + + T_az + ) + return zstallman + + +# +# MODFLOW 6 (sim) flopy objects returned if building the model +# + + +def build_models(idx, test): + # Base MF6 GWE model type + ws = test.workspace + name = cases[idx] + + print("Building MF6 model...()".format(name)) + + # generate names for each model + gwfname = "gwf-" + name + gwename = "gwe-" + name + + # sim_ws = os.path.join(ws, name) + sim = flopy.mf6.MFSimulation( + sim_name=name, sim_ws=ws, exe_name="mf6", version="mf6" + ) + + # Instantiating MODFLOW 6 time discretization + flopy.mf6.ModflowTdis( + sim, nper=nper, perioddata=per_mf6, time_units=time_units + ) + + # Instantiating MODFLOW 6 groundwater flow model + gwf = flopy.mf6.ModflowGwf( + sim, + modelname=gwfname, + save_flows=True, + model_nam_file="{}.nam".format(gwfname), + ) + + # Instantiating MODFLOW 6 solver for flow model + imsgwf = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="CG", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwfname), + ) + sim.register_ims_package(imsgwf, [gwfname]) + + # Instantiating MODFLOW 6 discretization package + flopy.mf6.ModflowGwfdis( + gwf, + nogrb=True, + length_units=length_units, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + filename="{}.dis".format(gwfname), + ) + + # Instantiating MODFLOW 6 node-property flow package + flopy.mf6.ModflowGwfnpf( + gwf, + save_specific_discharge=True, + icelltype=0, + k=hydraulic_conductivity, + filename="{}.npf".format(gwfname), + ) + + # Instantiating MODFLOW 6 initial conditions package for flow model + flopy.mf6.ModflowGwfic(gwf, strt=top, filename="{}.ic".format(gwfname)) + + # Instantiating VSC + if viscosity_on[idx]: + # Instantiate viscosity (VSC) package + vsc_filerecord = "{}.vsc.bin".format(gwfname) + vsc_pd = [(0, 0.0, 20.0, gwename, "temperature")] + flopy.mf6.ModflowGwfvsc( + gwf, + viscref=8.904e-4, + viscosity_filerecord=vsc_filerecord, + thermal_formulation="nonlinear", + thermal_a2=10.0, + thermal_a3=248.37, + thermal_a4=133.16, + nviscspecies=len(vsc_pd), + packagedata=vsc_pd, + pname="vsc", + filename="{}.vsc".format(gwfname), + ) + + # Instantiating MODFLOW 6 constant head package + flopy.mf6.ModflowGwfchd( + gwf, + stress_period_data=chd_mf6, + filename="{}.chd".format(gwfname), + ) + + # Instantiating MODFLOW 6 output control package for flow model + flopy.mf6.ModflowGwfoc( + gwf, + head_filerecord="{}.hds".format(gwfname), + budget_filerecord="{}.cbc".format(gwfname), + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "LAST"), ("BUDGET", "LAST")], + printrecord=[("HEAD", "LAST"), ("BUDGET", "LAST")], + ) + + # ---------------------------------- + # Instantiating MODFLOW 6 GWE model + # ---------------------------------- + + # Instantiating MODFLOW 6 groundwater heat transport package + gwe = flopy.mf6.MFModel( + sim, + model_type="gwe6", + modelname=gwename, + model_nam_file="{}.nam".format(gwename), + ) + gwe.name_file.save_flows = True + imsgwe = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwename), + ) + sim.register_ims_package(imsgwe, [gwe.name]) + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwedis( + gwe, + length_units=length_units, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + filename="{}.dis".format(gwename), + ) + + # Instantiating MODFLOW 6 transport initial concentrations + flopy.mf6.ModflowGweic( + gwe, strt=strt_temp, filename="{}.ic".format(gwename) + ) + + # Instantiating MODFLOW 6 transport advection package + flopy.mf6.ModflowGweadv( + gwe, scheme="TVD", filename="{}.adv".format(gwename) + ) + + # Instantiating MODFLOW 6 transport dispersion package + flopy.mf6.ModflowGwecnd( + gwe, + xt3d_off=True, + alh=alphal, + ath1=alphat, + ktw=ktw, + kts=kts, + pname="CND-1", + filename="{}.dsp".format(gwename), + ) + + # Instantiating MODFLOW 6 transport mass storage package (formerly "reaction" package in MT3DMS) + flopy.mf6.ModflowGweest( + gwe, + porosity=porosity, + cps=cps, + rhos=rhos, + packagedata=[cpw, rhow, lhv], + filename="{}.mst".format(gwename), + ) + + # Instantiating MODFLOW 6 transport constant concentration package + flopy.mf6.ModflowGwectp( + gwe, + stress_period_data=cnc_mf6, + pname="CTP-1", + filename="{}.tmp".format(gwename), + ) + + # Instantiating MODFLOW 6 transport source-sink mixing package + flopy.mf6.ModflowGwessm( + gwe, sources=[[]], filename="{}.ssm".format(gwename) + ) + + # Instantiate MODFLOW 6 heat transport output control package + flopy.mf6.ModflowGweoc( + gwe, + budget_filerecord="{}.cbc".format(gwename), + temperature_filerecord="{}.ucn".format(gwename), + temperatureprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + printrecord=[("TEMPERATURE", "LAST"), ("BUDGET", "LAST")], + ) + + # Instantiating MODFLOW 6 flow-transport exchange mechanism + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename, + filename="{}.gwfgwe".format(name), + ) + return sim, None + + +def check_output(idx, test): + print("evaluating results...") + + # read transport results from GWE model + name = cases[idx] + gwename = "gwe-" + name + + fpth = os.path.join(test.workspace, f"{gwename}.ucn") + try: + # load temperatures + tobj = flopy.utils.HeadFile( + fpth, precision="double", text="TEMPERATURE" + ) + times = tobj.get_times() + sim_temps = tobj.get_data(totim=times[540]) + except: + assert False, f'could not load concentration data from "{fpth}"' + + # Prepare to compare the results of MF6-GWE with analytical solution + zconc = np.zeros((nlay, 2)) + for i in range(nlay): + if i != (nlay - 1): + zconc[i + 1, 0] = -(60 - botm[i]) + zconc[i, 1] = sim_temps[i][0][0] + + # Analytical solution - Stallman analysis + tau = 365 * 86400 + t = 283824000.0 + c_w = 4174 + rho_w = 1000 + c_r = 800 + rho_r = 2630 + c_rho = c_r * rho_r * (1 - porosity) + c_w * rho_w * porosity + darcy_flux = 5.00e-07 + ko = 1.503 + analytical_temps = Stallman( + T_az, dT, tau, t, c_rho, darcy_flux, ko, c_w, rho_w, zconc[:, 0], nlay + ) + + # plt.plot(zconc[:, 1], zconc[:, 0], "k--", linewidth=0.5, label="MF6-GWE") + # plt.plot(zanal[:, 1], zanal[:, 0], "bo", mfc="none", label="Analytical") + # plt.xlim(T_az - dT, T_az + dT) + # plt.ylim(-top, 0) + # plt.ylabel("Depth (m)") + # plt.xlabel("Temperature (deg C)") + # plt.legend() + # plt.savefig("stallman.png") + + msg = f"gwe temperatures do not match analytical temperatures" + assert np.allclose(zconc[:, 1], analytical_temps[:, 1], atol=1e-1), msg + + return + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(cases)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t), + ) + test.run() From e8805c0c3cbb879425fe7687f13219c8f07fd1ff Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Wed, 7 Feb 2024 12:43:26 -0800 Subject: [PATCH 37/46] Adding streamflow energy transport (SFE) package --- doc/Common/gwe-obstypetable.tex | 4 +- doc/Common/gwe-sfeobs.tex | 27 +- doc/mf6io/gwe/gwe.tex | 4 + doc/mf6io/gwe/namefile.tex | 4 +- doc/mf6io/gwe/sfe.tex | 55 + doc/mf6io/mf6ivar/dfn/common.dfn | 3 + doc/mf6io/mf6ivar/dfn/gwe-sfe.dfn | 480 +++++++ .../mf6ivar/examples/gwe-sfe-example-obs.dat | 24 + .../mf6ivar/examples/gwe-sfe-example.dat | 24 + doc/mf6io/mf6ivar/md/mf6ivar.md | 38 + doc/mf6io/mf6ivar/mf6ivar.py | 1 + doc/mf6io/mf6ivar/tex/appendixA.tex | 4 + doc/mf6io/mf6ivar/tex/gwe-sfe-desc.tex | 101 ++ doc/mf6io/mf6ivar/tex/gwe-sfe-options.dat | 15 + doc/mf6io/mf6ivar/tex/gwe-sfe-packagedata.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-sfe-period.dat | 5 + make/makefile | 1 + msvs/mf6core.vfproj | 3 +- src/Model/GroundWaterEnergy/gwe1.f90 | 10 +- src/Model/GroundWaterEnergy/gwe1sfe1.f90 | 1147 +++++++++++++++++ src/Model/GroundWaterTransport/gwt1lkt1.f90 | 3 +- src/Model/GroundWaterTransport/gwt1mwt1.f90 | 3 +- src/Model/GroundWaterTransport/gwt1sft1.f90 | 3 +- src/Model/GroundWaterTransport/gwt1uzt1.f90 | 3 +- src/Model/TransportModel/tsp1apt1.f90 | 6 +- src/meson.build | 1 + 26 files changed, 1945 insertions(+), 29 deletions(-) create mode 100644 doc/mf6io/gwe/sfe.tex create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-sfe.dfn create mode 100644 doc/mf6io/mf6ivar/examples/gwe-sfe-example-obs.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-sfe-example.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-sfe-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-sfe-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-sfe-packagedata.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-sfe-period.dat create mode 100644 src/Model/GroundWaterEnergy/gwe1sfe1.f90 diff --git a/doc/Common/gwe-obstypetable.tex b/doc/Common/gwe-obstypetable.tex index 501f5cb63c3..ff089c6f6da 100644 --- a/doc/Common/gwe-obstypetable.tex +++ b/doc/Common/gwe-obstypetable.tex @@ -57,8 +57,8 @@ \hline % \input{../Common/gwe-esrobs.tex} \\ % \hline -% \input{../Common/gwe-sfeobs.tex} \\ -% \hline +\input{../Common/gwe-sfeobs.tex} \\ +\hline % \input{../Common/gwe-lkeobs.tex} \\ % \hline % \input{../Common/gwe-mweobs.tex} \\ diff --git a/doc/Common/gwe-sfeobs.tex b/doc/Common/gwe-sfeobs.tex index cf35588bad0..b6b602d8049 100644 --- a/doc/Common/gwe-sfeobs.tex +++ b/doc/Common/gwe-sfeobs.tex @@ -1,16 +1,17 @@ % general APT observations -SFE & temperature & ifno or boundname & -- & Reach temperature. If boundname is specified, boundname must be unique for each reach. \\ -SFE & flow-ja-face & ifno or boundname & ifno or -- & Energy flow between two reaches. If a boundname is specified for ID1, then the result is the total energy flow for all reaches. If a boundname is specified for ID1 then ID2 is not used.\\ -SFE & storage & ifno or boundname & -- & Simulated energy storage flow rate for a reach or group of reaches. \\ -SFE & constant & ifno or boundname & -- & Simulated energy constant-flow rate for a reach or group of reaches. \\ -SFE & from-mvr & ifno or boundname & -- & Simulated energy inflow into a reach or group of reaches from the MVE package. Energy inflow is calculated as the product of provider temperature and the mover flow rate. \\ -SFE & to-mvr & ifno or boundname & -- & Energy outflow from a reach, or a group of reaches that is available for the MVR package. If boundname is not specified for ID, then the outflow available for the MVR package from a specific reach is observed. \\ -SFE & sfe & ifno or boundname & -- & Energy flow rate for a reach or group of reaches and its aquifer connection(s). \\ +SFE & temperature & rno or boundname & -- & Reach temperature. If boundname is specified, boundname must be unique for each reach. \\ +SFE & flow-ja-face & rno or boundname & rno or -- & Energy flow between two reaches. If a boundname is specified for ID1, then the result is the total energy flow for all reaches. If a boundname is specified for ID1 then ID2 is not used.\\ +SFE & storage & rno or boundname & -- & Simulated energy storage flow rate for a reach or group of reaches. \\ +SFE & constant & rno or boundname & -- & Simulated energy constant-flow rate for a reach or group of reaches. \\ +SFE & from-mvr & rno or boundname & -- & Simulated energy inflow into a reach or group of reaches from the MVE package. Energy inflow is calculated as the product of provider temperature and the mover flow rate. \\ +SFE & to-mvr & rno or boundname & -- & Energy outflow from a reach, or a group of reaches that is available for the MVR package. If boundname is not specified for ID, then the outflow available for the MVR package from a specific reach is observed. \\ +SFE & sfe & rno or boundname & -- & Energy flow rate for a reach or group of reaches and its aquifer connection(s). \\ -%observations specific to the stream transport package +%observations specific to the stream energy transport package % rainfall evaporation runoff ext-inflow withdrawal outflow -SFE & rainfall & ifno or boundname & -- & Rainfall rate applied to a reach or group of reaches multiplied by the rainfall temperature. \\ -SFE & evaporation & ifno or boundname & -- & Simulated evaporation rate from a reach or group of reaches multiplied by the latent heat of vaporization, heat capacity of the simulated fluid, and the density of the simulated fluid. \\ -SFE & runoff & ifno or boundname & -- & Runoff rate applied to a reach or group of reaches multiplied by the runoff temperature. \\ -SFE & ext-inflow & ifno or boundname & -- & Energy inflow into a reach or group of reaches calculated as the external inflow rate multiplied by the inflow temperature. \\ -SFE & ext-outflow & ifno or boundname & -- & External outflow from a reach or group of reaches to an external boundary. If boundname is not specified for ID, then the external outflow from a specific reach is observed. In this case, ID is the reach ifno. +SFE & rainfall & rno or boundname & -- & Rainfall rate applied to a reach or group of reaches multiplied by the rainfall temperature. \\ +SFE & evaporation & rno or boundname & -- & Simulated evaporation rate from a reach or group of reaches multiplied by the latent heat of vaporization for determining the amount of energy lost from a reach. \\ +SFE & runoff & rno or boundname & -- & Runoff rate applied to a reach or group of reaches multiplied by the runoff temperature. \\ +SFE & ext-inflow & rno or boundname & -- & Energy inflow into a reach or group of reaches calculated as the external inflow rate multiplied by the inflow temperature. \\ +SFE & ext-outflow & rno or boundname & -- & External outflow from a reach or group of reaches to an external boundary. If boundname is not specified for ID, then the external outflow from a specific reach is observed. In this case, ID is the reach rno. \\ +SFE & strmbd-cond & rno or boundname & -- & Amount of heat conductively exchanged with the streambed material. diff --git a/doc/mf6io/gwe/gwe.tex b/doc/mf6io/gwe/gwe.tex index 7e49294e095..2655c0d07e5 100644 --- a/doc/mf6io/gwe/gwe.tex +++ b/doc/mf6io/gwe/gwe.tex @@ -125,6 +125,10 @@ \subsection{Constant Temperature (CTP) Package} \subsection{Energy Source Loading (ESL) Package} \input{gwe/esl} +\newpage +\subsection{Streamflow Energy Transport (SFE) Package} +\input{gwe/sfe} + \newpage \subsection{Flow Model Interface (FMI) Package} \input{gwe/fmi} diff --git a/doc/mf6io/gwe/namefile.tex b/doc/mf6io/gwe/namefile.tex index e23b8cb35de..613065d678b 100644 --- a/doc/mf6io/gwe/namefile.tex +++ b/doc/mf6io/gwe/namefile.tex @@ -29,10 +29,12 @@ \subsubsection{Explanation of Variables} IC6 & Initial Conditions Package \\ OC6 & Output Control Option \\ ADV6 & Advection Package \\ -DSP6 & Dispersion Package \\ +CND6 & Conduction Package \\ SSM6 & Source and Sink Mixing Package \\ EST6 & Energy Storage and Transfer Package \\ CTP6 & Constant Temperature Package & * \\ +ESL6 & Energy Source Loading Package & * \\ +SFE6 & Streamflow Energy Transport Package & * \\ OBS6 & Observations Option \\ \hline \end{tabular*} diff --git a/doc/mf6io/gwe/sfe.tex b/doc/mf6io/gwe/sfe.tex new file mode 100644 index 00000000000..4f1e5fca4db --- /dev/null +++ b/doc/mf6io/gwe/sfe.tex @@ -0,0 +1,55 @@ +Streamflow Energy Transport (SFE) Package information is read from the file that is specified by ``SFE6'' as the file type. There can be as many SFE Packages as necessary for a GWE model. Each SFE Package is designed to work with flows from a corresponding GWF SFR Package. By default \mf uses the SFE package name to determine which SFR Package corresponds to the SFE Package. Therefore, the package name of the SFE Package (as specified in the GWE name file) must match with the name of the corresponding SFR Package (as specified in the GWF name file). Alternatively, the name of the flow package can be specified using the FLOW\_PACKAGE\_NAME keyword in the options block. The GWE SFE Package cannot be used without a corresponding GWF SFR Package. + +The SFE Package does not have a dimensions block; instead, dimensions for the SFE Package are set using the dimensions from the corresponding SFR Package. For example, the SFR Package requires specification of the number of reaches (NREACHES). SFE sets the number of reaches equal to NREACHES. Therefore, the PACKAGEDATA block below must have NREACHES entries in it. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-sfe-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-sfe-packagedata.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-sfe-period.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-sfe-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-sfe-example.dat} + +\vspace{5mm} +\subsubsection{Available observation types} +Streamflow Energy Transport Package observations include reach temperature and all of the terms that contribute to the continuity equation for each reach. Additional SFE Package observations include energy flow rates for individual reaches, or groups of reaches. The data required for each SFE Package observation type is defined in table~\ref{table:gwe-sfeobstype}. Negative and positive values for \texttt{sfe} observations represent a loss from and gain to the GWE model, respectively. For all other flow terms, negative and positive values represent a loss from and gain from the SFE package, respectively. + +\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}} +\caption{Available SFE Package observation types} \tabularnewline + +\hline +\hline +\textbf{Stress Package} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endfirsthead + +\captionsetup{textformat=simple} +\caption*{\textbf{Table \arabic{table}.}{\quad}Available SFE Package observation types.---Continued} \tabularnewline + +\hline +\hline +\textbf{Stress Package} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endhead + + +\hline +\endfoot + +\input{../Common/gwe-sfeobs.tex} +\label{table:gwe-sfeobstype} +\end{longtable} + +\vspace{5mm} +\subsubsection{Example Observation Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-sfe-example-obs.dat} + + diff --git a/doc/mf6io/mf6ivar/dfn/common.dfn b/doc/mf6io/mf6ivar/dfn/common.dfn index b69ae67edf9..0fd5220c2f0 100644 --- a/doc/mf6io/mf6ivar/dfn/common.dfn +++ b/doc/mf6io/mf6ivar/dfn/common.dfn @@ -21,6 +21,9 @@ description keyword to indicate that the list of {#1} {#2} will be printed to th name print_concentration description keyword to indicate that the list of {#1} {#2} will be printed to the listing file for every stress period in which ``CONCENTRATION PRINT'' is specified in Output Control. If there is no Output Control option and PRINT\_{#3} is specified, then {#2} are printed for the last time step of each stress period. +name print_temperature +description keyword to indicate that the list of {#1} {#2} will be printed to the listing file for every stress period in which ``TEMPERATURE PRINT'' is specified in Output Control. If there is no Output Control option and PRINT\_{#3} is specified, then {#2} are printed for the last time step of each stress period. + name print_flows description keyword to indicate that the list of {#1} flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. diff --git a/doc/mf6io/mf6ivar/dfn/gwe-sfe.dfn b/doc/mf6io/mf6ivar/dfn/gwe-sfe.dfn new file mode 100644 index 00000000000..610e3911ff1 --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-sfe.dfn @@ -0,0 +1,480 @@ +# --------------------- gwe sfe options --------------------- +# flopy multi-package + +block options +name flow_package_name +type string +shape +reader urword +optional true +longname keyword to specify name of corresponding flow package +description keyword to specify the name of the corresponding flow package. If not specified, then the corresponding flow package must have the same name as this advanced transport package (the name associated with this package in the GWE name file). + +block options +name auxiliary +type string +shape (naux) +reader urword +optional true +longname keyword to specify aux variables +description REPLACE auxnames {'{#1}': 'Groundwater Energy Transport'} + +block options +name flow_package_auxiliary_name +type string +shape +reader urword +optional true +longname keyword to specify name of temperature auxiliary variable in flow package +description keyword to specify the name of an auxiliary variable provided in the corresponding flow package (i.e., FLOW\_PACKAE\_NAME). If specified, then the simulated temperatures from this advanced energy transport package will be copied into the auxiliary variable specified with this name. Note that the flow package must have an auxiliary variable with this name or the program will terminate with an error. If the flows for this advanced energy transport package are read from a file, then this option will have no effect. + +block options +name boundnames +type keyword +shape +reader urword +optional true +longname +description REPLACE boundnames {'{#1}': 'reach'} + +block options +name print_input +type keyword +reader urword +optional true +longname print input to listing file +description REPLACE print_input {'{#1}': 'reach'} + +block options +name print_temperature +type keyword +reader urword +optional true +longname print calculated temperature to listing file +description REPLACE print_temperature {'{#1}': 'reach', '{#2}': 'temperatures', '{#3}': 'TEMPERATURE'} + +block options +name print_flows +type keyword +reader urword +optional true +longname print calculated flows to listing file +description REPLACE print_flows {'{#1}': 'reach'} + +block options +name save_flows +type keyword +reader urword +optional true +longname save reach flows to budget file +description REPLACE save_flows {'{#1}': 'reach'} + +block options +name temperature_filerecord +type record temperature fileout tempfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name temperature +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname temperature keyword +description keyword to specify that record corresponds to temperature. + +block options +name tempfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the binary output file to write temperature information. + +block options +name budget_filerecord +type record budget fileout budgetfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name budget +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname budget keyword +description keyword to specify that record corresponds to the budget. + +block options +name fileout +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname file keyword +description keyword to specify that an output filename is expected next. + +block options +name budgetfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the binary output file to write budget information. + +block options +name budgetcsv_filerecord +type record budgetcsv fileout budgetcsvfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name budgetcsv +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname budget keyword +description keyword to specify that record corresponds to the budget CSV. + +block options +name budgetcsvfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. + +block options +name ts_filerecord +type record ts6 filein ts6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name ts6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname head keyword +description keyword to specify that record corresponds to a time-series file. + +block options +name filein +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname file keyword +description keyword to specify that an input filename is expected next. + +block options +name ts6_filename +type string +preserve_case true +in_record true +reader urword +optional false +tagged false +longname file name of time series information +description REPLACE timeseriesfile {} + +block options +name obs_filerecord +type record obs6 filein obs6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name obs6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname obs keyword +description keyword to specify that record corresponds to an observations file. + +block options +name obs6_filename +type string +preserve_case true +in_record true +tagged false +reader urword +optional false +longname obs6 input filename +description REPLACE obs6_filename {'{#1}': 'SFT'} + + +# --------------------- gwe sfe packagedata --------------------- + +block packagedata +name packagedata +type recarray rno strt ktf rbthcnd aux boundname +shape (maxbound) +reader urword +longname +description + +block packagedata +name rno +type integer +shape +tagged false +in_record true +reader urword +longname reach number for this entry +description integer value that defines the reach number associated with the specified PACKAGEDATA data on the line. RNO must be greater than zero and less than or equal to NREACHES. Reach information must be specified for every reach or the program will terminate with an error. The program will also terminate with an error if information for a reach is specified more than once. +numeric_index true + +block packagedata +name strt +type double precision +shape +tagged false +in_record true +reader urword +longname starting reach temperature +description real value that defines the starting temperature for the reach. + +block packagedata +name ktf +type double precision +shape +tagged false +in_record true +reader urword +longname boundary thermal conductivity +description is the thermal conductivity of the of the interface between the aquifer cell and the stream reach. + +block packagedata +name rbthcnd +type double precision +shape +tagged false +in_record true +reader urword +longname streambed thickness +description real value that defines the thickness of the streambed material through which conduction occurs. Must be greater than 0. + +block packagedata +name aux +type double precision +in_record true +tagged false +shape (naux) +reader urword +time_series true +optional true +longname auxiliary variables +description REPLACE aux {'{#1}': 'reach'} + +block packagedata +name boundname +type string +shape +tagged false +in_record true +reader urword +optional true +longname well name +description REPLACE boundname {'{#1}': 'reach'} + + +# --------------------- gwe sfe period --------------------- + +block period +name iper +type integer +block_variable True +in_record true +tagged false +shape +valid +reader urword +optional false +longname stress period number +description REPLACE iper {} + +block period +name reachperioddata +type recarray rno reachsetting +shape +reader urword +longname +description + +block period +name rno +type integer +shape +tagged false +in_record true +reader urword +longname reach number for this entry +description integer value that defines the reach number associated with the specified PERIOD data on the line. RNO must be greater than zero and less than or equal to NREACHES. +numeric_index true + +block period +name reachsetting +type keystring status temperature rainfall evaporation runoff inflow auxiliaryrecord +shape +tagged false +in_record true +reader urword +longname +description line of information that is parsed into a keyword and values. Keyword values that can be used to start the REACHSETTING string include: STATUS, TEMPERATURE, RAINFALL, EVAPORATION, RUNOFF, and AUXILIARY. These settings are used to assign the temperature of associated with the corresponding flow terms. Temperatures cannot be specified for all flow terms. For example, the Streamflow Package supports a ``DIVERSION'' flow term. Diversion water will be routed using the calculated temperature of the reach. + +block period +name status +type string +shape +tagged true +in_record true +reader urword +longname reach temperature status +description keyword option to define reach status. STATUS can be ACTIVE, INACTIVE, or CONSTANT. By default, STATUS is ACTIVE, which means that temperature will be calculated for the reach. If a reach is inactive, then there will be no energy fluxes into or out of the reach and the inactive value will be written for the reach temperature. If a reach is constant, then the temperature for the reach will be fixed at the user specified value. + +block period +name temperature +type string +shape +tagged true +in_record true +time_series true +reader urword +longname reach temperature +description real or character value that defines the temperature for the reach. The specified TEMPERATURE is only applied if the reach is a constant temperature reach. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name rainfall +type string +shape +tagged true +in_record true +reader urword +time_series true +longname rainfall temperature +description real or character value that defines the rainfall temperature $(^{\circ}C)$ for the reach. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name evaporation +type string +shape +tagged true +in_record true +reader urword +time_series true +longname evaporation temperature +description real or character value that defines the temperature of evaporated water $(^{\circ}C)$ for the reach. If this temperature value is larger than the simulated temperature in the reach, then the evaporated water will be removed at the same temperature as the reach. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name runoff +type string +shape +tagged true +in_record true +reader urword +time_series true +longname runoff temperature +description real or character value that defines the temperature of runoff $(^{\circ}C)$ for the reach. Value must be greater than or equal to zero. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name inflow +type string +shape +tagged true +in_record true +reader urword +time_series true +longname inflow temperature +description real or character value that defines the temperature of inflow $(^{\circ}C)$ for the reach. Value must be greater than or equal to zero. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name auxiliaryrecord +type record auxiliary auxname auxval +shape +tagged +in_record true +reader urword +longname +description + +block period +name auxiliary +type keyword +shape +in_record true +reader urword +longname +description keyword for specifying auxiliary variable. + +block period +name auxname +type string +shape +tagged false +in_record true +reader urword +longname +description name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. + +block period +name auxval +type double precision +shape +tagged false +in_record true +reader urword +time_series true +longname auxiliary variable value +description value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. diff --git a/doc/mf6io/mf6ivar/examples/gwe-sfe-example-obs.dat b/doc/mf6io/mf6ivar/examples/gwe-sfe-example-obs.dat new file mode 100644 index 00000000000..ec5baaedc76 --- /dev/null +++ b/doc/mf6io/mf6ivar/examples/gwe-sfe-example-obs.dat @@ -0,0 +1,24 @@ +BEGIN options + DIGITS 7 + PRINT_INPUT +END options + +BEGIN continuous FILEOUT gwe_sfe02.sfe.obs.csv + sfe-1-temp TEMPERATURE 1 + sfe-1-extinflow EXT-INFLOW 1 + sfe-1-rain RAINFALL 1 + sfe-1-roff RUNOFF 1 + sfe-1-stor STORAGE 1 + sfe-1-const CONSTANT 1 + sfe-1-gwe1 SFE 1 1 + sfe-1-gwe2 SFE 1 2 + sfe-2-gwe1 SFE 2 1 + sfe-1-mylake1 SFE MYREACHES + sfe-1-fjf FLOW-JA-FACE 1 2 + sfe-2-fjf FLOW-JA-FACE 2 1 + sfe-3-fjf FLOW-JA-FACE 2 3 + sfe-4-fjf FLOW-JA-FACE 3 2 + sfe-5-fjf FLOW-JA-FACE MYREACH1 + sfe-6-fjf FLOW-JA-FACE MYREACH2 + sfe-7-fjf FLOW-JA-FACE MYREACH3 +END continuous diff --git a/doc/mf6io/mf6ivar/examples/gwe-sfe-example.dat b/doc/mf6io/mf6ivar/examples/gwe-sfe-example.dat new file mode 100644 index 00000000000..3f819067162 --- /dev/null +++ b/doc/mf6io/mf6ivar/examples/gwe-sfe-example.dat @@ -0,0 +1,24 @@ +BEGIN OPTIONS + AUXILIARY aux1 aux2 + BOUNDNAMES + PRINT_INPUT + PRINT_TEMPERATURE + PRINT_FLOWS + SAVE_FLOWS + TEMPERATURE FILEOUT gwe_sfe_02.sfe.bin + BUDGET FILEOUT gwe_sfe_02.sfe.bud + OBS6 FILEIN gwe_sfe_02.sfe.obs +END OPTIONS + +BEGIN PACKAGEDATA +# L STRT aux1 aux2 bname + 1 5.000 9.90 99.90 REACH1 + 2 5.000 9.90 99.90 REACH2 + 3 5.000 9.90 99.90 REACH3 +END PACKAGEDATA + +BEGIN PERIOD 1 + 1 STATUS ACTIVE + 2 STATUS ACTIVE + 3 STATUS ACTIVE +END PERIOD 1 diff --git a/doc/mf6io/mf6ivar/md/mf6ivar.md b/doc/mf6io/mf6ivar/md/mf6ivar.md index ab412395945..780589a6758 100644 --- a/doc/mf6io/mf6ivar/md/mf6ivar.md +++ b/doc/mf6io/mf6ivar/md/mf6ivar.md @@ -1337,6 +1337,44 @@ | GWE | SSM | FILEINPUT | FILEIN | KEYWORD | keyword to specify that an input filename is expected next. | | GWE | SSM | FILEINPUT | SPT6_FILENAME | STRING | character string that defines the path and filename for the file containing source and sink input data for the flow package. The SPT6\_FILENAME file is a flexible input file that allows temperatures to be specified by stress period and with time series. Instructions for creating the SPT6\_FILENAME input file are provided in the next section on file input for boundary temperatures. | | GWE | SSM | FILEINPUT | MIXED | KEYWORD | keyword to specify that these stress package boundaries will have the mixed condition. The MIXED condition is described in the SOURCES block for AUXMIXED. The MIXED condition allows for water to be withdrawn at a temperature that is less than the cell temperature. It is intended primarily for representing evapotranspiration. | +| GWE | SFE | OPTIONS | FLOW_PACKAGE_NAME | STRING | keyword to specify the name of the corresponding flow package. If not specified, then the corresponding flow package must have the same name as this advanced transport package (the name associated with this package in the GWE name file). | +| GWE | SFE | OPTIONS | AUXILIARY | STRING (NAUX) | defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. | +| GWE | SFE | OPTIONS | FLOW_PACKAGE_AUXILIARY_NAME | STRING | keyword to specify the name of an auxiliary variable provided in the corresponding flow package (i.e., FLOW\_PACKAE\_NAME). If specified, then the simulated temperatures from this advanced energy transport package will be copied into the auxiliary variable specified with this name. Note that the flow package must have an auxiliary variable with this name or the program will terminate with an error. If the flows for this advanced energy transport package are read from a file, then this option will have no effect. | +| GWE | SFE | OPTIONS | BOUNDNAMES | KEYWORD | keyword to indicate that boundary names may be provided with the list of reach cells. | +| GWE | SFE | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of reach information will be written to the listing file immediately after it is read. | +| GWE | SFE | OPTIONS | PRINT_TEMPERATURE | KEYWORD | keyword to indicate that the list of reach temperatures will be printed to the listing file for every stress period in which ``TEMPERATURE PRINT'' is specified in Output Control. If there is no Output Control option and PRINT\_TEMPERATURE is specified, then temperatures are printed for the last time step of each stress period. | +| GWE | SFE | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of reach flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | +| GWE | SFE | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that reach flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | +| GWE | SFE | OPTIONS | TEMPERATURE | KEYWORD | keyword to specify that record corresponds to temperature. | +| GWE | SFE | OPTIONS | TEMPFILE | STRING | name of the binary output file to write temperature information. | +| GWE | SFE | OPTIONS | BUDGET | KEYWORD | keyword to specify that record corresponds to the budget. | +| GWE | SFE | OPTIONS | FILEOUT | KEYWORD | keyword to specify that an output filename is expected next. | +| GWE | SFE | OPTIONS | BUDGETFILE | STRING | name of the binary output file to write budget information. | +| GWE | SFE | OPTIONS | BUDGETCSV | KEYWORD | keyword to specify that record corresponds to the budget CSV. | +| GWE | SFE | OPTIONS | BUDGETCSVFILE | STRING | name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. | +| GWE | SFE | OPTIONS | TS6 | KEYWORD | keyword to specify that record corresponds to a time-series file. | +| GWE | SFE | OPTIONS | FILEIN | KEYWORD | keyword to specify that an input filename is expected next. | +| GWE | SFE | OPTIONS | TS6_FILENAME | STRING | defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. | +| GWE | SFE | OPTIONS | OBS6 | KEYWORD | keyword to specify that record corresponds to an observations file. | +| GWE | SFE | OPTIONS | OBS6_FILENAME | STRING | name of input file to define observations for the SFT package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the SFT package. | +| GWE | SFE | PACKAGEDATA | RNO | INTEGER | integer value that defines the reach number associated with the specified PACKAGEDATA data on the line. RNO must be greater than zero and less than or equal to NREACHES. Reach information must be specified for every reach or the program will terminate with an error. The program will also terminate with an error if information for a reach is specified more than once. | +| GWE | SFE | PACKAGEDATA | STRT | DOUBLE PRECISION | real value that defines the starting temperature for the reach. | +| GWE | SFE | PACKAGEDATA | KTF | DOUBLE PRECISION | is the thermal conductivity of the of the interface between the aquifer cell and the stream reach. | +| GWE | SFE | PACKAGEDATA | RBTHCND | DOUBLE PRECISION | real value that defines the thickness of the streambed material through which conduction occurs. Must be greater than 0. | +| GWE | SFE | PACKAGEDATA | AUX | DOUBLE PRECISION (NAUX) | represents the values of the auxiliary variables for each reach. The values of auxiliary variables must be present for each reach. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | SFE | PACKAGEDATA | BOUNDNAME | STRING | name of the reach cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. | +| GWE | SFE | PERIOD | IPER | INTEGER | integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. | +| GWE | SFE | PERIOD | RNO | INTEGER | integer value that defines the reach number associated with the specified PERIOD data on the line. RNO must be greater than zero and less than or equal to NREACHES. | +| GWE | SFE | PERIOD | REACHSETTING | KEYSTRING | line of information that is parsed into a keyword and values. Keyword values that can be used to start the REACHSETTING string include: STATUS, TEMPERATURE, RAINFALL, EVAPORATION, RUNOFF, and AUXILIARY. These settings are used to assign the temperature of associated with the corresponding flow terms. Temperatures cannot be specified for all flow terms. For example, the Streamflow Package supports a ``DIVERSION'' flow term. Diversion water will be routed using the calculated temperature of the reach. | +| GWE | SFE | PERIOD | STATUS | STRING | keyword option to define reach status. STATUS can be ACTIVE, INACTIVE, or CONSTANT. By default, STATUS is ACTIVE, which means that temperature will be calculated for the reach. If a reach is inactive, then there will be no energy fluxes into or out of the reach and the inactive value will be written for the reach temperature. If a reach is constant, then the temperature for the reach will be fixed at the user specified value. | +| GWE | SFE | PERIOD | TEMPERATURE | STRING | real or character value that defines the temperature for the reach. The specified TEMPERATURE is only applied if the reach is a constant temperature reach. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | SFE | PERIOD | RAINFALL | STRING | real or character value that defines the rainfall temperature $(^{\circ}C)$ for the reach. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | SFE | PERIOD | EVAPORATION | STRING | real or character value that defines the temperature of evaporated water $(^{\circ}C)$ for the reach. If this temperature value is larger than the simulated temperature in the reach, then the evaporated water will be removed at the same temperature as the reach. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | SFE | PERIOD | RUNOFF | STRING | real or character value that defines the temperature of runoff $(^{\circ}C)$ for the reach. Value must be greater than or equal to zero. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | SFE | PERIOD | INFLOW | STRING | real or character value that defines the temperature of inflow $(^{\circ}C)$ for the reach. Value must be greater than or equal to zero. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | SFE | PERIOD | AUXILIARY | KEYWORD | keyword for specifying auxiliary variable. | +| GWE | SFE | PERIOD | AUXNAME | STRING | name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. | +| GWE | SFE | PERIOD | AUXVAL | DOUBLE PRECISION | value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | | GWE | FMI | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that FMI flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | | GWE | FMI | OPTIONS | FLOW_IMBALANCE_CORRECTION | KEYWORD | correct for an imbalance in flows by assuming that any residual flow error comes in or leaves at the temperature of the cell. When this option is activated, the GWE Model budget written to the listing file will contain two additional entries: FLOW-ERROR and FLOW-CORRECTION. These two entries will be equal but opposite in sign. The FLOW-CORRECTION term is a mass flow that is added to offset the error caused by an imprecise flow balance. If these terms are not relatively small, the flow model should be rerun with stricter convergence tolerances. | | GWE | FMI | PACKAGEDATA | FLOWTYPE | STRING | is the word GWFBUDGET, GWFHEAD, GWFMOVER or the name of an advanced GWF stress package. If GWFBUDGET is specified, then the corresponding file must be a budget file from a previous GWF Model run. If an advanced GWF stress package name appears then the corresponding file must be the budget file saved by a LAK, SFR, MAW or UZF Package. | diff --git a/doc/mf6io/mf6ivar/mf6ivar.py b/doc/mf6io/mf6ivar/mf6ivar.py index e8c204d80df..328b3ee2d53 100644 --- a/doc/mf6io/mf6ivar/mf6ivar.py +++ b/doc/mf6io/mf6ivar/mf6ivar.py @@ -751,6 +751,7 @@ def write_appendix(texdir, allblocks): "gwe-nam", "gwe-oc", "gwe-ssm", + "gwe-sfe", "gwe-fmi", "utl-spc", "utl-spca", diff --git a/doc/mf6io/mf6ivar/tex/appendixA.tex b/doc/mf6io/mf6ivar/tex/appendixA.tex index dc136dd01d5..6272dfc456b 100644 --- a/doc/mf6io/mf6ivar/tex/appendixA.tex +++ b/doc/mf6io/mf6ivar/tex/appendixA.tex @@ -290,6 +290,10 @@ GWE & SSM & SOURCES & yes \\ GWE & SSM & FILEINPUT & yes \\ \hline +GWE & SFE & OPTIONS & yes \\ +GWE & SFE & PACKAGEDATA & yes \\ +GWE & SFE & PERIOD & yes \\ +\hline GWE & FMI & OPTIONS & yes \\ GWE & FMI & PACKAGEDATA & yes \\ \hline diff --git a/doc/mf6io/mf6ivar/tex/gwe-sfe-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-sfe-desc.tex new file mode 100644 index 00000000000..af8496fe18d --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-sfe-desc.tex @@ -0,0 +1,101 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{flow\_package\_name}---keyword to specify the name of the corresponding flow package. If not specified, then the corresponding flow package must have the same name as this advanced transport package (the name associated with this package in the GWE name file). + +\item \texttt{auxiliary}---defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. + +\item \texttt{flow\_package\_auxiliary\_name}---keyword to specify the name of an auxiliary variable provided in the corresponding flow package (i.e., FLOW\_PACKAE\_NAME). If specified, then the simulated temperatures from this advanced energy transport package will be copied into the auxiliary variable specified with this name. Note that the flow package must have an auxiliary variable with this name or the program will terminate with an error. If the flows for this advanced energy transport package are read from a file, then this option will have no effect. + +\item \texttt{BOUNDNAMES}---keyword to indicate that boundary names may be provided with the list of reach cells. + +\item \texttt{PRINT\_INPUT}---keyword to indicate that the list of reach information will be written to the listing file immediately after it is read. + +\item \texttt{PRINT\_TEMPERATURE}---keyword to indicate that the list of reach temperatures will be printed to the listing file for every stress period in which ``TEMPERATURE PRINT'' is specified in Output Control. If there is no Output Control option and PRINT\_TEMPERATURE is specified, then temperatures are printed for the last time step of each stress period. + +\item \texttt{PRINT\_FLOWS}---keyword to indicate that the list of reach flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. + +\item \texttt{SAVE\_FLOWS}---keyword to indicate that reach flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. + +\item \texttt{TEMPERATURE}---keyword to specify that record corresponds to temperature. + +\item \texttt{tempfile}---name of the binary output file to write temperature information. + +\item \texttt{BUDGET}---keyword to specify that record corresponds to the budget. + +\item \texttt{FILEOUT}---keyword to specify that an output filename is expected next. + +\item \texttt{budgetfile}---name of the binary output file to write budget information. + +\item \texttt{BUDGETCSV}---keyword to specify that record corresponds to the budget CSV. + +\item \texttt{budgetcsvfile}---name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. + +\item \texttt{TS6}---keyword to specify that record corresponds to a time-series file. + +\item \texttt{FILEIN}---keyword to specify that an input filename is expected next. + +\item \texttt{ts6\_filename}---defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. + +\item \texttt{OBS6}---keyword to specify that record corresponds to an observations file. + +\item \texttt{obs6\_filename}---name of input file to define observations for the SFT package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the SFT package. + +\end{description} +\item \textbf{Block: PACKAGEDATA} + +\begin{description} +\item \texttt{rno}---integer value that defines the reach number associated with the specified PACKAGEDATA data on the line. RNO must be greater than zero and less than or equal to NREACHES. Reach information must be specified for every reach or the program will terminate with an error. The program will also terminate with an error if information for a reach is specified more than once. + +\item \texttt{strt}---real value that defines the starting temperature for the reach. + +\item \texttt{ktf}---is the thermal conductivity of the of the interface between the aquifer cell and the stream reach. + +\item \texttt{rbthcnd}---real value that defines the thickness of the streambed material through which conduction occurs. Must be greater than 0. + +\item \textcolor{blue}{\texttt{aux}---represents the values of the auxiliary variables for each reach. The values of auxiliary variables must be present for each reach. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \texttt{boundname}---name of the reach cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. + +\end{description} +\item \textbf{Block: PERIOD} + +\begin{description} +\item \texttt{iper}---integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. + +\item \texttt{rno}---integer value that defines the reach number associated with the specified PERIOD data on the line. RNO must be greater than zero and less than or equal to NREACHES. + +\item \texttt{reachsetting}---line of information that is parsed into a keyword and values. Keyword values that can be used to start the REACHSETTING string include: STATUS, TEMPERATURE, RAINFALL, EVAPORATION, RUNOFF, and AUXILIARY. These settings are used to assign the temperature of associated with the corresponding flow terms. Temperatures cannot be specified for all flow terms. For example, the Streamflow Package supports a ``DIVERSION'' flow term. Diversion water will be routed using the calculated temperature of the reach. + +\begin{lstlisting}[style=blockdefinition] +STATUS +TEMPERATURE <@temperature@> +RAINFALL <@rainfall@> +EVAPORATION <@evaporation@> +RUNOFF <@runoff@> +INFLOW <@inflow@> +AUXILIARY <@auxval@> +\end{lstlisting} + +\item \texttt{status}---keyword option to define reach status. STATUS can be ACTIVE, INACTIVE, or CONSTANT. By default, STATUS is ACTIVE, which means that temperature will be calculated for the reach. If a reach is inactive, then there will be no energy fluxes into or out of the reach and the inactive value will be written for the reach temperature. If a reach is constant, then the temperature for the reach will be fixed at the user specified value. + +\item \textcolor{blue}{\texttt{temperature}---real or character value that defines the temperature for the reach. The specified TEMPERATURE is only applied if the reach is a constant temperature reach. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{rainfall}---real or character value that defines the rainfall temperature $(^{\circ}C)$ for the reach. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{evaporation}---real or character value that defines the temperature of evaporated water $(^{\circ}C)$ for the reach. If this temperature value is larger than the simulated temperature in the reach, then the evaporated water will be removed at the same temperature as the reach. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{runoff}---real or character value that defines the temperature of runoff $(^{\circ}C)$ for the reach. Value must be greater than or equal to zero. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{inflow}---real or character value that defines the temperature of inflow $(^{\circ}C)$ for the reach. Value must be greater than or equal to zero. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \texttt{AUXILIARY}---keyword for specifying auxiliary variable. + +\item \texttt{auxname}---name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. + +\item \textcolor{blue}{\texttt{auxval}---value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-sfe-options.dat b/doc/mf6io/mf6ivar/tex/gwe-sfe-options.dat new file mode 100644 index 00000000000..ef83c7fa718 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-sfe-options.dat @@ -0,0 +1,15 @@ +BEGIN OPTIONS + [FLOW_PACKAGE_NAME ] + [AUXILIARY ] + [FLOW_PACKAGE_AUXILIARY_NAME ] + [BOUNDNAMES] + [PRINT_INPUT] + [PRINT_TEMPERATURE] + [PRINT_FLOWS] + [SAVE_FLOWS] + [TEMPERATURE FILEOUT ] + [BUDGET FILEOUT ] + [BUDGETCSV FILEOUT ] + [TS6 FILEIN ] + [OBS6 FILEIN ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-sfe-packagedata.dat b/doc/mf6io/mf6ivar/tex/gwe-sfe-packagedata.dat new file mode 100644 index 00000000000..d75a5bae2d0 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-sfe-packagedata.dat @@ -0,0 +1,5 @@ +BEGIN PACKAGEDATA + [<@aux(naux)@>] [] + [<@aux(naux)@>] [] + ... +END PACKAGEDATA diff --git a/doc/mf6io/mf6ivar/tex/gwe-sfe-period.dat b/doc/mf6io/mf6ivar/tex/gwe-sfe-period.dat new file mode 100644 index 00000000000..1b56b2824e2 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-sfe-period.dat @@ -0,0 +1,5 @@ +BEGIN PERIOD + + + ... +END PERIOD diff --git a/make/makefile b/make/makefile index c94b0e8a471..f6d172d4bd1 100644 --- a/make/makefile +++ b/make/makefile @@ -280,6 +280,7 @@ $(OBJDIR)/gwf3buy8.o \ $(OBJDIR)/GhostNode.o \ $(OBJDIR)/gwf3evt8.o \ $(OBJDIR)/gwf3chd8.o \ +$(OBJDIR)/gwe1sfe1.o \ $(OBJDIR)/gwe1est1.o \ $(OBJDIR)/gwe1esl1.o \ $(OBJDIR)/gwe1ctp1.o \ diff --git a/msvs/mf6core.vfproj b/msvs/mf6core.vfproj index f630573d138..d8176d7a00a 100644 --- a/msvs/mf6core.vfproj +++ b/msvs/mf6core.vfproj @@ -151,7 +151,8 @@ - + + diff --git a/src/Model/GroundWaterEnergy/gwe1.f90 b/src/Model/GroundWaterEnergy/gwe1.f90 index 11d2e8a25a2..21fef839832 100644 --- a/src/Model/GroundWaterEnergy/gwe1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1.f90 @@ -767,7 +767,7 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & use GweCtpModule, only: ctp_create use GweEslModule, only: esl_create !use GweLkeModule, only: lke_create - !use GweSfeModule, only: sfe_create + use GweSfeModule, only: sfe_create !use GweMweModule, only: mwe_create !use GweUzeModule, only: uze_create use ApiModule, only: api_create @@ -798,10 +798,10 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & ! call lke_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & ! pakname, this%fmi, this%tsplab, this%eqnsclfac, & ! this%gwecommon) - !case ('SFE6') - ! call sfe_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & - ! pakname, this%fmi, this%tsplab, this%eqnsclfac, & - ! this%gwecommon) + case ('SFE6') + call sfe_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + pakname, this%fmi, this%eqnsclfac, this%gwecommon, & + this%depvartype, this%depvarunit, this%depvarunitabbrev) !case ('MWE6') ! call mwe_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & ! pakname, this%fmi, this%tsplab, this%eqnsclfac, & diff --git a/src/Model/GroundWaterEnergy/gwe1sfe1.f90 b/src/Model/GroundWaterEnergy/gwe1sfe1.f90 new file mode 100644 index 00000000000..76300171b31 --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1sfe1.f90 @@ -0,0 +1,1147 @@ +! -- Stream Energy Transport Module +! -- todo: Temperature decay? +! -- todo: save the sfe temperature into the sfr aux variable? (perhaps needed for GWT-GWE exchanges) +! -- todo: calculate the sfr VISC aux variable using temperature? +! +! SFR flows (sfrbudptr) index var SFE term Transport Type +!--------------------------------------------------------------------------------- + +! -- terms from SFR that will be handled by parent APT Package +! FLOW-JA-FACE idxbudfjf FLOW-JA-FACE cv2cv +! GWF (aux FLOW-AREA) idxbudgwf GWF cv2gwf +! STORAGE (aux VOLUME) idxbudsto none used for cv volumes +! FROM-MVR idxbudfmvr FROM-MVR q * tmpext = this%qfrommvr(:) ! kluge note: include rhow*cpw in comments for various terms +! TO-MVR idxbudtmvr TO-MVR q * tfeat + +! -- SFR terms +! RAINFALL idxbudrain RAINFALL q * train +! EVAPORATION idxbudevap EVAPORATION tfeat null() !< pointer to shared gwe data used by multiple packages but set in mst + + integer(I4B), pointer :: idxbudrain => null() !< index of rainfall terms in flowbudptr + integer(I4B), pointer :: idxbudevap => null() !< index of evaporation terms in flowbudptr + integer(I4B), pointer :: idxbudroff => null() !< index of runoff terms in flowbudptr + integer(I4B), pointer :: idxbudiflw => null() !< index of inflow terms in flowbudptr + integer(I4B), pointer :: idxbudoutf => null() !< index of outflow terms in flowbudptr + integer(I4B), pointer :: idxbudsbcd => null() !< index of streambed conduction terms in flowbudptr + + real(DP), dimension(:), pointer, contiguous :: temprain => null() !< rainfall temperature + real(DP), dimension(:), pointer, contiguous :: tempevap => null() !< evaporation temperature + real(DP), dimension(:), pointer, contiguous :: temproff => null() !< runoff temperature + real(DP), dimension(:), pointer, contiguous :: tempiflw => null() !< inflow temperature + + real(DP), dimension(:), pointer, contiguous :: ktf => null() !< thermal conductivity between the apt and groundwater cell + real(DP), dimension(:), pointer, contiguous :: rfeatthk => null() !< thickness of streambed/lakebed/filter-pack material through which thermal conduction occurs + + contains + + procedure :: bnd_da => sfe_da + procedure :: allocate_scalars + procedure :: apt_allocate_arrays => sfe_allocate_arrays + procedure :: find_apt_package => find_sfe_package + procedure :: pak_fc_expanded => sfe_fc_expanded + procedure :: pak_solve => sfe_solve + procedure :: pak_get_nbudterms => sfe_get_nbudterms + procedure :: pak_setup_budobj => sfe_setup_budobj + procedure :: pak_fill_budobj => sfe_fill_budobj + procedure :: sfe_rain_term + procedure :: sfe_evap_term + procedure :: sfe_roff_term + procedure :: sfe_iflw_term + procedure :: sfe_outf_term + procedure :: pak_df_obs => sfe_df_obs + procedure :: pak_rp_obs => sfe_rp_obs + procedure :: pak_bd_obs => sfe_bd_obs + procedure :: pak_set_stressperiod => sfe_set_stressperiod + + end type GweSfeType + +contains + + !> @brief Create a new sfe package + !< + subroutine sfe_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, & + fmi, eqnsclfac, gwecommon, dvt, dvu, dvua) + ! -- dummy + class(BndType), pointer :: packobj + integer(I4B), intent(in) :: id + integer(I4B), intent(in) :: ibcnum + integer(I4B), intent(in) :: inunit + integer(I4B), intent(in) :: iout + character(len=*), intent(in) :: namemodel + character(len=*), intent(in) :: pakname + type(TspFmiType), pointer :: fmi + real(DP), intent(in), pointer :: eqnsclfac !< Governing equation scale factor + type(GweInputDataType), intent(in), target :: gwecommon !< Shared data container for use by multiple GWE packages + character(len=*), intent(in) :: dvt !< For GWE, set to "TEMPERATURE" in TspAptType + character(len=*), intent(in) :: dvu !< For GWE, set to "energy" in TspAptType + character(len=*), intent(in) :: dvua !< For GWE, set to "E" in TspAptType + ! -- local + type(GweSfeType), pointer :: sfeobj + ! + ! -- Allocate the object and assign values to object variables + allocate (sfeobj) + packobj => sfeobj + ! + ! -- Create name and memory path + call packobj%set_names(ibcnum, namemodel, pakname, ftype) + packobj%text = text + ! + ! -- Allocate scalars + call sfeobj%allocate_scalars() + ! + ! -- Initialize package + call packobj%pack_initialize() + ! + packobj%inunit = inunit + packobj%iout = iout + packobj%id = id + packobj%ibcnum = ibcnum + packobj%ncolbnd = 1 + packobj%iscloc = 1 + ! + ! -- Store pointer to flow model interface. When the GwfGwt exchange is + ! created, it sets fmi%bndlist so that the GWT model has access to all + ! the flow packages + sfeobj%fmi => fmi + ! + ! -- Store pointer to governing equation scale factor + sfeobj%eqnsclfac => eqnsclfac + ! + ! -- Set labels that will be used in generalized APT class + sfeobj%depvartype = dvt + sfeobj%depvarunit = dvu + sfeobj%depvarunitabbrev = dvua + ! + ! -- Return + return + end subroutine sfe_create + + !> @brief Find corresponding sfe package + !< + subroutine find_sfe_package(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweSfeType) :: this + ! -- local + character(len=LINELENGTH) :: errmsg + class(BndType), pointer :: packobj + integer(I4B) :: ip, icount + integer(I4B) :: nbudterm + logical :: found + ! + ! -- Initialize found to false, and error later if flow package cannot + ! be found + found = .false. + ! + ! -- If user is specifying flows in a binary budget file, then set up + ! the budget file reader, otherwise set a pointer to the flow package + ! budobj + if (this%fmi%flows_from_file) then + call this%fmi%set_aptbudobj_pointer(this%flowpackagename, this%flowbudptr) + if (associated(this%flowbudptr)) found = .true. + ! + else + if (associated(this%fmi%gwfbndlist)) then + ! -- Look through gwfbndlist for a flow package with the same name as + ! this transport package name + do ip = 1, this%fmi%gwfbndlist%Count() + packobj => GetBndFromList(this%fmi%gwfbndlist, ip) + if (packobj%packName == this%flowpackagename) then + found = .true. + ! + ! -- Store BndType pointer to packobj, and then + ! use the select type to point to the budobj in flow package + this%flowpackagebnd => packobj + select type (packobj) + type is (SfrType) + this%flowbudptr => packobj%budobj + end select + end if + if (found) exit + end do + end if + end if + ! + ! -- Error if flow package not found + if (.not. found) then + write (errmsg, '(a)') 'COULD NOT FIND FLOW PACKAGE WITH NAME '& + &//trim(adjustl(this%flowpackagename))//'.' + call store_error(errmsg) + call this%parser%StoreErrorUnit() + end if + ! + ! -- Allocate space for idxbudssm, which indicates whether this is a + ! special budget term or one that is a general source and sink + nbudterm = this%flowbudptr%nbudterm + call mem_allocate(this%idxbudssm, nbudterm, 'IDXBUDSSM', this%memoryPath) + ! + ! -- Process budget terms and identify special budget terms + write (this%iout, '(/, a, a)') & + 'PROCESSING '//ftype//' INFORMATION FOR ', this%packName + write (this%iout, '(a)') ' IDENTIFYING FLOW TERMS IN '//flowtype//' PACKAGE' + write (this%iout, '(a, i0)') & + ' NUMBER OF '//flowtype//' = ', this%flowbudptr%ncv + icount = 1 + do ip = 1, this%flowbudptr%nbudterm + select case (trim(adjustl(this%flowbudptr%budterm(ip)%flowtype))) + case ('FLOW-JA-FACE') + this%idxbudfjf = ip + this%idxbudssm(ip) = 0 + case ('GWF') + this%idxbudgwf = ip + this%idxbudssm(ip) = 0 + case ('STORAGE') + this%idxbudsto = ip + this%idxbudssm(ip) = 0 + case ('RAINFALL') + this%idxbudrain = ip + this%idxbudssm(ip) = 0 + case ('EVAPORATION') + this%idxbudevap = ip + this%idxbudssm(ip) = 0 + case ('RUNOFF') + this%idxbudroff = ip + this%idxbudssm(ip) = 0 + case ('EXT-INFLOW') + this%idxbudiflw = ip + this%idxbudssm(ip) = 0 + case ('EXT-OUTFLOW') + this%idxbudoutf = ip + this%idxbudssm(ip) = 0 + case ('TO-MVR') + this%idxbudtmvr = ip + this%idxbudssm(ip) = 0 + case ('FROM-MVR') + this%idxbudfmvr = ip + this%idxbudssm(ip) = 0 + case ('AUXILIARY') + this%idxbudaux = ip + this%idxbudssm(ip) = 0 + case default + ! + ! -- Set idxbudssm equal to a column index for where the temperatures + ! are stored in the concbud(nbudssm, ncv) array + this%idxbudssm(ip) = icount + icount = icount + 1 + end select + write (this%iout, '(a, i0, " = ", a,/, a, i0)') & + ' TERM ', ip, trim(adjustl(this%flowbudptr%budterm(ip)%flowtype)), & + ' MAX NO. OF ENTRIES = ', this%flowbudptr%budterm(ip)%maxlist + end do + write (this%iout, '(a, //)') 'DONE PROCESSING '//ftype//' INFORMATION' + ! + ! -- Streambed conduction term + this%idxbudsbcd = this%idxbudgwf + ! + ! -- Return + return + end subroutine find_sfe_package + + !> @brief Add matrix terms related to SFE + !! + !! This will be called from TspAptType%apt_fc_expanded() + !! in order to add matrix terms specifically for SFE + !< + subroutine sfe_fc_expanded(this, rhs, ia, idxglo, matrix_sln) + ! -- dummy + class(GweSfeType) :: this + real(DP), dimension(:), intent(inout) :: rhs + integer(I4B), dimension(:), intent(in) :: ia + integer(I4B), dimension(:), intent(in) :: idxglo + class(MatrixBaseType), pointer :: matrix_sln + ! -- local + integer(I4B) :: j, n, n1, n2 + integer(I4B) :: iloc + integer(I4B) :: iposd, iposoffd + integer(I4B) :: ipossymd, ipossymoffd + integer(I4B) :: auxpos + real(DP) :: rrate + real(DP) :: rhsval + real(DP) :: hcofval + real(DP) :: ctherm + real(DP) :: wa !< wetted area + real(DP) :: ktf !< thermal conductivity of streambed material + real(DP) :: s !< thickness of conductive streambed material + ! + ! -- Add rainfall contribution + if (this%idxbudrain /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudrain)%nlist + call this%sfe_rain_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add evaporation contribution + if (this%idxbudevap /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudevap)%nlist + call this%sfe_evap_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add runoff contribution + if (this%idxbudroff /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudroff)%nlist + call this%sfe_roff_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add inflow contribution + if (this%idxbudiflw /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudiflw)%nlist + call this%sfe_iflw_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add outflow contribution + if (this%idxbudoutf /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudoutf)%nlist + call this%sfe_outf_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add streambed conduction contribution + do j = 1, this%flowbudptr%budterm(this%idxbudgwf)%nlist + ! + ! -- Set n to feature number and process if active feature + n = this%flowbudptr%budterm(this%idxbudgwf)%id1(j) + if (this%iboundpak(n) /= 0) then + ! + ! -- Set acoef and rhs to negative so they are relative to sfe and not gwe + auxpos = this%flowbudptr%budterm(this%idxbudgwf)%naux + wa = this%flowbudptr%budterm(this%idxbudgwf)%auxvar(auxpos, j) + ktf = this%ktf(n) + s = this%rfeatthk(n) + ctherm = ktf * wa / s + ! + ! -- Add to sfe row + iposd = this%idxdglo(j) + iposoffd = this%idxoffdglo(j) + call matrix_sln%add_value_pos(iposd, -ctherm) + call matrix_sln%add_value_pos(iposoffd, ctherm) + ! + ! -- Add to gwe row for sfe connection + ipossymd = this%idxsymdglo(j) + ipossymoffd = this%idxsymoffdglo(j) + call matrix_sln%add_value_pos(ipossymd, -ctherm) + call matrix_sln%add_value_pos(ipossymoffd, ctherm) + end if + end do + ! + ! -- Return + return + end subroutine sfe_fc_expanded + + !> @ brief Add terms specific to sfr to the explicit sfe solve + !< + subroutine sfe_solve(this) + ! -- dummy + class(GweSfeType) :: this + ! -- local + integer(I4B) :: j + integer(I4B) :: n1, n2 + real(DP) :: rrate + ! + ! -- Add rainfall contribution + if (this%idxbudrain /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudrain)%nlist + call this%sfe_rain_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add evaporation contribution + if (this%idxbudevap /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudevap)%nlist + call this%sfe_evap_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add runoff contribution + if (this%idxbudroff /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudroff)%nlist + call this%sfe_roff_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add inflow contribution + if (this%idxbudiflw /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudiflw)%nlist + call this%sfe_iflw_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add outflow contribution + if (this%idxbudoutf /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudoutf)%nlist + call this%sfe_outf_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! Note: explicit streambed conduction terms??? + ! + ! -- Return + return + end subroutine sfe_solve + + !> @brief Function to return the number of budget terms just for this package. + !! + !! This overrides a function in the parent class. + !< + function sfe_get_nbudterms(this) result(nbudterms) + ! -- dummy + class(GweSfeType) :: this + ! -- return + integer(I4B) :: nbudterms + ! + ! -- Number of budget terms is 6: + ! 1. rainfall + ! 2. evaporation + ! 3. runoff + ! 4. ext-inflow + ! 5. ext-outflow + ! 6. streambed-cond + nbudterms = 6 + ! + ! -- Return + return + end function sfe_get_nbudterms + + !> @brief Set up the budget object that stores all the sfe flows + !< + subroutine sfe_setup_budobj(this, idx) + ! -- modules + use ConstantsModule, only: LENBUDTXT + ! -- dummy + class(GweSfeType) :: this + integer(I4B), intent(inout) :: idx + ! -- local + integer(I4B) :: n, n1, n2 + integer(I4B) :: maxlist, naux + real(DP) :: q + character(len=LENBUDTXT) :: text + ! + ! -- + text = ' RAINFALL' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudrain)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- + text = ' EVAPORATION' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudevap)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- + text = ' RUNOFF' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudroff)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- + text = ' EXT-INFLOW' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudiflw)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- + text = ' EXT-OUTFLOW' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudoutf)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- Conduction through the wetted streambed + text = ' STREAMBED-COND' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudsbcd)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + call this%budobj%budterm(idx)%reset(maxlist) + q = DZERO + do n = 1, maxlist + n1 = this%flowbudptr%budterm(this%idxbudgwf)%id1(n) + n2 = this%flowbudptr%budterm(this%idxbudgwf)%id2(n) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + end do + ! + ! -- Return + return + end subroutine sfe_setup_budobj + + !> @brief Copy flow terms into this%budobj + !< + subroutine sfe_fill_budobj(this, idx, x, flowja, ccratin, ccratout) + ! -- dummy + class(GweSfeType) :: this + integer(I4B), intent(inout) :: idx + real(DP), dimension(:), intent(in) :: x + real(DP), dimension(:), contiguous, intent(inout) :: flowja + real(DP), intent(inout) :: ccratin + real(DP), intent(inout) :: ccratout + ! -- local + integer(I4B) :: j, n1, n2 + integer(I4B) :: nlist + integer(I4B) :: igwfnode + integer(I4B) :: idiag + integer(I4B) :: auxpos + real(DP) :: q + real(DP) :: ctherm + real(DP) :: wa !< wetted area + real(DP) :: ktf !< thermal conductivity of streambed material + real(DP) :: s !< thickness of conductive streambed materia + ! + ! -- Rain + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudrain)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%sfe_rain_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + ! + ! -- Evaporation + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudevap)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%sfe_evap_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + ! + ! -- Runoff + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudroff)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%sfe_roff_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + ! + ! -- Ext-inflow + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudiflw)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%sfe_iflw_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + ! + ! -- Ext-outflow + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudoutf)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%sfe_outf_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + ! + ! -- Strmbd-cond + idx = idx + 1 + call this%budobj%budterm(idx)%reset(this%maxbound) + do j = 1, this%flowbudptr%budterm(this%idxbudsbcd)%nlist + q = DZERO + n1 = this%flowbudptr%budterm(this%idxbudsbcd)%id1(j) + if (this%iboundpak(n1) /= 0) then + igwfnode = this%flowbudptr%budterm(this%idxbudsbcd)%id2(j) + ! -- For now, there is only 1 aux variable under 'GWF' + auxpos = this%flowbudptr%budterm(this%idxbudgwf)%naux + wa = this%flowbudptr%budterm(this%idxbudgwf)%auxvar(auxpos, j) + ktf = this%ktf(n1) + s = this%rfeatthk(n1) + ctherm = ktf * wa / s + q = ctherm * (x(igwfnode) - this%xnewpak(n1)) + end if + call this%budobj%budterm(idx)%update_term(n1, igwfnode, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + if (this%iboundpak(n1) /= 0) then + ! -- Contribution to gwe cell budget + this%simvals(n1) = this%simvals(n1) - q + idiag = this%dis%con%ia(igwfnode) + flowja(idiag) = flowja(idiag) - q + end if + end do + ! + ! -- Return + return + end subroutine sfe_fill_budobj + + !> @brief Allocate scalars specific to the streamflow energy transport (SFE) + !! package. + !< + subroutine allocate_scalars(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweSfeType) :: this + ! + ! -- Allocate scalars in TspAptType + call this%TspAptType%allocate_scalars() + ! + ! -- Allocate + call mem_allocate(this%idxbudrain, 'IDXBUDRAIN', this%memoryPath) + call mem_allocate(this%idxbudevap, 'IDXBUDEVAP', this%memoryPath) + call mem_allocate(this%idxbudroff, 'IDXBUDROFF', this%memoryPath) + call mem_allocate(this%idxbudiflw, 'IDXBUDIFLW', this%memoryPath) + call mem_allocate(this%idxbudoutf, 'IDXBUDOUTF', this%memoryPath) + call mem_allocate(this%idxbudsbcd, 'IDXBUDSBCD', this%memoryPath) + ! + ! -- Initialize + this%idxbudrain = 0 + this%idxbudevap = 0 + this%idxbudroff = 0 + this%idxbudiflw = 0 + this%idxbudoutf = 0 + this%idxbudsbcd = 0 + ! + ! -- Return + return + end subroutine allocate_scalars + + !> @brief Allocate arrays specific to the streamflow energy transport (SFE) + !! package. + !< + subroutine sfe_allocate_arrays(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweSfeType), intent(inout) :: this + ! -- local + integer(I4B) :: n + ! + ! -- Time series + call mem_allocate(this%temprain, this%ncv, 'TEMPRAIN', this%memoryPath) + call mem_allocate(this%tempevap, this%ncv, 'TEMPEVAP', this%memoryPath) + call mem_allocate(this%temproff, this%ncv, 'TEMPROFF', this%memoryPath) + call mem_allocate(this%tempiflw, this%ncv, 'TEMPIFLW', this%memoryPath) + ! + ! -- Call standard TspAptType allocate arrays + call this%TspAptType%apt_allocate_arrays() + ! + ! -- Initialize + do n = 1, this%ncv + this%temprain(n) = DZERO + this%tempevap(n) = DZERO + this%temproff(n) = DZERO + this%tempiflw(n) = DZERO + end do + ! + ! -- Return + return + end subroutine sfe_allocate_arrays + + !> @brief Deallocate memory + !< + subroutine sfe_da(this) + ! -- modules + use MemoryManagerModule, only: mem_deallocate + ! -- dummy + class(GweSfeType) :: this + ! + ! -- Deallocate scalars + call mem_deallocate(this%idxbudrain) + call mem_deallocate(this%idxbudevap) + call mem_deallocate(this%idxbudroff) + call mem_deallocate(this%idxbudiflw) + call mem_deallocate(this%idxbudoutf) + call mem_deallocate(this%idxbudsbcd) + ! + ! -- Deallocate time series + call mem_deallocate(this%temprain) + call mem_deallocate(this%tempevap) + call mem_deallocate(this%temproff) + call mem_deallocate(this%tempiflw) + ! + ! -- Deallocate scalars in TspAptType + call this%TspAptType%bnd_da() + ! + ! -- Return + return + end subroutine sfe_da + + !> @brief Rain term + !< + subroutine sfe_rain_term(this, ientry, n1, n2, rrate, rhsval, hcofval) + ! -- dummy + class(GweSfeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudrain)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudrain)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudrain)%flow(ientry) + ctmp = this%temprain(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac ! kluge note: think about budget / sensible heat issue + if (present(rhsval)) rhsval = -rrate + if (present(hcofval)) hcofval = DZERO + ! + ! -- Return + return + end subroutine sfe_rain_term + + !> @brief Evaporative term + !< + subroutine sfe_evap_term(this, ientry, n1, n2, rrate, rhsval, hcofval) + ! -- dummy + class(GweSfeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: heatlat + ! + n1 = this%flowbudptr%budterm(this%idxbudevap)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudevap)%id2(ientry) + ! -- note that qbnd is negative for evap + qbnd = this%flowbudptr%budterm(this%idxbudevap)%flow(ientry) + heatlat = this%gwecommon%gwerhow * this%gwecommon%gwelatheatvap + if (present(rrate)) rrate = qbnd * heatlat + !!if (present(rhsval)) rhsval = -rrate / this%eqnsclfac ! kluge note: divided by eqnsclfac for fc purposes because rrate is in terms of energy + if (present(rhsval)) rhsval = -rrate + if (present(hcofval)) hcofval = DZERO + ! + ! -- Return + return + end subroutine sfe_evap_term + + !> @brief Runoff term + !< + subroutine sfe_roff_term(this, ientry, n1, n2, rrate, rhsval, hcofval) + ! -- dummy + class(GweSfeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudroff)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudroff)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudroff)%flow(ientry) + ctmp = this%temproff(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac + if (present(rhsval)) rhsval = -rrate + if (present(hcofval)) hcofval = DZERO + ! + ! -- Return + return + end subroutine sfe_roff_term + + !> @brief Inflow Term + !! + !! Accounts for energy added via streamflow entering into a stream channel; + !! for example, energy entering the model domain via a specified flow in a + !! stream channel. + !< + subroutine sfe_iflw_term(this, ientry, n1, n2, rrate, rhsval, hcofval) + ! -- dummy + class(GweSfeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudiflw)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudiflw)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudiflw)%flow(ientry) + ctmp = this%tempiflw(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac + if (present(rhsval)) rhsval = -rrate + if (present(hcofval)) hcofval = DZERO + ! + ! -- Return + return + end subroutine sfe_iflw_term + + !> @brief Outflow term + !! + !! Accounts for the energy leaving a stream channel, for example, energy exiting the + !! model domain via a flow in a stream channel flowing out of the active domain. + !< + subroutine sfe_outf_term(this, ientry, n1, n2, rrate, rhsval, hcofval) + ! -- dummy + class(GweSfeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudoutf)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudoutf)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudoutf)%flow(ientry) + ctmp = this%xnewpak(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac + if (present(rhsval)) rhsval = DZERO + if (present(hcofval)) hcofval = qbnd * this%eqnsclfac + ! + ! -- Return + return + end subroutine sfe_outf_term + + !> @brief Observations + !! + !! Store the observation type supported by the APT package and overide + !! BndType%bnd_df_obs + !< + subroutine sfe_df_obs(this) + ! -- modules + ! -- dummy + class(GweSfeType) :: this + ! -- local + integer(I4B) :: indx + ! + ! -- Store obs type and assign procedure pointer + ! for temperature observation type. + call this%obs%StoreObsType('temperature', .false., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for flow between reaches. + call this%obs%StoreObsType('flow-ja-face', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID12 + ! + ! -- Store obs type and assign procedure pointer + ! for from-mvr observation type. + call this%obs%StoreObsType('from-mvr', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for to-mvr observation type. + call this%obs%StoreObsType('to-mvr', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for storage observation type. + call this%obs%StoreObsType('storage', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for constant observation type. + call this%obs%StoreObsType('constant', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for observation type: sfe + call this%obs%StoreObsType('sfe', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for rainfall observation type. + call this%obs%StoreObsType('rainfall', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for evaporation observation type. + call this%obs%StoreObsType('evaporation', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for runoff observation type. + call this%obs%StoreObsType('runoff', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for inflow observation type. + call this%obs%StoreObsType('ext-inflow', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for ext-outflow observation type. + call this%obs%StoreObsType('ext-outflow', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Return + return + end subroutine sfe_df_obs + + !> @brief Process package specific obs + !! + !! Method to process specific observations for this package. + !< + subroutine sfe_rp_obs(this, obsrv, found) + ! -- dummy + class(GweSfeType), intent(inout) :: this !< package class + type(ObserveType), intent(inout) :: obsrv !< observation object + logical, intent(inout) :: found !< indicate whether observation was found + ! -- local + ! + found = .true. + select case (obsrv%ObsTypeId) + case ('RAINFALL') + call this%rp_obs_byfeature(obsrv) + case ('EVAPORATION') + call this%rp_obs_byfeature(obsrv) + case ('RUNOFF') + call this%rp_obs_byfeature(obsrv) + case ('EXT-INFLOW') + call this%rp_obs_byfeature(obsrv) + case ('EXT-OUTFLOW') + call this%rp_obs_byfeature(obsrv) + case ('TO-MVR') + call this%rp_obs_byfeature(obsrv) + case default + found = .false. + end select + ! + ! -- Return + return + end subroutine sfe_rp_obs + + !> @brief Calculate observation value and pass it back to APT + !< + subroutine sfe_bd_obs(this, obstypeid, jj, v, found) + ! -- dummy + class(GweSfeType), intent(inout) :: this + character(len=*), intent(in) :: obstypeid + real(DP), intent(inout) :: v + integer(I4B), intent(in) :: jj + logical, intent(inout) :: found + ! -- local + integer(I4B) :: n1, n2 + ! + found = .true. + select case (obstypeid) + case ('RAINFALL') + if (this%iboundpak(jj) /= 0) then + call this%sfe_rain_term(jj, n1, n2, v) + end if + case ('EVAPORATION') + if (this%iboundpak(jj) /= 0) then + call this%sfe_evap_term(jj, n1, n2, v) + end if + case ('RUNOFF') + if (this%iboundpak(jj) /= 0) then + call this%sfe_roff_term(jj, n1, n2, v) + end if + case ('EXT-INFLOW') + if (this%iboundpak(jj) /= 0) then + call this%sfe_iflw_term(jj, n1, n2, v) + end if + case ('EXT-OUTFLOW') + if (this%iboundpak(jj) /= 0) then + call this%sfe_outf_term(jj, n1, n2, v) + end if + case default + found = .false. + end select + ! + ! -- Return + return + end subroutine sfe_bd_obs + + !> @brief Sets the stress period attributes for keyword use. + !< + subroutine sfe_set_stressperiod(this, itemno, keyword, found) + ! -- modules + use TimeSeriesManagerModule, only: read_value_or_time_series_adv + ! -- dummy + class(GweSfeType), intent(inout) :: this + integer(I4B), intent(in) :: itemno + character(len=*), intent(in) :: keyword + logical, intent(inout) :: found + ! -- local + character(len=LINELENGTH) :: text + integer(I4B) :: ierr + integer(I4B) :: jj + real(DP), pointer :: bndElem => null() + ! + ! RAINFALL + ! EVAPORATION + ! RUNOFF + ! INFLOW + ! WITHDRAWAL + ! + found = .true. + select case (keyword) + case ('RAINFALL') + ierr = this%apt_check_valid(itemno) + if (ierr /= 0) then + goto 999 + end if + call this%parser%GetString(text) + jj = 1 + bndElem => this%temprain(itemno) + call read_value_or_time_series_adv(text, itemno, jj, bndElem, & + this%packName, 'BND', this%tsManager, & + this%iprpak, 'RAINFALL') + case ('EVAPORATION') + ierr = this%apt_check_valid(itemno) + if (ierr /= 0) then + goto 999 + end if + call this%parser%GetString(text) + jj = 1 + bndElem => this%tempevap(itemno) + call read_value_or_time_series_adv(text, itemno, jj, bndElem, & + this%packName, 'BND', this%tsManager, & + this%iprpak, 'EVAPORATION') + case ('RUNOFF') + ierr = this%apt_check_valid(itemno) + if (ierr /= 0) then + goto 999 + end if + call this%parser%GetString(text) + jj = 1 + bndElem => this%temproff(itemno) + call read_value_or_time_series_adv(text, itemno, jj, bndElem, & + this%packName, 'BND', this%tsManager, & + this%iprpak, 'RUNOFF') + case ('INFLOW') + ierr = this%apt_check_valid(itemno) + if (ierr /= 0) then + goto 999 + end if + call this%parser%GetString(text) + jj = 1 + bndElem => this%tempiflw(itemno) + call read_value_or_time_series_adv(text, itemno, jj, bndElem, & + this%packName, 'BND', this%tsManager, & + this%iprpak, 'INFLOW') + case default + ! + ! -- Keyword not recognized so return to caller with found = .false. + found = .false. + end select + ! +999 continue + ! + ! -- Return + return + end subroutine sfe_set_stressperiod + +end module GweSfeModule diff --git a/src/Model/GroundWaterTransport/gwt1lkt1.f90 b/src/Model/GroundWaterTransport/gwt1lkt1.f90 index e8775deec83..9e441516268 100644 --- a/src/Model/GroundWaterTransport/gwt1lkt1.f90 +++ b/src/Model/GroundWaterTransport/gwt1lkt1.f90 @@ -542,12 +542,13 @@ end subroutine lkt_setup_budobj !> @brief Copy flow terms into this%budobj !< - subroutine lkt_fill_budobj(this, idx, x, ccratin, ccratout) + subroutine lkt_fill_budobj(this, idx, x, flowja, ccratin, ccratout) ! -- modules ! -- dummy class(GwtLktType) :: this integer(I4B), intent(inout) :: idx real(DP), dimension(:), intent(in) :: x + real(DP), dimension(:), contiguous, intent(inout) :: flowja real(DP), intent(inout) :: ccratin real(DP), intent(inout) :: ccratout ! -- local diff --git a/src/Model/GroundWaterTransport/gwt1mwt1.f90 b/src/Model/GroundWaterTransport/gwt1mwt1.f90 index 842a051235f..1cd782c9917 100644 --- a/src/Model/GroundWaterTransport/gwt1mwt1.f90 +++ b/src/Model/GroundWaterTransport/gwt1mwt1.f90 @@ -473,12 +473,13 @@ end subroutine mwt_setup_budobj !> @brief Copy flow terms into this%budobj !< - subroutine mwt_fill_budobj(this, idx, x, ccratin, ccratout) + subroutine mwt_fill_budobj(this, idx, x, flowja, ccratin, ccratout) ! -- modules ! -- dummy class(GwtMwtType) :: this integer(I4B), intent(inout) :: idx real(DP), dimension(:), intent(in) :: x + real(DP), dimension(:), contiguous, intent(inout) :: flowja real(DP), intent(inout) :: ccratin real(DP), intent(inout) :: ccratout ! -- local diff --git a/src/Model/GroundWaterTransport/gwt1sft1.f90 b/src/Model/GroundWaterTransport/gwt1sft1.f90 index fc6ffafc171..ef36c177631 100644 --- a/src/Model/GroundWaterTransport/gwt1sft1.f90 +++ b/src/Model/GroundWaterTransport/gwt1sft1.f90 @@ -502,12 +502,13 @@ end subroutine sft_setup_budobj !> @brief Copy flow terms into this%budobj !< - subroutine sft_fill_budobj(this, idx, x, ccratin, ccratout) + subroutine sft_fill_budobj(this, idx, x, flowja, ccratin, ccratout) ! -- modules ! -- dummy class(GwtSftType) :: this integer(I4B), intent(inout) :: idx real(DP), dimension(:), intent(in) :: x + real(DP), dimension(:), contiguous, intent(inout) :: flowja real(DP), intent(inout) :: ccratin real(DP), intent(inout) :: ccratout ! -- local diff --git a/src/Model/GroundWaterTransport/gwt1uzt1.f90 b/src/Model/GroundWaterTransport/gwt1uzt1.f90 index 4006062fb28..bd67facdf71 100644 --- a/src/Model/GroundWaterTransport/gwt1uzt1.f90 +++ b/src/Model/GroundWaterTransport/gwt1uzt1.f90 @@ -466,12 +466,13 @@ subroutine uzt_setup_budobj(this, idx) end subroutine uzt_setup_budobj !> @brief Copy flow terms into this%budobj - subroutine uzt_fill_budobj(this, idx, x, ccratin, ccratout) + subroutine uzt_fill_budobj(this, idx, x, flowja, ccratin, ccratout) ! -- modules ! -- dummy class(GwtUztType) :: this integer(I4B), intent(inout) :: idx real(DP), dimension(:), intent(in) :: x + real(DP), dimension(:), contiguous, intent(inout) :: flowja real(DP), intent(inout) :: ccratin real(DP), intent(inout) :: ccratout ! -- local diff --git a/src/Model/TransportModel/tsp1apt1.f90 b/src/Model/TransportModel/tsp1apt1.f90 index 4d2bb855b0d..f92089279f2 100644 --- a/src/Model/TransportModel/tsp1apt1.f90 +++ b/src/Model/TransportModel/tsp1apt1.f90 @@ -80,7 +80,6 @@ module TspAptModule integer(I4B), pointer :: idxprepak => null() !< budget-object index that precedes package-specific budget objects integer(I4B), pointer :: idxlastpak => null() !< budget-object index of last package-specific budget object real(DP), dimension(:), pointer, contiguous :: strt => null() !< starting feature concentration (or temperature) - real(DP), dimension(:), pointer, contiguous :: rfeatthk => null() !< thickness of streambed/lakebed/filter-pack material through which thermal conduction occurs integer(I4B), dimension(:), pointer, contiguous :: idxlocnode => null() !< map position in global rhs and x array of pack entry integer(I4B), dimension(:), pointer, contiguous :: idxpakdiag => null() !< map diag position of feature in global amat integer(I4B), dimension(:), pointer, contiguous :: idxdglo => null() !< map position in global array of package diagonal row entries @@ -2311,7 +2310,7 @@ subroutine apt_fill_budobj(this, x, flowja) ! ! -- individual package terms processed last idx = this%idxprepak - call this%pak_fill_budobj(idx, x, ccratin, ccratout) + call this%pak_fill_budobj(idx, x, flowja, ccratin, ccratout) ! ! --Terms are filled, now accumulate them for this time step call this%budobj%accumulate_terms() @@ -2322,12 +2321,13 @@ end subroutine apt_fill_budobj !> @brief Copy flow terms into this%budobj, must be overridden !< - subroutine pak_fill_budobj(this, idx, x, ccratin, ccratout) + subroutine pak_fill_budobj(this, idx, x, flowja, ccratin, ccratout) ! -- modules ! -- dummy class(TspAptType) :: this integer(I4B), intent(inout) :: idx real(DP), dimension(:), intent(in) :: x + real(DP), dimension(:), contiguous, intent(inout) :: flowja real(DP), intent(inout) :: ccratin real(DP), intent(inout) :: ccratout ! -- local diff --git a/src/meson.build b/src/meson.build index 2227eb67345..be95234745d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -70,6 +70,7 @@ modflow_sources = files( 'Model' / 'GroundWaterEnergy' / 'gwe1est1.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1ic1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1idm.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1sfe1.f90', 'Model' / 'GroundWaterFlow' / 'gwf3.f90', 'Model' / 'GroundWaterFlow' / 'gwf3api8.f90', 'Model' / 'GroundWaterFlow' / 'gwf3buy8.f90', From 3091a553e4bb5eccadfed61f1c4ca24b8f676537 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Wed, 7 Feb 2024 17:27:39 -0800 Subject: [PATCH 38/46] Add autotest for SFE --- autotest/test_gwe_sfe_strmbedcond.py | 799 +++++++++++++++++++++++ src/Model/GroundWaterEnergy/gwe1sfe1.f90 | 8 +- src/Model/TransportModel/tsp1apt1.f90 | 25 +- 3 files changed, 828 insertions(+), 4 deletions(-) create mode 100644 autotest/test_gwe_sfe_strmbedcond.py diff --git a/autotest/test_gwe_sfe_strmbedcond.py b/autotest/test_gwe_sfe_strmbedcond.py new file mode 100644 index 00000000000..6c9deb027e8 --- /dev/null +++ b/autotest/test_gwe_sfe_strmbedcond.py @@ -0,0 +1,799 @@ +# Test conduction between an advanced package feature, in this case stream +# reaches with varying channel geometries and the host GWE gw cells. +# This test should include: +# - no gw-sw interaction +# - with gw-sw interaction +# - hot gw cell warming an upstream reach +# - thermally hot stream water warming host gw cells +# + +import os + +import flopy +import numpy as np +import pytest +import math +from framework import TestFramework + +cases = ["sfe-conductn", "sfe-conducti", "sfe-conducto", "sfe-conductm"] +# +# The last letter in the names above indicates the following +# n = "no gw/sw exchange" +# i = "gwf into strm" +# o = "strm to gw" +# m = "mixed" (i.e., convection one direction, conductive gradient the other direction?) + +k11 = 500.0 +rhk = [0.0, k11, k11, k11] +strt_gw_temp = [4.0, 4.0, 4.0, 20.0] +strm_temp = [18.0, 18.0, 20.0, 4.0] +chd_condition = ["n", "i", "o", "m"] +surf_Q_in = [ + [8.64, 0.0], + [8640.0, 0.0], + [8640.0, 0.0], + [8640.0, 0.0], +] # 86400 m^3/d = 1 m^3/s = 35.315 cfs + + +def get_x_frac(x_coord1, rwid): + x_xsec1 = [val / rwid for val in x_coord1] + return x_xsec1 + + +def get_xy_pts(x, y, rwid): + x_xsec1 = get_x_frac(x, rwid) + x_sec_tab = [[xx, hh] for xx, hh, in zip(x_xsec1, y)] + return x_sec_tab + + +# Model units +length_units = "m" +time_units = "days" + +# model domain and grid definition +Lx = 90.0 +Ly = 90.0 +nrow = 3 +ncol = 3 +nlay = 1 +delr = Lx / ncol +delc = Ly / nrow +xmax = ncol * delr +ymax = nrow * delc +X, Y = np.meshgrid( + np.linspace(delr / 2, xmax - delr / 2, ncol), + np.linspace(ymax - delc / 2, 0 + delc / 2, nrow), +) +ibound = np.ones((nlay, nrow, ncol)) +# Because eqn uses negative values in the Y direction, need to do a little manipulation +Y_m = -1 * np.flipud(Y) +top = np.array( + [ + [101.50, 101.25, 101.00], + [101.25, 101.00, 100.75], + [101.50, 101.25, 101.00], + ] +) + +botm = np.array( + [ + [98.5, 98.25, 98.0], + [98.25, 98.0, 97.75], + [98.5, 98.25, 98.0], + ] +) +strthd = 98.75 +chd_on = True + +# NPF parameters +ss = 0.00001 +sy = 0.20 +hani = 1 +laytyp = 1 + +# Package boundary conditions +sfr_evaprate = 0.1 +rwid = [9.0, 10.0, 20] +# Channel geometry: trapezoidal +x_sec_tab1 = get_xy_pts( + [0.0, 2.0, 4.0, 5.0, 7.0, 9.0], + [0.66666667, 0.33333333, 0.0, 0.0, 0.33333333, 0.66666667], + rwid[0], +) + +x_sec_tab2 = get_xy_pts( + [0.0, 2.0, 4.0, 6.0, 8.0, 10.0], + [0.5, 0.25, 0.0, 0.0, 0.25, 0.5], + rwid[1], +) + +x_sec_tab3 = get_xy_pts( + [0.0, 4.0, 8.0, 12.0, 16.0, 20.0], + [0.33333333, 0.16666667, 0.0, 0.0, 0.16666667, 0.33333333], + rwid[2], +) +x_sec_tab = [x_sec_tab1, x_sec_tab2, x_sec_tab3] + + +def calc_wp(j, stg): + if j < 1: + rise = 1 / 3 + run = 2 + bot_wid = 1.0 + elif j < 2: + rise = 1 / 4 + run = 2 + bot_wid = 2.0 + else: + rise = 1 / 6 + run = 4 + bot_wid = 4.0 + + ang = math.atan2(rise, run) + hyp_len = stg / math.sin(ang) + wp = hyp_len * 2 + bot_wid + + return wp + + +def process_line(line): + m_arr = line.strip().split() + if any("=" in itm and len(itm) > 1 for itm in m_arr): + m_arr = [ + float(itm.split("=")[-1]) if len(itm.split("=")) > 1 else itm + for itm in m_arr + ] + nm = m_arr[-2] + else: + nm = m_arr[-3] + val = m_arr[-1] + return {nm: float(val)} + + +def get_bud(fname, srchStr): + in_bud_lst = {} + out_bud_lst = {} + with open(fname, "r") as f: + for line in f: + if srchStr in line: + # Read the package budget + line = next(f) + while not "TOTAL IN =" in line: + if "=" in line: + in_bud_lst.update(process_line(line)) + + line = next(f) + + # Get "total in" + dct = process_line(line) + T_in = dct["IN"] + + line = next(f) + while not "TOTAL OUT =" in line: + if "=" in line: + out_bud_lst.update(process_line(line)) + + line = next(f) + + # Get "total out" + dct = process_line(line) + T_out = dct["OUT"] + + break + + return T_in, T_out, in_bud_lst, out_bud_lst + + +def trenddetector(list_of_index, array_of_data, order=1): + result = np.polyfit(list_of_index, list(array_of_data), order) + slope = result[-2] + return float(slope) + + +# Transport related parameters +porosity = sy # porosity (unitless) +K_therm = 2.0 # Thermal conductivity # ($W/m/C$) +rhow = 1000 # Density of water ($kg/m^3$) +rhos = 2650 # Density of the aquifer material ($kg/m^3$) +Cpw = 4180 # Heat capacity of water ($J/kg/C$) +Cps = 880 # Heat capacity of the solids ($J/kg/C$) +lhv = 2454000.0 # Latent heat of vaporization ($J/kg$) +K_therm_strmbed = [ + 1.5, + 1.75, + 2.0, +] # Thermal conductivity of the streambed material ($W/m/C$) +rbthcnd = [0.0001, 0.0001, 0.0001, 0.0001] + +# time params +steady = {0: False, 1: False} +transient = {0: True, 1: True} +nstp = [1, 1] +tsmult = [1, 1] +perlen = [1, 1] + +nouter, ninner = 1000, 300 +hclose, rclose, relax = 1e-3, 1e-4, 0.97 + +# +# MODFLOW 6 flopy GWF object +# + + +def build_models(idx, test): + # Base simulation and model name and workspace + ws = test.workspace + name = cases[idx] + + print("Building model...{}".format(name)) + + # generate names for each model + gwfname = "gwf-" + name + gwename = "gwe-" + name + + sim = flopy.mf6.MFSimulation( + sim_name=name, sim_ws=ws, exe_name="mf6", version="mf6" + ) + + # Instantiating time discretization + tdis_rc = [] + for i in range(len(nstp)): + tdis_rc.append((perlen[i], nstp[i], tsmult[i])) + + flopy.mf6.ModflowTdis( + sim, nper=len(nstp), perioddata=tdis_rc, time_units=time_units + ) + + gwf = flopy.mf6.ModflowGwf( + sim, + modelname=gwfname, + save_flows=True, + newtonoptions="newton", + ) + + # Instantiating solver + ims = flopy.mf6.ModflowIms( + sim, + print_option="ALL", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="cooley", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwfname), + ) + sim.register_ims_package(ims, [gwfname]) + + # Instantiate discretization package + flopy.mf6.ModflowGwfdis( + gwf, + length_units=length_units, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + ) + + # Instantiate node property flow package + flopy.mf6.ModflowGwfnpf( + gwf, + save_specific_discharge=True, + icelltype=1, # >0 means saturated thickness varies with computed head + k=k11, + ) + + # Instantiate storage package + flopy.mf6.ModflowGwfsto( + gwf, + save_flows=False, + iconvert=laytyp, + ss=ss, + sy=sy, + steady_state=steady, + transient=transient, + ) + + # Instantiate initial conditions package + flopy.mf6.ModflowGwfic(gwf, strt=strthd) + + # Instantiate output control package + flopy.mf6.ModflowGwfoc( + gwf, + budget_filerecord=f"{gwfname}.cbc", + head_filerecord=f"{gwfname}.hds", + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + printrecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + ) + + # Instantiate constant head boundary package + if chd_condition[idx] == "n": + chdelev1 = top[0, 0] - 3.0 + chdelev2 = top[0, -1] - 3.0 + elif chd_condition[idx] == "i": + chdelev1 = top[0, 0] - 0.05 + chdelev2 = top[0, -1] - 0.05 + elif chd_condition[idx] == "o": + chdelev1 = top[0, 0] - 3.0 + chdelev2 = top[0, -1] - 3.0 + elif chd_condition[idx] == "m": + chdelev1 = top[0, 0] - 3.0 # convection from stream to gw, + chdelev2 = top[0, -1] - 3.0 # conduction from gw to strm + + # Instatiate constant head boundary package + if chd_on: + chdlist1 = [ + [(0, 0, 0), chdelev1, strt_gw_temp[idx]], + [(0, 0, ncol - 1), chdelev2, strt_gw_temp[idx]], + [(0, nrow - 1, 0), chdelev1, strt_gw_temp[idx]], + [(0, nrow - 1, ncol - 1), chdelev2, strt_gw_temp[idx]], + ] + flopy.mf6.ModflowGwfchd( + gwf, + stress_period_data=chdlist1, + print_input=True, + print_flows=True, + save_flows=False, + pname="CHD-1", + auxiliary="TEMPERATURE", + filename=f"{gwfname}.chd", + ) + + # Instantiate streamflow routing package + # Determine the middle row and store in rMid (account for 0-base) + rMid = 1 + # sfr data + nreaches = ncol + rlen = delr + roughness = 0.035 + rbth = 1.0 + strmbd_hk = rhk[idx] + strm_up = 100.25 + strm_dn = 99 + slope = ( + (strm_up - strm_dn) / ((ncol - 1) * delr) / 10 + ) # divide by 10 to further reduce slop + ustrf = 1.0 + ndv = 0 + strm_incision = 1.0 + + # use trapezoidal cross-section for channel geometry + sfr_xsec_tab_nm1 = "{}.xsec.tab1".format(gwfname) + sfr_xsec_tab_nm2 = "{}.xsec.tab2".format(gwfname) + sfr_xsec_tab_nm3 = "{}.xsec.tab3".format(gwfname) + sfr_xsec_tab_nm = [sfr_xsec_tab_nm1, sfr_xsec_tab_nm2, sfr_xsec_tab_nm3] + crosssections = [] + for n in range(nreaches): + # 3 reaches, 3 cross section types + crosssections.append([n, sfr_xsec_tab_nm[n]]) + + # Setup the tables + for n in range(len(x_sec_tab)): + flopy.mf6.ModflowUtlsfrtab( + gwf, + nrow=len(x_sec_tab[n]), + ncol=2, + table=x_sec_tab[n], + filename=sfr_xsec_tab_nm[n], + pname=f"sfrxsectable" + str(n + 1), + ) + + packagedata = [] + for irch in range(nreaches): + nconn = 1 + if 0 < irch < nreaches - 1: + nconn += 1 + rp = [ + irch, + (0, rMid, irch), + rlen, + rwid[irch], + slope, + top[rMid, irch] - strm_incision, + rbth, + strmbd_hk, + roughness, + nconn, + ustrf, + ndv, + ] + packagedata.append(rp) + + connectiondata = [] + for irch in range(nreaches): + rc = [irch] + if irch > 0: + rc.append(irch - 1) + if irch < nreaches - 1: + rc.append(-(irch + 1)) + connectiondata.append(rc) + + sfr_perioddata = {} + for t in np.arange(len(surf_Q_in[idx])): + sfrbndx = [] + for i in np.arange(nreaches): + if i == 0: + sfrbndx.append([i, "INFLOW", surf_Q_in[idx][t]]) + # sfrbndx.append([i, "EVAPORATION", sfr_evaprate]) + + sfr_perioddata.update({t: sfrbndx}) + + # Instantiate SFR observation points + sfr_obs = { + "{}.sfr.obs.csv".format(gwfname): [ + ("rch1_depth", "depth", 1), + ("rch2_depth", "depth", 2), + ("rch3_depth", "depth", 3), + ], + "digits": 8, + "print_input": True, + "filename": name + ".sfr.obs", + } + + budpth = f"{gwfname}.sfr.cbc" + flopy.mf6.ModflowGwfsfr( + gwf, + save_flows=True, + print_stage=True, + print_flows=True, + print_input=True, + length_conversion=1.0, + time_conversion=86400, + budget_filerecord=budpth, + mover=False, + nreaches=nreaches, + packagedata=packagedata, + connectiondata=connectiondata, + crosssections=crosssections, + perioddata=sfr_perioddata, + observations=sfr_obs, + pname="SFR-1", + filename="{}.sfr".format(gwfname), + ) + + # -------------------------------------------------- + # Setup the GWE model for simulating heat transport + # -------------------------------------------------- + gwe = flopy.mf6.ModflowGwe(sim, modelname=gwename) + + # Instantiating solver for GWT + imsgwe = flopy.mf6.ModflowIms( + sim, + print_option="ALL", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwename), + ) + sim.register_ims_package(imsgwe, [gwename]) + + # Instantiating DIS for GWE + flopy.mf6.ModflowGwedis( + gwe, + length_units=length_units, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + pname="DIS", + filename="{}.dis".format(gwename), + ) + + # Instantiate Mobile Storage and Transfer package + flopy.mf6.ModflowGweest( + gwe, + save_flows=True, + porosity=porosity, + cps=Cps, + rhos=rhos, + packagedata=[Cpw, rhow, lhv], + pname="EST", + filename="{}.est".format(gwename), + ) + + # Instantiate Energy Transport Initial Conditions package + flopy.mf6.ModflowGweic(gwe, strt=strt_gw_temp[idx]) + + # Instantiate Advection package + flopy.mf6.ModflowGweadv(gwe, scheme="UPSTREAM") + + # Instantiate Dispersion package (also handles conduction) + flopy.mf6.ModflowGwecnd( + gwe, + xt3d_off=True, + ktw=0.5918, + kts=0.2700, + pname="CND", + filename="{}.cnd".format(gwename), + ) + + # Instantiating MODFLOW 6 transport source-sink mixing package + # [b/c at least one boundary back is active (SFR), ssm must be on] + sourcerecarray = [("CHD-1", "AUX", "TEMPERATURE")] + flopy.mf6.ModflowGwessm( + gwe, sources=sourcerecarray, filename="{}.ssm".format(gwename) + ) + + # Instantiate Streamflow Energy Transport package + sfepackagedata = [] + for irno in range(ncol): + t = (irno, strm_temp[idx], K_therm_strmbed[irno], rbthcnd[idx]) + sfepackagedata.append(t) + + sfeperioddata = [] + for irno in range(ncol): + if irno == 0: + sfeperioddata.append((irno, "INFLOW", strm_temp[idx])) + # sfeperioddata.append((irno, sfr_applied_bnd[idx], sfe_applied_temp[idx])) + + flopy.mf6.modflow.ModflowGwesfe( + gwe, + boundnames=False, + save_flows=True, + print_input=False, + print_flows=False, + print_temperature=True, + temperature_filerecord=gwename + ".sfe.bin", + budget_filerecord=gwename + ".sfe.bud", + packagedata=sfepackagedata, + reachperioddata=sfeperioddata, + flow_package_name="SFR-1", + pname="SFE-1", + filename="{}.sfe".format(gwename), + ) + + # Instantiate Output Control package for transport + flopy.mf6.ModflowGweoc( + gwe, + temperature_filerecord="{}.ucn".format(gwename), + saverecord=[("TEMPERATURE", "ALL")], + temperatureprintrecord=[ + ("COLUMNS", 3, "WIDTH", 20, "DIGITS", 8, "GENERAL") + ], + printrecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + filename="{}.oc".format(gwename), + ) + + # Instantiate Gwf-Gwe Exchange package + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename, + filename="{}.gwfgwe".format(gwename), + ) + + return sim, None + + +def check_output(idx, test): + print("evaluating results...") + + # read flow results from model + name = cases[idx] + gwfname = "gwf-" + name + + fname = gwfname + ".sfr.cbc" + fname = os.path.join(test.workspace, fname) + assert os.path.isfile(fname) + + sfrobj = flopy.utils.binaryfile.CellBudgetFile(fname, precision="double") + sfr_wetted_interface_area = sfrobj.get_data(text="gwf") + + # Retrieve simulated stage of each reach + sfr_pth0 = os.path.join(test.workspace, f"{gwfname}.sfr.obs.csv") + sfrstg = np.genfromtxt(sfr_pth0, names=True, delimiter=",") + + # Extract shared wetted interfacial areas + shared_area = [] + for t in range(len(sfr_wetted_interface_area)): + sp_area = [] + for i in range(ncol): + sp_area.append(sfr_wetted_interface_area[t][i][3]) + + shared_area.append(sp_area) + + shared_area = np.array(shared_area) + + # Calculate wetted streambed area for comparison + for j, stg in enumerate(list(sfrstg[0])[1:]): + wp = calc_wp(j, stg) + wa = wp * delr + msg = ( + "Wetted streambed area for reach " + + str(j) + + "in stress period 1 does not match explicitly-calculated answer" + ) + assert np.isclose(wa, shared_area[0, j], atol=1e-4), msg + + msg = ( + "Wetted streambed area of all reaches should be zero in stess " + "period 2" + ) + for val in list(sfrstg[1])[1:]: + assert val == 0.0, msg + + # Sub-scenario checks + # initialize search term + srchStr = "SFE-1 BUDGET FOR ENTIRE MODEL AT END OF TIME STEP 1, STRESS PERIOD 1" + fname = "gwe-" + name + ".lst" + fname = os.path.join(test.workspace, fname) + + # gw exchng (item 'GWF') should be zero in heat transport budget + T_in, T_out, in_bud_lst, out_bud_lst = get_bud(fname, srchStr) + assert np.isclose( + T_in, T_out, atol=0.1 + ), "There is a heat budget discrepancy" + + # Get temperature of streamwater + fname1 = "gwe-" + name + ".sfe.bin" + fname1 = os.path.join(test.workspace, fname1) + sfeobj = flopy.utils.HeadFile( + fname1, precision="double", text="TEMPERATURE" + ) + sfe_temps = sfeobj.get_alldata() + + # Get temperature of gw + fname2 = "gwe-" + name + ".ucn" + fname2 = os.path.join(test.workspace, fname2) + gwobj = flopy.utils.HeadFile( + fname2, precision="double", text="TEMPERATURE" + ) + gw_temps = gwobj.get_alldata() + + msg1 = "Budget item 'GWF' should be 0.0 for this scenario" + msg2 = "Thermal conduction is occurring in the wrong direction" + msg3 = ( + "There should be a decreasing temperatures trend in " + "downstream direction owing to conductive losses" + ) + msg4 = ( + "There should be an increasing temperature trend in " + "the row of cells hosting the stream owing to increasing " + "conductive losses from the stream to the aquifer " + "(i.e., greater shared wetted areas)" + ) + if ( + name[-1] == "n" + ): # no gw/sw convective exchange, simulates conductive exchange only + + assert in_bud_lst["GWF"] == 0.0, msg1 + assert out_bud_lst["GWF"] == 0.0, msg1 + + # Determine gw/sfe temperature gradient direction + if sfe_temps[0, 0, 0, 0] > gw_temps[0, 0, 0, 0]: + # conduction will be from stream to gw + assert in_bud_lst["STREAMBED-COND"] == 0.0, msg2 + assert out_bud_lst["STREAMBED-COND"] > 0.0, msg2 + + slp = trenddetector( + np.arange(0, sfe_temps.shape[-1]), sfe_temps[0, 0, 0, :] + ) + assert slp < 0.0, msg3 + + slp = trenddetector( + np.arange(0, gw_temps.shape[-2]), gw_temps[0, 0, 1, :] + ) + assert slp > 0.0, msg4 + + else: + assert in_bud_lst["STREAMBED-COND"] > 0.0, msg2 + assert out_bud_lst["STREAMBED-COND"] == 0.0, msg2 + + # streamflow gain from aquifer ("into stream") + if name[-1] == "i": + + msg = "Budget item 'GWF' should reflect heat entering stream" + assert in_bud_lst["GWF"] > 0.0, msg + assert out_bud_lst["GWF"] == 0.0, msg + + # Determine gw/sfe temperature gradient direction + if sfe_temps[0, 0, 0, 0] > gw_temps[0, 0, 0, 0]: + # conduction will be from stream to gw + assert in_bud_lst["STREAMBED-COND"] == 0.0, msg2 + assert out_bud_lst["STREAMBED-COND"] > 0.0, msg2 + + slp = trenddetector( + np.arange(0, sfe_temps.shape[-1]), sfe_temps[0, 0, 0, :] + ) + assert slp < 0.0, msg3 + + slp = trenddetector( + np.arange(0, gw_temps.shape[-2]), gw_temps[0, 0, 1, :] + ) + assert slp > 0.0, msg4 + + else: + assert in_bud_lst["STREAMBED-COND"] > 0.0, msg2 + assert out_bud_lst["STREAMBED-COND"] == 0.0, msg2 + + # streamflow loss to aquifer ("out of stream") + if name[-1] == "o": + + msg = "Budget item 'GWF' should reflect heat exiting stream" + assert in_bud_lst["GWF"] == 0.0, msg + assert out_bud_lst["GWF"] > 0.0, msg + + # Determine gw/sfe temperature gradient direction + if sfe_temps[0, 0, 0, 0] > gw_temps[0, 0, 0, 0]: + # conduction will be from stream to gw + assert in_bud_lst["STREAMBED-COND"] == 0.0, msg2 + assert out_bud_lst["STREAMBED-COND"] > 0.0, msg2 + + slp = trenddetector( + np.arange(0, sfe_temps.shape[-1]), sfe_temps[0, 0, 0, :] + ) + assert slp < 0.0, msg3 + + slp = trenddetector( + np.arange(0, gw_temps.shape[-2]), gw_temps[0, 0, 1, :] + ) + assert slp < 0.0, msg4 + + else: + assert in_bud_lst["STREAMBED-COND"] > 0.0, msg2 + assert out_bud_lst["STREAMBED-COND"] == 0.0, msg2 + + # Reverse temperature gradient (cold stream, warm aquifer) + # Loss of streamwater to aquifer + # Thus, convection from strm to gw, conduction from gw to strm + if name[-1] == "m": # 'm' for mixed + + msg = "Budget item 'GWF' should reflect heat exiting stream" + assert in_bud_lst["GWF"] == 0.0, msg + assert out_bud_lst["GWF"] > 0.0, msg + + # Determine gw/sfe temperature gradient direction + if sfe_temps[0, 0, 0, 0] > gw_temps[0, 0, 0, 0]: + # conduction will be from stream to gw + assert in_bud_lst["STREAMBED-COND"] == 0.0, msg2 + assert out_bud_lst["STREAMBED-COND"] > 0.0, msg2 + + else: + assert in_bud_lst["STREAMBED-COND"] > 0.0, msg2 + assert out_bud_lst["STREAMBED-COND"] == 0.0, msg2 + + slp = trenddetector( + np.arange(0, sfe_temps.shape[-1]), sfe_temps[0, 0, 0, :] + ) + assert slp > 0.0, msg3 + + slp = trenddetector( + np.arange(0, gw_temps.shape[-2]), gw_temps[0, 0, 1, :] + ) + assert slp > 0.0, msg4 + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(cases)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t), + ) + test.run() diff --git a/src/Model/GroundWaterEnergy/gwe1sfe1.f90 b/src/Model/GroundWaterEnergy/gwe1sfe1.f90 index 76300171b31..e2e514d1d11 100644 --- a/src/Model/GroundWaterEnergy/gwe1sfe1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1sfe1.f90 @@ -70,9 +70,6 @@ module GweSfeModule real(DP), dimension(:), pointer, contiguous :: temproff => null() !< runoff temperature real(DP), dimension(:), pointer, contiguous :: tempiflw => null() !< inflow temperature - real(DP), dimension(:), pointer, contiguous :: ktf => null() !< thermal conductivity between the apt and groundwater cell - real(DP), dimension(:), pointer, contiguous :: rfeatthk => null() !< thickness of streambed/lakebed/filter-pack material through which thermal conduction occurs - contains procedure :: bnd_da => sfe_da @@ -148,6 +145,11 @@ subroutine sfe_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, & ! -- Store pointer to governing equation scale factor sfeobj%eqnsclfac => eqnsclfac ! + ! -- Store pointer to shared data module for accessing cpw, rhow + ! for the budget calculations, and for accessing the latent heat of + ! vaporization for evaporative cooling. + sfeobj%gwecommon => gwecommon + ! ! -- Set labels that will be used in generalized APT class sfeobj%depvartype = dvt sfeobj%depvarunit = dvu diff --git a/src/Model/TransportModel/tsp1apt1.f90 b/src/Model/TransportModel/tsp1apt1.f90 index f92089279f2..c37b82b693a 100644 --- a/src/Model/TransportModel/tsp1apt1.f90 +++ b/src/Model/TransportModel/tsp1apt1.f90 @@ -61,7 +61,6 @@ module TspAptModule character(len=LENFTYPE) :: ftype = 'APT' character(len=LENVARNAME) :: text = ' APT' - character(len=LENVARNAME) :: tsptype = 'GWT' !< to be removed once TSP refactor is further sorted out type, extends(BndType) :: TspAptType @@ -80,6 +79,8 @@ module TspAptModule integer(I4B), pointer :: idxprepak => null() !< budget-object index that precedes package-specific budget objects integer(I4B), pointer :: idxlastpak => null() !< budget-object index of last package-specific budget object real(DP), dimension(:), pointer, contiguous :: strt => null() !< starting feature concentration (or temperature) + real(DP), dimension(:), pointer, contiguous :: ktf => null() !< thermal conductivity between the apt and groundwater cell + real(DP), dimension(:), pointer, contiguous :: rfeatthk => null() !< thickness of streambed/lakebed/filter-pack material through which thermal conduction occurs integer(I4B), dimension(:), pointer, contiguous :: idxlocnode => null() !< map position in global rhs and x array of pack entry integer(I4B), dimension(:), pointer, contiguous :: idxpakdiag => null() !< map diag position of feature in global amat integer(I4B), dimension(:), pointer, contiguous :: idxdglo => null() !< map position in global array of package diagonal row entries @@ -1273,6 +1274,8 @@ subroutine apt_da(this) call mem_deallocate(this%qsto) call mem_deallocate(this%ccterm) call mem_deallocate(this%strt) + call mem_deallocate(this%ktf) + call mem_deallocate(this%rfeatthk) call mem_deallocate(this%lauxvar) call mem_deallocate(this%xoldpak) if (this%imatrows == 0) then @@ -1545,6 +1548,8 @@ subroutine apt_read_cvs(this) ! ! -- allocate apt data call mem_allocate(this%strt, this%ncv, 'STRT', this%memoryPath) + call mem_allocate(this%ktf, this%ncv, 'KTF', this%memoryPath) + call mem_allocate(this%rfeatthk, this%ncv, 'RFEATTHK', this%memoryPath) call mem_allocate(this%lauxvar, this%naux, this%ncv, 'LAUXVAR', & this%memoryPath) ! @@ -1561,6 +1566,8 @@ subroutine apt_read_cvs(this) ! do n = 1, this%ncv this%strt(n) = DEP20 + this%ktf(n) = DZERO + this%rfeatthk(n) = DZERO this%lauxvar(:, n) = DZERO this%xoldpak(n) = DEP20 if (this%imatrows == 0) then @@ -1608,6 +1615,22 @@ subroutine apt_read_cvs(this) ! -- strt this%strt(n) = this%parser%GetDouble() ! + ! -- If GWE model, read additional thermal conductivity terms + if (this%depvartype == 'TEMPERATURE') then + ! -- Skip for UZE + if (trim(adjustl(this%text)) /= 'UZE') then + this%ktf(n) = this%parser%GetDouble() + this%rfeatthk(n) = this%parser%GetDouble() + if (this%rfeatthk(n) <= DZERO) then + write (errmsg, '(4x,a)') & + '****ERROR. Specified thickness used for thermal & + &conduction MUST BE > 0 else divide by zero error occurs' + call store_error(errmsg) + cycle + end if + end if + end if + ! ! -- get aux data do iaux = 1, this%naux call this%parser%GetString(caux(iaux)) From c52dc145b430b23a21f91fdb6673af386d147d98 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Thu, 8 Feb 2024 07:50:23 -0800 Subject: [PATCH 39/46] Adding lake energy transport (LKE) package. Includes new autotest --- autotest/test_gwe_lke_conduction.py | 780 +++++++ doc/Common/gwe-lkeobs.tex | 31 +- doc/mf6io/gwe/gwe.tex | 4 + doc/mf6io/gwe/lke.tex | 55 + doc/mf6io/gwe/namefile.tex | 1 + doc/mf6io/mf6io_copy.bbl | 289 +++ doc/mf6io/mf6ivar/dfn/gwe-lke.dfn | 481 ++++ .../mf6ivar/examples/gwe-lke-example-obs.dat | 25 + .../mf6ivar/examples/gwe-lke-example.dat | 24 + doc/mf6io/mf6ivar/md/mf6ivar.md | 38 + doc/mf6io/mf6ivar/mf6ivar.py | 1 + doc/mf6io/mf6ivar/tex/appendixA.tex | 4 + doc/mf6io/mf6ivar/tex/gwe-lke-desc.tex | 101 + doc/mf6io/mf6ivar/tex/gwe-lke-options.dat | 15 + doc/mf6io/mf6ivar/tex/gwe-lke-packagedata.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-lke-period.dat | 5 + doc/mf6io/usgs.bst | 2080 +++++++++++++++++ make/makefile | 1 + msvs/mf6core.vfproj | 1 + src/Model/GroundWaterEnergy/gwe1.f90 | 50 +- src/Model/GroundWaterEnergy/gwe1lke1.f90 | 1241 ++++++++++ src/Model/TransportModel/tsp1apt1.f90 | 4 +- 22 files changed, 5189 insertions(+), 47 deletions(-) create mode 100644 autotest/test_gwe_lke_conduction.py create mode 100644 doc/mf6io/gwe/lke.tex create mode 100644 doc/mf6io/mf6io_copy.bbl create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-lke.dfn create mode 100644 doc/mf6io/mf6ivar/examples/gwe-lke-example-obs.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-lke-example.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-lke-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-lke-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-lke-packagedata.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-lke-period.dat create mode 100644 doc/mf6io/usgs.bst create mode 100644 src/Model/GroundWaterEnergy/gwe1lke1.f90 diff --git a/autotest/test_gwe_lke_conduction.py b/autotest/test_gwe_lke_conduction.py new file mode 100644 index 00000000000..412df9816e9 --- /dev/null +++ b/autotest/test_gwe_lke_conduction.py @@ -0,0 +1,780 @@ +# Simple single lake model. Lake cut into top two layers of a 5 layer +# model. Model is loosely based on the first example problem in +# Merritt and Konikow (2000) which also is one of the MT3D-USGS test +# problems. This test developed to isolate lake-aquifer interaction; +# no SFR or other advanced packages. Problem set up to have only +# conductive exchange with groundwater, then groundwater pass-through: +# that is, gw inflow on the left side, gw outflow on the +# right side of the lake. +# +# starting groundwater temperature: 4.0 +# left chd boundary inflow temperature: 4.0 +# starting lake temperature: 20.0 +# + +import os + +import numpy as np +import pytest +import flopy +from framework import TestFramework + + +def process_line(line): + m_arr = line.strip().split() + if any("=" in itm and len(itm) > 1 for itm in m_arr): + m_arr = [ + float(itm.split("=")[-1]) if len(itm.split("=")) > 1 else itm + for itm in m_arr + ] + nm = m_arr[-2] + else: + nm = m_arr[-3] + val = m_arr[-1] + return {nm: float(val)} + + +def get_bud(fname, srchStr): + in_bud_lst = {} + out_bud_lst = {} + with open(fname, "r") as f: + for line in f: + if srchStr in line: + # Read the package budget + line = next(f) + while not "TOTAL IN =" in line: + if "=" in line: + in_bud_lst.update(process_line(line)) + + line = next(f) + + # Get "total in" + dct = process_line(line) + T_in = dct["IN"] + + line = next(f) + while not "TOTAL OUT =" in line: + if "=" in line: + out_bud_lst.update(process_line(line)) + + line = next(f) + + # Get "total out" + dct = process_line(line) + T_out = dct["OUT"] + + break + + return T_in, T_out, in_bud_lst, out_bud_lst + + +def trenddetector(list_of_index, array_of_data, order=1): + result = np.polyfit(list_of_index, list(array_of_data), order) + slope = result[-2] + return float(slope) + + +cases = ["lke-conductn", "lke-conductm", "lke-conductr"] + +# +# The last letter in the names above indicates the following +# n = "no lk/gw exchange" +# m = "mixed" (i.e., convection one direction, conductive gradient the other direction?) +# r = "reversed thermal gradients (warm gw, cold lake) + +strt_gw_temp = [4.0, 4.0, 20.0] +strt_lk_temp = [20.0, 20.0, 4.0] +lak_leakance = [0.0, 1.0, 1.0] +strt_lk_stg = [33.75, 33.75, 33.75] +lkbdthkcnd = [ + 0.0001, + 0.0001, + 0.0001, +] # Thickness to consider for feature/gw conduction + +# Model units +length_units = "m" +time_units = "days" + +# model domain and grid definition +delr = [ + 76.2, + 304.8, + 304.8, + 304.8, + 304.8, + 304.8, + 152.4, + 152.4, + 152.4, + 152.4, + 152.4, + 304.8, + 304.8, + 304.8, + 304.8, + 304.8, + 76.2, +] + +delc = [ + 76.2, + 304.8, + 304.8, + 304.8, + 304.8, + 304.8, + 152.4, + 152.4, + 152.4, + 152.4, + 152.4, + 304.8, + 304.8, + 304.8, + 304.8, + 304.8, + 76.2, +] + +fixedstrthds = [ + 35.052, + 34.9267, + 34.7216, + 34.5062, + 34.2755, + 34.0237, + 33.8143, + 33.6657, + 33.5077, + 33.3394, + 33.1599, + 32.8728, + 32.4431, + 31.9632, + 31.4353, + 30.8627, + 30.48, +] + +nrow = len(delc) +ncol = len(delr) +top = np.ones((nrow, ncol)) * 35.6616 +bot1 = np.ones_like(top) * 32.6136 +bot2 = np.ones_like(top) * 29.5656 +bot3 = np.ones_like(top) * 26.5176 +bot4 = np.ones_like(top) * 23.4696 +bot5 = np.ones_like(top) * 20.4216 +botm = np.array([bot1, bot2, bot3, bot4, bot5]) +nlay = botm.shape[0] +ibound = np.ones_like(botm) + +# deactive gw cells where lake cells are active +ibound[0, 6:11, 6:11] = 0 # layer 1 +ibound[1, 7:10, 7:10] = 0 # layer 2 + +strthd = np.zeros_like(ibound) +for j in np.arange(ncol): + strthd[:, :, j] = fixedstrthds[j] + +# setup lake array +lakibnd = np.zeros_like(ibound) +lakibnd[0] = 1 - ibound[0] # layer 1 +lakibnd[1] = 1 - ibound[1] # layer 2 + +# NPF parameters +k11 = 9.144 # = 30 ft/day +k33 = 0.9144 # = 30 ft/day +ss = 3e-4 +sy = 0.20 +hani = 1 +laytyp = 1 + +# Package boundary conditions +chdl = 35.052 +chdr = 30.48 +viscref = 8.904e-4 + +# time params +transient = {0: True} +nstp = [10] +tsmult = [1.0] +perlen = [5000] + +# solver params +nouter, ninner = 1000, 300 +hclose, rclose, relax = 1e-3, 1e-4, 0.97 + +# Transport related parameters +al = 1 # longitudinal dispersivity ($m$) +ath1 = al # horizontal transverse dispersivity +atv = al # vertical transverse dispersivity +mixelm = 0 # Upstream vs TVD (Upstream selected) +porosity = 0.20 # porosity (unitless) +K_therm = 2.0 # Thermal conductivity # ($W/m/C$) +rhow = 1000 # Density of water ($kg/m^3$) +rhos = 2650 # Density of the aquifer material ($kg/m^3$) +Cpw = 4180 # Heat Capacity of water ($J/kg/C$) +Cps = 880 # Heat capacity of the solids ($J/kg/C$) +lhv = 2454000.0 # Latent heat of vaporization ($J/kg$) +K_therm_lakebed = 1.5 # Thermal conductivity of the lakebed material ($W/m/C$) + + +# +# MODFLOW 6 flopy GWF & GWE simulation object (sim) is returned +# + + +def build_models(idx, test): + global lak_lkup_dict + + # Base simulation and model name and workspace + ws = test.workspace + name = cases[idx] + + print("Building model...{}".format(name)) + + # generate names for each model + gwfname = "gwf-" + name + gwename = "gwe-" + name + + sim = flopy.mf6.MFSimulation( + sim_name=name, sim_ws=ws, exe_name="mf6", version="mf6" + ) + + tdis_rc = [] + for i in range(len(nstp)): + tdis_rc.append((perlen[i], nstp[i], tsmult[i])) + + flopy.mf6.ModflowTdis( + sim, nper=len(nstp), perioddata=tdis_rc, time_units=time_units + ) + + gwf = flopy.mf6.ModflowGwf( + sim, modelname=gwfname, save_flows=True, newtonoptions="newton" + ) + + # Instantiating solver + ims = flopy.mf6.ModflowIms( + sim, + print_option="ALL", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="cooley", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwfname), + ) + sim.register_ims_package(ims, [gwfname]) + + # Instantiate discretization package + flopy.mf6.ModflowGwfdis( + gwf, + length_units=length_units, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=ibound, + filename="{}.dis".format(gwfname), + ) + + # Instantiate node property flow package + flopy.mf6.ModflowGwfnpf( + gwf, + save_specific_discharge=True, + icelltype=1, # >0 means saturated thickness varies with computed head + k=k11, + k33=k33, + ) + + # Instantiate storage package + flopy.mf6.ModflowGwfsto( + gwf, + save_flows=False, + iconvert=laytyp, + ss=ss, + sy=sy, + transient=transient, + ) + + # Instantiate initial conditions package + flopy.mf6.ModflowGwfic(gwf, strt=strthd) + + # Instantiate output control package + flopy.mf6.ModflowGwfoc( + gwf, + budget_filerecord=f"{gwfname}.cbc", + head_filerecord=f"{gwfname}.hds", + headprintrecord=[("COLUMNS", 17, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + printrecord=[("HEAD", "ALL"), ("BUDGET", "LAST")], + ) + + # Instantiate constant head package + # (for driving gw flow from left to right) + chdlistl = [] + chdlistr = [] + for k in np.arange(nlay): + for i in np.arange(nrow): + # left side + if botm[k, i, 0] <= chdl: + chdlistl.append([(k, i, 0), chdl, strt_gw_temp[idx]]) + # right side + if botm[k, i, -1] <= chdr: + chdlistr.append([(k, i, ncol - 1), chdr, 10.0]) + + flopy.mf6.ModflowGwfchd( + gwf, + stress_period_data=chdlistl, + print_input=True, + print_flows=True, + save_flows=False, + pname="CHD-L", + auxiliary="TEMPERATURE", + filename=f"{gwfname}.left.chd", + ) + + flopy.mf6.ModflowGwfchd( + gwf, + stress_period_data=chdlistr, + print_input=True, + print_flows=True, + save_flows=False, + pname="CHD-R", + auxiliary="TEMPERATURE", + filename=f"{gwfname}.right.chd", + ) + + # Instantiate lake package + lakeconnectiondata = [] + nlakecon = [0] # Expand this to [0, 0, ...] for each additional lake + ilakconn = -1 + lak_lkup_dict = {} + for k in [0, 1]: + for i in range(nrow): + for j in range(ncol): + if lakibnd[k, i, j] == 0: + continue + else: + ilak = int(lakibnd[k, i, j] - 1) + # back + if i > 0: + if ( + lakibnd[k, i - 1, j] == 0 + and ibound[k, i - 1, j] == 1 + ): + ilakconn += 1 + # by setting belev==telev, MF6 will automatically + # re-assign elevations based on cell dimensions + h = [ + ilak, # + ilakconn, # + (k, i - 1, j), # + "horizontal", # + lak_leakance[idx], # + 0.0, # + 0.0, # + delc[i] / 2.0, # + delr[j], # + ] + lakeconnectiondata.append(h) + lak_lkup_dict.update({ilakconn: (k, i, j)}) + + # left + if j > 0: + if ( + lakibnd[k, i, j - 1] == 0 + and ibound[k, i, j - 1] == 1 + ): + ilakconn += 1 + h = [ + ilak, + ilakconn, + (k, i, j - 1), + "horizontal", + lak_leakance[idx], + 0.0, + 0.0, + delr[j] / 2.0, + delc[i], + ] + lakeconnectiondata.append(h) + lak_lkup_dict.update({ilakconn: (k, i, j)}) + + # right + if j < ncol - 1: + if ( + lakibnd[k, i, j + 1] == 0 + and ibound[k, i, j + 1] == 1 + ): + ilakconn += 1 + h = [ + ilak, + ilakconn, + (k, i, j + 1), + "horizontal", + lak_leakance[idx], + 0.0, + 0.0, + delr[j] / 2.0, + delc[i], + ] + lakeconnectiondata.append(h) + lak_lkup_dict.update({ilakconn: (k, i, j)}) + + # front + if i < nrow - 1: + if ( + lakibnd[k, i + 1, j] == 0 + and ibound[k, i + 1, j] == 1 + ): + ilakconn += 1 + h = [ + ilak, + ilakconn, + (k, i + 1, j), + "horizontal", + lak_leakance[idx], + 0.0, + 0.0, + delc[i] / 2.0, + delr[j], + ] + lakeconnectiondata.append(h) + lak_lkup_dict.update({ilakconn: (k, i, j)}) + + # vertical + if lakibnd[k, i, j] == 1 and ibound[k + 1, i, j] == 1: + ilakconn += 1 + v = [ + ilak, + ilakconn, + (k + 1, i, j), + "vertical", + lak_leakance[idx], + 0.0, + 0.0, + 0.0, + 0.0, + ] + lakeconnectiondata.append(v) + lak_lkup_dict.update({ilakconn: (k, i, j)}) + + strtStg = strt_lk_stg[idx] + lakpackagedata = [ + [0, strtStg, len(lakeconnectiondata), strt_lk_temp[idx], "lake1"] + ] + lak_pkdat_dict = {"filename": "lak_pakdata.in", "data": lakpackagedata} + + lakeperioddata = {0: []} + + lak_obs = { + "{}.lakeobs".format(gwfname): [ + ("lakestage", "stage", "lake1"), + ("gwexchng", "lak", "lake1"), + ] + } + lak = flopy.mf6.ModflowGwflak( + gwf, + auxiliary="TEMPERATURE", + time_conversion=86400.0, + print_stage=True, + print_flows=True, + budget_filerecord=gwfname + ".lak.bud", + length_conversion=1.0, + mover=False, + pname="LAK-1", + boundnames=True, + nlakes=len(lakpackagedata), + noutlets=0, + packagedata=lak_pkdat_dict, + connectiondata=lakeconnectiondata, + perioddata=lakeperioddata, + observations=lak_obs, + filename="{}.lak".format(gwfname), + ) + + # pull in the tabfile defining the lake stage, vol, & surface area + fname = os.path.join("data", "vsc04-laktab", "stg-vol-surfarea.dat") + tabinput = [] + with open(fname, "r") as f: + # peel off the hdr line + hdr = next(f) + for line in f: + m_arr = line.strip().split(",") + # , , , + tabinput.append([float(m_arr[0]), m_arr[1], m_arr[2]]) + + tab6_filename = "{}.laktab".format(gwfname) + flopy.mf6.ModflowUtllaktab( + gwf, + nrow=len(tabinput), + ncol=3, + table=tabinput, + filename=tab6_filename, + pname="LAK_tab", + parent_file=lak, + ) + + # ----------------- + # Create GWE model + # ----------------- + + gwe = flopy.mf6.ModflowGwe( + sim, modelname=gwename, model_nam_file="{}.nam".format(gwename) + ) + gwe.name_file.save_flows = True + + imsgwe = flopy.mf6.ModflowIms( + sim, + print_option="ALL", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename=f"{gwename}.ims", + ) + sim.register_ims_package(imsgwe, [gwename]) + + # Instantiating MODFLOW 6 enregy transport discretization package + flopy.mf6.ModflowGwedis( + gwe, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=ibound, + filename="{}.dis".format(gwename), + ) + + # Instantiating MODFLOW 6 energy transport initial temperatures + strttemp = strt_gw_temp[idx] + flopy.mf6.ModflowGweic( + gwe, strt=strttemp, filename="{}.ic".format(gwename) + ) + + # Instantiate mobile storage and transfer package + flopy.mf6.ModflowGweest( + gwe, + porosity=porosity, + cps=Cps, + rhos=rhos, + packagedata=[Cpw, rhow, lhv], + pname="MST-1", + filename=f"{gwename}.mst", + ) + + # Instantiating MODFLOW 6 energy transport advection package + if mixelm == 0: + scheme = "UPSTREAM" + elif mixelm == -1: + scheme = "TVD" + else: + raise Exception() + + # Instantiate advection package + flopy.mf6.ModflowGweadv( + gwe, scheme=scheme, filename="{}.adv".format(gwename) + ) + + # Instantiate dispersion package + flopy.mf6.ModflowGwecnd( + gwe, + xt3d_off=True, + ktw=0.5918, + kts=0.2700, + filename="{}.dsp".format(gwename), + ) + + # Instantiate source/sink mixing package + sourcerecarray = [ + ("CHD-L", "AUX", "TEMPERATURE"), + ("CHD-R", "AUX", "TEMPERATURE"), + ] + flopy.mf6.ModflowGwessm( + gwe, sources=sourcerecarray, filename=f"{gwename}.ssm" + ) + + # Instantiating MODFLOW 6 transport output control package + flopy.mf6.ModflowGweoc( + gwe, + budget_filerecord="{}.cbc".format(gwename), + temperature_filerecord="{}.ucn".format(gwename), + temperatureprintrecord=[ + ("COLUMNS", 17, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + printrecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + filename="{}.oc".format(gwename), + ) + + # Instantiating MODFLOW 6 lake energy transport (lke) package + lkepackagedata = [ + (0, strt_lk_temp[idx], K_therm_lakebed, lkbdthkcnd[idx], "lake1") + ] + + # lkeperioddata = {0: [(0, "STATUS", "CONSTANT"), (0, "TEMPERATURE", 4.0)]} + + # note: for specifying lake number, use fortran indexing! + lke_obs = { + "{}.lakobs".format(gwename): [ + ("resTemp", "temperature", 1), + ("resGwEnerExchng", "lke", "lake1"), + ] + } + + flopy.mf6.ModflowGwelke( + gwe, # Set time_conversion for use with Manning's eqn. + flow_package_name="LAK-1", + flow_package_auxiliary_name="TEMPERATURE", + budget_filerecord=gwename + ".lke.bud", + boundnames=True, + save_flows=True, + print_input=True, + print_flows=False, + print_temperature=True, + packagedata=lkepackagedata, + # lakeperioddata=lkeperioddata, + observations=lke_obs, + pname="LKE-1", + filename="{}.lke".format(gwename), + ) + + # GWF-GWE exchange + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename, + filename=f"{name}.gwfgwe", + ) + + return sim, None + + +def check_output(idx, test): + print("evaluating results...") + + # read flow results from model + name = cases[idx] + gwename = "gwe-" + name + + # Retrieve simulated temperature for the lake + fname = gwename + ".lakobs" + lktemp_file = os.path.join(test.workspace, fname) + lktemp = np.genfromtxt(lktemp_file, names=True, delimiter=",") + lktemp = lktemp["RESTEMP"].astype(float).reshape((lktemp.size, 1)) + + # Retrieve groundwater temperatures + fname = gwename + ".ucn" + fname = os.path.join(test.workspace, fname) + assert os.path.isfile(fname) + gwtempobj = flopy.utils.HeadFile( + fname, precision="double", text="TEMPERATURE" + ) + gwe_temps = gwtempobj.get_alldata() + + # gw exchng (item 'GWF') should be zero in heat transport budget + srchStr = "LKE-1 BUDGET FOR ENTIRE MODEL AT END OF TIME STEP 1, STRESS PERIOD 1" + fname = gwename + ".lst" + fname = os.path.join(test.workspace, fname) + + # Retrieve budget + T_in, T_out, in_bud_lst, out_bud_lst = get_bud(fname, srchStr) + assert np.isclose( + T_in, T_out, atol=0.1 + ), "There is a heat budget discrepancy where there shouldn't be" + + msg1 = "Budget item 'GWF' should be 0.0 for this scenario" + msg2 = ( + "Thermal conduction is occurring in the wrong direction based " + "on the thermal gradient between the lake and groundwater system" + ) + msg3 = ( + "There should be a cooling trend in the lake based on heat loss " + "to the groundwater system" + ) + msg4 = ( + "There should be a warming trend in the groundwater adjacent " + "to the lake" + ) + msg5 = ( + "Budget item 'GWF' should reflect heat entering the lake " + "(via gw/sw exchange)" + ) + msg6 = ( + "Budget item 'GWF' should reflect heat exiting the lake " + "(via gw/sw exchange)" + ) + + if name[-1] == "n": + + assert in_bud_lst["GWF"] == 0.0, msg1 + assert out_bud_lst["GWF"] == 0.0, msg1 + + if name[-1] != "n": + + assert in_bud_lst["GWF"] > 0.0, msg5 + assert out_bud_lst["GWF"] > 0.0, msg6 + + # Determine gw/sfe temperature gradient direction + if lktemp[0] > gwe_temps[0, 0, 0, 0]: + # conduction will be from lake to gw cells + assert in_bud_lst["LAKEBED-COND"] == 0.0, msg2 + assert out_bud_lst["LAKEBED-COND"] > 0.0, msg2 + + slp = trenddetector(np.arange(len(lktemp)), lktemp) + # Lake should be cooling through conductive exchange with cold gw + assert slp < 0.0, msg3 + + slp = trenddetector(np.arange(lktemp.shape[0]), gwe_temps[:, 1, 8, 11]) + # gw should be warming through conductive exchange with a warm lake + assert slp > 0.0, msg4 + + else: # thermally reversed scenario (cold lake, warm gw) + + # conduction will be from gw cells to lake + assert in_bud_lst["LAKEBED-COND"] > 0.0, msg2 + assert out_bud_lst["LAKEBED-COND"] == 0.0, msg2 + + slp = trenddetector(np.arange(len(lktemp)), lktemp) + # Lake should be warming through conductive exchange with warm gw + assert slp > 0.0, msg3 + + slp = trenddetector(np.arange(lktemp.shape[0]), gwe_temps[:, 1, 8, 11]) + # gw should be cooling through conductive exchange with a cold lake + assert slp < 0.0, msg4 + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(cases)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t), + ) + test.run() diff --git a/doc/Common/gwe-lkeobs.tex b/doc/Common/gwe-lkeobs.tex index ac32aee4ffe..f66ba397ae3 100644 --- a/doc/Common/gwe-lkeobs.tex +++ b/doc/Common/gwe-lkeobs.tex @@ -1,25 +1,18 @@ % general APT observations -LKE & temperature & ifno or boundname & -- & Lake temperature. If boundname is specified, boundname must be unique for each lake. \\ -LKE & flow-ja-face & ifno or boundname & ifno or -- & Energy flow between two lakes connected by an outlet. If more than one outlet is used to connect the same two lakes, then the energy flow for only the first outlet can be observed. If a boundname is specified for ID1, then the result is the total energy flow for all outlets for a lake. If a boundname is specified for ID1 then ID2 is not used.\\ -LKE & storage & ifno or boundname & -- & Simulated energy storage flow rate for a lake or group of lakes. \\ -LKE & constant & ifno or boundname & -- & Simulated energy constant-flow rate for a lake or group of lakes. \\ -LKE & from-mvr & ifno or boundname & -- & Simulated energy inflow into a lake or group of lakes from the MVE package. Energy inflow is calculated as the product of provider temperature and the mover flow rate. \\ +LKE & temperature & lakeno or boundname & -- & Lake temperature. If boundname is specified, boundname must be unique for each lake. \\ +LKE & flow-ja-face & lakeno or boundname & lakeno or -- & Energy flow between two lakes connected by an outlet. If more than one outlet is used to connect the same two lakes, then the energy flow for only the first outlet can be observed. If a boundname is specified for ID1, then the result is the total energy flow for all outlets for a lake. If a boundname is specified for ID1 then ID2 is not used.\\ +LKE & storage & lakeno or boundname & -- & Simulated energy storage flow rate for a lake or group of lakes. \\ +LKE & constant & lakeno or boundname & -- & Simulated energy constant-flow rate for a lake or group of lakes. \\ +LKE & from-mvr & lakeno or boundname & -- & Simulated energy inflow into a lake or group of lakes from the MVE package. Energy inflow is calculated as the product of provider temperature and the mover flow rate. \\ LKE & to-mvr & outletno or boundname & -- & Energy outflow from a lake outlet, a lake, or a group of lakes that is available for the MVR package. If boundname is not specified for ID, then the outflow available for the MVR package from a specific lake outlet is observed. In this case, ID is the outlet number, which must be between 1 and NOUTLETS. \\ -LKE & lkt & ifno or boundname & \texttt{iconn} or -- & Energy flow rate for a lake or group of lakes and its aquifer connection(s). If boundname is not specified for ID, then the simulated lake-aquifer flow rate at a specific lake connection is observed. In this case, ID2 must be specified and is the connection number \texttt{iconn} for lake \texttt{ifno}. \\ +LKE & lke & lakeno or boundname & \texttt{iconn} or -- & Energy flow rate for a lake or group of lakes and its aquifer connection(s). If boundname is not specified for ID, then the simulated lake-aquifer flow rate at a specific lake connection is observed. In this case, ID2 must be specified and is the connection number \texttt{iconn} for lake \texttt{lakeno}. \\ %observations specific to the lake package % rainfall evaporation runoff ext-inflow withdrawal outflow -LKE & rainfall & ifno or boundname & -- & Rainfall rate applied to a lake or group of lakes multiplied by the rainfall temperature. \\ -LKE & evaporation & ifno or boundname & -- & Simulated evaporation rate from a lake or group of lakes multiplied by latent heat of vaporization, heat capcity of the simulated fluid, and the density of the simulated fluid. \\ -LKE & runoff & ifno or boundname & -- & Runoff rate applied to a lake or group of lakes multiplied by the runoff temperature. \\ -LKE & ext-inflow & ifno or boundname & -- & Energy inflow into a lake or group of lakes calculated as the external inflow rate multiplied by the inflow temperature. \\ -LKE & withdrawal & ifno or boundname & -- & Specified withdrawal rate from a lake or group of lakes multiplied by the simulated lake temperature. \\ -LKE & ext-outflow & ifno or boundname & -- & External outflow from a lake or a group of lakes, through their outlets, to an external boundary. If the water mover is active, the reported ext-outflow value plus the rate to mover is equal to the total outlet outflow. +LKE & rainfall & lakeno or boundname & -- & Rainfall rate applied to a lake or group of lakes multiplied by the rainfall temperature. \\ +LKE & evaporation & lakeno or boundname & -- & Simulated evaporation rate from a lake or group of lakes multiplied by the latent heat of evaporation for determining the energy lost from a lake. \\ +LKE & runoff & lakeno or boundname & -- & Runoff rate applied to a lake or group of lakes multiplied by the runoff temperature. \\ +LKE & ext-inflow & lakeno or boundname & -- & Energy inflow into a lake or group of lakes calculated as the external inflow rate multiplied by the inflow temperature. \\ +LKE & withdrawal & lakeno or boundname & -- & Specified withdrawal rate from a lake or group of lakes multiplied by the simulated lake temperature. \\ +LKE & ext-outflow & lakeno or boundname & -- & External outflow from a lake or a group of lakes, through their outlets, to an external boundary. If the water mover is active, the reported ext-outflow value plus the rate to mover is equal to the total outlet outflow. -%LKE & outlet-inflow & ifno or boundname & -- & Simulated inflow from upstream lake outlets into a lake or group of lakes. \\ -%LKE & inflow & ifno or boundname & -- & Sum of specified inflow and simulated inflow from upstream lake outlets into a lake or group of lakes. \\ -%LKE & outlet & outletno or boundname & -- & Simulate outlet flow rate from a lake outlet, a lake, or a group of lakes. If boundname is not specified for ID, then the flow from a specific lake outlet is observed. In this case, ID is the outlet number outletno. \\ -%LKE & volume & ifno or boundname & -- & Simulated lake volume or group of lakes. \\ -%LKE & surface-area & ifno or boundname & -- & Simulated surface area for a lake or group of lakes. \\ -%LKE & wetted-area & ifno or boundname & \texttt{iconn} or -- & Simulated wetted-area for a lake or group of lakes and its aquifer connection(s). If boundname is not specified for ID, then the wetted area of a specific lake connection is observed. In this case, ID2 must be specified and is the connection number \texttt{iconn}. \\ -%LKE & conductance & ifno or boundname & \texttt{iconn} or -- & Calculated conductance for a lake or group of lakes and its aquifer connection(s). If boundname is not specified for ID, then the calculated conductance of a specific lake connection is observed. In this case, ID2 must be specified and is the connection number \texttt{iconn}. diff --git a/doc/mf6io/gwe/gwe.tex b/doc/mf6io/gwe/gwe.tex index 2655c0d07e5..6840cf3baa1 100644 --- a/doc/mf6io/gwe/gwe.tex +++ b/doc/mf6io/gwe/gwe.tex @@ -129,6 +129,10 @@ \subsection{Energy Source Loading (ESL) Package} \subsection{Streamflow Energy Transport (SFE) Package} \input{gwe/sfe} +\newpage +\subsection{Lake Energy Transport (LKE) Package} +\input{gwe/lke} + \newpage \subsection{Flow Model Interface (FMI) Package} \input{gwe/fmi} diff --git a/doc/mf6io/gwe/lke.tex b/doc/mf6io/gwe/lke.tex new file mode 100644 index 00000000000..4b9e28581c5 --- /dev/null +++ b/doc/mf6io/gwe/lke.tex @@ -0,0 +1,55 @@ +Lake Energy Transport (LKE) Package information is read from the file that is specified by ``LKE6'' as the file type. There can be as many LKE Packages as necessary for a GWE model. Each LKE Package is designed to work with flows from a single corresponding GWF LAK Package. By default \mf uses the LKE package name to determine which LAK Package corresponds to the LKE Package. Therefore, the package name of the LKE Package (as specified in the GWE name file) must match with the name of the corresponding LAK Package (as specified in the GWF name file). Alternatively, the name of the flow package can be specified using the FLOW\_PACKAGE\_NAME keyword in the options block. The GWE LKE Package cannot be used without a corresponding GWF LAK Package. + +The LKE Package does not have a dimensions block; instead, dimensions for the LKE Package are set using the dimensions from the corresponding LAK Package. For example, the LAK Package requires specification of the number of lakes (NLAKES). LKE sets the number of lakes equal to NLAKES. Therefore, the PACKAGEDATA block below must have NLAKES entries in it. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-lke-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-lke-packagedata.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-lke-period.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-lke-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-lke-example.dat} + +\vspace{5mm} +\subsubsection{Available observation types} +Lake Energy Transport Package observations include lake temperature and all of the terms that contribute to the continuity equation for each lake. Additional LKE Package observations include energy flow rates for individual outlets, lakes, or groups of lakes (\texttt{outlet}). The data required for each LKE Package observation type is defined in table~\ref{table:gwe-lkeobstype}. Negative and positive values for \texttt{lke} observations represent a loss from and gain to the GWE model, respectively. For all other flow terms, negative and positive values represent a loss from and gain from the LKE package, respectively. + +\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}} +\caption{Available LKE Package observation types} \tabularnewline + +\hline +\hline +\textbf{Stress Package} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endfirsthead + +\captionsetup{textformat=simple} +\caption*{\textbf{Table \arabic{table}.}{\quad}Available LKE Package observation types.---Continued} \tabularnewline + +\hline +\hline +\textbf{Stress Package} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endhead + + +\hline +\endfoot + +\input{../Common/gwe-lkeobs.tex} +\label{table:gwe-lkeobstype} +\end{longtable} + +\vspace{5mm} +\subsubsection{Example Observation Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-lke-example-obs.dat} + + diff --git a/doc/mf6io/gwe/namefile.tex b/doc/mf6io/gwe/namefile.tex index 613065d678b..12afbd6b30e 100644 --- a/doc/mf6io/gwe/namefile.tex +++ b/doc/mf6io/gwe/namefile.tex @@ -35,6 +35,7 @@ \subsubsection{Explanation of Variables} CTP6 & Constant Temperature Package & * \\ ESL6 & Energy Source Loading Package & * \\ SFE6 & Streamflow Energy Transport Package & * \\ +LKE6 & Lake Energy Transport Package & * \\ OBS6 & Observations Option \\ \hline \end{tabular*} diff --git a/doc/mf6io/mf6io_copy.bbl b/doc/mf6io/mf6io_copy.bbl new file mode 100644 index 00000000000..9a3a5427419 --- /dev/null +++ b/doc/mf6io/mf6io_copy.bbl @@ -0,0 +1,289 @@ +\begin{thebibliography}{41} +\providecommand{\natexlab}[1]{#1} +\expandafter\ifx\csname urlstyle\endcsname\relax + \providecommand{\doi}[1]{doi:\discretionary{}{}{}#1}\else + \providecommand{\doi}{doi:\discretionary{}{}{}\begingroup + \urlstyle{rm}\Url}\fi + +\bibitem[{Anderman and Hill(2000)}]{anderman2000modflow} +Anderman, E.R., and Hill, M.C., 2000, MODFLOW-2000, the U.S. Geological Survey + modular ground-water model-documentation of the Hydrogeologic-Unit Flow (HUF) + Package: {U.S. Geological Survey Open-File Report 2000--342, 89 p.} + +\bibitem[{Anderman and Hill(2003)}]{anderman2003modflow} +Anderman, E.R., and Hill, M.C., 2003, MODFLOW-2000, the U.S. Geological Survey + modular ground-water model---Three additions to the Hydrogeologic-Unit Flow + (HUF) Package: Alternative storage for the uppermost active cells, flows in + hydrogeologic units, and the hydraulic-conductivity depth-dependence (KDEP) + capability: {U.S. Geological Survey Open-File Report 2003--347, 36 p.} + +\bibitem[{Bakker and others(2013)Bakker, Schaars, Hughes, Langevin, and + Dausman}]{bakker2013documentation} +Bakker, Mark, Schaars, Frans, Hughes, J.D., Langevin, C.D., and Dausman, A.M., + 2013, Documentation of the seawater intrusion (SWI2) package for MODFLOW: + {U.S. Geological Survey Techniques and Methods, book 6, chap. A46, 47 p.}, + accessed June 27, 2017, at \url{https://pubs.er.usgs.gov/publication/tm6A46}. + +\bibitem[{Banta(2000)}]{modflowdrtpack} +Banta, E.R., 2000, MODFLOW-2000, the U.S. Geological Survey Modular + Ground-Water Model; documentation of packages for simulating + evapotranspiration with a segmented function (ETS1) and drains with return + flow (DRT1): {U.S. Geological Survey Open File Report 2000--466, 127 p}. + +\bibitem[{Banta(2011)}]{banta2011modflow} +Banta, E.R., 2011, MODFLOW-CDSS, a version of MODFLOW-2005 with modifications + for Colorado Decision Support Systems: {U.S. Geological Survey Open-File + Report 2011--1213, 19 p.}, accessed June 27, 2017, at + \url{https://pubs.er.usgs.gov/publication/ofr20111213}. + +\bibitem[{Bedekar and others(2016)Bedekar, Morway, Langevin, and + Tonkin}]{mt3dusgs} +Bedekar, Vivek, Morway, E.D., Langevin, C.D., and Tonkin, M.J., 2016, MT3D-USGS + version 1: A U.S. Geological Survey release of MT3DMS updated with new and + expanded transport capabilities for use with MODFLOW: {U.S. Geological Survey + Techniques and Methods, book 6, chap. A53, 69 p.}, + \url{https://doi.org/10.3133/tm6a53}, \url{http://dx.doi.org/10.3133/tm6A53}. + +\bibitem[{Fenske and others(1996)Fenske, Leake, and + Prudic}]{fenske1996documentation} +Fenske, J.P., Leake, S.A., and Prudic, D.E., 1996, Documentation of a computer + program (RES1) to simulate leakage from reservoirs using the modular + finite-difference ground-water flow model (MODFLOW): {U.S. Geological Survey + Open-File Report 96--364, 51 p.}, accessed June 27, 2017, at + \url{https://pubs.er.usgs.gov/publication/ofr96364}. + +\bibitem[{Halford and Hanson(2002)}]{halford2002} +Halford, K.J., and Hanson, R.T., 2002, User guide for the drawdown-limited, + multi-node well (MNW) package for the U.S. Geological Survey's modular + three-dimensional finite-difference ground-water flow model, versions + MODFLOW-96 and MODFLOW-2000: {U.S. Geological Survey Open-File Report + 02--293, 33 p.} + +\bibitem[{Hanson and Leake(1999)}]{hanson1999documentation} +Hanson, R.T., and Leake, S.A., 1999, Documentation for HYDMOD---A program for + extracting and processing time-series data from the U.S. Geological Survey's + modular three-dimensional finite-difference ground-water flow model: {U.S. + Geological Survey Open-File Report 98--564, 57 p.}, accessed June 27, 2017, + at \url{https://pubs.er.usgs.gov/publication/ofr98564}. + +\bibitem[{Harbaugh(2005)}]{modflow2005} +Harbaugh, A.W., 2005, MODFLOW-2005, the U.S. Geological Survey modular + ground-water model---the Ground-Water Flow Process: {U.S. Geological Survey + Techniques and Methods, book 6, chap. A16, variously paged}, accessed June + 27, 2017, at \url{https://pubs.usgs.gov/tm/2005/tm6A16/}. + +\bibitem[{Healy and Ronan(1996)}]{healy1996} +Healy, R.W., and Ronan, A.D., 1996, Documentation of Computer Program VS2DH for + Simulation of Energy Transport in Variably Saturated Porous Media: + Modification of the U.S. Geological Survey's Computer Program VS2DT: {U.S. + Geological Survey Water-Resources Investigation Report 96-4230, 36 p.}, + accessed September 27, 2022, at \url{https://doi.org/10.3133/wri964230}, at + \url{https://pubs.usgs.gov/wri/1996/4230/report.pdf}. + +\bibitem[{Hecht-Mendez and others(2010)Hecht-Mendez, Molina-Giraldo, Blum, and + Bayer}]{hechtmendez} +Hecht-Mendez, J., Molina-Giraldo, N., Blum, P., and Bayer, P., 2010, Evaluating + mt3dms for heat transport simulation of closed geothermal systems: + Groundwater, v.~48, no.~5, p.~741--756, + \url{https://doi.org/10.1111/j.1745-6584.2010.00678.x}. + +\bibitem[{Hill(1990)}]{hill1990preconditioned} +Hill, M.C., 1990, Preconditioned Conjugate-Gradient 2 (PCG2), a computer + program for solving ground-water flow equations: {U.S. Geological Survey + Water-Resources Investigations Report 90--4048, 25 p.}, accessed June 27, + 2017, at \url{https://pubs.usgs.gov/wri/wrir_90-4048}. + +\bibitem[{Hill and others(2000)Hill, Banta, Harbaugh, and + Anderman}]{hill2000modflow} +Hill, M.C., Banta, E.R., Harbaugh, A.W., and Anderman, E.R., 2000, + MODFLOW-2000, the U.S. Geological Survey modular ground-water model---User + guide to the observation, sensitivity, and parameter-estimation processes and + three post-processing programs: {U.S. Geological Survey Open-File Report + 00--184, 210 p.} + +\bibitem[{Hoffmann and others(2003)Hoffmann, Leake, Galloway, and + Wilson}]{hoffmann2003modflow} +Hoffmann, J{\"o}rn, Leake, S.A., Galloway, D.L., and Wilson, A.M., 2003, + MODFLOW-2000 Ground-Water Model---User Guide to the Subsidence and + Aquifer-System Compaction (SUB) Package: {U.S. Geological Survey Open-File + Report 03--233, 44 p.}, accessed June 27, 2017, at + \url{https://pubs.usgs.gov/of/2003/ofr03-233/}. + +\bibitem[{Hsieh and Freckleton(1993)}]{hsieh1993hfb} +Hsieh, P.A., and Freckleton, J.R., 1993, Documentation of a computer program to + simulate horizontal-flow barriers using the U.S. Geological Survey's modular + three-dimensional finite-difference ground-water flow model: {U.S. Geological + Survey Open-File Report 92--477, 32 p.}, accessed June 27, 2017, at + \url{https://pubs.er.usgs.gov/publication/ofr92477}. + +\bibitem[{Hughes and others(2012)Hughes, Langevin, Chartier, and + White}]{hughes2012documentation} +Hughes, J.D., Langevin, C.D., Chartier, K.L., and White, J.T., 2012, + Documentation of the Surface-Water Routing (SWR1) Process for modeling + surface-water flow with the U.S. Geological Survey modular groundwater model + (MODFLOW-2005): {U.S. Geological Survey Techniques and Methods, book 6, chap. + A40 (Version 1.0), 113 p.}, accessed June 27, 2017, at + \url{https://pubs.usgs.gov/tm/6a40/}. + +\bibitem[{Hughes and others(2017)Hughes, Langevin, and + Banta}]{modflow6framework} +Hughes, J.D., Langevin, C.D., and Banta, E.R., 2017, Documentation for the + MODFLOW 6 framework: {U.S. Geological Survey Techniques and Methods, book 6, + chap. A57, 36 p.}, \url{https://doi.org/10.3133/tm6A57}. + +\bibitem[{Hughes and others(2022{\natexlab{a}})Hughes, Russcher, Langevin, + Morway, and McDonald}]{modflow6api} +Hughes, J.D., Russcher, M.J., Langevin, C.D., Morway, E.D., and McDonald, R.R., + 2022{\natexlab{a}}, The {MODFLOW Application Programming Interface} for + simulation control and software interoperability: Environmental Modelling \& + Software, v. 148, 105257, + \url{https://doi.org/10.1016/j.envsoft.2021.105257}. + +\bibitem[{Hughes and others(2022{\natexlab{b}})Hughes, Leake, Galloway, and + White}]{modflow6csub} +Hughes, J.D., Leake, S.A., Galloway, D.L., and White, J.T., 2022{\natexlab{b}}, + Documentation for the Skeletal Storage, Compaction, and Subsidence (CSUB) + Package of MODFLOW 6: {U.S. Geological Survey Techniques and Methods, book 6, + chap. A62, 57 p.}, \url{https://doi.org/10.3133/tm6A62}. + +\bibitem[{Kipp(1987)}]{kipp1987} +Kipp, K.L., 1987, HST3D: A Computer Code for Simulation of Heat and Solute + Transport in Three-Dimensional Ground-Water Flow Systems: {U.S. Geological + Survey Water-Resources Investigation Report 86-4095, 517 p.}, accessed + September 27, 2022, at \url{https://pubs.usgs.gov/wri/1986/4095/report.pdf}. + +\bibitem[{Konikow and others(2009)Konikow, Hornberger, Halford, and + Hanson}]{konikow2009} +Konikow, L.F., Hornberger, G.Z., Halford, K.J., and Hanson, R.T., 2009, Revised + multi-node well (MNW2) package for MODFLOW ground-water flow model: {U.S. + Geological Survey Techniques and Methods, book 6, chap. A30, 67 p.}, accessed + June 27, 2017, at \url{https://pubs.usgs.gov/tm/tm6a30/}. + +\bibitem[{Langevin and others(2008)Langevin, Thorne~Jr, Dausman, Sukop, and + Guo}]{langevin2008seawat} +Langevin, C.D., Thorne~Jr, D.T., Dausman, A.M., Sukop, M.C., and Guo, Weixing, + 2008, {SEAWAT} Version 4---A computer program for simulation of multi-species + solute and heat transport: {U.S. Geological Survey Techniques and Methods, + book 6, chap. A22, 39 p.}, accessed June 27, 2017, at + \url{https://pubs.er.usgs.gov/publication/tm6A22}. + +\bibitem[{Langevin and others(2017)Langevin, Hughes, Provost, Banta, Niswonger, + and Panday}]{modflow6gwf} +Langevin, C.D., Hughes, J.D., Provost, A.M., Banta, E.R., Niswonger, R.G., and + Panday, Sorab, 2017, Documentation for the MODFLOW 6 Groundwater Flow (GWF) + Model: {U.S. Geological Survey Techniques and Methods, book 6, chap. A55, 197 + p.}, \url{https://doi.org/10.3133/tm6A55}. + +\bibitem[{Langevin and others(2020)Langevin, Panday, and + Provost}]{langevin2020hydraulic} +Langevin, C.D., Panday, Sorab, and Provost, A.M., 2020, Hydraulic-head + formulation for density-dependent flow and transport: Groundwater, v.~58, + no.~3, p.~349--362. + +\bibitem[{Langevin and others(2022)Langevin, Provost, Panday, and + Hughes}]{modflow6gwt} +Langevin, C.D., Provost, A.M., Panday, Sorab, and Hughes, J.D., 2022, + Documentation for the MODFLOW 6 Groundwater Transport (GWT) Model: {U.S. + Geological Survey Techniques and Methods, book 6, chap. A61, 56 p.}, + \url{https://doi.org/10.3133/tm6A61}. + +\bibitem[{Leake and Galloway(2007)}]{leake2007modflow} +Leake, S.A., and Galloway, D.L., 2007, MODFLOW Ground-water model---User guide + to the Subsidence and Aquifer-System Compaction Package (SUB-WT) for + Water-Table Aquifers: {U.S. Geological Survey Techniques and Methods, book 6, + chap. A23, 42 p.}, accessed June 27, 2017, at + \url{https://pubs.er.usgs.gov/publication/tm6A23}. + +\bibitem[{Leake and Lilly(1997)}]{leake1997documentation} +Leake, S.A., and Lilly, M.R., 1997, Documentation of computer program (FHB1) + for assignment of transient specified-flow and specified-head boundaries in + applications of the modular finite-diference ground-water flow model + (MODFLOW): {U.S. Geological Survey Open-File Report 97--571, 50 p.}, accessed + June 27, 2017, at \url{https://pubs.er.usgs.gov/publication/ofr97571}. + +\bibitem[{Ma and Zheng(2010)}]{mazheng2010} +Ma, Rui, and Zheng, Chunmiao, 2010, Effects of density and viscosity in + modeling heat as a groundwater tracer: Groundwater, v.~48, no.~3, + p.~380--389, \url{https://doi.org/10.1111/j.1745-6584.2009.00660.x}. + +\bibitem[{Maddock and others(2012)Maddock, Baird, Hanson, Schmid, and + Ajami}]{modflowripetpack} +Maddock, Thomas, III, Baird, K.J., Hanson, R.T., Schmid, Wolfgang, and Ajami, + Hoori, 2012, RIP-ET---A Riparian Evapotranspiration Package for MODFLOW-2005: + {U.S. Geological Survey Techniques and Methods, book 6, chap. A39, 76 p.}, + accessed June 27, 2017, at \url{https://pubs.usgs.gov/tm/tm6a39/}. + +\bibitem[{Merritt and Konikow(2000)}]{modflowlak3pack} +Merritt, M.L., and Konikow, L.F., 2000, Documentation of a computer program to + simulate lake-aquifer interaction using the MODFLOW ground-water flow model + and the MOC3D solute-transport model: {U.S. Geological Survey Water-Resources + Investigations Report 00--4167, 146 p.}, accessed June 27, 2017, at + \url{https://pubs.er.usgs.gov/publication/wri004167}. + +\bibitem[{Niswonger and Prudic(2005)}]{modflowsfr2pack} +Niswonger, R.G., and Prudic, D.E., 2005, Documentation of the + Streamflow-Routing (SFR2) Package to include unsaturated flow beneath + streams---A modification to SFR1: {U.S. Geological Survey Techniques and + Methods, book 6, chap. A13, 50 p.}, accessed June 27, 2017, at + \url{https://pubs.er.usgs.gov/publication/tm6A13}. + +\bibitem[{Niswonger and others(2006)Niswonger, Prudic, and Regan}]{UZF} +Niswonger, R.G., Prudic, D.E., and Regan, R.S., 2006, Documentation of the + Unsaturated-Zone Flow (UZF1) Package for modeling unsaturated flow between + the land surface and the water table with {MODFLOW}-2005: {U.S. Geological + Survey Techniques and Methods, book 6, chap. A19, 62 p.}, accessed June 27, + 2017, at \url{https://pubs.usgs.gov/tm/2006/tm6a19/}. + +\bibitem[{Panday and others(2013)Panday, Langevin, Niswonger, Ibaraki, and + Hughes}]{modflowusg} +Panday, Sorab, Langevin, C.D., Niswonger, R.G., Ibaraki, Motomu, and Hughes, + J.D., 2013, MODFLOW-USG version 1---An unstructured grid version of MODFLOW + for simulating groundwater flow and tightly coupled processes using a control + volume finite-difference formulation: {U.S. Geological Survey Techniques and + Methods, book 6, chap. A45, 66 p.}, accessed June 27, 2017, at + \url{https://pubs.usgs.gov/tm/06/a45/}. + +\bibitem[{Provost and others(2017)Provost, Langevin, and Hughes}]{modflow6xt3d} +Provost, A.M., Langevin, C.D., and Hughes, J.D., 2017, Documentation for the + ``XT3D'' Option in the Node Property Flow (NPF) Package of MODFLOW 6: {U.S. + Geological Survey Techniques and Methods, book 6, chap. A56, 46 p.}, + \url{https://doi.org/10.3133/tm6A56}. + +\bibitem[{Prudic(1989)}]{prudic1989str} +Prudic, D.E., 1989, Documentation of a computer program to simulate + stream-aquifer relations using a modular, finite-difference, ground-water + flow model: {U.S. Geological Survey Open-File Report 88--729, 113 p.}, + accessed June 27, 2017, at + \url{https://pubs.er.usgs.gov/publication/ofr88729}. + +\bibitem[{Prudic and others(2004)Prudic, Konikow, and Banta}]{modflowsfr1pack} +Prudic, D.E., Konikow, L.F., and Banta, E.R., 2004, A New Streamflow-Routing + (SFR1) Package to simulate stream-aquifer interaction with MODFLOW-2000: + {U.S. Geological Survey Open File Report 2004--1042, 104 p.}, accessed June + 27, 2017, at \url{https://pubs.er.usgs.gov/publication/ofr20041042}. + +\bibitem[{Voss(1984)}]{Voss1984sutra} +Voss, C.I., 1984, SUTRA---A finite-element simulation model for + saturated-unsaturated fluid-density-dependent ground-water flow with energy + transport or chemically-reactive single-species solute transport: {U.S. + Geological Survey Water-Resources Investigations Report 84--4369, 409 p.} + +\bibitem[{Zheng(2010)}]{zheng2010supplemental} +Zheng, Chunmiao, 2010, MT3DMS v5.3, Supplemental User's Guide: {Technical + Report Prepared for the U.S. Army Corps of Engineers, 51 p.} + +\bibitem[{Zheng and Wang(1999)}]{zheng1999mt3dms} +Zheng, Chunmiao, and Wang, P.P., 1999, MT3DMS---A modular three-dimensional + multi-species transport model for simulation of advection, dispersion and + chemical reactions of contaminants in groundwater systems; Documentation and + user's guide: {Contract report SERDP--99--1: Vicksburg, Miss., U.S. Army + Engineer Research and Development Center, 169 p.} + +\bibitem[{Zheng and others(2001)Zheng, Hill, and Hsieh}]{zheng2001modflow} +Zheng, Chunmiao, Hill, M.C., and Hsieh, P.A., 2001, MODFLOW-2000, the U.S. + Geological Survey Modular Ground-Water Model---User guide to the LMT6 + package, the linkage with MT3DMS for multi-species mass transport modeling: + {U.S. Geological Survey Open-File Report 01--82, 43 p.}, accessed June 27, + 2017, at \url{https://pubs.er.usgs.gov/publication/ofr0182}. + +\end{thebibliography} diff --git a/doc/mf6io/mf6ivar/dfn/gwe-lke.dfn b/doc/mf6io/mf6ivar/dfn/gwe-lke.dfn new file mode 100644 index 00000000000..b59b50420b2 --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-lke.dfn @@ -0,0 +1,481 @@ +# --------------------- gwe lke options --------------------- +# flopy multi-package + +block options +name flow_package_name +type string +shape +reader urword +optional true +longname keyword to specify name of corresponding flow package +description keyword to specify the name of the corresponding flow package. If not specified, then the corresponding flow package must have the same name as this advanced transport package (the name associated with this package in the GWE name file). + +block options +name auxiliary +type string +shape (naux) +reader urword +optional true +longname keyword to specify aux variables +description REPLACE auxnames {'{#1}': 'Groundwater Energy Transport'} + +block options +name flow_package_auxiliary_name +type string +shape +reader urword +optional true +longname keyword to specify name of temperature auxiliary variable in flow package +description keyword to specify the name of an auxiliary variable in the corresponding flow package. If specified, then the simulated temperatures from this advanced transport package will be copied into the auxiliary variable specified with this name. Note that the flow package must have an auxiliary variable with this name or the program will terminate with an error. If the flows for this advanced transport package are read from a file, then this option will have no effect. + +block options +name boundnames +type keyword +shape +reader urword +optional true +longname +description REPLACE boundnames {'{#1}': 'lake'} + +block options +name print_input +type keyword +reader urword +optional true +longname print input to listing file +description REPLACE print_input {'{#1}': 'lake'} + +block options +name print_temperature +type keyword +reader urword +optional true +longname print calculated temperatures to listing file +description REPLACE print_temperature {'{#1}': 'lake', '{#2}': 'temperature', '{#3}': 'TEMPERATURE'} + +block options +name print_flows +type keyword +reader urword +optional true +longname print calculated flows to listing file +description REPLACE print_flows {'{#1}': 'lake'} + +block options +name save_flows +type keyword +reader urword +optional true +longname save lake flows to budget file +description REPLACE save_flows {'{#1}': 'lake'} + +block options +name temperature_filerecord +type record temperature fileout tempfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name temperature +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname stage keyword +description keyword to specify that record corresponds to temperature. + +block options +name tempfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the binary output file to write temperature information. + +block options +name budget_filerecord +type record budget fileout budgetfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name budget +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname budget keyword +description keyword to specify that record corresponds to the budget. + +block options +name fileout +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname file keyword +description keyword to specify that an output filename is expected next. + +block options +name budgetfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the binary output file to write budget information. + +block options +name budgetcsv_filerecord +type record budgetcsv fileout budgetcsvfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name budgetcsv +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname budget keyword +description keyword to specify that record corresponds to the budget CSV. + +block options +name budgetcsvfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. + +block options +name ts_filerecord +type record ts6 filein ts6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name ts6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname head keyword +description keyword to specify that record corresponds to a time-series file. + +block options +name filein +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname file keyword +description keyword to specify that an input filename is expected next. + +block options +name ts6_filename +type string +preserve_case true +in_record true +reader urword +optional false +tagged false +longname file name of time series information +description REPLACE timeseriesfile {} + +block options +name obs_filerecord +type record obs6 filein obs6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name obs6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname obs keyword +description keyword to specify that record corresponds to an observations file. + +block options +name obs6_filename +type string +preserve_case true +in_record true +tagged false +reader urword +optional false +longname obs6 input filename +description REPLACE obs6_filename {'{#1}': 'LKE'} + + +# --------------------- gwe lke packagedata --------------------- + +block packagedata +name packagedata +type recarray lakeno strt ktf rbthcnd aux boundname +shape (maxbound) +reader urword +longname +description + +block packagedata +name lakeno +type integer +shape +tagged false +in_record true +reader urword +longname lake number for this entry +description integer value that defines the lake number associated with the specified PACKAGEDATA data on the line. LAKENO must be greater than zero and less than or equal to NLAKES. Lake information must be specified for every lake or the program will terminate with an error. The program will also terminate with an error if information for a lake is specified more than once. +numeric_index true + +block packagedata +name strt +type double precision +shape +tagged false +in_record true +reader urword +longname starting lake temperature +description real value that defines the starting temperature for the lake. + +block packagedata +name ktf +type double precision +shape +tagged false +in_record true +reader urword +longname boundary thermal conductivity +description is the thermal conductivity of the of the interface between the aquifer cell and the lake. + +block packagedata +name rbthcnd +type double precision +shape +tagged false +in_record true +reader urword +longname streambed thickness +description real value that defines the thickness of the lakebed material through which conduction occurs. Must be greater than 0. + +block packagedata +name aux +type double precision +in_record true +tagged false +shape (naux) +reader urword +time_series true +optional true +longname auxiliary variables +description REPLACE aux {'{#1}': 'lake'} + +block packagedata +name boundname +type string +shape +tagged false +in_record true +reader urword +optional true +longname lake name +description REPLACE boundname {'{#1}': 'lake'} + + +# --------------------- gwe lke period --------------------- + +block period +name iper +type integer +block_variable True +in_record true +tagged false +shape +valid +reader urword +optional false +longname stress period number +description REPLACE iper {} + +block period +name lakeperioddata +type recarray lakeno laksetting +shape +reader urword +longname +description + +block period +name lakeno +type integer +shape +tagged false +in_record true +reader urword +longname lake number for this entry +description integer value that defines the lake number associated with the specified PERIOD data on the line. LAKENO must be greater than zero and less than or equal to NLAKES. +numeric_index true + +block period +name laksetting +type keystring status temperature rainfall evaporation runoff ext-inflow auxiliaryrecord +shape +tagged false +in_record true +reader urword +longname +description line of information that is parsed into a keyword and values. Keyword values that can be used to start the LAKSETTING string include: STATUS, TEMPERATURE, RAINFALL, EVAPORATION, RUNOFF, and AUXILIARY. These settings are used to assign the temperature associated with the corresponding flow terms. Temperatures cannot be specified for all flow terms. For example, the Lake Package supports a ``WITHDRAWAL'' flow term. If this withdrawal term is active, then water will be withdrawn from the lake at the calculated temperature of the lake. + +block period +name status +type string +shape +tagged true +in_record true +reader urword +longname lake temperature status +description keyword option to define lake status. STATUS can be ACTIVE, INACTIVE, or CONSTANT. By default, STATUS is ACTIVE, which means that temperature will be calculated for the lake. If a lake is inactive, then there will be no solute mass fluxes into or out of the lake and the inactive value will be written for the lake temperature. If a lake is constant, then the temperature for the lake will be fixed at the user specified value. + +block period +name temperature +type string +shape +tagged true +in_record true +time_series true +reader urword +longname lake temperature +description real or character value that defines the temperature for the lake. The specified TEMPERATURE is only applied if the lake is a constant temperature lake. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name rainfall +type string +shape +tagged true +in_record true +reader urword +time_series true +longname rainfall temperature +description real or character value that defines the rainfall temperature for the lake. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name evaporation +type string +shape +tagged true +in_record true +reader urword +time_series true +longname evaporation temperature +description real or character value that defines the temperature of evaporated water $(^{\circ}C)$ for the reach. If this temperature value is larger than the simulated temperature in the reach, then the evaporated water will be removed at the same temperature as the reach. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + + +block period +name runoff +type string +shape +tagged true +in_record true +reader urword +time_series true +longname runoff temperature +description real or character value that defines the temperature of runoff for the lake. Value must be greater than or equal to zero. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name ext-inflow +type string +shape +tagged true +in_record true +reader urword +time_series true +longname ext-inflow temperature +description real or character value that defines the temperature of external inflow for the lake. Value must be greater than or equal to zero. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name auxiliaryrecord +type record auxiliary auxname auxval +shape +tagged +in_record true +reader urword +longname +description + +block period +name auxiliary +type keyword +shape +in_record true +reader urword +longname +description keyword for specifying auxiliary variable. + +block period +name auxname +type string +shape +tagged false +in_record true +reader urword +longname +description name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. + +block period +name auxval +type double precision +shape +tagged false +in_record true +reader urword +time_series true +longname auxiliary variable value +description value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. diff --git a/doc/mf6io/mf6ivar/examples/gwe-lke-example-obs.dat b/doc/mf6io/mf6ivar/examples/gwe-lke-example-obs.dat new file mode 100644 index 00000000000..c37a5c8f190 --- /dev/null +++ b/doc/mf6io/mf6ivar/examples/gwe-lke-example-obs.dat @@ -0,0 +1,25 @@ +BEGIN options + DIGITS 7 + PRINT_INPUT +END options + +BEGIN continuous FILEOUT gwe_lke02.lke.obs.csv + lke-1-temp TEMPERATURE 1 + lke-1-extinflow EXT-INFLOW 1 + lke-1-rain RAINFALL 1 + lke-1-roff RUNOFF 1 + lke-1-wdrl WITHDRAWAL 1 + lke-1-stor STORAGE 1 + lke-1-const CONSTANT 1 + lke-1-gwe1 LKE 1 1 + lke-1-gwe2 LKE 1 2 + lke-2-gwe1 LKE 2 1 + lke-1-mylake1 LKE MYLAKE1 + lke-1-fjf FLOW-JA-FACE 1 2 + lke-2-fjf FLOW-JA-FACE 2 1 + lke-3-fjf FLOW-JA-FACE 2 3 + lke-4-fjf FLOW-JA-FACE 3 2 + lke-5-fjf FLOW-JA-FACE MYLAKE1 + lke-6-fjf FLOW-JA-FACE MYLAKE2 + lke-7-fjf FLOW-JA-FACE MYLAKE3 +END continuous diff --git a/doc/mf6io/mf6ivar/examples/gwe-lke-example.dat b/doc/mf6io/mf6ivar/examples/gwe-lke-example.dat new file mode 100644 index 00000000000..1ffe73824fa --- /dev/null +++ b/doc/mf6io/mf6ivar/examples/gwe-lke-example.dat @@ -0,0 +1,24 @@ +BEGIN OPTIONS + AUXILIARY aux1 aux2 + BOUNDNAMES + PRINT_INPUT + PRINT_TEMPERATURE + PRINT_FLOWS + SAVE_FLOWS + TEMPERATURE FILEOUT gwe_lke_02.lke.bin + BUDGET FILEOUT gwe_lke_02.lke.bud + OBS6 FILEIN gwe_lke_02.lke.obs +END OPTIONS + +BEGIN PACKAGEDATA +# L STRT aux1 aux2 bname + 1 5.0 99.0 999.0 MYLAKE1 + 2 6.0 99.0 999.0 MYLAKE2 + 3 7.0 99.0 999.0 MYLAKE3 +END PACKAGEDATA + +BEGIN PERIOD 1 + 1 STATUS ACTIVE + 2 STATUS ACTIVE + 3 STATUS ACTIVE +END PERIOD 1 diff --git a/doc/mf6io/mf6ivar/md/mf6ivar.md b/doc/mf6io/mf6ivar/md/mf6ivar.md index 780589a6758..84a5897a9dd 100644 --- a/doc/mf6io/mf6ivar/md/mf6ivar.md +++ b/doc/mf6io/mf6ivar/md/mf6ivar.md @@ -1298,6 +1298,44 @@ | GWE | EST | PACKAGEDATA | RHOW | DOUBLE PRECISION | is a user-specified value of the density of water. Value will remain fixed for the entire simulation. For example, if working in SI units, values may be entered as kg/m3. | | GWE | EST | PACKAGEDATA | LATHEATVAP | DOUBLE PRECISION | is the user-specified value for the latent heat of vaporization. For example, if working in SI units, values may be entered as kJ/kg. | | GWE | IC | GRIDDATA | STRT | DOUBLE PRECISION (NODES) | is the initial (starting) temperature---that is, the temperature at the beginning of the GWE Model simulation. STRT must be specified for all GWE Model simulations. One value is read for every model cell. | +| GWE | LKE | OPTIONS | FLOW_PACKAGE_NAME | STRING | keyword to specify the name of the corresponding flow package. If not specified, then the corresponding flow package must have the same name as this advanced transport package (the name associated with this package in the GWE name file). | +| GWE | LKE | OPTIONS | AUXILIARY | STRING (NAUX) | defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. | +| GWE | LKE | OPTIONS | FLOW_PACKAGE_AUXILIARY_NAME | STRING | keyword to specify the name of an auxiliary variable in the corresponding flow package. If specified, then the simulated temperatures from this advanced transport package will be copied into the auxiliary variable specified with this name. Note that the flow package must have an auxiliary variable with this name or the program will terminate with an error. If the flows for this advanced transport package are read from a file, then this option will have no effect. | +| GWE | LKE | OPTIONS | BOUNDNAMES | KEYWORD | keyword to indicate that boundary names may be provided with the list of lake cells. | +| GWE | LKE | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of lake information will be written to the listing file immediately after it is read. | +| GWE | LKE | OPTIONS | PRINT_TEMPERATURE | KEYWORD | keyword to indicate that the list of lake temperature will be printed to the listing file for every stress period in which ``TEMPERATURE PRINT'' is specified in Output Control. If there is no Output Control option and PRINT\_TEMPERATURE is specified, then temperature are printed for the last time step of each stress period. | +| GWE | LKE | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of lake flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | +| GWE | LKE | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that lake flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | +| GWE | LKE | OPTIONS | TEMPERATURE | KEYWORD | keyword to specify that record corresponds to temperature. | +| GWE | LKE | OPTIONS | TEMPFILE | STRING | name of the binary output file to write temperature information. | +| GWE | LKE | OPTIONS | BUDGET | KEYWORD | keyword to specify that record corresponds to the budget. | +| GWE | LKE | OPTIONS | FILEOUT | KEYWORD | keyword to specify that an output filename is expected next. | +| GWE | LKE | OPTIONS | BUDGETFILE | STRING | name of the binary output file to write budget information. | +| GWE | LKE | OPTIONS | BUDGETCSV | KEYWORD | keyword to specify that record corresponds to the budget CSV. | +| GWE | LKE | OPTIONS | BUDGETCSVFILE | STRING | name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. | +| GWE | LKE | OPTIONS | TS6 | KEYWORD | keyword to specify that record corresponds to a time-series file. | +| GWE | LKE | OPTIONS | FILEIN | KEYWORD | keyword to specify that an input filename is expected next. | +| GWE | LKE | OPTIONS | TS6_FILENAME | STRING | defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. | +| GWE | LKE | OPTIONS | OBS6 | KEYWORD | keyword to specify that record corresponds to an observations file. | +| GWE | LKE | OPTIONS | OBS6_FILENAME | STRING | name of input file to define observations for the LKE package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the LKE package. | +| GWE | LKE | PACKAGEDATA | LAKENO | INTEGER | integer value that defines the lake number associated with the specified PACKAGEDATA data on the line. LAKENO must be greater than zero and less than or equal to NLAKES. Lake information must be specified for every lake or the program will terminate with an error. The program will also terminate with an error if information for a lake is specified more than once. | +| GWE | LKE | PACKAGEDATA | STRT | DOUBLE PRECISION | real value that defines the starting temperature for the lake. | +| GWE | LKE | PACKAGEDATA | KTF | DOUBLE PRECISION | is the thermal conductivity of the of the interface between the aquifer cell and the lake. | +| GWE | LKE | PACKAGEDATA | RBTHCND | DOUBLE PRECISION | real value that defines the thickness of the lakebed material through which conduction occurs. Must be greater than 0. | +| GWE | LKE | PACKAGEDATA | AUX | DOUBLE PRECISION (NAUX) | represents the values of the auxiliary variables for each lake. The values of auxiliary variables must be present for each lake. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | LKE | PACKAGEDATA | BOUNDNAME | STRING | name of the lake cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. | +| GWE | LKE | PERIOD | IPER | INTEGER | integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. | +| GWE | LKE | PERIOD | LAKENO | INTEGER | integer value that defines the lake number associated with the specified PERIOD data on the line. LAKENO must be greater than zero and less than or equal to NLAKES. | +| GWE | LKE | PERIOD | LAKSETTING | KEYSTRING | line of information that is parsed into a keyword and values. Keyword values that can be used to start the LAKSETTING string include: STATUS, TEMPERATURE, RAINFALL, EVAPORATION, RUNOFF, and AUXILIARY. These settings are used to assign the temperature associated with the corresponding flow terms. Temperatures cannot be specified for all flow terms. For example, the Lake Package supports a ``WITHDRAWAL'' flow term. If this withdrawal term is active, then water will be withdrawn from the lake at the calculated temperature of the lake. | +| GWE | LKE | PERIOD | STATUS | STRING | keyword option to define lake status. STATUS can be ACTIVE, INACTIVE, or CONSTANT. By default, STATUS is ACTIVE, which means that temperature will be calculated for the lake. If a lake is inactive, then there will be no solute mass fluxes into or out of the lake and the inactive value will be written for the lake temperature. If a lake is constant, then the temperature for the lake will be fixed at the user specified value. | +| GWE | LKE | PERIOD | TEMPERATURE | STRING | real or character value that defines the temperature for the lake. The specified TEMPERATURE is only applied if the lake is a constant temperature lake. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | LKE | PERIOD | RAINFALL | STRING | real or character value that defines the rainfall temperature for the lake. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | LKE | PERIOD | EVAPORATION | STRING | real or character value that defines the temperature of evaporated water $(^{\circ}C)$ for the reach. If this temperature value is larger than the simulated temperature in the reach, then the evaporated water will be removed at the same temperature as the reach. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | LKE | PERIOD | RUNOFF | STRING | real or character value that defines the temperature of runoff for the lake. Value must be greater than or equal to zero. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | LKE | PERIOD | EXT-INFLOW | STRING | real or character value that defines the temperature of external inflow for the lake. Value must be greater than or equal to zero. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | LKE | PERIOD | AUXILIARY | KEYWORD | keyword for specifying auxiliary variable. | +| GWE | LKE | PERIOD | AUXNAME | STRING | name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. | +| GWE | LKE | PERIOD | AUXVAL | DOUBLE PRECISION | value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | | GWE | NAM | OPTIONS | LIST | STRING | is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the ``.lst'' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. | | GWE | NAM | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of all model stress package information will be written to the listing file immediately after it is read. | | GWE | NAM | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of all model package flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | diff --git a/doc/mf6io/mf6ivar/mf6ivar.py b/doc/mf6io/mf6ivar/mf6ivar.py index 328b3ee2d53..25d59480ac5 100644 --- a/doc/mf6io/mf6ivar/mf6ivar.py +++ b/doc/mf6io/mf6ivar/mf6ivar.py @@ -748,6 +748,7 @@ def write_appendix(texdir, allblocks): "gwe-esl", "gwe-est", "gwe-ic", + "gwe-lke", "gwe-nam", "gwe-oc", "gwe-ssm", diff --git a/doc/mf6io/mf6ivar/tex/appendixA.tex b/doc/mf6io/mf6ivar/tex/appendixA.tex index 6272dfc456b..ccdf2aab7a3 100644 --- a/doc/mf6io/mf6ivar/tex/appendixA.tex +++ b/doc/mf6io/mf6ivar/tex/appendixA.tex @@ -280,6 +280,10 @@ \hline GWE & IC & GRIDDATA & no \\ \hline +GWE & LKE & OPTIONS & yes \\ +GWE & LKE & PACKAGEDATA & yes \\ +GWE & LKE & PERIOD & yes \\ +\hline GWE & NAM & OPTIONS & yes \\ GWE & NAM & PACKAGES & yes \\ \hline diff --git a/doc/mf6io/mf6ivar/tex/gwe-lke-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-lke-desc.tex new file mode 100644 index 00000000000..7a240c13d5d --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-lke-desc.tex @@ -0,0 +1,101 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{flow\_package\_name}---keyword to specify the name of the corresponding flow package. If not specified, then the corresponding flow package must have the same name as this advanced transport package (the name associated with this package in the GWE name file). + +\item \texttt{auxiliary}---defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. + +\item \texttt{flow\_package\_auxiliary\_name}---keyword to specify the name of an auxiliary variable in the corresponding flow package. If specified, then the simulated temperatures from this advanced transport package will be copied into the auxiliary variable specified with this name. Note that the flow package must have an auxiliary variable with this name or the program will terminate with an error. If the flows for this advanced transport package are read from a file, then this option will have no effect. + +\item \texttt{BOUNDNAMES}---keyword to indicate that boundary names may be provided with the list of lake cells. + +\item \texttt{PRINT\_INPUT}---keyword to indicate that the list of lake information will be written to the listing file immediately after it is read. + +\item \texttt{PRINT\_TEMPERATURE}---keyword to indicate that the list of lake temperature will be printed to the listing file for every stress period in which ``TEMPERATURE PRINT'' is specified in Output Control. If there is no Output Control option and PRINT\_TEMPERATURE is specified, then temperature are printed for the last time step of each stress period. + +\item \texttt{PRINT\_FLOWS}---keyword to indicate that the list of lake flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. + +\item \texttt{SAVE\_FLOWS}---keyword to indicate that lake flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. + +\item \texttt{TEMPERATURE}---keyword to specify that record corresponds to temperature. + +\item \texttt{tempfile}---name of the binary output file to write temperature information. + +\item \texttt{BUDGET}---keyword to specify that record corresponds to the budget. + +\item \texttt{FILEOUT}---keyword to specify that an output filename is expected next. + +\item \texttt{budgetfile}---name of the binary output file to write budget information. + +\item \texttt{BUDGETCSV}---keyword to specify that record corresponds to the budget CSV. + +\item \texttt{budgetcsvfile}---name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. + +\item \texttt{TS6}---keyword to specify that record corresponds to a time-series file. + +\item \texttt{FILEIN}---keyword to specify that an input filename is expected next. + +\item \texttt{ts6\_filename}---defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. + +\item \texttt{OBS6}---keyword to specify that record corresponds to an observations file. + +\item \texttt{obs6\_filename}---name of input file to define observations for the LKE package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the LKE package. + +\end{description} +\item \textbf{Block: PACKAGEDATA} + +\begin{description} +\item \texttt{lakeno}---integer value that defines the lake number associated with the specified PACKAGEDATA data on the line. LAKENO must be greater than zero and less than or equal to NLAKES. Lake information must be specified for every lake or the program will terminate with an error. The program will also terminate with an error if information for a lake is specified more than once. + +\item \texttt{strt}---real value that defines the starting temperature for the lake. + +\item \texttt{ktf}---is the thermal conductivity of the of the interface between the aquifer cell and the lake. + +\item \texttt{rbthcnd}---real value that defines the thickness of the lakebed material through which conduction occurs. Must be greater than 0. + +\item \textcolor{blue}{\texttt{aux}---represents the values of the auxiliary variables for each lake. The values of auxiliary variables must be present for each lake. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \texttt{boundname}---name of the lake cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. + +\end{description} +\item \textbf{Block: PERIOD} + +\begin{description} +\item \texttt{iper}---integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. + +\item \texttt{lakeno}---integer value that defines the lake number associated with the specified PERIOD data on the line. LAKENO must be greater than zero and less than or equal to NLAKES. + +\item \texttt{laksetting}---line of information that is parsed into a keyword and values. Keyword values that can be used to start the LAKSETTING string include: STATUS, TEMPERATURE, RAINFALL, EVAPORATION, RUNOFF, and AUXILIARY. These settings are used to assign the temperature associated with the corresponding flow terms. Temperatures cannot be specified for all flow terms. For example, the Lake Package supports a ``WITHDRAWAL'' flow term. If this withdrawal term is active, then water will be withdrawn from the lake at the calculated temperature of the lake. + +\begin{lstlisting}[style=blockdefinition] +STATUS +TEMPERATURE <@temperature@> +RAINFALL <@rainfall@> +EVAPORATION <@evaporation@> +RUNOFF <@runoff@> +EXT-INFLOW <@ext-inflow@> +AUXILIARY <@auxval@> +\end{lstlisting} + +\item \texttt{status}---keyword option to define lake status. STATUS can be ACTIVE, INACTIVE, or CONSTANT. By default, STATUS is ACTIVE, which means that temperature will be calculated for the lake. If a lake is inactive, then there will be no solute mass fluxes into or out of the lake and the inactive value will be written for the lake temperature. If a lake is constant, then the temperature for the lake will be fixed at the user specified value. + +\item \textcolor{blue}{\texttt{temperature}---real or character value that defines the temperature for the lake. The specified TEMPERATURE is only applied if the lake is a constant temperature lake. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{rainfall}---real or character value that defines the rainfall temperature for the lake. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{evaporation}---real or character value that defines the temperature of evaporated water $(^{\circ}C)$ for the reach. If this temperature value is larger than the simulated temperature in the reach, then the evaporated water will be removed at the same temperature as the reach. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{runoff}---real or character value that defines the temperature of runoff for the lake. Value must be greater than or equal to zero. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{ext-inflow}---real or character value that defines the temperature of external inflow for the lake. Value must be greater than or equal to zero. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \texttt{AUXILIARY}---keyword for specifying auxiliary variable. + +\item \texttt{auxname}---name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. + +\item \textcolor{blue}{\texttt{auxval}---value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-lke-options.dat b/doc/mf6io/mf6ivar/tex/gwe-lke-options.dat new file mode 100644 index 00000000000..ef83c7fa718 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-lke-options.dat @@ -0,0 +1,15 @@ +BEGIN OPTIONS + [FLOW_PACKAGE_NAME ] + [AUXILIARY ] + [FLOW_PACKAGE_AUXILIARY_NAME ] + [BOUNDNAMES] + [PRINT_INPUT] + [PRINT_TEMPERATURE] + [PRINT_FLOWS] + [SAVE_FLOWS] + [TEMPERATURE FILEOUT ] + [BUDGET FILEOUT ] + [BUDGETCSV FILEOUT ] + [TS6 FILEIN ] + [OBS6 FILEIN ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-lke-packagedata.dat b/doc/mf6io/mf6ivar/tex/gwe-lke-packagedata.dat new file mode 100644 index 00000000000..74aaecb370e --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-lke-packagedata.dat @@ -0,0 +1,5 @@ +BEGIN PACKAGEDATA + [<@aux(naux)@>] [] + [<@aux(naux)@>] [] + ... +END PACKAGEDATA diff --git a/doc/mf6io/mf6ivar/tex/gwe-lke-period.dat b/doc/mf6io/mf6ivar/tex/gwe-lke-period.dat new file mode 100644 index 00000000000..dfe899b47ef --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-lke-period.dat @@ -0,0 +1,5 @@ +BEGIN PERIOD + + + ... +END PERIOD diff --git a/doc/mf6io/usgs.bst b/doc/mf6io/usgs.bst new file mode 100644 index 00000000000..326cc9cf966 --- /dev/null +++ b/doc/mf6io/usgs.bst @@ -0,0 +1,2080 @@ +%% +%% This is file `usgs.bst', +%%% ADAPTED BY MIKE FIENEN FROM agufull08.bst +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% merlin.mbs (with options: `head,ay,nat,seq-labc,nm-rev1,jnrlst,lab,lab-it,keyxyr,blkyear,dt-beg,yr-par,xmth,note-yr,thtit-a,trnum-it,vol-it,volp-com,pgsep-c,num-xser,ser-vol,ser-ed,pg-bk,pg-pre,pre-edn,agu-doi,doi,edpar,bkedcap,edby,blk-com,pp,ed,abr,ednx,xedn,jabr,and-com,em-it,nfss,{}') +%% physjour.mbs (with options: `ay,nat,seq-labc,nm-rev1,jnrlst,lab,lab-it,keyxyr,blkyear,dt-beg,yr-par,xmth,note-yr,thtit-a,trnum-it,vol-it,volp-com,pgsep-c,num-xser,ser-vol,ser-ed,pg-bk,pg-pre,pre-edn,agu-doi,doi,edpar,bkedcap,edby,blk-com,pp,ed,abr,ednx,xedn,jabr,and-com,em-it,nfss,{}') +%% geojour.mbs (with options: `ay,nat,seq-labc,nm-rev1,jnrlst,lab,lab-it,keyxyr,blkyear,dt-beg,yr-par,xmth,note-yr,thtit-a,trnum-it,vol-it,volp-com,pgsep-c,num-xser,ser-vol,ser-ed,pg-bk,pg-pre,pre-edn,agu-doi,doi,edpar,bkedcap,edby,blk-com,pp,ed,abr,ednx,xedn,jabr,and-com,em-it,nfss,{}') +%% photjour.mbs (with options: `ay,nat,seq-labc,nm-rev1,jnrlst,lab,lab-it,keyxyr,blkyear,dt-beg,yr-par,xmth,note-yr,thtit-a,trnum-it,vol-it,volp-com,pgsep-c,num-xser,ser-vol,ser-ed,pg-bk,pg-pre,pre-edn,agu-doi,doi,edpar,bkedcap,edby,blk-com,pp,ed,abr,ednx,xedn,jabr,and-com,em-it,nfss,{}') +%% merlin.mbs (with options: `tail,ay,nat,seq-labc,nm-rev1,jnrlst,lab,lab-it,keyxyr,blkyear,dt-beg,yr-par,xmth,note-yr,thtit-a,trnum-it,vol-it,volp-com,pgsep-c,num-xser,ser-vol,ser-ed,pg-bk,pg-pre,pre-edn,agu-doi,doi,edpar,bkedcap,edby,blk-com,pp,ed,abr,ednx,xedn,jabr,and-com,em-it,nfss,{}') +%% ---------------------------------------- +%% *** For journals of the American Geophysical Union *** +%% *** NOTE: this version does not limit the number of authors in ref list. +%% *** Use agu08.bst to limit authors to maximum 9. +%% *** +%% ---------------------------------------- +%% *** Version 3.1 from 2008/08/27 +%% *** Multiple authors of same first author and year now in order of citation +%% *** and other minor fixes +%% *** Renamed to agu08.bst and agufull08.bst +%% *** +%% *** Version 3.0 from 2004/02/06 +%% *** Changed date format for AGU journals +%% *** The date now appears in parentheses after authors +%% *** +%% *** Version 2.2 from 2003/06/26 +%% *** (with bug fix from 2003/08/19) +%% *** Includes new fields eid and doi +%% *** The eid is what the AGU calls "citation number" +%% *** and doi is the DOI number; both of these are +%% *** used as substitution for page number +%% *** The issue number is now also included as +%% *** 84(3) for vol. 84, nr. 3 +%% *** +%% *** Version 2.1d from 1999/05/20 +%% *** Book editors done right as P. James (Ed.), +%% *** Missing italics with some authors fixed +%% *** +%% *** Version 2.1c from 1999/02/11 +%% *** This version does not crash older BibTeX installations with +%% *** more than 3000 wiz-functions +%% *** +%% *** Version 2.1b from 1997/11/18 +%% *** (page numbers over 9999 are broken with commas, as 12,345) +%% *** +%% *** Version 2.1a from 1997/05/26 +%% *** (contains improvements from copy editor comments, +%% *** notes added with first word lowercase (bug in 2.1 fixed) +%% *** and journal `number' never output +%% *** abbreviation for grl corrected) +%% *** +%% +%% Copyright 1994-2008 Patrick W Daly + % =============================================================== + % IMPORTANT NOTICE: + % This bibliographic style (bst) file has been generated from one or + % more master bibliographic style (mbs) files, listed above. + % + % This generated file can be redistributed and/or modified under the terms + % of the LaTeX Project Public License Distributed from CTAN + % archives in directory macros/latex/base/lppl.txt; either + % version 1 of the License, or any later version. + % =============================================================== + % Name and version information of the main mbs file: + % \ProvidesFile{merlin.mbs}[2008/08/27 4.30 (PWD, AO, DPC)] + % For use with BibTeX version 0.99a or later + %------------------------------------------------------------------- + % This bibliography style file is intended for texts in ENGLISH + % This is an author-year citation style bibliography. As such, it is + % non-standard LaTeX, and requires a special package file to function properly. + % Such a package is natbib.sty by Patrick W. Daly + % The form of the \bibitem entries is + % \bibitem[Jones et al.(1990)]{key}... + % \bibitem[Jones et al.(1990)Jones, Baker, and Smith]{key}... + % The essential feature is that the label (the part in brackets) consists + % of the author names, as they should appear in the citation, with the year + % in parentheses following. There must be no space before the opening + % parenthesis! + % With natbib v5.3, a full list of authors may also follow the year. + % In natbib.sty, it is possible to define the type of enclosures that is + % really wanted (brackets or parentheses), but in either case, there must + % be parentheses in the label. + % The \cite command functions as follows: + % \citet{key} ==>> Jones et al. (1990) + % \citet*{key} ==>> Jones, Baker, and Smith (1990) + % \citep{key} ==>> (Jones et al., 1990) + % \citep*{key} ==>> (Jones, Baker, and Smith, 1990) + % \citep[chap. 2]{key} ==>> (Jones et al., 1990, chap. 2) + % \citep[e.g.][]{key} ==>> (e.g. Jones et al., 1990) + % \citep[e.g.][p. 32]{key} ==>> (e.g. Jones et al., 1990, p. 32) + % \citeauthor{key} ==>> Jones et al. + % \citeauthor*{key} ==>> Jones, Baker, and Smith + % \citeyear{key} ==>> 1990 + %--------------------------------------------------------------------- + +ENTRY + { address + author + booktitle + chapter + doi + urldate + url + urllink + edition + editor + eid + howpublished + institution + journal + key + month + note + number + organization + pages + publisher + school + series + title + type + volume + year + } + {} + { label extra.label sort.label short.list } +INTEGERS { output.state before.all mid.sentence after.sentence after.block } +FUNCTION {init.state.consts} +{ #0 'before.all := + #1 'mid.sentence := + #2 'after.sentence := + #3 'after.block := +} +STRINGS { s t} +FUNCTION {output.nonnull} +{ 's := + output.state mid.sentence = + { ", " * write$ } + { output.state after.block = + { add.period$ write$ + newline$ + "\newblock " write$ + } + { output.state before.all = + 'write$ + { add.period$ " " * write$ } + if$ + } + if$ + mid.sentence 'output.state := + } + if$ + s +} +FUNCTION {outputc.nonnull} +{ 's := + output.state mid.sentence = + { ": " * write$ } + { output.state after.block = + { add.period$ write$ + newline$ + "\newblock " write$ + } + { output.state before.all = + 'write$ + { add.period$ " " * write$ } + if$ + } + if$ + mid.sentence 'output.state := + } + if$ + s +} +FUNCTION {output} +{ duplicate$ empty$ + 'pop$ + 'output.nonnull + if$ +} +FUNCTION {outputc} +{ duplicate$ empty$ + 'pop$ + 'outputc.nonnull + if$ +} +FUNCTION {output.check} +{ 't := + duplicate$ empty$ + { pop$ "empty " t * " in " * cite$ * warning$ } + 'output.nonnull + if$ +} +FUNCTION {outputc.check} +{ 't := + duplicate$ empty$ + { pop$ "empty " t * " in " * cite$ * warning$ } + 'outputc.nonnull + if$ +} +FUNCTION {fin.entry} +{ add.period$ + write$ + newline$ +} + +FUNCTION {new.block} +{ output.state before.all = + 'skip$ + { after.block 'output.state := } + if$ +} +FUNCTION {new.sentence} +{ output.state after.block = + 'skip$ + { output.state before.all = + 'skip$ + { after.sentence 'output.state := } + if$ + } + if$ +} +FUNCTION {add.blank} +{ " " * before.all 'output.state := +} + +FUNCTION {date.block} +{ + skip$ +} + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} +FUNCTION {and} +{ 'skip$ + { pop$ #0 } + if$ +} +FUNCTION {or} +{ { pop$ #1 } + 'skip$ + if$ +} +FUNCTION {new.block.checkb} +{ empty$ + swap$ empty$ + and + 'skip$ + 'new.block + if$ +} +FUNCTION {field.or.null} +{ duplicate$ empty$ + { pop$ "" } + 'skip$ + if$ +} +FUNCTION {emphasize} +{ duplicate$ empty$ + { pop$ "" } + { "\textit{" swap$ * "}" * } + if$ +} +FUNCTION {cite.name.font} +%{ emphasize } +{ } +FUNCTION {tie.or.space.prefix} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ +} + +FUNCTION {capitalize} +{ "u" change.case$ "t" change.case$ } + +FUNCTION {space.word} +{ " " swap$ * " " * } + % Here are the language-specific definitions for explicit words. + % Each function has a name bbl.xxx where xxx is the English word. + % The language selected here is ENGLISH +FUNCTION {bbl.and} +{ "and" } + +FUNCTION {bbl.etal} +{ "and others" } + +FUNCTION {bbl.andothers} +{ "and others" } + +FUNCTION {bbl.editors} +{ "eds." } + +FUNCTION {bbl.editor} +{ "ed." } + +FUNCTION {bbl.edby} +{ "edited by" } + +FUNCTION {bbl.edition} +{ "ed." } + +FUNCTION {bbl.volume} +{ "v." } + +FUNCTION {bbl.of} +{ "of" } + +FUNCTION {bbl.number} +{ "no." } + +FUNCTION {bbl.nr} +{ "no." } + +FUNCTION {bbl.in} +{ "\emph{in}" } + +FUNCTION {bbl.pages} +{ "p." } + +FUNCTION {bbl.page} +{ "p." } + +FUNCTION {bbl.chapter} +{ "Chap." } + +FUNCTION {bbl.techrep} +%{ "Tech. Rep." } REMOVE THE TECH REPORT WORDS FOR USGS +{""} +FUNCTION {bbl.mthesis} +{ "M.S. thesis" } + +FUNCTION {bbl.phdthesis} +{ "Ph.D. thesis" } + +MACRO {jan} {"Jan."} + +MACRO {feb} {"Feb."} + +MACRO {mar} {"Mar."} + +MACRO {apr} {"Apr."} + +MACRO {may} {"May"} + +MACRO {jun} {"Jun."} + +MACRO {jul} {"Jul."} + +MACRO {aug} {"Aug."} + +MACRO {sep} {"Sep."} + +MACRO {oct} {"Oct."} + +MACRO {nov} {"Nov."} + +MACRO {dec} {"Dec."} + + %------------------------------------------------------------------- + % Begin module: + % \ProvidesFile{physjour.mbs}[2002/01/14 2.2 (PWD)] +MACRO {aa}{"Astron. \& Astrophys."} +MACRO {aasup}{"Astron. \& Astrophys. Suppl. Ser."} +MACRO {aj} {"Astron. J."} +MACRO {aph} {"Acta Phys."} +MACRO {advp} {"Adv. Phys."} +MACRO {ajp} {"Amer. J. Phys."} +MACRO {ajm} {"Amer. J. Math."} +MACRO {amsci} {"Amer. Sci."} +MACRO {anofd} {"Ann. Fluid Dyn."} +MACRO {am} {"Ann. Math."} +MACRO {ap} {"Ann. Phys. (NY)"} +MACRO {adp} {"Ann. Phys. (Leipzig)"} +MACRO {ao} {"Appl. Opt."} +MACRO {apl} {"Appl. Phys. Lett."} +MACRO {app} {"Astroparticle Phys."} +MACRO {apj} {"Astrophys. J."} +MACRO {apjsup} {"Astrophys. J. Suppl."} +MACRO {apss} {"Astrophys. Space Sci."} +MACRO {araa} {"Ann. Rev. Astron. Astrophys."} +MACRO {baas} {"Bull. Amer. Astron. Soc."} +MACRO {baps} {"Bull. Amer. Phys. Soc."} +MACRO {cmp} {"Comm. Math. Phys."} +MACRO {cpam} {"Commun. Pure Appl. Math."} +MACRO {cppcf} {"Comm. Plasma Phys. \& Controlled Fusion"} +MACRO {cpc} {"Comp. Phys. Comm."} +MACRO {cqg} {"Class. Quant. Grav."} +MACRO {cra} {"C. R. Acad. Sci. A"} +MACRO {fed} {"Fusion Eng. \& Design"} +MACRO {ft} {"Fusion Tech."} +MACRO {grg} {"Gen. Relativ. Gravit."} +MACRO {ieeens} {"IEEE Trans. Nucl. Sci."} +MACRO {ieeeps} {"IEEE Trans. Plasma Sci."} +MACRO {ijimw} {"Interntl. J. Infrared \& Millimeter Waves"} +MACRO {ip} {"Infrared Phys."} +MACRO {irp} {"Infrared Phys."} +MACRO {jap} {"J. Appl. Phys."} +MACRO {jasa} {"J. Acoust. Soc. America"} +MACRO {jcp} {"J. Comp. Phys."} +MACRO {jetp} {"Sov. Phys.--JETP"} +MACRO {jfe} {"J. Fusion Energy"} +MACRO {jfm} {"J. Fluid Mech."} +MACRO {jmp} {"J. Math. Phys."} +MACRO {jne} {"J. Nucl. Energy"} +MACRO {jnec} {"J. Nucl. Energy, C: Plasma Phys., Accelerators, Thermonucl. Res."} +MACRO {jnm} {"J. Nucl. Mat."} +MACRO {jpc} {"J. Phys. Chem."} +MACRO {jpp} {"J. Plasma Phys."} +MACRO {jpsj} {"J. Phys. Soc. Japan"} +MACRO {jsi} {"J. Sci. Instrum."} +MACRO {jvst} {"J. Vac. Sci. \& Tech."} +MACRO {nat} {"Nature"} +MACRO {nature} {"Nature"} +MACRO {nedf} {"Nucl. Eng. \& Design/Fusion"} +MACRO {nf} {"Nucl. Fusion"} +MACRO {nim} {"Nucl. Inst. \& Meth."} +MACRO {nimpr} {"Nucl. Inst. \& Meth. in Phys. Res."} +MACRO {np} {"Nucl. Phys."} +MACRO {npb} {"Nucl. Phys. B"} +MACRO {nt/f} {"Nucl. Tech./Fusion"} +MACRO {npbpc} {"Nucl. Phys. B (Proc. Suppl.)"} +MACRO {inc} {"Nuovo Cimento"} +MACRO {nc} {"Nuovo Cimento"} +MACRO {pf} {"Phys. Fluids"} +MACRO {pfa} {"Phys. Fluids A: Fluid Dyn."} +MACRO {pfb} {"Phys. Fluids B: Plasma Phys."} +MACRO {pl} {"Phys. Lett."} +MACRO {pla} {"Phys. Lett. A"} +MACRO {plb} {"Phys. Lett. B"} +MACRO {prep} {"Phys. Rep."} +MACRO {pnas} {"Proc. Nat. Acad. Sci. USA"} +MACRO {pp} {"Phys. Plasmas"} +MACRO {ppcf} {"Plasma Phys. \& Controlled Fusion"} +MACRO {phitrsl} {"Philos. Trans. Roy. Soc. London"} +MACRO {prl} {"Phys. Rev. Lett."} +MACRO {pr} {"Phys. Rev."} +MACRO {physrev} {"Phys. Rev."} +MACRO {pra} {"Phys. Rev. A"} +MACRO {prb} {"Phys. Rev. B"} +MACRO {prc} {"Phys. Rev. C"} +MACRO {prd} {"Phys. Rev. D"} +MACRO {pre} {"Phys. Rev. E"} +MACRO {ps} {"Phys. Scripta"} +MACRO {procrsl} {"Proc. Roy. Soc. London"} +MACRO {rmp} {"Rev. Mod. Phys."} +MACRO {rsi} {"Rev. Sci. Inst."} +MACRO {science} {"Science"} +MACRO {sciam} {"Sci. Am."} +MACRO {sam} {"Stud. Appl. Math."} +MACRO {sjpp} {"Sov. J. Plasma Phys."} +MACRO {spd} {"Sov. Phys.--Doklady"} +MACRO {sptp} {"Sov. Phys.--Tech. Phys."} +MACRO {spu} {"Sov. Phys.--Uspeki"} +MACRO {st} {"Sky and Telesc."} + % End module: physjour.mbs + %------------------------------------------------------------------- + % Begin module: + % \ProvidesFile{geojour.mbs}[2002/07/10 2.0h (PWD)] +MACRO {aisr} {"Adv. Space Res."} +MACRO {ag} {"Ann. Geophys."} +MACRO {anigeo} {"Ann. Geofis."} +MACRO {angl} {"Ann. Glaciol."} +MACRO {andmet} {"Ann. d. Meteor."} +MACRO {andgeo} {"Ann. d. Geophys."} +MACRO {andphy} {"Ann. Phys.-Paris"} +MACRO {afmgb} {"Arch. Meteor. Geophys. Bioklimatol."} +MACRO {atph} {"Atm\'osphera"} +MACRO {aao} {"Atmos. Ocean"} +MACRO {ass}{"Astrophys. Space Sci."} +MACRO {atenv} {"Atmos. Environ."} +MACRO {aujag} {"Aust. J. Agr. Res."} +MACRO {aumet} {"Aust. Meteorol. Mag."} +MACRO {blmet} {"Bound.-Lay. Meteorol."} +MACRO {bams} {"Bull. Amer. Meteorol. Soc."} +MACRO {cch} {"Clim. Change"} +MACRO {cdyn} {"Clim. Dynam."} +MACRO {cbul} {"Climatol. Bull."} +MACRO {cap} {"Contrib. Atmos. Phys."} +MACRO {dsr} {"Deep-Sea Res."} +MACRO {dhz} {"Dtsch. Hydrogr. Z."} +MACRO {dao} {"Dynam. Atmos. Oceans"} +MACRO {eco} {"Ecology"} +MACRO {empl}{"Earth, Moon and Planets"} +MACRO {envres} {"Environ. Res."} +MACRO {envst} {"Environ. Sci. Technol."} +MACRO {ecms} {"Estuarine Coastal Mar. Sci."} +MACRO {expa}{"Exper. Astron."} +MACRO {geoint} {"Geofis. Int."} +MACRO {geopub} {"Geofys. Publ."} +MACRO {geogeo} {"Geol. Geofiz."} +MACRO {gafd} {"Geophys. Astrophys. Fluid Dyn."} +MACRO {gfd} {"Geophys. Fluid Dyn."} +MACRO {geomag} {"Geophys. Mag."} +MACRO {georl} {"Geophys. Res. Lett."} +MACRO {grl} {"Geophys. Res. Lett."} +MACRO {ga} {"Geophysica"} +MACRO {gs} {"Geophysics"} +MACRO {ieeetap} {"IEEE Trans. Antenn. Propag."} +MACRO {ijawp} {"Int. J. Air Water Pollut."} +MACRO {ijc} {"Int. J. Climatol."} +MACRO {ijrs} {"Int. J. Remote Sens."} +MACRO {jam} {"J. Appl. Meteorol."} +MACRO {jaot} {"J. Atmos. Ocean. Technol."} +MACRO {jatp} {"J. Atmos. Terr. Phys."} +MACRO {jastp} {"J. Atmos. Solar-Terr. Phys."} +MACRO {jce} {"J. Climate"} +MACRO {jcam} {"J. Climate Appl. Meteor."} +MACRO {jcm} {"J. Climate Meteor."} +MACRO {jcy} {"J. Climatol."} +MACRO {jgr} {"J. Geophys. Res."} +MACRO {jga} {"J. Glaciol."} +MACRO {jh} {"J. Hydrol."} +MACRO {jmr} {"J. Mar. Res."} +MACRO {jmrj} {"J. Meteor. Res. Japan"} +MACRO {jm} {"J. Meteor."} +MACRO {jpo} {"J. Phys. Oceanogr."} +MACRO {jra} {"J. Rech. Atmos."} +MACRO {jaes} {"J. Aeronaut. Sci."} +MACRO {japca} {"J. Air Pollut. Control Assoc."} +MACRO {jas} {"J. Atmos. Sci."} +MACRO {jmts} {"J. Mar. Technol. Soc."} +MACRO {jmsj} {"J. Meteorol. Soc. Japan"} +MACRO {josj} {"J. Oceanogr. Soc. Japan"} +MACRO {jwm} {"J. Wea. Mod."} +MACRO {lao} {"Limnol. Oceanogr."} +MACRO {mwl} {"Mar. Wea. Log"} +MACRO {mau} {"Mausam"} +MACRO {meteor} {"``Meteor'' Forschungsergeb."} +MACRO {map} {"Meteorol. Atmos. Phys."} +MACRO {metmag} {"Meteor. Mag."} +MACRO {metmon} {"Meteor. Monogr."} +MACRO {metrun} {"Meteor. Rundsch."} +MACRO {metzeit} {"Meteor. Z."} +MACRO {metgid} {"Meteor. Gidrol."} +MACRO {mwr} {"Mon. Weather Rev."} +MACRO {nwd} {"Natl. Weather Dig."} +MACRO {nzjmfr} {"New Zeal. J. Mar. Freshwater Res."} +MACRO {npg} {"Nonlin. Proc. Geophys."} +MACRO {om} {"Oceanogr. Meteorol."} +MACRO {ocac} {"Oceanol. Acta"} +MACRO {oceanus} {"Oceanus"} +MACRO {paleoc} {"Paleoceanography"} +MACRO {pce} {"Phys. Chem. Earth"} +MACRO {pmg} {"Pap. Meteor. Geophys."} +MACRO {ppom} {"Pap. Phys. Oceanogr. Meteor."} +MACRO {physzeit} {"Phys. Z."} +MACRO {pps} {"Planet. Space Sci."} +MACRO {pss} {"Planet. Space Sci."} +MACRO {pag} {"Pure Appl. Geophys."} +MACRO {qjrms} {"Quart. J. Roy. Meteorol. Soc."} +MACRO {quatres} {"Quat. Res."} +MACRO {rsci} {"Radio Sci."} +MACRO {rse} {"Remote Sens. Environ."} +MACRO {rgeo} {"Rev. Geophys."} +MACRO {rgsp} {"Rev. Geophys. Space Phys."} +MACRO {rdgeo} {"Rev. Geofis."} +MACRO {revmeta} {"Rev. Meteorol."} +MACRO {sgp}{"Surveys in Geophys."} +MACRO {sp} {"Solar Phys."} +MACRO {ssr} {"Space Sci. Rev."} +MACRO {tellus} {"Tellus"} +MACRO {tac} {"Theor. Appl. Climatol."} +MACRO {tagu} {"Trans. Am. Geophys. Union (EOS)"} +MACRO {wrr} {"Water Resour. Res."} +MACRO {weather} {"Weather"} +MACRO {wafc} {"Weather Forecast."} +MACRO {ww} {"Weatherwise"} +MACRO {wmob} {"WMO Bull."} +MACRO {zeitmet} {"Z. Meteorol."} + % End module: geojour.mbs + %------------------------------------------------------------------- + % Begin module: + % \ProvidesFile{photjour.mbs}[1999/02/24 2.0b (PWD)] + +MACRO {appopt} {"Appl. Opt."} +MACRO {bell} {"Bell Syst. Tech. J."} +MACRO {ell} {"Electron. Lett."} +MACRO {jasp} {"J. Appl. Spectr."} +MACRO {jqe} {"IEEE J. Quantum Electron."} +MACRO {jlwt} {"J. Lightwave Technol."} +MACRO {jmo} {"J. Mod. Opt."} +MACRO {josa} {"J. Opt. Soc. America"} +MACRO {josaa} {"J. Opt. Soc. Amer.~A"} +MACRO {josab} {"J. Opt. Soc. Amer.~B"} +MACRO {jdp} {"J. Phys. (Paris)"} +MACRO {oc} {"Opt. Commun."} +MACRO {ol} {"Opt. Lett."} +MACRO {phtl} {"IEEE Photon. Technol. Lett."} +MACRO {pspie} {"Proc. Soc. Photo-Opt. Instrum. Eng."} +MACRO {sse} {"Solid-State Electron."} +MACRO {sjot} {"Sov. J. Opt. Technol."} +MACRO {sjqe} {"Sov. J. Quantum Electron."} +MACRO {sleb} {"Sov. Phys.--Leb. Inst. Rep."} +MACRO {stph} {"Sov. Phys.--Techn. Phys."} +MACRO {stphl} {"Sov. Techn. Phys. Lett."} +MACRO {vr} {"Vision Res."} +MACRO {zph} {"Z. f. Physik"} +MACRO {zphb} {"Z. f. Physik~B"} +MACRO {zphd} {"Z. f. Physik~D"} + +MACRO {CLEO} {"CLEO"} +MACRO {ASSL} {"Adv. Sol.-State Lasers"} +MACRO {OSA} {"OSA"} + % End module: photjour.mbs +%% Copyright 1994-2008 Patrick W Daly +MACRO {acmcs} {"ACM Comput. Surv."} + +MACRO {acta} {"Acta Inf."} + +MACRO {cacm} {"Commun. ACM"} + +MACRO {ibmjrd} {"IBM J. Res. Dev."} + +MACRO {ibmsj} {"IBM Syst.~J."} + +MACRO {ieeese} {"IEEE Trans. Software Eng."} + +MACRO {ieeetc} {"IEEE Trans. Comput."} + +MACRO {ieeetcad} + {"IEEE Trans. Comput. Aid. Des."} + +MACRO {ipl} {"Inf. Process. Lett."} + +MACRO {jacm} {"J.~ACM"} + +MACRO {jcss} {"J.~Comput. Syst. Sci."} + +MACRO {scp} {"Sci. Comput. Program."} + +MACRO {sicomp} {"SIAM J. Comput."} + +MACRO {tocs} {"ACM Trans. Comput. Syst."} + +MACRO {tods} {"ACM Trans. Database Syst."} + +MACRO {tog} {"ACM Trans. Graphic."} + +MACRO {toms} {"ACM Trans. Math. Software"} + +MACRO {toois} {"ACM Trans. Office Inf. Syst."} + +MACRO {toplas} {"ACM Trans. Progr. Lang. Syst."} + +MACRO {tcs} {"Theor. Comput. Sci."} + +FUNCTION {bibinfo.check} +{ swap$ + duplicate$ missing$ + { + pop$ pop$ + "" + } + { duplicate$ empty$ + { + swap$ pop$ + } + { swap$ + pop$ + } + if$ + } + if$ +} +FUNCTION {bibinfo.warn} +{ swap$ + duplicate$ missing$ + { + swap$ "missing " swap$ * " in " * cite$ * warning$ pop$ + "" + } + { duplicate$ empty$ + { + swap$ "empty " swap$ * " in " * cite$ * warning$ + } + { swap$ + pop$ + } + if$ + } + if$ +} + + +STRINGS {ss tt fm} +FUNCTION {format.onlyfirst} +{ + 'ss := %% Make a copy of the name in s + %% Extract the First (and possible Medium) names + %% and store it in variable fm + ss #1 "{ff}" format.name$ 'fm := + + %% Note that now fm could contain: + %% * An empty string ("") if the author has no first name (only Last name was provided) + %% * A single word (like "First") if the author has no medium name + %% * A sequence of words (like "First Medium") + %% For the last case we want to abbreviate "Medium", without dot + + %% Test if we are in the first case + fm empty$ { + % If empty (no first name), use the standard formatting + ss #1 "{vv~}{ll}{, f{.}.}{, jj}" format.name$ + }{ % Otherwise, attempt the trick + %% Now the trick. Interpret "First Medium" + %% as if "Medium" were a last name, and abbreviate it + fm #1 "{f.}{l}" format.name$ 'tt := %% And store the result in tt + %% Consider the particular case in which no Medium name is present + %% In this case, "First" will be interpreted as a last name, and + %% thus abbreviated. This can be detected because the resulting + %% string has length 1 + tt text.length$ #1 > { %% If there was a medium name + fm #1 "{f.}{l.}" format.name$ 'tt := + tt %% Store the abbreviated version + }{ %% Else store the original version of the name + fm + } if$ + + %% After the above, the top of the stack will contain + %% either "First" unabbreviated (if the author has not middle name) + %% or "First M", as required + 'tt := %% Copy that value to tt + + %% Now complete the standard formatting of the author, omitting + %% the first name part, which is stored in tt + ss #1 "{vv~}{ll}{, jj}" format.name$ + %% And concatenate to it the value of tt + ", " * + tt * + }if$ %% If the trick has to be done +} + +INTEGERS { nameptr namesleft numnames } +STRINGS { bibinfo} + +FUNCTION {format.names} +{ 'bibinfo := + duplicate$ empty$ 'skip$ { + 's := + "" 't := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + "{vv~}{ll}{, ff}{, jj}" + format.name$ + bibinfo bibinfo.check + format.onlyfirst 't := + nameptr #1 > + { + namesleft #1 > + { ", " * t * } + { + s nameptr "{ll}" format.name$ duplicate$ "others" = + { 't := } + { pop$ } + if$ + numnames #1 > + { "," * } + 'skip$ + if$ + t "others" = + { + " " * bbl.etal * + } + { + bbl.and + space.word * t * + } + if$ + } + if$ + } + 't + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + } if$ +} + + +FUNCTION {format.names.ed} +{ + 'bibinfo := + duplicate$ empty$ 'skip$ { + 's := + "" 't := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + "{f.~}{vv~}{ll}{, jj}" + format.name$ + bibinfo bibinfo.check + 't := + nameptr #1 > + { + namesleft #1 > + { ", " * t * } + { + s nameptr "{ll}" format.name$ duplicate$ "others" = + { 't := } + { pop$ } + if$ + numnames #2 > + { "," * } + 'skip$ + if$ + t "others" = + { + + " " * bbl.etal * + } + { + bbl.and + space.word * t * + } + if$ + } + if$ + } + 't + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + } if$ +} +FUNCTION {format.key} +{ empty$ + { key field.or.null } + { "" } + if$ +} + +FUNCTION {format.authors} +{ author "author" format.names +} +FUNCTION {get.bbl.editor} +{ editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ } + +FUNCTION {format.editors} +{ editor "editor" format.names duplicate$ empty$ 'skip$ + { + " " * + get.bbl.editor + capitalize + "(" swap$ * ")" * + * + } + if$ +} +FUNCTION {format.book.pages} +{ pages "pages" bibinfo.check + duplicate$ empty$ 'skip$ + { "~" * bbl.pages * } + if$ +} +FUNCTION {format.doi} +{ doi empty$ + { "" } + { + urldate empty$ + { + "\url{https://doi.org/" doi * "}" * + } + { + "at \url{https://doi.org/" doi * "}" * + } + if$ + } + if$ +} +FUNCTION {format.urldate} +{ urldate empty$ + { "" } + { + url empty$ + { + doi empty$ + { "" } + { + "accessed " urldate * + } + if$ + } + { + "accessed " urldate * + } + if$ + } + if$ +} +FUNCTION {format.url} +{ url empty$ + { "" } + { + urldate empty$ + { + "\url{" url * "}" * + } + { + "at \url{" url * "}" * + } + if$ + } + if$ +} +FUNCTION {format.urllink} +{ urllink empty$ + { "" } + { + " (Available online at \url{" urllink * "})" * + } + if$ +} +FUNCTION {format.note} +{ + note empty$ + { "" } + { note #1 #1 substring$ + duplicate$ "{" = + 'skip$ + { output.state mid.sentence = + { "l" } + { "u" } + if$ + change.case$ + } + if$ + note #2 global.max$ substring$ * "note" bibinfo.check + } + if$ +} + +FUNCTION {format.title} +{ title + duplicate$ empty$ 'skip$ + { "t" change.case$ } + if$ + "title" bibinfo.check +} +FUNCTION {format.full.names} +{'s := + "" 't := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + "{vv~}{ll}" format.name$ + 't := + nameptr #1 > + { + namesleft #1 > + { ", " * t * } + { + s nameptr "{ll}" format.name$ duplicate$ "others" = + { 't := } + { pop$ } + if$ + t "others" = + { + " " * bbl.etal * + cite.name.font + } + { + numnames #2 > + { "," * } + 'skip$ + if$ + bbl.and + space.word * t * + } + if$ + } + if$ + } + 't + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + t "others" = + 'skip$ + { cite.name.font } + if$ +} + +FUNCTION {author.editor.key.full} +{ author empty$ + { editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { editor format.full.names } + if$ + } + { author format.full.names } + if$ +} + +FUNCTION {author.key.full} +{ author empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { author format.full.names } + if$ +} + +FUNCTION {editor.key.full} +{ editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { editor format.full.names } + if$ +} + +FUNCTION {make.full.names} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.key.full + { type$ "proceedings" = + 'editor.key.full + 'author.key.full + if$ + } + if$ +} + +FUNCTION {output.bibitem} +{ newline$ + "\bibitem[{" write$ + label write$ + ")" make.full.names duplicate$ short.list = + { pop$ } + { * } + if$ + "}]{" * write$ + cite$ write$ + "}" write$ + newline$ + "" + before.all 'output.state := +} + +FUNCTION {if.digit} +{ duplicate$ "0" = + swap$ duplicate$ "1" = + swap$ duplicate$ "2" = + swap$ duplicate$ "3" = + swap$ duplicate$ "4" = + swap$ duplicate$ "5" = + swap$ duplicate$ "6" = + swap$ duplicate$ "7" = + swap$ duplicate$ "8" = + swap$ "9" = or or or or or or or or or +} +FUNCTION {n.separate} +{ 't := + "" + #0 'numnames := + { t empty$ not } + { t #-1 #1 substring$ if.digit + { numnames #1 + 'numnames := } + { #0 'numnames := } + if$ + t #-1 #1 substring$ swap$ * + t #-2 global.max$ substring$ 't := + numnames #5 = + { duplicate$ #1 #2 substring$ swap$ + #3 global.max$ substring$ + "," swap$ * * + } + 'skip$ + if$ + } + while$ +} +FUNCTION {n.dashify} +{ + n.separate + 't := + "" + { t empty$ not } + { t #1 #1 substring$ "-" = + { t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } + { "-" * + t #2 global.max$ substring$ 't := + } + while$ + } + if$ + } + { t #1 #1 substring$ * + t #2 global.max$ substring$ 't := + } + if$ + } + while$ +} + +FUNCTION {word.in} +{ bbl.in + " " * } + +FUNCTION {format.date} +{ year "year" bibinfo.check duplicate$ empty$ + { + } + 'skip$ + if$ + extra.label * + before.all 'output.state := + ", " swap$ * "" * +} +FUNCTION {format.btitle} +{ title "title" bibinfo.check + duplicate$ empty$ 'skip$ + { + %emphasize + } + if$ +} +FUNCTION {either.or.check} +{ empty$ + 'pop$ + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} +FUNCTION {format.bvolume} +{ volume empty$ + { "" } + { bbl.volume volume tie.or.space.prefix + "volume" bibinfo.check * * + series "series" bibinfo.check + duplicate$ empty$ 'pop$ + + % { emphasize ", " * swap$ * } % REMOVE ITALICS FOR USGS + { ", " * swap$ * } + if$ + "volume and number" number either.or.check + } + if$ +} +FUNCTION {format.number.series} +{ volume empty$ + { number empty$ + { series field.or.null } + { series empty$ + { number "number" bibinfo.check } + { output.state mid.sentence = + { bbl.number } + { bbl.number capitalize } + if$ + number tie.or.space.prefix "number" bibinfo.check * * + bbl.in space.word * + series "series" bibinfo.check * + } + if$ + } + if$ + } + { "" } + if$ +} + +FUNCTION {format.edition} +{ edition duplicate$ empty$ 'skip$ + { + output.state mid.sentence = + { "l" } + { "t" } + if$ change.case$ + "edition" bibinfo.check + " " * bbl.edition * + } + if$ +} +INTEGERS { multiresult } +FUNCTION {multi.page.check} +{ 't := + #0 'multiresult := + { multiresult not + t empty$ not + and + } + { t #1 #1 substring$ + duplicate$ "-" = + swap$ duplicate$ "," = + swap$ "+" = + or or + { #1 'multiresult := } + { t #2 global.max$ substring$ 't := } + if$ + } + while$ + multiresult +} +FUNCTION {format.pages} +{ pages duplicate$ empty$ 'skip$ + { duplicate$ multi.page.check + { + bbl.pages swap$ + n.dashify + } + { + bbl.page swap$ + } + if$ + tie.or.space.prefix + "pages" bibinfo.check + * * + } + if$ +} +FUNCTION {format.journal.pages} +{ pages duplicate$ empty$ 'pop$ + { swap$ duplicate$ empty$ + { pop$ pop$ format.pages } + { + ", p.~" * + swap$ + n.dashify + "pages" bibinfo.check + * + } + if$ + } + if$ +} +FUNCTION {format.journal.eid} +{ eid "eid" bibinfo.check + duplicate$ empty$ 'pop$ + { swap$ duplicate$ empty$ 'skip$ + { + ", " * + } + if$ + swap$ * + } + if$ +} +FUNCTION {format.vol.num.pages} +{ volume field.or.null + duplicate$ empty$ 'skip$ + { + bbl.volume swap$ tie.or.space.prefix + "volume" bibinfo.check + * * + } + if$ + number "number" bibinfo.check duplicate$ empty$ 'skip$ + { + swap$ duplicate$ empty$ + { "there's a number but no volume in " cite$ * warning$ } + 'skip$ + if$ + swap$ + ", " bbl.nr * number tie.or.space.prefix pop$ * swap$ * + } + if$ * + eid empty$ + { format.journal.pages } + { format.journal.eid } + if$ +} + +FUNCTION {format.chapter.pages} +{ chapter empty$ + 'format.pages + { type empty$ + { bbl.chapter } + { type "l" change.case$ + "type" bibinfo.check + } + if$ + chapter tie.or.space.prefix + "chapter" bibinfo.check + * * + pages empty$ + 'skip$ + { ", " * format.pages * } + if$ + } + if$ +} + +FUNCTION {format.booktitle} +{ + booktitle "booktitle" bibinfo.check + %emphasize +} + +FUNCTION {format.editor} +{ + editor "editor" format.names + duplicate$ empty$ 'pop$ + { + %emphasize + } + if$ +} + +FUNCTION {format.in.ed.booktitle} +{ format.booktitle duplicate$ empty$ 'skip$ + { + format.bvolume duplicate$ empty$ 'pop$ + { ", " swap$ * * } + if$ + editor "editor" format.names.ed duplicate$ empty$ 'pop$ + { + bbl.edby + " " * swap$ * + swap$ + "," * + " " * swap$ + * } + if$ + word.in swap$ * + } + if$ +} + +FUNCTION {formatc.in.ed.booktitle} +{ format.editor duplicate$ empty$ 'skip$ + { + format.bvolume duplicate$ empty$ 'pop$ + { ", " swap$ * * } + if$ + format.booktitle duplicate$ empty$ 'pop$ + { + swap$ + "," * + " " * swap$ + * } + if$ + word.in swap$ * + } + if$ +} + +FUNCTION {format.thesis.type} +{ type duplicate$ empty$ + 'pop$ + { swap$ pop$ + "t" change.case$ "type" bibinfo.check + } + if$ +} +FUNCTION {format.tr.number} +{ number "number" bibinfo.check + type duplicate$ empty$ + { pop$ bbl.techrep } + 'skip$ + if$ + "type" bibinfo.check + swap$ duplicate$ empty$ + { pop$ "t" change.case$ } + { tie.or.space.prefix * * } + if$ +} +FUNCTION {format.article.crossref} +{ + word.in + " \cite{" * crossref * "}" * +} +FUNCTION {format.book.crossref} +{ volume duplicate$ empty$ + { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ + pop$ word.in + } + { bbl.volume + swap$ tie.or.space.prefix "volume" bibinfo.check * * bbl.of space.word * + } + if$ + " \cite{" * crossref * "}" * +} +FUNCTION {format.incoll.inproc.crossref} +{ + word.in + " \cite{" * crossref * "}" * +} +FUNCTION {format.org.or.pub} +{ 't := + "" + address empty$ t empty$ and + 'skip$ + { + t empty$ + { address "address" bibinfo.check * + } + { t * + address empty$ + 'skip$ + { ", " * address "address" bibinfo.check * } + if$ + } + if$ + } + if$ +} +FUNCTION {formatc.org.or.pub} +{ 't := + "" + address empty$ t empty$ and + 'skip$ + { + t empty$ + { address "address" bibinfo.check * + } + { t * + address empty$ + 'skip$ + { ": " * address "address" bibinfo.check * } + if$ + } + if$ + } + if$ +} +FUNCTION {format.publisher.address} +{ format.org.or.pub publisher "publisher" bibinfo.warn +} +FUNCTION {formatc.publisher.address} +{ formatc.org.or.pub publisher "publisher" bibinfo.warn +} + +FUNCTION {format.organization.address} +{ organization "organization" bibinfo.check format.org.or.pub +} + +FUNCTION {article} +{ output.bibitem + format.authors "author" output.check + author format.key output + format.date "year" output.check + date.block + format.title "title" output.check + crossref missing$ + { + journal + "journal" bibinfo.check + %emphasize + "journal" outputc.check + format.vol.num.pages output + format.urldate output + format.doi output + format.url output + format.urllink output + } + { format.article.crossref output.nonnull + format.pages output + } + if$ + format.note output + fin.entry +} +FUNCTION {book} +{ output.bibitem + author empty$ + { format.editors "author and editor" output.check + editor format.key output + } + { format.authors output.nonnull + crossref missing$ + { "author and editor" editor either.or.check } + 'skip$ + if$ + } + if$ + format.date "year" output.check + date.block + format.btitle "title" output.check + publisher empty$ + { format.number.series outputc.nonnull } + { formatc.publisher.address output + format.book.pages output + } + if$ + format.urldate output + format.doi output + format.url output + format.urllink output + format.note output + fin.entry +} +FUNCTION {booklet} +{ output.bibitem + format.authors output + author format.key output + format.date "year" output.check + date.block + format.title "title" output.check + howpublished "howpublished" bibinfo.check output + address "address" bibinfo.check output + format.book.pages output + format.urldate output + format.doi output + format.url output + format.urllink output + format.note output + fin.entry +} + +FUNCTION {inbook} +{ output.bibitem + author empty$ + { format.editors "author and editor" output.check + editor format.key output + } + { format.authors output.nonnull + crossref missing$ + { "author and editor" editor either.or.check } + 'skip$ + if$ + } + if$ + format.date "year" output.check + date.block + format.btitle "title" output.check + publisher empty$ + { format.number.series outputc.nonnull } + { formatc.publisher.address output + format.book.pages output + } +% crossref missing$ +% { +% format.bvolume output +% format.chapter.pages "chapter and pages" output.check +% format.number.series output +% format.edition output +% formatc.publisher.address output +% } +% { +% format.chapter.pages "chapter and pages" output.check +% format.book.crossref output.nonnull +% } + if$ + format.urldate output + format.doi output + format.url output + format.urllink output + format.note output + fin.entry +} + +FUNCTION {incollection} +{ output.bibitem + format.authors "author" output.check + author format.key output + format.date "year" output.check + date.block + format.title "title" output.check + publisher empty$ + { formatc.in.ed.booktitle "booktitle" output.check + format.number.series outputc.nonnull } + { formatc.in.ed.booktitle "booktitle" output.check + formatc.publisher.address output + format.book.pages output + } +% crossref missing$ +% { format.in.ed.booktitle "booktitle" output.check +% format.number.series output +% format.edition output +% format.chapter.pages output +% formatc.publisher.address output +% } +% { format.incoll.inproc.crossref output.nonnull +% format.chapter.pages output +% } + if$ + format.urldate output + format.doi output + format.url output + format.urllink output + format.note output + fin.entry +} +FUNCTION {inproceedings} +{ output.bibitem + format.authors "author" output.check + author format.key output + format.date "year" output.check + date.block + format.title "title" output.check + crossref missing$ + { format.in.ed.booktitle "booktitle" output.check + format.number.series output + publisher empty$ + { format.organization.address output } + { organization "organization" bibinfo.check output + format.publisher.address output + } + if$ + format.pages output + } + { format.incoll.inproc.crossref output.nonnull + format.pages output + } + if$ + format.urldate output + format.doi output + format.url output + format.urllink output + format.note output + fin.entry +} +FUNCTION {conference} { inproceedings } +FUNCTION {manual} +{ output.bibitem + format.authors output + author format.key output + format.date "year" output.check + date.block + format.btitle "title" output.check + organization "organization" bibinfo.check output + address "address" bibinfo.check output + format.edition output + format.urldate output + format.doi output + format.url output + format.urllink output + format.note output + fin.entry +} + +FUNCTION {mastersthesis} +{ output.bibitem + format.authors "author" output.check + author format.key output + format.date "year" output.check + date.block + format.title + "title" output.check + bbl.mthesis format.thesis.type output.nonnull + school "school" bibinfo.warn output + address "address" bibinfo.check output + format.urldate output + format.doi output + format.url output + format.urllink output + format.note output + format.book.pages output + fin.entry +} + +FUNCTION {misc} +{ output.bibitem + format.authors output + author format.key output + format.date "year" output.check + date.block + format.title output + howpublished "howpublished" bibinfo.check output + format.urldate output + format.doi output + format.url output + format.urllink output + format.note output + fin.entry +} +FUNCTION {phdthesis} +{ output.bibitem + format.authors "author" output.check + author format.key output + format.date "year" output.check + date.block + format.title + "title" output.check + bbl.phdthesis format.thesis.type output.nonnull + school "school" bibinfo.warn output + address "address" bibinfo.check output + format.urldate output + format.doi output + format.url output + format.urllink output + format.note output + format.book.pages output + fin.entry +} + +FUNCTION {proceedings} +{ output.bibitem + format.editors output + editor format.key output + format.date "year" output.check + date.block + format.btitle "title" output.check + format.bvolume output + format.number.series output + publisher empty$ + { format.organization.address output } + { organization "organization" bibinfo.check output + format.publisher.address output + } + if$ + format.urldate output + format.doi output + format.url output + format.urllink output + format.note output + fin.entry +} + +FUNCTION {techreport} +{ output.bibitem + format.authors "author" output.check + author format.key output + format.date "year" output.check + date.block + format.title + "title" output.check + % format.tr.number emphasize output.nonnull + institution "institution" bibinfo.warn output + address "address" bibinfo.check output + format.book.pages output + fin.entry +} + +FUNCTION {online} +{ output.bibitem + format.authors "author" output.check + author format.key output + format.date "year" output.check + date.block + format.title + "title" output.check + % format.tr.number emphasize output.nonnull + + fin.entry +} + +FUNCTION {unpublished} +{ output.bibitem + format.authors "author" output.check + author format.key output + format.date "year" output.check + date.block + format.title "title" output.check + format.urldate output + format.doi output + format.url output + format.urllink output + format.note "note" output.check + fin.entry +} + +FUNCTION {default.type} { misc } +READ +FUNCTION {sortify} +{ purify$ + "l" change.case$ +} +INTEGERS { len } +FUNCTION {chop.word} +{ 's := + 'len := + s #1 len substring$ = + { s len #1 + global.max$ substring$ } + 's + if$ +} +FUNCTION {format.lab.names} +{ 's := + "" 't := + s #1 "{vv~}{ll}" format.name$ + s num.names$ duplicate$ + #2 > + { pop$ + " " * bbl.etal * + cite.name.font + "others" 't := + } + { #2 < + 'skip$ + { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { + " " * bbl.etal * + cite.name.font + "others" 't := + } + { bbl.and space.word * s #2 "{vv~}{ll}" format.name$ + * } + if$ + } + if$ + } + if$ + t "others" = + 'skip$ + { cite.name.font } + if$ +} + +FUNCTION {author.key.label} +{ author empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {author.editor.key.label} +{ author empty$ + { editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { editor format.lab.names } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {editor.key.label} +{ editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { editor format.lab.names } + if$ +} + +FUNCTION {calc.short.authors} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.key.label + { type$ "proceedings" = + 'editor.key.label + 'author.key.label + if$ + } + if$ + 'short.list := +} + +FUNCTION {calc.label} +{ calc.short.authors + short.list + "(" + * + year duplicate$ empty$ + short.list key field.or.null = or + { pop$ "" } + 'skip$ + if$ + * + 'label := +} + +FUNCTION {sort.format.names} +{ 's := + #1 'nameptr := + "" + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" + format.name$ 't := + nameptr #1 > + { + " " * + namesleft #1 = t "others" = and + { "zzzzz" 't := } + 'skip$ + if$ + numnames #2 > nameptr #2 = and + { "zz" * year field.or.null * " " * + #1 'namesleft := + } + { t sortify * } + if$ + } + { t sortify * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {sort.format.title} +{ 't := + "A " #2 + "An " #3 + "The " #4 t chop.word + chop.word + chop.word + sortify + #1 global.max$ substring$ +} +FUNCTION {author.sort} +{ author empty$ + { key empty$ + { "to sort, need author or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { author sort.format.names } + if$ +} +FUNCTION {author.editor.sort} +{ author empty$ + { editor empty$ + { key empty$ + { "to sort, need author, editor, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ + } + { author sort.format.names } + if$ +} +FUNCTION {editor.sort} +{ editor empty$ + { key empty$ + { "to sort, need editor or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ +} +FUNCTION {presort} +{ calc.label + label sortify + " " + * + type$ "book" = + type$ "inbook" = + or + 'author.editor.sort + { type$ "proceedings" = + 'editor.sort + 'author.sort + if$ + } + if$ + #1 entry.max$ substring$ + 'sort.label := + sort.label + * + #1 entry.max$ substring$ + 'sort.key$ := +} + +ITERATE {presort} +SORT +STRINGS { last.label next.extra } +INTEGERS { last.extra.num last.extra.num.extended last.extra.num.blank number.label } +FUNCTION {initialize.extra.label.stuff} +{ #0 int.to.chr$ 'last.label := + "" 'next.extra := + #0 'last.extra.num := + "a" chr.to.int$ #1 - 'last.extra.num.blank := + last.extra.num.blank 'last.extra.num.extended := + #0 'number.label := +} +FUNCTION {forward.pass} +{ last.label label = + { last.extra.num #1 + 'last.extra.num := + last.extra.num "z" chr.to.int$ > + { "a" chr.to.int$ 'last.extra.num := + last.extra.num.extended #1 + 'last.extra.num.extended := + } + 'skip$ + if$ + last.extra.num.extended last.extra.num.blank > + { last.extra.num.extended int.to.chr$ + last.extra.num int.to.chr$ + * 'extra.label := } + { last.extra.num int.to.chr$ 'extra.label := } + if$ + } + { "a" chr.to.int$ 'last.extra.num := + "" 'extra.label := + label 'last.label := + } + if$ + number.label #1 + 'number.label := +} +FUNCTION {reverse.pass} +{ next.extra "b" = + { "a" 'extra.label := } + 'skip$ + if$ + extra.label 'next.extra := + extra.label + duplicate$ empty$ + 'skip$ + { "{\natexlab{" swap$ * "}}" * } + if$ + 'extra.label := + label extra.label * 'label := +} +EXECUTE {initialize.extra.label.stuff} +ITERATE {forward.pass} +REVERSE {reverse.pass} +FUNCTION {bib.sort.order} +{ sort.label + " " + * + year field.or.null sortify + * + #1 entry.max$ substring$ + 'sort.key$ := +} +ITERATE {bib.sort.order} +SORT +FUNCTION {begin.bib} +{ preamble$ empty$ + 'skip$ + { preamble$ write$ newline$ } + if$ + "\begin{thebibliography}{" number.label int.to.str$ * "}" * + write$ newline$ + "\providecommand{\natexlab}[1]{#1}" + write$ newline$ + "\expandafter\ifx\csname urlstyle\endcsname\relax" + write$ newline$ + " \providecommand{\doi}[1]{doi:\discretionary{}{}{}#1}\else" + write$ newline$ + " \providecommand{\doi}{doi:\discretionary{}{}{}\begingroup \urlstyle{rm}\Url}\fi" + write$ newline$ +} +EXECUTE {begin.bib} +EXECUTE {init.state.consts} +ITERATE {call.type$} +FUNCTION {end.bib} +{ newline$ + "\end{thebibliography}" write$ newline$ +} +EXECUTE {end.bib} +%% End of customized bst file +%% +%% End of file `agufull08.bst'. diff --git a/make/makefile b/make/makefile index f6d172d4bd1..234a6587e3e 100644 --- a/make/makefile +++ b/make/makefile @@ -281,6 +281,7 @@ $(OBJDIR)/GhostNode.o \ $(OBJDIR)/gwf3evt8.o \ $(OBJDIR)/gwf3chd8.o \ $(OBJDIR)/gwe1sfe1.o \ +$(OBJDIR)/gwe1lke1.o \ $(OBJDIR)/gwe1est1.o \ $(OBJDIR)/gwe1esl1.o \ $(OBJDIR)/gwe1ctp1.o \ diff --git a/msvs/mf6core.vfproj b/msvs/mf6core.vfproj index d8176d7a00a..33f4b78abb0 100644 --- a/msvs/mf6core.vfproj +++ b/msvs/mf6core.vfproj @@ -152,6 +152,7 @@ + diff --git a/src/Model/GroundWaterEnergy/gwe1.f90 b/src/Model/GroundWaterEnergy/gwe1.f90 index 21fef839832..e2c86d2c738 100644 --- a/src/Model/GroundWaterEnergy/gwe1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1.f90 @@ -86,7 +86,7 @@ module GweModule &'MWE6 ', 'UZE6 ', 'API6 ', ' ', ' ', & ! 10 &40*' '/ ! 50 - ! -- size of supported model package arrays + ! -- Size of supported model package arrays integer(I4B), parameter :: NIUNIT_GWE = GWE_NBASEPKG + GWE_NMULTIPKG contains @@ -133,7 +133,7 @@ subroutine gwe_cr(filename, id, modelname) ! -- Call parent class routine call this%tsp_cr(filename, id, modelname, 'GWE', indis) ! - ! -- create model packages + ! -- Create model packages call this%create_packages(indis) ! ! -- Return @@ -288,7 +288,7 @@ subroutine gwe_ar(this) ! -- Call dis_ar to write binary grid file !call this%dis%dis_ar(this%npf%icelltype) ! - ! -- set up output control + ! -- Set up output control call this%oc%oc_ar(this%x, this%dis, DHNOFLO, this%depvartype) call this%budget%set_ibudcsv(this%oc%ibudcsv) ! @@ -357,7 +357,7 @@ subroutine gwe_ad(this) if (iFailedStepRetry > 0) irestore = 1 if (irestore == 0) then ! - ! -- copy x into xold + ! -- Copy x into xold do n = 1, this%dis%nodes if (this%ibound(n) == 0) then this%xold(n) = DZERO @@ -367,7 +367,7 @@ subroutine gwe_ad(this) end do else ! - ! -- copy xold into x if this time step is a redo + ! -- Copy xold into x if this time step is a redo do n = 1, this%dis%nodes this%x(n) = this%xold(n) end do @@ -400,7 +400,6 @@ end subroutine gwe_ad !! subroutines !< subroutine gwe_cf(this, kiter) - ! -- modules ! -- dummy class(GweModelType) :: this integer(I4B), intent(in) :: kiter @@ -424,7 +423,6 @@ end subroutine gwe_cf !! subroutines !< subroutine gwe_fc(this, kiter, matrix_sln, inwtflag) - ! -- modules ! -- dummy class(GweModelType) :: this integer(I4B), intent(in) :: kiter @@ -434,7 +432,7 @@ subroutine gwe_fc(this, kiter, matrix_sln, inwtflag) class(BndType), pointer :: packobj integer(I4B) :: ip ! - ! -- call fc routines + ! -- Call fc routines call this%fmi%fmi_fc(this%dis%nodes, this%xold, this%nja, matrix_sln, & this%idxglo, this%rhs) if (this%inmvt > 0) then @@ -456,7 +454,7 @@ subroutine gwe_fc(this, kiter, matrix_sln, inwtflag) call this%ssm%ssm_fc(matrix_sln, this%idxglo, this%rhs) end if ! - ! -- packages + ! -- Packages do ip = 1, this%bndlist%Count() packobj => GetBndFromList(this%bndlist, ip) call packobj%bnd_fc(this%rhs, this%ia, this%idxglo, matrix_sln) @@ -481,8 +479,6 @@ subroutine gwe_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak) character(len=LENPAKLOC), intent(inout) :: cpak integer(I4B), intent(inout) :: ipak real(DP), intent(inout) :: dpak - ! -- local - ! -- formats ! ! -- If mover is on, then at least 2 outers required if (this%inmvt > 0) call this%mvt%mvt_cc(kiter, iend, icnvgmod, cpak, dpak) @@ -740,10 +736,10 @@ subroutine allocate_scalars(this, modelname) class(GweModelType) :: this character(len=*), intent(in) :: modelname ! - ! -- allocate parent class scalars + ! -- Allocate parent class scalars call this%allocate_tsp_scalars(modelname) ! - ! -- allocate members that are part of model class + ! -- Allocate members that are part of model class call mem_allocate(this%inest, 'INEST', this%memoryPath) call mem_allocate(this%incnd, 'INCND', this%memoryPath) ! @@ -766,7 +762,7 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & use SimModule, only: store_error use GweCtpModule, only: ctp_create use GweEslModule, only: esl_create - !use GweLkeModule, only: lke_create + use GweLkeModule, only: lke_create use GweSfeModule, only: sfe_create !use GweMweModule, only: mwe_create !use GweUzeModule, only: uze_create @@ -794,10 +790,10 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & case ('ESL6') call esl_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & pakname, this%gwecommon) - !case ('LKE6') - ! call lke_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & - ! pakname, this%fmi, this%tsplab, this%eqnsclfac, & - ! this%gwecommon) + case ('LKE6') + call lke_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + pakname, this%fmi, this%eqnsclfac, this%gwecommon, & + this%depvartype, this%depvarunit, this%depvarunitabbrev) case ('SFE6') call sfe_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & pakname, this%fmi, this%eqnsclfac, this%gwecommon, & @@ -838,9 +834,11 @@ end subroutine package_create !> @brief Cast to GweModelType !< function CastAsGweModel(model) result(gwemodel) + ! -- dummy class(*), pointer :: model !< The object to be cast + ! -- return class(GweModelType), pointer :: gwemodel !< The GWE model - + ! gwemodel => null() if (.not. associated(model)) return select type (model) @@ -877,10 +875,10 @@ subroutine create_bndpkgs(this, bndpkgs, pkgtypes, pkgnames, & character(len=LENMEMPATH) :: mempath integer(I4B), pointer :: inunit integer(I4B) :: n - + ! if (allocated(bndpkgs)) then ! - ! -- create stress packages + ! -- Create stress packages ipakid = 1 bndptype = '' do n = 1, size(bndpkgs) @@ -901,7 +899,7 @@ subroutine create_bndpkgs(this, bndpkgs, pkgtypes, pkgnames, & ipaknum = ipaknum + 1 end do ! - ! -- cleanup + ! -- Cleanup deallocate (bndpkgs) end if ! @@ -942,10 +940,10 @@ subroutine create_gwe_packages(this, indis) integer(I4B) :: n character(len=LENMEMPATH) :: mempathcnd = '' ! - ! -- set input memory paths, input/model and input/model/namfile + ! -- Set input memory paths, input/model and input/model/namfile model_mempath = create_mem_path(component=this%name, context=idm_context) ! - ! -- set pointers to model path package info + ! -- Set pointers to model path package info call mem_setptr(pkgtypes, 'PKGTYPES', model_mempath) call mem_setptr(pkgnames, 'PKGNAMES', model_mempath) call mem_setptr(mempaths, 'MEMPATHS', model_mempath) @@ -953,13 +951,13 @@ subroutine create_gwe_packages(this, indis) ! do n = 1, size(pkgtypes) ! - ! attributes for this input package + ! -- Attributes for this input package pkgtype = pkgtypes(n) pkgname = pkgnames(n) mempath = mempaths(n) inunit => inunits(n) ! - ! -- create dis package as it is a prerequisite for other packages + ! -- Create dis package as it is a prerequisite for other packages select case (pkgtype) case ('EST6') this%inest = inunit diff --git a/src/Model/GroundWaterEnergy/gwe1lke1.f90 b/src/Model/GroundWaterEnergy/gwe1lke1.f90 new file mode 100644 index 00000000000..46c932ffad8 --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1lke1.f90 @@ -0,0 +1,1241 @@ +! -- Lake Energy Transport Module +! -- todo: what to do about reactions in lake? Decay? +! -- todo: save the lke temperatures into the lak aux variable? +! +! LAK flows (lakbudptr) index var LKT term Transport Type +!--------------------------------------------------------------------------------- + +! -- terms from LAK that will be handled by parent APT Package +! FLOW-JA-FACE idxbudfjf FLOW-JA-FACE cv2cv +! GWF (aux FLOW-AREA) idxbudgwf GWF cv2gwf +! STORAGE (aux VOLUME) idxbudsto none used for cv volumes +! FROM-MVR idxbudfmvr FROM-MVR q * cext = this%qfrommvr(:) +! TO-MVR idxbudtmvr TO-MVR q * cfeat + +! -- LAK terms +! RAINFALL idxbudrain RAINFALL q * crain +! EVAPORATION idxbudevap EVAPORATION cfeat null() !< pointer to shared gwe data used by multiple packages but set in mst + + integer(I4B), pointer :: idxbudrain => null() ! index of rainfall terms in flowbudptr + integer(I4B), pointer :: idxbudevap => null() ! index of evaporation terms in flowbudptr + integer(I4B), pointer :: idxbudroff => null() ! index of runoff terms in flowbudptr + integer(I4B), pointer :: idxbudiflw => null() ! index of inflow terms in flowbudptr + integer(I4B), pointer :: idxbudwdrl => null() ! index of withdrawal terms in flowbudptr + integer(I4B), pointer :: idxbudoutf => null() ! index of outflow terms in flowbudptr + integer(I4B), pointer :: idxbudlbcd => null() ! index of lakebed conduction terms in flowbudptr + + real(DP), dimension(:), pointer, contiguous :: temprain => null() ! rainfall temperature + real(DP), dimension(:), pointer, contiguous :: tempevap => null() ! evaporation temperature + real(DP), dimension(:), pointer, contiguous :: temproff => null() ! runoff temperature + real(DP), dimension(:), pointer, contiguous :: tempiflw => null() ! inflow temperature + + contains + + procedure :: bnd_da => lke_da + procedure :: allocate_scalars + procedure :: apt_allocate_arrays => lke_allocate_arrays + procedure :: find_apt_package => find_lke_package + procedure :: pak_fc_expanded => lke_fc_expanded + procedure :: pak_solve => lke_solve + procedure :: pak_get_nbudterms => lke_get_nbudterms + procedure :: pak_setup_budobj => lke_setup_budobj + procedure :: pak_fill_budobj => lke_fill_budobj + procedure :: lke_rain_term + procedure :: lke_evap_term + procedure :: lke_roff_term + procedure :: lke_iflw_term + procedure :: lke_wdrl_term + procedure :: lke_outf_term + procedure :: pak_df_obs => lke_df_obs + procedure :: pak_rp_obs => lke_rp_obs + procedure :: pak_bd_obs => lke_bd_obs + procedure :: pak_set_stressperiod => lke_set_stressperiod + + end type GweLkeType + +contains + + !> @brief Create a new lke package + !< + subroutine lke_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, & + fmi, eqnsclfac, gwecommon, dvt, dvu, dvua) + ! -- dummy + class(BndType), pointer :: packobj + integer(I4B), intent(in) :: id + integer(I4B), intent(in) :: ibcnum + integer(I4B), intent(in) :: inunit + integer(I4B), intent(in) :: iout + character(len=*), intent(in) :: namemodel + character(len=*), intent(in) :: pakname + type(TspFmiType), pointer :: fmi + real(DP), intent(in), pointer :: eqnsclfac !< governing equation scale factor + type(GweInputDataType), intent(in), target :: gwecommon !< shared data container for use by multiple GWE packages + character(len=*), intent(in) :: dvt !< For GWE, set to "TEMPERATURE" in TspAptType + character(len=*), intent(in) :: dvu !< For GWE, set to "energy" in TspAptType + character(len=*), intent(in) :: dvua !< For GWE, set to "E" in TspAptType + ! -- local + type(GweLkeType), pointer :: lkeobj + ! + ! -- Allocate the object and assign values to object variables + allocate (lkeobj) + packobj => lkeobj + ! + ! -- Create name and memory path + call packobj%set_names(ibcnum, namemodel, pakname, ftype) + packobj%text = text + ! + ! -- Allocate scalars + call lkeobj%allocate_scalars() + ! + ! -- Initialize package + call packobj%pack_initialize() + ! + packobj%inunit = inunit + packobj%iout = iout + packobj%id = id + packobj%ibcnum = ibcnum + packobj%ncolbnd = 1 + packobj%iscloc = 1 + ! + ! -- Store pointer to flow model interface. When the GwfGwe exchange is + ! created, it sets fmi%bndlist so that the GWE model has access to all + ! the flow packages + lkeobj%fmi => fmi + ! + ! -- Store pointer to governing equation scale factor + lkeobj%eqnsclfac => eqnsclfac + ! + ! -- Store pointer to shared data module for accessing cpw, rhow + ! for the budget calculations, and for accessing the latent heat of + ! vaporization for evaporative cooling. + lkeobj%gwecommon => gwecommon + ! + ! -- Set labels that will be used in generalized APT class + lkeobj%depvartype = dvt + lkeobj%depvarunit = dvu + lkeobj%depvarunitabbrev = dvua + ! + ! -- Return + return + end subroutine lke_create + + !> @brief Find corresponding lke package + !< + subroutine find_lke_package(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweLkeType) :: this + ! -- local + character(len=LINELENGTH) :: errmsg + class(BndType), pointer :: packobj + integer(I4B) :: ip, icount + integer(I4B) :: nbudterm + logical :: found + ! + ! -- Initialize found to false, and error later if flow package cannot + ! be found + found = .false. + ! + ! -- If user is specifying flows in a binary budget file, then set up + ! the budget file reader, otherwise set a pointer to the flow package + ! budobj + if (this%fmi%flows_from_file) then + call this%fmi%set_aptbudobj_pointer(this%flowpackagename, this%flowbudptr) + if (associated(this%flowbudptr)) found = .true. + ! + else + if (associated(this%fmi%gwfbndlist)) then + ! -- Look through gwfbndlist for a flow package with the same name as + ! this transport package name + do ip = 1, this%fmi%gwfbndlist%Count() + packobj => GetBndFromList(this%fmi%gwfbndlist, ip) + if (packobj%packName == this%flowpackagename) then + found = .true. + ! + ! -- Store BndType pointer to packobj, and then + ! use the select type to point to the budobj in flow package + this%flowpackagebnd => packobj + select type (packobj) + type is (LakType) + this%flowbudptr => packobj%budobj + end select + end if + if (found) exit + end do + end if + end if + ! + ! -- Error if flow package not found + if (.not. found) then + write (errmsg, '(a)') 'COULD NOT FIND FLOW PACKAGE WITH NAME '& + &//trim(adjustl(this%flowpackagename))//'.' + call store_error(errmsg) + call this%parser%StoreErrorUnit() + end if + ! + ! -- Allocate space for idxbudssm, which indicates whether this is a + ! special budget term or one that is a general source and sink + nbudterm = this%flowbudptr%nbudterm + call mem_allocate(this%idxbudssm, nbudterm, 'IDXBUDSSM', this%memoryPath) + ! + ! -- Process budget terms and identify special budget terms + write (this%iout, '(/, a, a)') & + 'PROCESSING '//ftype//' INFORMATION FOR ', this%packName + write (this%iout, '(a)') ' IDENTIFYING FLOW TERMS IN '//flowtype//' PACKAGE' + write (this%iout, '(a, i0)') & + ' NUMBER OF '//flowtype//' = ', this%flowbudptr%ncv + icount = 1 + do ip = 1, this%flowbudptr%nbudterm + select case (trim(adjustl(this%flowbudptr%budterm(ip)%flowtype))) + case ('FLOW-JA-FACE') + this%idxbudfjf = ip + this%idxbudssm(ip) = 0 + case ('GWF') + this%idxbudgwf = ip + this%idxbudlbcd = ip + this%idxbudssm(ip) = 0 + case ('STORAGE') + this%idxbudsto = ip + this%idxbudssm(ip) = 0 + case ('RAINFALL') + this%idxbudrain = ip + this%idxbudssm(ip) = 0 + case ('EVAPORATION') + this%idxbudevap = ip + this%idxbudssm(ip) = 0 + case ('RUNOFF') + this%idxbudroff = ip + this%idxbudssm(ip) = 0 + case ('EXT-INFLOW') + this%idxbudiflw = ip + this%idxbudssm(ip) = 0 + case ('WITHDRAWAL') + this%idxbudwdrl = ip + this%idxbudssm(ip) = 0 + case ('EXT-OUTFLOW') + this%idxbudoutf = ip + this%idxbudssm(ip) = 0 + case ('TO-MVR') + this%idxbudtmvr = ip + this%idxbudssm(ip) = 0 + case ('FROM-MVR') + this%idxbudfmvr = ip + this%idxbudssm(ip) = 0 + case ('AUXILIARY') + this%idxbudaux = ip + this%idxbudssm(ip) = 0 + case default + ! + ! -- Set idxbudssm equal to a column index for where the temperatures + ! are stored in the tempbud(nbudssm, ncv) array + this%idxbudssm(ip) = icount + icount = icount + 1 + end select + write (this%iout, '(a, i0, " = ", a,/, a, i0)') & + ' TERM ', ip, trim(adjustl(this%flowbudptr%budterm(ip)%flowtype)), & + ' MAX NO. OF ENTRIES = ', this%flowbudptr%budterm(ip)%maxlist + end do + write (this%iout, '(a, //)') 'DONE PROCESSING '//ftype//' INFORMATION' + ! + ! -- Return + return + end subroutine find_lke_package + + !> @brief Add matrix terms related to LKE + !! + !! This will be called from TspAptType%apt_fc_expanded() + !! in order to add matrix terms specifically for LKE + !< + subroutine lke_fc_expanded(this, rhs, ia, idxglo, matrix_sln) + ! -- dummy + class(GweLkeType) :: this + real(DP), dimension(:), intent(inout) :: rhs + integer(I4B), dimension(:), intent(in) :: ia + integer(I4B), dimension(:), intent(in) :: idxglo + class(MatrixBaseType), pointer :: matrix_sln + ! -- local + integer(I4B) :: j, n, n1, n2 + integer(I4B) :: iloc + integer(I4B) :: iposd, iposoffd + integer(I4B) :: ipossymd, ipossymoffd + integer(I4B) :: auxpos + real(DP) :: rrate + real(DP) :: rhsval + real(DP) :: hcofval + real(DP) :: ctherm !< thermal conductance + real(DP) :: wa !< wetted area + real(DP) :: ktf !< thermal conductivity of streambed material + real(DP) :: s !< thickness of conductive streambed material + ! + ! -- Add rainfall contribution + if (this%idxbudrain /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudrain)%nlist + call this%lke_rain_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add evaporation contribution + if (this%idxbudevap /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudevap)%nlist + call this%lke_evap_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add runoff contribution + if (this%idxbudroff /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudroff)%nlist + call this%lke_roff_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add inflow contribution + if (this%idxbudiflw /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudiflw)%nlist + call this%lke_iflw_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add withdrawal contribution + if (this%idxbudwdrl /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudwdrl)%nlist + call this%lke_wdrl_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add outflow contribution + if (this%idxbudoutf /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudoutf)%nlist + call this%lke_outf_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add lakebed conduction contribution + do j = 1, this%flowbudptr%budterm(this%idxbudgwf)%nlist + ! + ! -- Set n to feature number and process if active feature + n = this%flowbudptr%budterm(this%idxbudgwf)%id1(j) + if (this%iboundpak(n) /= 0) then + ! + ! -- Set acoef and rhs to negative so they are relative to sfe and not gwe + auxpos = this%flowbudptr%budterm(this%idxbudgwf)%naux + wa = this%flowbudptr%budterm(this%idxbudgwf)%auxvar(auxpos, j) + ktf = this%ktf(n) + s = this%rfeatthk(n) + ctherm = ktf * wa / s + ! + ! -- Add to sfe row + iposd = this%idxdglo(j) + iposoffd = this%idxoffdglo(j) + call matrix_sln%add_value_pos(iposd, -ctherm) ! kluge note: make sure the signs on ctherm are correct here and below + call matrix_sln%add_value_pos(iposoffd, ctherm) + ! + ! -- Add to gwe row for sfe connection + ipossymd = this%idxsymdglo(j) + ipossymoffd = this%idxsymoffdglo(j) + call matrix_sln%add_value_pos(ipossymd, -ctherm) + call matrix_sln%add_value_pos(ipossymoffd, ctherm) + end if + end do + ! + ! -- Return + return + end subroutine lke_fc_expanded + + !> @brief Add terms specific to lakes to the explicit lake solve + !< + subroutine lke_solve(this) + ! -- dummy + class(GweLkeType) :: this + ! -- local + integer(I4B) :: j + integer(I4B) :: n1, n2 + real(DP) :: rrate + ! + ! -- Add rainfall contribution + if (this%idxbudrain /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudrain)%nlist + call this%lke_rain_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add evaporation contribution + if (this%idxbudevap /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudevap)%nlist + call this%lke_evap_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add runoff contribution + if (this%idxbudroff /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudroff)%nlist + call this%lke_roff_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add inflow contribution + if (this%idxbudiflw /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudiflw)%nlist + call this%lke_iflw_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add withdrawal contribution + if (this%idxbudwdrl /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudwdrl)%nlist + call this%lke_wdrl_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add outflow contribution + if (this%idxbudoutf /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudoutf)%nlist + call this%lke_outf_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Return + return + end subroutine lke_solve + + !> @brief Function to return the number of budget terms just for this package. + !! + !! This overrides a function in the parent class. + !< + function lke_get_nbudterms(this) result(nbudterms) + ! -- dummy + class(GweLkeType) :: this + ! -- Return + integer(I4B) :: nbudterms + ! + ! -- Number of budget terms is 7 + ! 1) rainfall + ! 2) evap + ! 3) runoff + ! 4) ext-inflow + ! 5) withdrawl + ! 6) ext-outflow + ! 7) lakebed-cond + ! + nbudterms = 7 + ! + ! -- Return + return + end function lke_get_nbudterms + + !> @brief Set up the budget object that stores all the lake flows + !< + subroutine lke_setup_budobj(this, idx) + ! -- modules + use ConstantsModule, only: LENBUDTXT + ! -- dummy + class(GweLkeType) :: this + integer(I4B), intent(inout) :: idx + ! -- local + integer(I4B) :: n, n1, n2 + integer(I4B) :: maxlist, naux + real(DP) :: q + character(len=LENBUDTXT) :: text + ! + ! -- Addition of heat associated with rainfall directly on the lake surface + text = ' RAINFALL' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudrain)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- Evaporative cooling from lake surface + text = ' EVAPORATION' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudevap)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- Addition of heat associated with runoff that flows to the lake + text = ' RUNOFF' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudroff)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- Addition of heat associated with user-specified inflow to the lake + text = ' EXT-INFLOW' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudiflw)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- Removal of heat associated with user-specified withdrawal from lake + text = ' WITHDRAWAL' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudwdrl)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- Removal of heat associated with outflow from lake that leaves + ! model domain + text = ' EXT-OUTFLOW' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudoutf)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- Conductive exchange of heat through the wetted lakebed + text = ' LAKEBED-COND' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudlbcd)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + call this%budobj%budterm(idx)%reset(maxlist) + q = DZERO + do n = 1, maxlist + n1 = this%flowbudptr%budterm(this%idxbudgwf)%id1(n) + n2 = this%flowbudptr%budterm(this%idxbudgwf)%id2(n) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + end do + ! + ! -- Return + return + end subroutine lke_setup_budobj + + !> @brief Copy flow terms into this%budobj + !< + subroutine lke_fill_budobj(this, idx, x, flowja, ccratin, ccratout) + ! -- dummy + class(GweLkeType) :: this + integer(I4B), intent(inout) :: idx + real(DP), dimension(:), intent(in) :: x + real(DP), dimension(:), contiguous, intent(inout) :: flowja + real(DP), intent(inout) :: ccratin + real(DP), intent(inout) :: ccratout + ! -- local + integer(I4B) :: j, n1, n2 + integer(I4B) :: nlist + integer(I4B) :: igwfnode + integer(I4B) :: idiag + integer(I4B) :: auxpos + real(DP) :: q + real(DP) :: ctherm !< thermal conductance + real(DP) :: wa !< wetted area + real(DP) :: ktf !< thermal conductivity of streambed material + real(DP) :: s !< thickness of conductive streambed materia + ! + ! -- Rain + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudrain)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%lke_rain_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + ! + ! -- Evaporation + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudevap)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%lke_evap_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + ! + ! -- Runoff + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudroff)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%lke_roff_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + ! + ! -- Est-Inflow + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudiflw)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%lke_iflw_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + ! + ! -- Withdrawal + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudwdrl)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%lke_wdrl_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + ! + ! -- Ext-Outflow + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudoutf)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%lke_outf_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + ! + ! -- Lakebed-Cond + idx = idx + 1 + call this%budobj%budterm(idx)%reset(this%maxbound) + do j = 1, this%flowbudptr%budterm(this%idxbudlbcd)%nlist + q = DZERO + n1 = this%flowbudptr%budterm(this%idxbudlbcd)%id1(j) + if (this%iboundpak(n1) /= 0) then + igwfnode = this%flowbudptr%budterm(this%idxbudlbcd)%id2(j) + auxpos = this%flowbudptr%budterm(this%idxbudgwf)%naux ! for now there is only 1 aux variable under 'GWF' + wa = this%flowbudptr%budterm(this%idxbudgwf)%auxvar(auxpos, j) + ktf = this%ktf(n1) + s = this%rfeatthk(n1) + ctherm = ktf * wa / s + q = ctherm * (x(igwfnode) - this%xnewpak(n1)) + end if + call this%budobj%budterm(idx)%update_term(n1, igwfnode, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + if (this%iboundpak(n1) /= 0) then + ! -- Contribution to gwe cell budget + this%simvals(n1) = this%simvals(n1) - q + idiag = this%dis%con%ia(igwfnode) + flowja(idiag) = flowja(idiag) - q + end if + end do + ! + ! -- Return + return + end subroutine lke_fill_budobj + + !> @brief Allocate scalars specific to the lake energy transport (LKE) + !! package. + !< + subroutine allocate_scalars(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweLkeType) :: this + ! + ! -- Allocate scalars in TspAptType + call this%TspAptType%allocate_scalars() + ! + ! -- Allocate + call mem_allocate(this%idxbudrain, 'IDXBUDRAIN', this%memoryPath) + call mem_allocate(this%idxbudevap, 'IDXBUDEVAP', this%memoryPath) + call mem_allocate(this%idxbudroff, 'IDXBUDROFF', this%memoryPath) + call mem_allocate(this%idxbudiflw, 'IDXBUDIFLW', this%memoryPath) + call mem_allocate(this%idxbudwdrl, 'IDXBUDWDRL', this%memoryPath) + call mem_allocate(this%idxbudoutf, 'IDXBUDOUTF', this%memoryPath) + call mem_allocate(this%idxbudlbcd, 'IDXBUDLBCD', this%memoryPath) + ! + ! -- Initialize + this%idxbudrain = 0 + this%idxbudevap = 0 + this%idxbudroff = 0 + this%idxbudiflw = 0 + this%idxbudwdrl = 0 + this%idxbudoutf = 0 + this%idxbudlbcd = 0 + ! + ! -- Return + return + end subroutine allocate_scalars + + !> @brief Allocate arrays specific to the lake energy transport (LKE) + !! package. + !< + subroutine lke_allocate_arrays(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweLkeType), intent(inout) :: this + ! -- local + integer(I4B) :: n + ! + ! -- Time series + call mem_allocate(this%temprain, this%ncv, 'TEMPRAIN', this%memoryPath) + call mem_allocate(this%tempevap, this%ncv, 'TEMPEVAP', this%memoryPath) + call mem_allocate(this%temproff, this%ncv, 'TEMPROFF', this%memoryPath) + call mem_allocate(this%tempiflw, this%ncv, 'TEMPIFLW', this%memoryPath) + ! + ! -- Call standard TspAptType allocate arrays + call this%TspAptType%apt_allocate_arrays() + ! + ! -- Initialize + do n = 1, this%ncv + this%temprain(n) = DZERO + this%tempevap(n) = DZERO + this%temproff(n) = DZERO + this%tempiflw(n) = DZERO + end do + ! + ! + ! -- Return + return + end subroutine lke_allocate_arrays + + !> @brief Deallocate memory + !< + subroutine lke_da(this) + ! -- modules + use MemoryManagerModule, only: mem_deallocate + ! -- dummy + class(GweLkeType) :: this + ! + ! -- Deallocate scalars + call mem_deallocate(this%idxbudrain) + call mem_deallocate(this%idxbudevap) + call mem_deallocate(this%idxbudroff) + call mem_deallocate(this%idxbudiflw) + call mem_deallocate(this%idxbudwdrl) + call mem_deallocate(this%idxbudoutf) + call mem_deallocate(this%idxbudlbcd) + ! + ! -- Deallocate time series + call mem_deallocate(this%temprain) + call mem_deallocate(this%tempevap) + call mem_deallocate(this%temproff) + call mem_deallocate(this%tempiflw) + ! + ! -- Deallocate scalars in TspAptType + call this%TspAptType%bnd_da() + ! + ! -- Return + return + end subroutine lke_da + + !> @brief Rain term + !< + subroutine lke_rain_term(this, ientry, n1, n2, rrate, & + rhsval, hcofval) + ! -- dummy + class(GweLkeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudrain)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudrain)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudrain)%flow(ientry) + ctmp = this%temprain(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac + if (present(rhsval)) rhsval = -rrate + if (present(hcofval)) hcofval = DZERO + ! + ! -- Return + return + end subroutine lke_rain_term + + !> @brief Evaporative term + !< + subroutine lke_evap_term(this, ientry, n1, n2, rrate, & + rhsval, hcofval) + ! -- dummy + class(GweLkeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: heatlat + ! + n1 = this%flowbudptr%budterm(this%idxbudevap)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudevap)%id2(ientry) + ! -- Note that qbnd is negative for evap + qbnd = this%flowbudptr%budterm(this%idxbudevap)%flow(ientry) + heatlat = this%gwecommon%gwerhow * this%gwecommon%gwelatheatvap + if (present(rrate)) rrate = qbnd * heatlat + if (present(rhsval)) rhsval = -rrate + if (present(hcofval)) hcofval = DZERO + ! + ! -- Return + return + end subroutine lke_evap_term + + !> @brief Runoff term + !< + subroutine lke_roff_term(this, ientry, n1, n2, rrate, & + rhsval, hcofval) + ! -- dummy + class(GweLkeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudroff)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudroff)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudroff)%flow(ientry) + ctmp = this%temproff(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac + if (present(rhsval)) rhsval = -rrate + if (present(hcofval)) hcofval = DZERO + ! + ! -- Return + return + end subroutine lke_roff_term + + !> @brief Inflow Term + !! + !! Accounts for energy flowing into a lake from a connected stream, for + !! example. + !< + subroutine lke_iflw_term(this, ientry, n1, n2, rrate, & + rhsval, hcofval) + ! -- dummy + class(GweLkeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudiflw)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudiflw)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudiflw)%flow(ientry) + ctmp = this%tempiflw(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac + if (present(rhsval)) rhsval = -rrate + if (present(hcofval)) hcofval = DZERO + ! + ! -- Return + return + end subroutine lke_iflw_term + + !> @brief Specified withdrawal term + !! + !! Accounts for energy associated with a withdrawal of water from a lake + !! or group of lakes. + !< + subroutine lke_wdrl_term(this, ientry, n1, n2, rrate, & + rhsval, hcofval) + ! -- dummy + class(GweLkeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudwdrl)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudwdrl)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudwdrl)%flow(ientry) + ctmp = this%xnewpak(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac + if (present(rhsval)) rhsval = DZERO + if (present(hcofval)) hcofval = qbnd * this%eqnsclfac + ! + ! -- Return + return + end subroutine lke_wdrl_term + + !> @brief Outflow term + !! + !! Accounts for the energy leaving a lake, for example, energy exiting a + !! lake via a flow into a draining stream channel. + !< + subroutine lke_outf_term(this, ientry, n1, n2, rrate, & + rhsval, hcofval) + ! -- dummy + class(GweLkeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudoutf)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudoutf)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudoutf)%flow(ientry) + ctmp = this%xnewpak(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac + if (present(rhsval)) rhsval = DZERO + if (present(hcofval)) hcofval = qbnd * this%eqnsclfac + ! + ! -- Return + return + end subroutine lke_outf_term + + !> @brief Defined observation types + !! + !! Store the observation type supported by the APT package and overide + !! BndType%bnd_df_obs + !< + subroutine lke_df_obs(this) + ! -- dummy + class(GweLkeType) :: this + ! -- local + integer(I4B) :: indx + ! + ! -- Store obs type and assign procedure pointer + ! for temperature observation type. + call this%obs%StoreObsType('temperature', .false., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for flow between features, such as lake to lake. + call this%obs%StoreObsType('flow-ja-face', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID12 + ! + ! -- Store obs type and assign procedure pointer + ! for from-mvr observation type. + call this%obs%StoreObsType('from-mvr', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for to-mvr observation type. + call this%obs%StoreObsType('to-mvr', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for storage observation type. + call this%obs%StoreObsType('storage', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for constant observation type. + call this%obs%StoreObsType('constant', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for observation type: lke + call this%obs%StoreObsType('lke', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for rainfall observation type. + call this%obs%StoreObsType('rainfall', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for evaporation observation type. + call this%obs%StoreObsType('evaporation', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for runoff observation type. + call this%obs%StoreObsType('runoff', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for inflow observation type. + call this%obs%StoreObsType('ext-inflow', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for withdrawal observation type. + call this%obs%StoreObsType('withdrawal', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for ext-outflow observation type. + call this%obs%StoreObsType('ext-outflow', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Return + return + end subroutine lke_df_obs + + !> @brief Process package specific obs + !! + !! Method to process specific observations for this package. + !< + subroutine lke_rp_obs(this, obsrv, found) + ! -- dummy + class(GweLkeType), intent(inout) :: this !< package class + type(ObserveType), intent(inout) :: obsrv !< observation object + logical, intent(inout) :: found !< indicate whether observation was found + ! + found = .true. + select case (obsrv%ObsTypeId) + case ('RAINFALL') + call this%rp_obs_byfeature(obsrv) + case ('EVAPORATION') + call this%rp_obs_byfeature(obsrv) + case ('RUNOFF') + call this%rp_obs_byfeature(obsrv) + case ('EXT-INFLOW') + call this%rp_obs_byfeature(obsrv) + case ('WITHDRAWAL') + call this%rp_obs_byfeature(obsrv) + case ('EXT-OUTFLOW') + call this%rp_obs_byfeature(obsrv) + case ('TO-MVR') + call this%rp_obs_budterm(obsrv, & + this%flowbudptr%budterm(this%idxbudtmvr)) + case default + found = .false. + end select + ! + ! -- Return + return + end subroutine lke_rp_obs + + !> @brief Calculate observation value and pass it back to APT + !< + subroutine lke_bd_obs(this, obstypeid, jj, v, found) + ! -- dummy + class(GweLkeType), intent(inout) :: this + character(len=*), intent(in) :: obstypeid + real(DP), intent(inout) :: v + integer(I4B), intent(in) :: jj + logical, intent(inout) :: found + ! -- local + integer(I4B) :: n1, n2 + ! + found = .true. + select case (obstypeid) + case ('RAINFALL') + if (this%iboundpak(jj) /= 0) then + call this%lke_rain_term(jj, n1, n2, v) + end if + case ('EVAPORATION') + if (this%iboundpak(jj) /= 0) then + call this%lke_evap_term(jj, n1, n2, v) + end if + case ('RUNOFF') + if (this%iboundpak(jj) /= 0) then + call this%lke_roff_term(jj, n1, n2, v) + end if + case ('EXT-INFLOW') + if (this%iboundpak(jj) /= 0) then + call this%lke_iflw_term(jj, n1, n2, v) + end if + case ('WITHDRAWAL') + if (this%iboundpak(jj) /= 0) then + call this%lke_wdrl_term(jj, n1, n2, v) + end if + case ('EXT-OUTFLOW') + if (this%iboundpak(jj) /= 0) then + call this%lke_outf_term(jj, n1, n2, v) + end if + case default + found = .false. + end select + ! + ! -- Return + return + end subroutine lke_bd_obs + + !> @brief Sets the stress period attributes for keyword use. + !< + subroutine lke_set_stressperiod(this, itemno, keyword, found) + ! -- modules + use TimeSeriesManagerModule, only: read_value_or_time_series_adv + ! -- dummy + class(GweLkeType), intent(inout) :: this + integer(I4B), intent(in) :: itemno + character(len=*), intent(in) :: keyword + logical, intent(inout) :: found + ! -- local + character(len=LINELENGTH) :: text + integer(I4B) :: ierr + integer(I4B) :: jj + real(DP), pointer :: bndElem => null() + ! + ! RAINFALL + ! EVAPORATION + ! RUNOFF + ! EXT-INFLOW + ! WITHDRAWAL + ! + found = .true. + select case (keyword) + case ('RAINFALL') + ierr = this%apt_check_valid(itemno) + if (ierr /= 0) then + goto 999 + end if + call this%parser%GetString(text) + jj = 1 + bndElem => this%temprain(itemno) + call read_value_or_time_series_adv(text, itemno, jj, bndElem, & + this%packName, 'BND', this%tsManager, & + this%iprpak, 'RAINFALL') + case ('EVAPORATION') + ierr = this%apt_check_valid(itemno) + if (ierr /= 0) then + goto 999 + end if + call this%parser%GetString(text) + jj = 1 + bndElem => this%tempevap(itemno) + call read_value_or_time_series_adv(text, itemno, jj, bndElem, & + this%packName, 'BND', this%tsManager, & + this%iprpak, 'EVAPORATION') + case ('RUNOFF') + ierr = this%apt_check_valid(itemno) + if (ierr /= 0) then + goto 999 + end if + call this%parser%GetString(text) + jj = 1 + bndElem => this%temproff(itemno) + call read_value_or_time_series_adv(text, itemno, jj, bndElem, & + this%packName, 'BND', this%tsManager, & + this%iprpak, 'RUNOFF') + case ('EXT-INFLOW') + ierr = this%apt_check_valid(itemno) + if (ierr /= 0) then + goto 999 + end if + call this%parser%GetString(text) + jj = 1 + bndElem => this%tempiflw(itemno) + call read_value_or_time_series_adv(text, itemno, jj, bndElem, & + this%packName, 'BND', this%tsManager, & + this%iprpak, 'EXT-INFLOW') + case default + ! + ! -- Keyword not recognized so return to caller with found = .false. + found = .false. + end select + ! +999 continue + ! + ! -- Return + return + end subroutine lke_set_stressperiod + +end module GweLkeModule diff --git a/src/Model/TransportModel/tsp1apt1.f90 b/src/Model/TransportModel/tsp1apt1.f90 index c37b82b693a..facc861b3bb 100644 --- a/src/Model/TransportModel/tsp1apt1.f90 +++ b/src/Model/TransportModel/tsp1apt1.f90 @@ -2813,7 +2813,7 @@ subroutine apt_rp_obs(this) ' must be assigned to a feature with a unique boundname.' call store_error(errmsg) end if - case ('LKT', 'SFT', 'MWT', 'UZT') + case ('LKT', 'SFT', 'MWT', 'UZT', 'LKE', 'SFE') call this%rp_obs_budterm(obsrv, & this%flowbudptr%budterm(this%idxbudgwf)) case ('FLOW-JA-FACE') @@ -2898,7 +2898,7 @@ subroutine apt_bd_obs(this) if (this%iboundpak(jj) /= 0) then v = this%xnewpak(jj) end if - case ('LKT', 'SFT', 'MWT', 'UZT') + case ('LKT', 'SFT', 'MWT', 'UZT', 'LKE', 'SFE') n = this%flowbudptr%budterm(this%idxbudgwf)%id1(jj) if (this%iboundpak(n) /= 0) then igwfnode = this%flowbudptr%budterm(this%idxbudgwf)%id2(jj) From f2b33102b80576df7c9f76c76fd07bc0fce2f26f Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Thu, 8 Feb 2024 08:34:04 -0800 Subject: [PATCH 40/46] forgot meson update --- src/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/src/meson.build b/src/meson.build index be95234745d..28d973721a6 100644 --- a/src/meson.build +++ b/src/meson.build @@ -70,6 +70,7 @@ modflow_sources = files( 'Model' / 'GroundWaterEnergy' / 'gwe1est1.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1ic1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1idm.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1lke1.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1sfe1.f90', 'Model' / 'GroundWaterFlow' / 'gwf3.f90', 'Model' / 'GroundWaterFlow' / 'gwf3api8.f90', From 9eebdf56a2235f7c7a7482085c70eb339c10f91e Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Thu, 8 Feb 2024 11:49:51 -0800 Subject: [PATCH 41/46] Adding multi-aquifer well energy transport (MWE) package. Includes new autotest --- autotest/test_gwe_mwe_conduction.py | 570 +++++++++ doc/Common/gwe-mweobs.tex | 16 +- doc/mf6io/gwe/gwe.tex | 4 + doc/mf6io/gwe/mwe.tex | 55 + doc/mf6io/gwe/namefile.tex | 1 + doc/mf6io/mf6ivar/dfn/gwe-mwe.dfn | 447 ++++++++ .../mf6ivar/examples/gwe-mwe-example-obs.dat | 43 + .../mf6ivar/examples/gwe-mwe-example.dat | 24 + doc/mf6io/mf6ivar/md/mf6ivar.md | 35 + doc/mf6io/mf6ivar/mf6ivar.py | 1 + doc/mf6io/mf6ivar/tex/appendixA.tex | 4 + doc/mf6io/mf6ivar/tex/gwe-mwe-desc.tex | 92 ++ doc/mf6io/mf6ivar/tex/gwe-mwe-options.dat | 15 + doc/mf6io/mf6ivar/tex/gwe-mwe-packagedata.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-mwe-period.dat | 5 + doc/mf6io/mf6ivar/tex/gwf-rcha-desc.tex | 2 +- make/makefile | 1 + msvs/mf6core.vfproj | 1 + src/Model/GroundWaterEnergy/gwe1.f90 | 10 +- src/Model/GroundWaterEnergy/gwe1mwe1.f90 | 1018 +++++++++++++++++ src/Model/TransportModel/tsp1apt1.f90 | 4 +- src/meson.build | 1 + 22 files changed, 2338 insertions(+), 16 deletions(-) create mode 100644 autotest/test_gwe_mwe_conduction.py create mode 100644 doc/mf6io/gwe/mwe.tex create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-mwe.dfn create mode 100644 doc/mf6io/mf6ivar/examples/gwe-mwe-example-obs.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-mwe-example.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-mwe-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-mwe-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-mwe-packagedata.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-mwe-period.dat create mode 100644 src/Model/GroundWaterEnergy/gwe1mwe1.f90 diff --git a/autotest/test_gwe_mwe_conduction.py b/autotest/test_gwe_mwe_conduction.py new file mode 100644 index 00000000000..b5570a0527f --- /dev/null +++ b/autotest/test_gwe_mwe_conduction.py @@ -0,0 +1,570 @@ +# Test mwe package. Looks at wetted area of well for calculating +# heat conduction exchange. This test is related to test_gwf_maw06.py but +# with some further customization for testing GWE capabilities. +# - Test has 0 flow conductance with gw cells in layers 1-3 +# - Test uses MAW to inject water into layer 4 (bottom layer) +# - Test includes conductive exchng only between MWE feature and +# layers 1 to 3 +# - Water extracted by normal WEL features in bottom corners of model +# - Water table saturates only ~1/2 of top layer; therefore +# conductive exchange + +import os + +import flopy +import numpy as np +import pytest +from framework import TestFramework + + +def process_line(line): + m_arr = line.strip().split() + if any("=" in itm and len(itm) > 1 for itm in m_arr): + m_arr = [ + float(itm.split("=")[-1]) if len(itm.split("=")) > 1 else itm + for itm in m_arr + ] + nm = m_arr[-2] + else: + nm = m_arr[-3] + val = m_arr[-1] + return {nm: float(val)} + + +def get_bud(fname, srchStr): + in_bud_lst = {} + out_bud_lst = {} + with open(fname, "r") as f: + for line in f: + if srchStr in line: + # Read the package budget + line = next(f) + while not "TOTAL IN =" in line: + if "=" in line: + in_bud_lst.update(process_line(line)) + + line = next(f) + + # Get "total in" + dct = process_line(line) + T_in = dct["IN"] + + line = next(f) + while not "TOTAL OUT =" in line: + if "=" in line: + out_bud_lst.update(process_line(line)) + + line = next(f) + + # Get "total out" + dct = process_line(line) + T_out = dct["OUT"] + + break + + return T_in, T_out, in_bud_lst, out_bud_lst + + +def get_welbore_heat_flow(fname, srchStr): + ener_Q = [] + with open(fname, "r") as f: + for line in f: + if srchStr in line: + # Read an established format + for i in np.arange(3): # read & discard 3 lines + line = next(f) + for i in np.arange( + 4 + ): # read & digest 4 lines of needed output + line = next(f) + m_arr = line.strip().split() + ener_Q.append([int(m_arr[0]), float(m_arr[2])]) + break + + return np.array(ener_Q) + + +def trenddetector(list_of_index, array_of_data, order=1): + result = np.polyfit(list_of_index, list(array_of_data), order) + slope = result[-2] + return float(slope) + + +cases = ["mwe_01"] +mawstrt = 3.5 + +# Flow related parameters +lx = 70.0 +ly = 70.0 +nlay = 4 +nrow = 7 +ncol = 7 +nper = 1 +delc = ly / nrow +delr = lx / ncol +top = 4.0 +botm = [3.0, 2.0, 1.0, 0.0] +strt = 3.5 +transient = {0: True} + +perlen = [10.0] +nstp = [10] +tsmult = [1.0] + +Kh = [1.0, 1.0, 1e-6, 100] +Kv = [1.0, 1.0, 1e-6, 100] + +Sy = 0.3 +Ss = 0.0 + +# Transport related parameters +mixelm = 0 # Upstream vs TVD (Upstream selected) +strttemp = 1.0 # Initial temperature ($^{\circ}C$) +porosity = Sy # porosity (unitless) +ktw = 0.5918 # Thermal Conductivity of Water ($W/m/^{\circ}C$) +kts = 0.2700 # Thermal Conductivity of Aquifer Solids ($W/m/^{\circ}C$) +rhow = 1000 # Density of water ($kg/m^3$) +rhos = 2650 # Density of the aquifer material ($kg/m^3$) +Cpw = 4180 # Heat Capacity of water ($J/kg/C$) +Cps = 880 # Heat capacity of the solids ($J/kg/C$) +lhv = 2454000.0 # Latent heat of vaporization ($J/kg$) +K_therm_maw = 1.5 # Thermal conductivity of the lakebed material ($W/m/C$) +wthkcnd = 0.01 +mawradius = 0.1 +mawbottom = 0.0 + +# Solver settings +nouter, ninner = 700, 10 +hclose, rclose, relax = 1e-8, 1e-6, 0.97 + + +def build_models(idx, test): + + tdis_rc = [] + for i in range(nper): + tdis_rc.append((perlen[i], nstp[i], tsmult[i])) + + name = cases[idx] + + # Instantiate MODFLOW 6 simulation + ws = test.workspace + sim = flopy.mf6.MFSimulation( + sim_name=name, version="mf6", exe_name="mf6", sim_ws=ws + ) + + # Instantiate Time Discretization package + flopy.mf6.ModflowTdis( + sim, time_units="DAYS", nper=nper, perioddata=tdis_rc + ) + + # Instantiate Groundwater Flow model + gwfname = "gwf-" + name + gwename = "gwe-" + name + newtonoptions = "NEWTON UNDER_RELAXATION" + gwf = flopy.mf6.ModflowGwf( + sim, modelname=gwfname, newtonoptions=newtonoptions + ) + + ims = flopy.mf6.ModflowIms( + sim, + print_option="ALL", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="SIMPLE", + under_relaxation_gamma=0.1, + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename=f"{gwfname}.ims", + ) + sim.register_ims_package(ims, [gwfname]) + + # Instantiate Discretization package + flopy.mf6.ModflowGwfdis( + gwf, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + length_units="METERS", + pname="DIS", + filename=f"{gwfname}.dis", + ) + + # Instantiate Initial Conditions package + flopy.mf6.ModflowGwfic( + gwf, + strt=strt, + pname="IC", + filename=f"{gwfname}.ic", + ) + + # Instantiate Node Property Flow package + flopy.mf6.ModflowGwfnpf( + gwf, + xt3doptions=False, + save_flows=True, + save_specific_discharge=True, + icelltype=1, + k=Kh, + k33=Kv, + pname="NPF", + filename=f"{gwfname}.npf", + ) + + # Instantiate Storage package + flopy.mf6.ModflowGwfsto( + gwf, + sy=Sy, + ss=Ss, + iconvert=1, + transient=transient, + pname="STO", + filename=f"{gwfname}.sto", + ) + + # Instantiate Well package (for extracting MAW-injected water) + wellist = [] + for i in [0, nrow - 1]: + for j in [0, ncol - 1]: + wellist.append([(nlay - 1, i, j), -7.0, 0.01]) + + flopy.mf6.ModflowGwfwel( + gwf, + stress_period_data=wellist, + print_input=True, + print_flows=True, + save_flows=False, + pname="WEL", + auxiliary="TEMPERATURE", + filename=f"{gwfname}.wel", + ) + + # Instantiate Multi-Aquifer Well package (injects water) + mstrt = mawstrt + mawcondeqn = "SPECIFIED" + mawngwfnodes = nlay + # + mawpackagedata = [ + [0, mawradius, mawbottom, mstrt, mawcondeqn, mawngwfnodes] + ] + # + conncond = [0.0, 0.0, 0.0, 1000.0] + mawconnectiondata = [ + [0, icon, (icon, 3, 3), top, mawbottom, conncond[icon], -999.0] + for icon in range(nlay) + ] + # + mawperioddata = [[0, "STATUS", "ACTIVE"], [0, "RATE", 28.0]] + maw = flopy.mf6.ModflowGwfmaw( + gwf, + print_input=True, + print_head=True, + print_flows=True, + save_flows=True, + head_filerecord=f"{gwfname}.maw.bin", + budget_filerecord=f"{gwfname}.maw.cbc", + packagedata=mawpackagedata, + connectiondata=mawconnectiondata, + perioddata=mawperioddata, + pname="MAW-1", + ) + opth = f"{gwfname}.maw.obs" + obsdata = { + f"{gwfname}.maw.obs.csv": [ + ("whead", "head", (0,)), + ] + } + maw.obs.initialize( + filename=opth, digits=20, print_input=True, continuous=obsdata + ) + + # Instantiate Output Control package + flopy.mf6.ModflowGwfoc( + gwf, + budget_filerecord=f"{gwfname}.cbc", + head_filerecord=f"{gwfname}.hds", + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[ + ( + "HEAD", + "ALL", + ), + ( + "BUDGET", + "ALL", + ), + ], + printrecord=[ + ( + "HEAD", + "ALL", + ), + ( + "BUDGET", + "ALL", + ), + ], + ) + + # Create GWE model + # ---------------- + gwe = flopy.mf6.ModflowGwe( + sim, modelname=gwename, model_nam_file="{}.nam".format(gwename) + ) + gwe.name_file.save_flows = True + + imsgwe = flopy.mf6.ModflowIms( + sim, + print_option="ALL", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename=f"{gwename}.ims", + ) + sim.register_ims_package(imsgwe, [gwename]) + + # Instantiating MODFLOW 6 enregy transport discretization package + flopy.mf6.ModflowGwedis( + gwe, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + pname="DIS", + filename="{}.dis".format(gwename), + ) + + # Instantiating MODFLOW 6 energy transport initial temperatures + flopy.mf6.ModflowGweic( + gwe, strt=strttemp, filename="{}.ic".format(gwename) + ) + + # Instantiate mobile storage and transfer package + flopy.mf6.ModflowGweest( + gwe, + porosity=porosity, + cps=Cps, + rhos=rhos, + packagedata=[Cpw, rhow, lhv], + pname="MST-1", + filename=f"{gwename}.mst", + ) + + # Instantiating MODFLOW 6 energy transport advection package + if mixelm == 0: + scheme = "UPSTREAM" + elif mixelm == -1: + scheme = "TVD" + else: + raise Exception() + + # Instantiate advection package + flopy.mf6.ModflowGweadv( + gwe, scheme=scheme, pname="ADV", filename="{}.adv".format(gwename) + ) + + # Instantiate dispersion package + flopy.mf6.ModflowGwecnd( + gwe, + xt3d_off=True, + ktw=0.5918, + kts=0.2700, + filename="{}.dsp".format(gwename), + ) + + # Instantiate source/sink mixing package + sourcerecarray = [ + ("WEL", "AUX", "TEMPERATURE"), + ] + flopy.mf6.ModflowGwessm( + gwe, sources=sourcerecarray, filename=f"{gwename}.ssm" + ) + + # Instantiating MODFLOW 6 transport output control package + flopy.mf6.ModflowGweoc( + gwe, + budget_filerecord="{}.cbc".format(gwename), + temperature_filerecord="{}.ucn".format(gwename), + temperatureprintrecord=[ + ("COLUMNS", 17, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + printrecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + filename="{}.oc".format(gwename), + ) + + # Instantiating MODFLOW 6 multi-well energy transport (mwe) package + # ,, , , + mwepackagedata = [(0, 1.0, K_therm_maw, wthkcnd, "well1")] + + mweperioddata = {0: [(0, "RATE", 40.0)]} + + # note: for specifying lake number, use fortran indexing! + mwe_obs = { + "{}.mweobs".format(gwename): [ + ("MweTemp", "temperature", 1), + ] + } + + flopy.mf6.ModflowGwemwe( + gwe, + flow_package_name="MAW-1", + budget_filerecord=gwename + ".mwe.bud", + boundnames=True, + save_flows=True, + print_input=True, + print_flows=True, + print_temperature=True, + packagedata=mwepackagedata, + mweperioddata=mweperioddata, + observations=mwe_obs, + pname="MWE-1", + filename="{}.mwe".format(gwename), + ) + + # Instantiate GWF-GWE exchange + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename, + filename=f"{name}.gwfgwe", + ) + + return sim, None + + +def check_output(idx, test): + print("evaluating results...") + + top_local = [4.0, 3.0, 2.0, 1.0] + botm_local = [3.0, 2.0, 1.0, 0.0] + + # calculate volume of water and make sure it is conserved + name = cases[idx] + gwfname = "gwf-" + name + fname = gwfname + ".maw.bin" + fname = os.path.join(test.workspace, fname) + assert os.path.isfile(fname) + bobj = flopy.utils.HeadFile(fname, text="HEAD") + stage = bobj.get_alldata().flatten() + + name = cases[idx] + gwfname = "gwf-" + name + fname = gwfname + ".maw.cbc" + fname = os.path.join(test.workspace, fname) + assert os.path.isfile(fname) + bobj = flopy.utils.CellBudgetFile(fname, precision="double") + gwfarea = bobj.get_data(text="GWF") + + # Retrieve simulated temperature for the multi-aquifer well + gwename = "gwe-" + name + fname = gwename + ".mweobs" + mwtemp_file = os.path.join(test.workspace, fname) + assert os.path.isfile(mwtemp_file) + mwtemp = np.genfromtxt(mwtemp_file, names=True, delimiter=",") + mwtemp = mwtemp["MWETEMP"].astype(float).reshape((mwtemp.size, 1)) + + # Retrieve gw temperatures + fname = gwename + ".ucn" + fname = os.path.join(test.workspace, fname) + assert os.path.isfile(fname) + gwtempobj = flopy.utils.HeadFile( + fname, precision="double", text="TEMPERATURE" + ) + gwe_temps = gwtempobj.get_alldata() + + # Calculate conductive exchange external to MF6 and compare to MF6 values + # Evaluates first time step only + wellbore_cnd_time1 = [] + for i in np.arange(nlay): + if stage[0] > top_local[i]: + thk = top_local[i] - botm_local[i] + elif stage[0] > botm_local[i]: + thk = stage[0] - botm_local[i] + else: + thk = 0 + + # Check that MF6 (GWF) wellbore wetted area matches explicitly calc + + wa = 2 * mawradius * np.pi * thk + welborecnd = K_therm_maw * wa / wthkcnd + gw_temp = gwe_temps[0, i, 3, 3] + deltaT = mwtemp[0][0] - gw_temp + + wellbore_cnd_time1.append(welborecnd * deltaT) + + # Retrieve budget + fname = os.path.join(test.workspace, gwename + ".lst") + srchStr = ( + "MWE-1 BUDGET FOR ENTIRE MODEL AT END OF TIME STEP 1, " + "STRESS PERIOD 1" + ) + T_in, T_out, in_bud_lst, out_bud_lst = get_bud(fname, srchStr) + assert np.isclose( + T_in, T_out, atol=0.1 + ), "There is a heat budget discrepancy where there shouldn't be" + + msg1 = ( + "Conductive heat exchanges calculated explicitly and by MF6 " + "do not match" + ) + msg2 = ( + "Individually summing well bore 'heat flows' is not matching " + "the global budget heat flow into the aquifer" + ) + msg3 = "Groundwater should be warming, but isn't" + + # Get MF6 saved wellbore heat "flows" + srchStr = "MWE PACKAGE (MWE-1) FLOW RATES PERIOD 1 STEP 1" + wbcnd_mf6 = get_welbore_heat_flow(fname, srchStr) + + # Check top 3 layers (4th layer handled different) + for i in np.arange(nlay - 1): + assert np.isclose( + wbcnd_mf6[i, 1], round(wellbore_cnd_time1[i], 4) + ), msg1 + + # Layer 4 "heat flow" includes convection and conduction, compare + # "heat flow" from all layers to global budget line item 'IN: GWF' + glob_bud_gw_in = out_bud_lst["GWF"] + out_bud_lst["WELLBORE-COND"] + mwe_out = wbcnd_mf6.sum(axis=0)[1] + assert np.isclose(mwe_out, glob_bud_gw_in, rtol=1e-9), msg2 + + # Ensure that temperatures near the injection point are rising + slp = trenddetector(np.arange(gwe_temps.shape[0]), gwe_temps[:, 3, 3, 3]) + assert slp > 0.0, msg3 + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(cases)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t), + ) + test.run() diff --git a/doc/Common/gwe-mweobs.tex b/doc/Common/gwe-mweobs.tex index 3594db046cf..a2c51bf6a3b 100644 --- a/doc/Common/gwe-mweobs.tex +++ b/doc/Common/gwe-mweobs.tex @@ -1,13 +1,13 @@ % general APT observations -MWE & temperature & ifno or boundname & -- & Well temperature. If boundname is specified, boundname must be unique for each well. \\ +MWE & temperature & mawno or boundname & -- & Well temperature. If boundname is specified, boundname must be unique for each well. \\ %flowjaface not included -MWE & storage & ifno or boundname & -- & Simulated energy storage flow rate for a well or group of wells. \\ -MWE & constant & ifno or boundname & -- & Simulated energy constant-flow rate for a well or group of wells. \\ -MWE & from-mvr & ifno or boundname & -- & Simulated energy inflow into a well or group of wells from the MVE package. Energy inflow is calculated as the product of provider temperature and the mover flow rate. \\ -MWE & mwt & ifno or boundname & \texttt{iconn} or -- & Energy flow rate for a well or group of wells and its aquifer connection(s). If boundname is not specified for ID, then the simulated well-aquifer flow rate at a specific well connection is observed. In this case, ID2 must be specified and is the connection number \texttt{iconn} for well \texttt{ifno}. \\ +MWE & storage & mawno or boundname & -- & Simulated energy storage flow rate for a well or group of wells. \\ +MWE & constant & mawno or boundname & -- & Simulated energy constant-flow rate for a well or group of wells. \\ +MWE & from-mvr & mawno or boundname & -- & Simulated energy inflow into a well or group of wells from the MVE package. Energy inflow is calculated as the product of provider temperature and the mover flow rate. \\ +MWE & mwe & mawno or boundname & \texttt{iconn} or -- & Energy flow rate for a well or group of wells and its aquifer connection(s). If boundname is not specified for ID, then the simulated well-aquifer flow rate at a specific well connection is observed. In this case, ID2 must be specified and is the connection number \texttt{iconn} for well \texttt{mawno}. \\ -% observations specific to the mwt package -MWE & rate & ifno or boundname & -- & Simulated energy flow rate for a well or group of wells. \\ -MWE & fw-rate & ifno or boundname & -- & Simulated energy flow rate for a flowing well or group of flowing wells. \\ +% observations specific to the mwe package +MWE & rate & mawno or boundname & -- & Simulated energy flow rate for a well or group of wells. \\ +MWE & fw-rate & mawno or boundname & -- & Simulated energy flow rate for a flowing well or group of flowing wells. \\ MWE & rate-to-mvr & well or boundname & -- & Simulated energy flow rate that is sent to the MVE Package for a well or group of wells.\\ MWE & fw-rate-to-mvr & well or boundname & -- & Simulated energy flow rate that is sent to the MVE Package from a flowing well or group of flowing wells. \\ diff --git a/doc/mf6io/gwe/gwe.tex b/doc/mf6io/gwe/gwe.tex index 6840cf3baa1..0e7e30211bc 100644 --- a/doc/mf6io/gwe/gwe.tex +++ b/doc/mf6io/gwe/gwe.tex @@ -133,6 +133,10 @@ \subsection{Streamflow Energy Transport (SFE) Package} \subsection{Lake Energy Transport (LKE) Package} \input{gwe/lke} +\newpage +\subsection{Multi-Aquifer Well Energy Transport (MWE) Package} +\input{gwe/mwe} + \newpage \subsection{Flow Model Interface (FMI) Package} \input{gwe/fmi} diff --git a/doc/mf6io/gwe/mwe.tex b/doc/mf6io/gwe/mwe.tex new file mode 100644 index 00000000000..70fc673987d --- /dev/null +++ b/doc/mf6io/gwe/mwe.tex @@ -0,0 +1,55 @@ +Multi-Aquifer Well Energy Transport (MWE) Package information is read from the file that is specified by ``MWE6'' as the file type. There can be as many MWE Packages as necessary for a GWE model. Each MWE Package is designed to work with flows from a corresponding GWF MAW Package. By default \mf uses the MWE package name to determine which MAW Package corresponds to the MWE Package. Therefore, the package name of the MWE Package (as specified in the GWE name file) must match with the name of the corresponding MAW Package (as specified in the GWF name file). Alternatively, the name of the flow package can be specified using the FLOW\_PACKAGE\_NAME keyword in the options block. The GWE MWE Package cannot be used without a corresponding GWF MAW Package. + +The MWE Package does not have a dimensions block; instead, dimensions for the MWE Package are set using the dimensions from the corresponding MAW Package. For example, the MAW Package requires specification of the number of wells (NMAWWELLS). MWE sets the number of wells equal to NMAWWELLS. Therefore, the PACKAGEDATA block below must have NMAWWELLS entries in it. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-mwe-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-mwe-packagedata.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-mwe-period.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-mwe-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-mwe-example.dat} + +\vspace{5mm} +\subsubsection{Available observation types} +Multi-Aquifer Well Energy Transport Package observations include well temperature and all of the terms that contribute to the continuity equation for each well. Additional MWE Package observations include energy flow rates for individual wells, or groups of wells; the well volume (\texttt{volume}); and the conductance for a well-aquifer connection conductance (\texttt{conductance}). The data required for each MWE Package observation type is defined in table~\ref{table:gwe-mweobstype}. Negative and positive values for \texttt{mwe} observations represent a loss from and gain to the GWE model, respectively. For all other flow terms, negative and positive values represent a loss from and gain from the MWE package, respectively. + +\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}} +\caption{Available MWE Package observation types} \tabularnewline + +\hline +\hline +\textbf{Stress Package} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endfirsthead + +\captionsetup{textformat=simple} +\caption*{\textbf{Table \arabic{table}.}{\quad}Available MWE Package observation types.---Continued} \tabularnewline + +\hline +\hline +\textbf{Stress Package} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endhead + + +\hline +\endfoot + +\input{../Common/gwe-mweobs.tex} +\label{table:gwe-mweobstype} +\end{longtable} + +\vspace{5mm} +\subsubsection{Example Observation Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-mwe-example-obs.dat} + + diff --git a/doc/mf6io/gwe/namefile.tex b/doc/mf6io/gwe/namefile.tex index 12afbd6b30e..4419af99530 100644 --- a/doc/mf6io/gwe/namefile.tex +++ b/doc/mf6io/gwe/namefile.tex @@ -36,6 +36,7 @@ \subsubsection{Explanation of Variables} ESL6 & Energy Source Loading Package & * \\ SFE6 & Streamflow Energy Transport Package & * \\ LKE6 & Lake Energy Transport Package & * \\ +MWE6 & Multi-Aquifer Well Energy Transport Package & * \\ OBS6 & Observations Option \\ \hline \end{tabular*} diff --git a/doc/mf6io/mf6ivar/dfn/gwe-mwe.dfn b/doc/mf6io/mf6ivar/dfn/gwe-mwe.dfn new file mode 100644 index 00000000000..c805b6533fe --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-mwe.dfn @@ -0,0 +1,447 @@ +# --------------------- gwe mwe options --------------------- +# flopy multi-package + +block options +name flow_package_name +type string +shape +reader urword +optional true +longname keyword to specify name of corresponding flow package +description keyword to specify the name of the corresponding flow package. If not specified, then the corresponding flow package must have the same name as this advanced transport package (the name associated with this package in the GWE name file). + +block options +name auxiliary +type string +shape (naux) +reader urword +optional true +longname keyword to specify aux variables +description REPLACE auxnames {'{#1}': 'Groundwater Energy Transport'} + +block options +name flow_package_auxiliary_name +type string +shape +reader urword +optional true +longname keyword to specify name of temperature auxiliary variable in flow package +description keyword to specify the name of an auxiliary variable in the corresponding flow package. If specified, then the simulated temperatures from this advanced transport package will be copied into the auxiliary variable specified with this name. Note that the flow package must have an auxiliary variable with this name or the program will terminate with an error. If the flows for this advanced transport package are read from a file, then this option will have no effect. + +block options +name boundnames +type keyword +shape +reader urword +optional true +longname +description REPLACE boundnames {'{#1}': 'well'} + +block options +name print_input +type keyword +reader urword +optional true +longname print input to listing file +description REPLACE print_input {'{#1}': 'well'} + +block options +name print_temperature +type keyword +reader urword +optional true +longname print calculated temperatures to listing file +description REPLACE print_temperature {'{#1}': 'well', '{#2}': 'temperature', '{#3}': 'TEMPERATURE'} + +block options +name print_flows +type keyword +reader urword +optional true +longname print calculated flows to listing file +description REPLACE print_flows {'{#1}': 'well'} + +block options +name save_flows +type keyword +reader urword +optional true +longname save well flows to budget file +description REPLACE save_flows {'{#1}': 'well'} + +block options +name temperature_filerecord +type record temperature fileout tempfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name temperature +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname stage keyword +description keyword to specify that record corresponds to temperature. + +block options +name tempfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the binary output file to write temperature information. + +block options +name budget_filerecord +type record budget fileout budgetfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name budget +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname budget keyword +description keyword to specify that record corresponds to the budget. + +block options +name fileout +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname file keyword +description keyword to specify that an output filename is expected next. + +block options +name budgetfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the binary output file to write budget information. + +block options +name budgetcsv_filerecord +type record budgetcsv fileout budgetcsvfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name budgetcsv +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname budget keyword +description keyword to specify that record corresponds to the budget CSV. + +block options +name budgetcsvfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. + +block options +name ts_filerecord +type record ts6 filein ts6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name ts6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname head keyword +description keyword to specify that record corresponds to a time-series file. + +block options +name filein +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname file keyword +description keyword to specify that an input filename is expected next. + +block options +name ts6_filename +type string +preserve_case true +in_record true +reader urword +optional false +tagged false +longname file name of time series information +description REPLACE timeseriesfile {} + +block options +name obs_filerecord +type record obs6 filein obs6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name obs6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname obs keyword +description keyword to specify that record corresponds to an observations file. + +block options +name obs6_filename +type string +preserve_case true +in_record true +tagged false +reader urword +optional false +longname obs6 input filename +description REPLACE obs6_filename {'{#1}': 'MWE'} + + +# --------------------- gwe mwe packagedata --------------------- + +block packagedata +name packagedata +type recarray mawno strt ktf fthk aux boundname +shape (maxbound) +reader urword +longname +description + +block packagedata +name mawno +type integer +shape +tagged false +in_record true +reader urword +longname well number for this entry +description integer value that defines the well number associated with the specified PACKAGEDATA data on the line. MAWNO must be greater than zero and less than or equal to NMAWWELLS. Well information must be specified for every well or the program will terminate with an error. The program will also terminate with an error if information for a well is specified more than once. +numeric_index true + +block packagedata +name strt +type double precision +shape +tagged false +in_record true +reader urword +longname starting well temperature +description real value that defines the starting temperature for the well. + +block packagedata +name ktf +type double precision +shape +tagged false +in_record true +reader urword +longname thermal conductivity of the feature +description is the thermal conductivity of the of the interface between the aquifer cell and the feature. + +block packagedata +name fthk +type double precision +shape +tagged false +in_record true +reader urword +longname thickness of the well feature +description real value that defines the thickness of the material through which conduction occurs. Must be greater than 0. + +block packagedata +name aux +type double precision +in_record true +tagged false +shape (naux) +reader urword +time_series true +optional true +longname auxiliary variables +description REPLACE aux {'{#1}': 'well'} + +block packagedata +name boundname +type string +shape +tagged false +in_record true +reader urword +optional true +longname well name +description REPLACE boundname {'{#1}': 'well'} + + +# --------------------- gwe mwe period --------------------- + +block period +name iper +type integer +block_variable True +in_record true +tagged false +shape +valid +reader urword +optional false +longname stress period number +description REPLACE iper {} + +block period +name mweperioddata +type recarray mawno mwesetting +shape +reader urword +longname +description + +block period +name mawno +type integer +shape +tagged false +in_record true +reader urword +longname well number for this entry +description integer value that defines the well number associated with the specified PERIOD data on the line. MAWNO must be greater than zero and less than or equal to NMAWWELLS. +numeric_index true + +block period +name mwesetting +type keystring status temperature rate auxiliaryrecord +shape +tagged false +in_record true +reader urword +longname +description line of information that is parsed into a keyword and values. Keyword values that can be used to start the MWESETTING string include: STATUS, TEMPERATURE, RAINFALL, EVAPORATION, RUNOFF, and AUXILIARY. These settings are used to assign the temperature of associated with the corresponding flow terms. Temperatures cannot be specified for all flow terms. For example, the Multi-Aquifer Well Package supports a ``WITHDRAWAL'' flow term. If this withdrawal term is active, then water will be withdrawn from the well at the calculated temperature of the well. + +block period +name status +type string +shape +tagged true +in_record true +reader urword +longname well temperature status +description keyword option to define well status. STATUS can be ACTIVE, INACTIVE, or CONSTANT. By default, STATUS is ACTIVE, which means that temperature will be calculated for the well. If a well is inactive, then there will be no solute mass fluxes into or out of the well and the inactive value will be written for the well temperature. If a well is constant, then the temperature for the well will be fixed at the user specified value. + +block period +name temperature +type string +shape +tagged true +in_record true +time_series true +reader urword +longname well temperature +description real or character value that defines the temperature for the well. The specified TEMPERATURE is only applied if the well is a constant temperature well. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name rate +type string +shape +tagged true +in_record true +reader urword +time_series true +longname well injection temperature +description real or character value that defines the injection solute temperature $^{\circ}C$ for the well. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name auxiliaryrecord +type record auxiliary auxname auxval +shape +tagged +in_record true +reader urword +longname +description + +block period +name auxiliary +type keyword +shape +in_record true +reader urword +longname +description keyword for specifying auxiliary variable. + +block period +name auxname +type string +shape +tagged false +in_record true +reader urword +longname +description name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. + +block period +name auxval +type double precision +shape +tagged false +in_record true +reader urword +time_series true +longname auxiliary variable value +description value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. diff --git a/doc/mf6io/mf6ivar/examples/gwe-mwe-example-obs.dat b/doc/mf6io/mf6ivar/examples/gwe-mwe-example-obs.dat new file mode 100644 index 00000000000..a3a8ced3ad9 --- /dev/null +++ b/doc/mf6io/mf6ivar/examples/gwe-mwe-example-obs.dat @@ -0,0 +1,43 @@ +BEGIN options + DIGITS 12 + PRINT_INPUT +END options + +BEGIN continuous FILEOUT gwe_mwe_02.mwe.obs.csv + mwe1mwe MWE 1 1 + mwe2mwe MWE 2 1 + mwe3mwe MWE 3 1 + mwe4mwe MWE 4 1 + mwe1temp TEMPERATURE 1 + mwe2temp TEMPERATURE 2 + mwe3temp TEMPERATURE 3 + mwe4temp TEMPERATURE 4 + mwe1stor STORAGE 1 + mwe2stor STORAGE 2 + mwe3stor STORAGE 3 + mwe4stor STORAGE 4 + mwe1cnst CONSTANT 1 + mwe2cnst CONSTANT 2 + mwe3cnst CONSTANT 3 + mwe4cnst CONSTANT 4 + mwe1fmvr FROM-MVR 1 + mwe2fmvr FROM-MVR 2 + mwe3fmvr FROM-MVR 3 + mwe4fmvr FROM-MVR 4 + mwe1rate RATE 1 + mwe2rate RATE 2 + mwe3rate RATE 3 + mwe4rate RATE 4 + mwe1rtmv RATE-TO-MVR 1 + mwe2rtmv RATE-TO-MVR 2 + mwe3rtmv RATE-TO-MVR 3 + mwe4rtmv RATE-TO-MVR 4 + mwe1fwrt FW-RATE 1 + mwe2fwrt FW-RATE 2 + mwe3fwrt FW-RATE 3 + mwe4fwrt FW-RATE 4 + mwe1frtm FW-RATE-TO-MVR 1 + mwe2frtm FW-RATE-TO-MVR 2 + mwe3frtm FW-RATE-TO-MVR 3 + mwe4frtm FW-RATE-TO-MVR 4 +END continuous FILEOUT gwe_mwe_02.mwe.obs.csv \ No newline at end of file diff --git a/doc/mf6io/mf6ivar/examples/gwe-mwe-example.dat b/doc/mf6io/mf6ivar/examples/gwe-mwe-example.dat new file mode 100644 index 00000000000..4616f3fa7bc --- /dev/null +++ b/doc/mf6io/mf6ivar/examples/gwe-mwe-example.dat @@ -0,0 +1,24 @@ +BEGIN OPTIONS + AUXILIARY aux1 aux2 + BOUNDNAMES + PRINT_INPUT + PRINT_TEMPERATURE + PRINT_FLOWS + SAVE_FLOWS + TEMPERATURE FILEOUT gwe_mwe_02.mwe.bin + BUDGET FILEOUT gwe_mwe_02.mwe.bud + OBS6 FILEIN gwe_mwe_02.mwe.obs +END OPTIONS + +BEGIN PACKAGEDATA +# L STRT aux1 aux2 bname + 1 10.00 99.00 999.00 MYWELL1 + 2 10.00 99.00 999.00 MYWELL2 + 3 10.00 99.00 999.00 MYWELL3 +END PACKAGEDATA + +BEGIN PERIOD 1 + 1 STATUS ACTIVE + 2 STATUS ACTIVE + 3 STATUS ACTIVE +END PERIOD 1 diff --git a/doc/mf6io/mf6ivar/md/mf6ivar.md b/doc/mf6io/mf6ivar/md/mf6ivar.md index 84a5897a9dd..aeb29f13a33 100644 --- a/doc/mf6io/mf6ivar/md/mf6ivar.md +++ b/doc/mf6io/mf6ivar/md/mf6ivar.md @@ -1336,6 +1336,41 @@ | GWE | LKE | PERIOD | AUXILIARY | KEYWORD | keyword for specifying auxiliary variable. | | GWE | LKE | PERIOD | AUXNAME | STRING | name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. | | GWE | LKE | PERIOD | AUXVAL | DOUBLE PRECISION | value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | MWE | OPTIONS | FLOW_PACKAGE_NAME | STRING | keyword to specify the name of the corresponding flow package. If not specified, then the corresponding flow package must have the same name as this advanced transport package (the name associated with this package in the GWE name file). | +| GWE | MWE | OPTIONS | AUXILIARY | STRING (NAUX) | defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. | +| GWE | MWE | OPTIONS | FLOW_PACKAGE_AUXILIARY_NAME | STRING | keyword to specify the name of an auxiliary variable in the corresponding flow package. If specified, then the simulated temperatures from this advanced transport package will be copied into the auxiliary variable specified with this name. Note that the flow package must have an auxiliary variable with this name or the program will terminate with an error. If the flows for this advanced transport package are read from a file, then this option will have no effect. | +| GWE | MWE | OPTIONS | BOUNDNAMES | KEYWORD | keyword to indicate that boundary names may be provided with the list of well cells. | +| GWE | MWE | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of well information will be written to the listing file immediately after it is read. | +| GWE | MWE | OPTIONS | PRINT_TEMPERATURE | KEYWORD | keyword to indicate that the list of well temperature will be printed to the listing file for every stress period in which ``TEMPERATURE PRINT'' is specified in Output Control. If there is no Output Control option and PRINT\_TEMPERATURE is specified, then temperature are printed for the last time step of each stress period. | +| GWE | MWE | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of well flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | +| GWE | MWE | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that well flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | +| GWE | MWE | OPTIONS | TEMPERATURE | KEYWORD | keyword to specify that record corresponds to temperature. | +| GWE | MWE | OPTIONS | TEMPFILE | STRING | name of the binary output file to write temperature information. | +| GWE | MWE | OPTIONS | BUDGET | KEYWORD | keyword to specify that record corresponds to the budget. | +| GWE | MWE | OPTIONS | FILEOUT | KEYWORD | keyword to specify that an output filename is expected next. | +| GWE | MWE | OPTIONS | BUDGETFILE | STRING | name of the binary output file to write budget information. | +| GWE | MWE | OPTIONS | BUDGETCSV | KEYWORD | keyword to specify that record corresponds to the budget CSV. | +| GWE | MWE | OPTIONS | BUDGETCSVFILE | STRING | name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. | +| GWE | MWE | OPTIONS | TS6 | KEYWORD | keyword to specify that record corresponds to a time-series file. | +| GWE | MWE | OPTIONS | FILEIN | KEYWORD | keyword to specify that an input filename is expected next. | +| GWE | MWE | OPTIONS | TS6_FILENAME | STRING | defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. | +| GWE | MWE | OPTIONS | OBS6 | KEYWORD | keyword to specify that record corresponds to an observations file. | +| GWE | MWE | OPTIONS | OBS6_FILENAME | STRING | name of input file to define observations for the MWE package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the MWE package. | +| GWE | MWE | PACKAGEDATA | MAWNO | INTEGER | integer value that defines the well number associated with the specified PACKAGEDATA data on the line. MAWNO must be greater than zero and less than or equal to NMAWWELLS. Well information must be specified for every well or the program will terminate with an error. The program will also terminate with an error if information for a well is specified more than once. | +| GWE | MWE | PACKAGEDATA | STRT | DOUBLE PRECISION | real value that defines the starting temperature for the well. | +| GWE | MWE | PACKAGEDATA | KTF | DOUBLE PRECISION | is the thermal conductivity of the of the interface between the aquifer cell and the feature. | +| GWE | MWE | PACKAGEDATA | FTHK | DOUBLE PRECISION | real value that defines the thickness of the material through which conduction occurs. Must be greater than 0. | +| GWE | MWE | PACKAGEDATA | AUX | DOUBLE PRECISION (NAUX) | represents the values of the auxiliary variables for each well. The values of auxiliary variables must be present for each well. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | MWE | PACKAGEDATA | BOUNDNAME | STRING | name of the well cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. | +| GWE | MWE | PERIOD | IPER | INTEGER | integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. | +| GWE | MWE | PERIOD | MAWNO | INTEGER | integer value that defines the well number associated with the specified PERIOD data on the line. MAWNO must be greater than zero and less than or equal to NMAWWELLS. | +| GWE | MWE | PERIOD | MWESETTING | KEYSTRING | line of information that is parsed into a keyword and values. Keyword values that can be used to start the MWESETTING string include: STATUS, TEMPERATURE, RAINFALL, EVAPORATION, RUNOFF, and AUXILIARY. These settings are used to assign the temperature of associated with the corresponding flow terms. Temperatures cannot be specified for all flow terms. For example, the Multi-Aquifer Well Package supports a ``WITHDRAWAL'' flow term. If this withdrawal term is active, then water will be withdrawn from the well at the calculated temperature of the well. | +| GWE | MWE | PERIOD | STATUS | STRING | keyword option to define well status. STATUS can be ACTIVE, INACTIVE, or CONSTANT. By default, STATUS is ACTIVE, which means that temperature will be calculated for the well. If a well is inactive, then there will be no solute mass fluxes into or out of the well and the inactive value will be written for the well temperature. If a well is constant, then the temperature for the well will be fixed at the user specified value. | +| GWE | MWE | PERIOD | TEMPERATURE | STRING | real or character value that defines the temperature for the well. The specified TEMPERATURE is only applied if the well is a constant temperature well. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | MWE | PERIOD | RATE | STRING | real or character value that defines the injection solute temperature $^{\circ}C$ for the well. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | MWE | PERIOD | AUXILIARY | KEYWORD | keyword for specifying auxiliary variable. | +| GWE | MWE | PERIOD | AUXNAME | STRING | name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. | +| GWE | MWE | PERIOD | AUXVAL | DOUBLE PRECISION | value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | | GWE | NAM | OPTIONS | LIST | STRING | is name of the listing file to create for this GWE model. If not specified, then the name of the list file will be the basename of the GWE model name file and the ``.lst'' extension. For example, if the GWE name file is called ``my.model.nam'' then the list file will be called ``my.model.lst''. | | GWE | NAM | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of all model stress package information will be written to the listing file immediately after it is read. | | GWE | NAM | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of all model package flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | diff --git a/doc/mf6io/mf6ivar/mf6ivar.py b/doc/mf6io/mf6ivar/mf6ivar.py index 25d59480ac5..1170f4a7428 100644 --- a/doc/mf6io/mf6ivar/mf6ivar.py +++ b/doc/mf6io/mf6ivar/mf6ivar.py @@ -749,6 +749,7 @@ def write_appendix(texdir, allblocks): "gwe-est", "gwe-ic", "gwe-lke", + "gwe-mwe", "gwe-nam", "gwe-oc", "gwe-ssm", diff --git a/doc/mf6io/mf6ivar/tex/appendixA.tex b/doc/mf6io/mf6ivar/tex/appendixA.tex index ccdf2aab7a3..cf214f3156f 100644 --- a/doc/mf6io/mf6ivar/tex/appendixA.tex +++ b/doc/mf6io/mf6ivar/tex/appendixA.tex @@ -284,6 +284,10 @@ GWE & LKE & PACKAGEDATA & yes \\ GWE & LKE & PERIOD & yes \\ \hline +GWE & MWE & OPTIONS & yes \\ +GWE & MWE & PACKAGEDATA & yes \\ +GWE & MWE & PERIOD & yes \\ +\hline GWE & NAM & OPTIONS & yes \\ GWE & NAM & PACKAGES & yes \\ \hline diff --git a/doc/mf6io/mf6ivar/tex/gwe-mwe-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-mwe-desc.tex new file mode 100644 index 00000000000..04ee7036eb2 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-mwe-desc.tex @@ -0,0 +1,92 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{flow\_package\_name}---keyword to specify the name of the corresponding flow package. If not specified, then the corresponding flow package must have the same name as this advanced transport package (the name associated with this package in the GWE name file). + +\item \texttt{auxiliary}---defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. + +\item \texttt{flow\_package\_auxiliary\_name}---keyword to specify the name of an auxiliary variable in the corresponding flow package. If specified, then the simulated temperatures from this advanced transport package will be copied into the auxiliary variable specified with this name. Note that the flow package must have an auxiliary variable with this name or the program will terminate with an error. If the flows for this advanced transport package are read from a file, then this option will have no effect. + +\item \texttt{BOUNDNAMES}---keyword to indicate that boundary names may be provided with the list of well cells. + +\item \texttt{PRINT\_INPUT}---keyword to indicate that the list of well information will be written to the listing file immediately after it is read. + +\item \texttt{PRINT\_TEMPERATURE}---keyword to indicate that the list of well temperature will be printed to the listing file for every stress period in which ``TEMPERATURE PRINT'' is specified in Output Control. If there is no Output Control option and PRINT\_TEMPERATURE is specified, then temperature are printed for the last time step of each stress period. + +\item \texttt{PRINT\_FLOWS}---keyword to indicate that the list of well flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. + +\item \texttt{SAVE\_FLOWS}---keyword to indicate that well flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. + +\item \texttt{TEMPERATURE}---keyword to specify that record corresponds to temperature. + +\item \texttt{tempfile}---name of the binary output file to write temperature information. + +\item \texttt{BUDGET}---keyword to specify that record corresponds to the budget. + +\item \texttt{FILEOUT}---keyword to specify that an output filename is expected next. + +\item \texttt{budgetfile}---name of the binary output file to write budget information. + +\item \texttt{BUDGETCSV}---keyword to specify that record corresponds to the budget CSV. + +\item \texttt{budgetcsvfile}---name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. + +\item \texttt{TS6}---keyword to specify that record corresponds to a time-series file. + +\item \texttt{FILEIN}---keyword to specify that an input filename is expected next. + +\item \texttt{ts6\_filename}---defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. + +\item \texttt{OBS6}---keyword to specify that record corresponds to an observations file. + +\item \texttt{obs6\_filename}---name of input file to define observations for the MWE package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the MWE package. + +\end{description} +\item \textbf{Block: PACKAGEDATA} + +\begin{description} +\item \texttt{mawno}---integer value that defines the well number associated with the specified PACKAGEDATA data on the line. MAWNO must be greater than zero and less than or equal to NMAWWELLS. Well information must be specified for every well or the program will terminate with an error. The program will also terminate with an error if information for a well is specified more than once. + +\item \texttt{strt}---real value that defines the starting temperature for the well. + +\item \texttt{ktf}---is the thermal conductivity of the of the interface between the aquifer cell and the feature. + +\item \texttt{fthk}---real value that defines the thickness of the material through which conduction occurs. Must be greater than 0. + +\item \textcolor{blue}{\texttt{aux}---represents the values of the auxiliary variables for each well. The values of auxiliary variables must be present for each well. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \texttt{boundname}---name of the well cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. + +\end{description} +\item \textbf{Block: PERIOD} + +\begin{description} +\item \texttt{iper}---integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. + +\item \texttt{mawno}---integer value that defines the well number associated with the specified PERIOD data on the line. MAWNO must be greater than zero and less than or equal to NMAWWELLS. + +\item \texttt{mwesetting}---line of information that is parsed into a keyword and values. Keyword values that can be used to start the MWESETTING string include: STATUS, TEMPERATURE, RAINFALL, EVAPORATION, RUNOFF, and AUXILIARY. These settings are used to assign the temperature of associated with the corresponding flow terms. Temperatures cannot be specified for all flow terms. For example, the Multi-Aquifer Well Package supports a ``WITHDRAWAL'' flow term. If this withdrawal term is active, then water will be withdrawn from the well at the calculated temperature of the well. + +\begin{lstlisting}[style=blockdefinition] +STATUS +TEMPERATURE <@temperature@> +RATE <@rate@> +AUXILIARY <@auxval@> +\end{lstlisting} + +\item \texttt{status}---keyword option to define well status. STATUS can be ACTIVE, INACTIVE, or CONSTANT. By default, STATUS is ACTIVE, which means that temperature will be calculated for the well. If a well is inactive, then there will be no solute mass fluxes into or out of the well and the inactive value will be written for the well temperature. If a well is constant, then the temperature for the well will be fixed at the user specified value. + +\item \textcolor{blue}{\texttt{temperature}---real or character value that defines the temperature for the well. The specified TEMPERATURE is only applied if the well is a constant temperature well. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{rate}---real or character value that defines the injection solute temperature $^{\circ}C$ for the well. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \texttt{AUXILIARY}---keyword for specifying auxiliary variable. + +\item \texttt{auxname}---name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. + +\item \textcolor{blue}{\texttt{auxval}---value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-mwe-options.dat b/doc/mf6io/mf6ivar/tex/gwe-mwe-options.dat new file mode 100644 index 00000000000..ef83c7fa718 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-mwe-options.dat @@ -0,0 +1,15 @@ +BEGIN OPTIONS + [FLOW_PACKAGE_NAME ] + [AUXILIARY ] + [FLOW_PACKAGE_AUXILIARY_NAME ] + [BOUNDNAMES] + [PRINT_INPUT] + [PRINT_TEMPERATURE] + [PRINT_FLOWS] + [SAVE_FLOWS] + [TEMPERATURE FILEOUT ] + [BUDGET FILEOUT ] + [BUDGETCSV FILEOUT ] + [TS6 FILEIN ] + [OBS6 FILEIN ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-mwe-packagedata.dat b/doc/mf6io/mf6ivar/tex/gwe-mwe-packagedata.dat new file mode 100644 index 00000000000..0d46cfac181 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-mwe-packagedata.dat @@ -0,0 +1,5 @@ +BEGIN PACKAGEDATA + [<@aux(naux)@>] [] + [<@aux(naux)@>] [] + ... +END PACKAGEDATA diff --git a/doc/mf6io/mf6ivar/tex/gwe-mwe-period.dat b/doc/mf6io/mf6ivar/tex/gwe-mwe-period.dat new file mode 100644 index 00000000000..4c9a183703a --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-mwe-period.dat @@ -0,0 +1,5 @@ +BEGIN PERIOD + + + ... +END PERIOD diff --git a/doc/mf6io/mf6ivar/tex/gwf-rcha-desc.tex b/doc/mf6io/mf6ivar/tex/gwf-rcha-desc.tex index a3230eee906..1f558f3244e 100644 --- a/doc/mf6io/mf6ivar/tex/gwf-rcha-desc.tex +++ b/doc/mf6io/mf6ivar/tex/gwf-rcha-desc.tex @@ -35,7 +35,7 @@ \item \texttt{irch}---IRCH is the layer number that defines the layer in each vertical column where recharge is applied. If IRCH is omitted, recharge by default is applied to cells in layer 1. IRCH can only be used if READASARRAYS is specified in the OPTIONS block. If IRCH is specified, it must be specified as the first variable in the PERIOD block or MODFLOW will terminate with an error. -\item \textcolor{blue}{\texttt{recharge}---is the recharge flux rate ($LT^{-1}$). This rate is multiplied inside the program by the surface area of the cell to calculate the volumetric recharge rate. The recharge array may be defined by a time-array series (see the "Using Time-Array Series in a Package" section).} +\item \textcolor{blue}{\texttt{recharge}---is the recharge flux rate ($LT^{-1}$). This rate is multiplied inside the program by the surface area of the cell to calculate the volumetric recharge rate. The recharge array may be defined by a time-array series (see the ``Using Time-Array Series in a Package'' section).} \item \textcolor{blue}{\texttt{aux}---is an array of values for auxiliary variable aux(iaux), where iaux is a value from 1 to naux, and aux(iaux) must be listed as part of the auxiliary variables. A separate array can be specified for each auxiliary variable. If an array is not specified for an auxiliary variable, then a value of zero is assigned. If the value specified here for the auxiliary variable is the same as auxmultname, then the recharge array will be multiplied by this array.} diff --git a/make/makefile b/make/makefile index 234a6587e3e..99010bb3e1a 100644 --- a/make/makefile +++ b/make/makefile @@ -281,6 +281,7 @@ $(OBJDIR)/GhostNode.o \ $(OBJDIR)/gwf3evt8.o \ $(OBJDIR)/gwf3chd8.o \ $(OBJDIR)/gwe1sfe1.o \ +$(OBJDIR)/gwe1mwe1.o \ $(OBJDIR)/gwe1lke1.o \ $(OBJDIR)/gwe1est1.o \ $(OBJDIR)/gwe1esl1.o \ diff --git a/msvs/mf6core.vfproj b/msvs/mf6core.vfproj index 33f4b78abb0..afc7f577759 100644 --- a/msvs/mf6core.vfproj +++ b/msvs/mf6core.vfproj @@ -153,6 +153,7 @@ + diff --git a/src/Model/GroundWaterEnergy/gwe1.f90 b/src/Model/GroundWaterEnergy/gwe1.f90 index e2c86d2c738..dd5536dba78 100644 --- a/src/Model/GroundWaterEnergy/gwe1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1.f90 @@ -764,7 +764,7 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & use GweEslModule, only: esl_create use GweLkeModule, only: lke_create use GweSfeModule, only: sfe_create - !use GweMweModule, only: mwe_create + use GweMweModule, only: mwe_create !use GweUzeModule, only: uze_create use ApiModule, only: api_create ! -- dummy @@ -798,10 +798,10 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & call sfe_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & pakname, this%fmi, this%eqnsclfac, this%gwecommon, & this%depvartype, this%depvarunit, this%depvarunitabbrev) - !case ('MWE6') - ! call mwe_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & - ! pakname, this%fmi, this%tsplab, this%eqnsclfac, & - ! this%gwecommon) + case ('MWE6') + call mwe_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + pakname, this%fmi, this%eqnsclfac, this%gwecommon, & + this%depvartype, this%depvarunit, this%depvarunitabbrev) !case ('UZE6') ! call uze_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & ! pakname, this%fmi, this%tsplab, this%eqnsclfac, & diff --git a/src/Model/GroundWaterEnergy/gwe1mwe1.f90 b/src/Model/GroundWaterEnergy/gwe1mwe1.f90 new file mode 100644 index 00000000000..4b6bb76a38d --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1mwe1.f90 @@ -0,0 +1,1018 @@ +! -- Multi-Aquifer Well Energy Transport Module +! -- todo: save the mwe temperature into the mwe aux variable? +! -- todo: calculate the maw DENSE aux variable using temperature? +! +! MAW flows (flowbudptr) index var MWE term Transport Type +!--------------------------------------------------------------------------------- + +! -- terms from MAW that will be handled by parent APT Package +! FLOW-JA-FACE idxbudfjf FLOW-JA-FACE cv2cv (note that this doesn't exist for MAW) +! GWF (aux FLOW-AREA) idxbudgwf GWF cv2gwf +! STORAGE (aux VOLUME) idxbudsto none used for cv volumes +! FROM-MVR idxbudfmvr FROM-MVR q * text = this%qfrommvr(:) +! TO-MVR idxbudtmvr TO-MVR q * tfeat + +! -- MAW terms +! RATE idxbudrate RATE q < 0: q * twell, else q * tuser +! FW-RATE idxbudfwrt FW-RATE q * twell +! RATE-TO-MVR idxbudrtmv RATE-TO-MVR q * twell +! FW-RATE-TO-MVR idxbudfrtm FW-RATE-TO-MVR q * twell +! WELL-AQUIFER CONDUCTION idxbudmwcd MW-CONDUCTION K_t_f * WetArea / thickness + +! -- terms from MAW that should be skipped +! CONSTANT-TO-MVR ? CONSTANT-TO-MVR q * twell + +! -- terms from a flow file that should be skipped +! CONSTANT none none none +! AUXILIARY none none none + +! -- terms that are written to the energy transport budget file +! none none STORAGE (aux ENER) dE/dt +! none none AUXILIARY none +! none none CONSTANT accumulate +! +! +module GweMweModule + + use KindModule, only: DP, I4B + use ConstantsModule, only: DZERO, LINELENGTH + use SimModule, only: store_error + use BndModule, only: BndType, GetBndFromList + use TspFmiModule, only: TspFmiType + use MawModule, only: MawType + use ObserveModule, only: ObserveType + use TspAptModule, only: TspAptType, apt_process_obsID, & + apt_process_obsID12 + use GweInputDataModule, only: GweInputDataType + use MatrixBaseModule + + implicit none + + public mwe_create + + character(len=*), parameter :: ftype = 'MWE' + character(len=*), parameter :: flowtype = 'MAW' + character(len=16) :: text = ' MWE' + + type, extends(TspAptType) :: GweMweType + + type(GweInputDataType), pointer :: gwecommon => null() !< pointer to shared gwe data used by multiple packages but set in mst + + integer(I4B), pointer :: idxbudrate => null() ! index of well rate terms in flowbudptr + integer(I4B), pointer :: idxbudfwrt => null() ! index of flowing well rate terms in flowbudptr + integer(I4B), pointer :: idxbudrtmv => null() ! index of rate to mover terms in flowbudptr + integer(I4B), pointer :: idxbudfrtm => null() ! index of flowing well rate to mover terms in flowbudptr + integer(I4B), pointer :: idxbudmwcd => null() ! index of well bore conduction terms in flowbudptr + real(DP), dimension(:), pointer, contiguous :: temprate => null() ! well rate temperature + + contains + + procedure :: bnd_da => mwe_da + procedure :: allocate_scalars + procedure :: apt_allocate_arrays => mwe_allocate_arrays + procedure :: find_apt_package => find_mwe_package + procedure :: pak_fc_expanded => mwe_fc_expanded + procedure :: pak_solve => mwe_solve + procedure :: pak_get_nbudterms => mwe_get_nbudterms + procedure :: pak_setup_budobj => mwe_setup_budobj + procedure :: pak_fill_budobj => mwe_fill_budobj + procedure :: mwe_rate_term + procedure :: mwe_fwrt_term + procedure :: mwe_rtmv_term + procedure :: mwe_frtm_term + procedure :: pak_df_obs => mwe_df_obs + procedure :: pak_rp_obs => mwe_rp_obs + procedure :: pak_bd_obs => mwe_bd_obs + procedure :: pak_set_stressperiod => mwe_set_stressperiod + + end type GweMweType + +contains + + !> Create new MWE package + !< + subroutine mwe_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, & + fmi, eqnsclfac, gwecommon, dvt, dvu, dvua) + ! -- dummy + class(BndType), pointer :: packobj + integer(I4B), intent(in) :: id + integer(I4B), intent(in) :: ibcnum + integer(I4B), intent(in) :: inunit + integer(I4B), intent(in) :: iout + character(len=*), intent(in) :: namemodel + character(len=*), intent(in) :: pakname + type(TspFmiType), pointer :: fmi + real(DP), intent(in), pointer :: eqnsclfac !< governing equation scale factor + type(GweInputDataType), intent(in), target :: gwecommon !< shared data container for use by multiple GWE packages + character(len=*), intent(in) :: dvt !< For GWE, set to "TEMPERATURE" in TspAptType + character(len=*), intent(in) :: dvu !< For GWE, set to "energy" in TspAptType + character(len=*), intent(in) :: dvua !< For GWE, set to "E" in TspAptType + ! -- local + type(GweMweType), pointer :: mweobj + ! + ! -- Allocate the object and assign values to object variables + allocate (mweobj) + packobj => mweobj + ! + ! -- Create name and memory path + call packobj%set_names(ibcnum, namemodel, pakname, ftype) + packobj%text = text + ! + ! -- Allocate scalars + call mweobj%allocate_scalars() + ! + ! -- Initialize package + call packobj%pack_initialize() + ! + packobj%inunit = inunit + packobj%iout = iout + packobj%id = id + packobj%ibcnum = ibcnum + packobj%ncolbnd = 1 + packobj%iscloc = 1 + ! + ! -- Store pointer to flow model interface. When the GwfGwe exchange is + ! created, it sets fmi%bndlist so that the GWE model has access to all + ! the flow packages + mweobj%fmi => fmi + ! + ! -- Store pointer to governing equation scale factor + mweobj%eqnsclfac => eqnsclfac + ! + ! -- Store pointer to shared data module for accessing cpw, rhow + ! for the budget calculations, and for accessing the latent heat of + ! vaporization for evaporative cooling. + mweobj%gwecommon => gwecommon + ! + ! -- Set labels that will be used in generalized APT class + mweobj%depvartype = dvt + mweobj%depvarunit = dvu + mweobj%depvarunitabbrev = dvua + ! + ! -- Return + return + end subroutine mwe_create + + !> @brief Find corresponding mwe package + !< + subroutine find_mwe_package(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweMweType) :: this + ! -- local + character(len=LINELENGTH) :: errmsg + class(BndType), pointer :: packobj + integer(I4B) :: ip, icount + integer(I4B) :: nbudterm + logical :: found + ! + ! -- Initialize found to false, and error later if flow package cannot + ! be found + found = .false. + ! + ! -- If user is specifying flows in a binary budget file, then set up + ! the budget file reader, otherwise set a pointer to the flow package + ! budobj + if (this%fmi%flows_from_file) then + call this%fmi%set_aptbudobj_pointer(this%flowpackagename, this%flowbudptr) + if (associated(this%flowbudptr)) found = .true. + ! + else + if (associated(this%fmi%gwfbndlist)) then + ! -- Look through gwfbndlist for a flow package with the same name as + ! this transport package name + do ip = 1, this%fmi%gwfbndlist%Count() + packobj => GetBndFromList(this%fmi%gwfbndlist, ip) + if (packobj%packName == this%flowpackagename) then + found = .true. + ! + ! -- Store BndType pointer to packobj, and then + ! use the select type to point to the budobj in flow package + this%flowpackagebnd => packobj + select type (packobj) + type is (MawType) + this%flowbudptr => packobj%budobj + end select + end if + if (found) exit + end do + end if + end if + ! + ! -- Error if flow package not found + if (.not. found) then + write (errmsg, '(a)') 'COULD NOT FIND FLOW PACKAGE WITH NAME '& + &//trim(adjustl(this%flowpackagename))//'.' + call store_error(errmsg) + call this%parser%StoreErrorUnit() + end if + ! + ! -- Allocate space for idxbudssm, which indicates whether this is a + ! special budget term or one that is a general source and sink + nbudterm = this%flowbudptr%nbudterm + call mem_allocate(this%idxbudssm, nbudterm, 'IDXBUDSSM', this%memoryPath) + ! + ! -- Process budget terms and identify special budget terms + write (this%iout, '(/, a, a)') & + 'PROCESSING '//ftype//' INFORMATION FOR ', this%packName + write (this%iout, '(a)') ' IDENTIFYING FLOW TERMS IN '//flowtype//' PACKAGE' + write (this%iout, '(a, i0)') & + ' NUMBER OF '//flowtype//' = ', this%flowbudptr%ncv + icount = 1 + do ip = 1, this%flowbudptr%nbudterm + select case (trim(adjustl(this%flowbudptr%budterm(ip)%flowtype))) + case ('FLOW-JA-FACE') + this%idxbudfjf = ip + this%idxbudssm(ip) = 0 + case ('GWF') + this%idxbudgwf = ip + this%idxbudssm(ip) = 0 + case ('STORAGE') + this%idxbudsto = ip + this%idxbudssm(ip) = 0 + case ('RATE') + this%idxbudrate = ip + this%idxbudssm(ip) = 0 + case ('FW-RATE') + this%idxbudfwrt = ip + this%idxbudssm(ip) = 0 + case ('RATE-TO-MVR') + this%idxbudrtmv = ip + this%idxbudssm(ip) = 0 + case ('FW-RATE-TO-MVR') + this%idxbudfrtm = ip + this%idxbudssm(ip) = 0 + case ('TO-MVR') + this%idxbudtmvr = ip + this%idxbudssm(ip) = 0 + case ('FROM-MVR') + this%idxbudfmvr = ip + this%idxbudssm(ip) = 0 + case ('AUXILIARY') + this%idxbudaux = ip + this%idxbudssm(ip) = 0 + case default + ! + ! -- Set idxbudssm equal to a column index for where the tempeartures + ! are stored in the tempbud(nbudssm, ncv) array + this%idxbudssm(ip) = icount + icount = icount + 1 + end select + write (this%iout, '(a, i0, " = ", a,/, a, i0)') & + ' TERM ', ip, trim(adjustl(this%flowbudptr%budterm(ip)%flowtype)), & + ' MAX NO. OF ENTRIES = ', this%flowbudptr%budterm(ip)%maxlist + end do + write (this%iout, '(a, //)') 'DONE PROCESSING '//ftype//' INFORMATION' + ! + ! -- Streambed conduction term + this%idxbudmwcd = this%idxbudgwf + ! + ! -- Return + return + end subroutine find_mwe_package + + !> @brief Add matrix terms related to MWE + !! + !! This routine is called from TspAptType%apt_fc_expanded() in + !! order to add matrix terms specifically for MWE + !< + subroutine mwe_fc_expanded(this, rhs, ia, idxglo, matrix_sln) + ! -- dummy + class(GweMweType) :: this + real(DP), dimension(:), intent(inout) :: rhs + integer(I4B), dimension(:), intent(in) :: ia + integer(I4B), dimension(:), intent(in) :: idxglo + class(MatrixBaseType), pointer :: matrix_sln + ! -- local + integer(I4B) :: j, n, n1, n2 + integer(I4B) :: iloc + integer(I4B) :: iposd, iposoffd + integer(I4B) :: ipossymd, ipossymoffd + integer(I4B) :: auxpos + real(DP) :: rrate + real(DP) :: rhsval + real(DP) :: hcofval + real(DP) :: ctherm ! kluge? + real(DP) :: wa !< wetted area + real(DP) :: ktf !< thermal conductivity of streambed material + real(DP) :: s !< thickness of conductive wellbore material + ! + ! -- Add puping rate contribution + if (this%idxbudrate /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudrate)%nlist + call this%mwe_rate_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add flowing well rate contribution + if (this%idxbudfwrt /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudfwrt)%nlist + call this%mwe_fwrt_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add rate to mover contribution + if (this%idxbudrtmv /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudrtmv)%nlist + call this%mwe_rtmv_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add puping rate contribution + if (this%idxbudfrtm /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudfrtm)%nlist + call this%mwe_frtm_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) + iposd = this%idxpakdiag(n1) + call matrix_sln%add_value_pos(iposd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add wellbore conduction contribution + do j = 1, this%flowbudptr%budterm(this%idxbudgwf)%nlist + ! + ! -- Set n to feature number and process if active features + n = this%flowbudptr%budterm(this%idxbudgwf)%id1(j) + if (this%iboundpak(n) /= 0) then + ! + ! -- Set acoef and rhs to negative so they are relative to mwe and not gwe + auxpos = this%flowbudptr%budterm(this%idxbudgwf)%naux + wa = this%flowbudptr%budterm(this%idxbudgwf)%auxvar(auxpos, j) + ktf = this%ktf(n) + s = this%rfeatthk(n) + ctherm = ktf * wa / s + ! + ! -- Add to mwe row + iposd = this%idxdglo(j) + iposoffd = this%idxoffdglo(j) + call matrix_sln%add_value_pos(iposd, -ctherm) ! kluge note: make sure the signs on ctherm are correct here and below + call matrix_sln%add_value_pos(iposoffd, ctherm) + ! + ! -- Add to gwe row for mwe connection + ipossymd = this%idxsymdglo(j) + ipossymoffd = this%idxsymoffdglo(j) + call matrix_sln%add_value_pos(ipossymd, -ctherm) + call matrix_sln%add_value_pos(ipossymoffd, ctherm) + end if + end do + ! + ! -- Return + return + end subroutine mwe_fc_expanded + + !> @brief Add terms specific to multi-aquifer wells to the explicit multi- + !! aquifer well energy transport solve + !< + subroutine mwe_solve(this) + ! -- dummy + class(GweMweType) :: this + ! -- local + integer(I4B) :: j + integer(I4B) :: n1, n2 + real(DP) :: rrate + ! + ! -- Add well pumping contribution + if (this%idxbudrate /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudrate)%nlist + call this%mwe_rate_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add flowing well rate contribution + if (this%idxbudfwrt /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudfwrt)%nlist + call this%mwe_fwrt_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add well pumping rate to mover contribution + if (this%idxbudrtmv /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudrtmv)%nlist + call this%mwe_rtmv_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add flowing well rate to mover contribution + if (this%idxbudfrtm /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudfrtm)%nlist + call this%mwe_frtm_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Return + return + end subroutine mwe_solve + + !> @brief Function to return the number of budget terms just for this package + !! + !! This overrides a function in the parent class. + !< + function mwe_get_nbudterms(this) result(nbudterms) + ! -- dummy + class(GweMweType) :: this + ! -- return + integer(I4B) :: nbudterms + ! + ! -- Number of potential budget terms is 5 + nbudterms = 1 ! RATE + if (this%idxbudfwrt /= 0) nbudterms = nbudterms + 1 + if (this%idxbudrtmv /= 0) nbudterms = nbudterms + 1 + if (this%idxbudfrtm /= 0) nbudterms = nbudterms + 1 + if (this%idxbudmwcd /= 0) nbudterms = nbudterms + 1 + ! + ! -- Return + return + end function mwe_get_nbudterms + + !> @brief Set up the budget object that stores all the mwe flows + !< + subroutine mwe_setup_budobj(this, idx) + ! -- modules + use ConstantsModule, only: LENBUDTXT + ! -- dummy + class(GweMweType) :: this + integer(I4B), intent(inout) :: idx + ! -- local + integer(I4B) :: n, n1, n2 + integer(I4B) :: maxlist, naux + real(DP) :: q + character(len=LENBUDTXT) :: text + ! + ! -- User-specified rate + text = ' RATE' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudrate)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- Flowing well rate + if (this%idxbudfwrt /= 0) then + text = ' FW-RATE' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudfwrt)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + end if + ! + ! -- User-specified flow rate to mover + if (this%idxbudrtmv /= 0) then + text = ' RATE-TO-MVR' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudrtmv)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + end if + ! + ! -- Fflowing well rate to mover + if (this%idxbudfrtm /= 0) then + text = ' FW-RATE-TO-MVR' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudfrtm)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + end if + ! + ! -- Conduction through wellbore (and/or filter pack) + text = ' WELLBORE-COND' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudmwcd)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + call this%budobj%budterm(idx)%reset(maxlist) + q = DZERO + do n = 1, maxlist + n1 = this%flowbudptr%budterm(this%idxbudgwf)%id1(n) + n2 = this%flowbudptr%budterm(this%idxbudgwf)%id2(n) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + end do + ! + ! -- Return + return + end subroutine mwe_setup_budobj + + !> @brief Copy flow terms into this%budobj + !< + subroutine mwe_fill_budobj(this, idx, x, flowja, ccratin, ccratout) + ! -- dummy + class(GweMweType) :: this + integer(I4B), intent(inout) :: idx + real(DP), dimension(:), intent(in) :: x + real(DP), dimension(:), contiguous, intent(inout) :: flowja + real(DP), intent(inout) :: ccratin + real(DP), intent(inout) :: ccratout + ! -- local + integer(I4B) :: j, n1, n2 + integer(I4B) :: nlist + integer(I4B) :: igwfnode + integer(I4B) :: idiag + integer(I4B) :: auxpos + real(DP) :: q + real(DP) :: ctherm + real(DP) :: wa !< wetted area + real(DP) :: ktf !< thermal conductivity of streambed material + real(DP) :: s !< thickness of conductive streambed materia + ! + ! -- Rate + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudrate)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%mwe_rate_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + ! + ! -- FW-Rate + if (this%idxbudfwrt /= 0) then + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudfwrt)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%mwe_fwrt_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + end if + ! + ! -- Rate-To-MVR + if (this%idxbudrtmv /= 0) then + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudrtmv)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%mwe_rtmv_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + end if + ! + ! -- FW-Rate-To-MVR + if (this%idxbudfrtm /= 0) then + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudfrtm)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%mwe_frtm_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + end do + end if + ! + ! -- Wellbore-Cond + idx = idx + 1 + call this%budobj%budterm(idx)%reset(this%maxbound) + do j = 1, this%flowbudptr%budterm(this%idxbudmwcd)%nlist + q = DZERO + n1 = this%flowbudptr%budterm(this%idxbudmwcd)%id1(j) + if (this%iboundpak(n1) /= 0) then + igwfnode = this%flowbudptr%budterm(this%idxbudmwcd)%id2(j) + auxpos = this%flowbudptr%budterm(this%idxbudgwf)%naux + wa = this%flowbudptr%budterm(this%idxbudgwf)%auxvar(auxpos, j) + ktf = this%ktf(n1) + s = this%rfeatthk(n1) + ctherm = ktf * wa / s + q = ctherm * (x(igwfnode) - this%xnewpak(n1)) + end if + call this%budobj%budterm(idx)%update_term(n1, igwfnode, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + if (this%iboundpak(n1) /= 0) then + ! -- Contribution to gwe cell budget + this%simvals(j) = this%simvals(j) - q + idiag = this%dis%con%ia(igwfnode) + flowja(idiag) = flowja(idiag) - q + end if + end do + ! + ! -- Return + return + end subroutine mwe_fill_budobj + + !> @brief Allocate scalars specific to the multi-aquifer well energy + !! transport (MWE) package. + !< + subroutine allocate_scalars(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweMweType) :: this + ! + ! -- Allocate scalars in TspAptType + call this%TspAptType%allocate_scalars() + ! + ! -- Allocate + call mem_allocate(this%idxbudrate, 'IDXBUDRATE', this%memoryPath) + call mem_allocate(this%idxbudfwrt, 'IDXBUDFWRT', this%memoryPath) + call mem_allocate(this%idxbudrtmv, 'IDXBUDRTMV', this%memoryPath) + call mem_allocate(this%idxbudfrtm, 'IDXBUDFRTM', this%memoryPath) + call mem_allocate(this%idxbudmwcd, 'IDXBUDMWCD', this%memoryPath) + ! + ! -- Initialize + this%idxbudrate = 0 + this%idxbudfwrt = 0 + this%idxbudrtmv = 0 + this%idxbudfrtm = 0 + this%idxbudmwcd = 0 + ! + ! -- Return + return + end subroutine allocate_scalars + + !> @brief Allocate arrays specific to the streamflow mass transport (SFT) + !! package + !< + subroutine mwe_allocate_arrays(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweMweType), intent(inout) :: this + ! -- local + integer(I4B) :: n + ! + ! -- Time series + call mem_allocate(this%temprate, this%ncv, 'TEMPRATE', this%memoryPath) + ! + ! -- Call standard TspAptType allocate arrays + call this%TspAptType%apt_allocate_arrays() + ! + ! -- Initialize + do n = 1, this%ncv + this%temprate(n) = DZERO + end do + ! + ! -- Return + return + end subroutine mwe_allocate_arrays + + !> @brief Deallocate memory associated with MWE package + !< + subroutine mwe_da(this) + ! -- modules + use MemoryManagerModule, only: mem_deallocate + ! -- dummy + class(GweMweType) :: this + ! + ! -- Deallocate scalars + call mem_deallocate(this%idxbudrate) + call mem_deallocate(this%idxbudfwrt) + call mem_deallocate(this%idxbudrtmv) + call mem_deallocate(this%idxbudfrtm) + call mem_deallocate(this%idxbudmwcd) + ! + ! -- Deallocate time series + call mem_deallocate(this%temprate) + ! + ! -- Deallocate scalars in TspAptType + call this%TspAptType%bnd_da() + ! + ! -- Return + return + end subroutine mwe_da + + !> @brief Thermal transport matrix term(s) associcated with a user-specified + !! flow rate (mwe_rate_term) + !< + subroutine mwe_rate_term(this, ientry, n1, n2, rrate, rhsval, hcofval) + ! -- dummy + class(GweMweType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + real(DP) :: h, r + ! + n1 = this%flowbudptr%budterm(this%idxbudrate)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudrate)%id2(ientry) + ! -- Note that qbnd is negative for an extracting well + qbnd = this%flowbudptr%budterm(this%idxbudrate)%flow(ientry) + if (qbnd < DZERO) then + ctmp = this%xnewpak(n1) + h = qbnd + r = DZERO + else + ctmp = this%temprate(n1) + h = DZERO + r = -qbnd * ctmp + end if + if (present(rrate)) rrate = qbnd * ctmp * this%eqnsclfac + if (present(rhsval)) rhsval = r * this%eqnsclfac + if (present(hcofval)) hcofval = h * this%eqnsclfac + ! + ! -- Return + return + end subroutine mwe_rate_term + + !> @brief Thermal transport matrix term(s) associcated with a flowing- + !! well rate term associated with pumping (or injection) + !< + subroutine mwe_fwrt_term(this, ientry, n1, n2, rrate, rhsval, hcofval) + ! -- dummy + class(GweMweType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudfwrt)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudfwrt)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudfwrt)%flow(ientry) + ctmp = this%xnewpak(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac + if (present(rhsval)) rhsval = DZERO + if (present(hcofval)) hcofval = qbnd * this%eqnsclfac + ! + ! -- Return + return + end subroutine mwe_fwrt_term + + !> @brief Thermal transport matrix term(s) associcated with pumped-water- + !! to-mover term (mwe_rtmv_term) + !< + subroutine mwe_rtmv_term(this, ientry, n1, n2, rrate, rhsval, hcofval) + ! -- dummy + class(GweMweType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudrtmv)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudrtmv)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudrtmv)%flow(ientry) + ctmp = this%xnewpak(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac + if (present(rhsval)) rhsval = DZERO + if (present(hcofval)) hcofval = qbnd * this%eqnsclfac + ! + ! -- Return + return + end subroutine mwe_rtmv_term + + !> @brief Thermal transport matrix term(s) associcated with the flowing- + !! well-rate-to-mover term (mwe_frtm_term) + !< + subroutine mwe_frtm_term(this, ientry, n1, n2, rrate, rhsval, hcofval) + ! -- dummy + class(GweMweType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudfrtm)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudfrtm)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudfrtm)%flow(ientry) + ctmp = this%xnewpak(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac + if (present(rhsval)) rhsval = DZERO + if (present(hcofval)) hcofval = qbnd * this%eqnsclfac + ! + ! -- Return + return + end subroutine mwe_frtm_term + + !> @brief Observations + !! + !! Store the observation type supported by the APT package and overide + !! BndType%bnd_df_obs + !< + subroutine mwe_df_obs(this) + ! -- dummy + class(GweMweType) :: this + ! -- local + integer(I4B) :: indx + ! + ! -- Store obs type and assign procedure pointer + ! for temperature observation type. + call this%obs%StoreObsType('temperature', .false., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Flow-ja-face not supported for MWE + !call this%obs%StoreObsType('flow-ja-face', .true., indx) + !this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for from-mvr observation type. + call this%obs%StoreObsType('from-mvr', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- To-mvr not supported for mwe + !call this%obs%StoreObsType('to-mvr', .true., indx) + !this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for storage observation type. + call this%obs%StoreObsType('storage', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for constant observation type. + call this%obs%StoreObsType('constant', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for observation type: mwe + call this%obs%StoreObsType('mwe', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID12 + ! + ! -- Store obs type and assign procedure pointer + ! for rate observation type. + call this%obs%StoreObsType('rate', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for observation type. + call this%obs%StoreObsType('fw-rate', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for observation type. + call this%obs%StoreObsType('rate-to-mvr', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for observation type. + call this%obs%StoreObsType('fw-rate-to-mvr', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Return + return + end subroutine mwe_df_obs + + !> @brief Process package specific obs + !! + !! Method to process specific observations for this package. + !< + subroutine mwe_rp_obs(this, obsrv, found) + ! -- dummy + class(GweMweType), intent(inout) :: this !< package class + type(ObserveType), intent(inout) :: obsrv !< observation object + logical, intent(inout) :: found !< indicate whether observation was found + ! + found = .true. + select case (obsrv%ObsTypeId) + case ('RATE') + call this%rp_obs_byfeature(obsrv) + case ('FW-RATE') + call this%rp_obs_byfeature(obsrv) + case ('RATE-TO-MVR') + call this%rp_obs_byfeature(obsrv) + case ('FW-RATE-TO-MVR') + call this%rp_obs_byfeature(obsrv) + case default + found = .false. + end select + ! + ! -- Return + return + end subroutine mwe_rp_obs + + !> @brief Calculate observation value and pass it back to APT + !< + subroutine mwe_bd_obs(this, obstypeid, jj, v, found) + ! -- dummy + class(GweMweType), intent(inout) :: this + character(len=*), intent(in) :: obstypeid + real(DP), intent(inout) :: v + integer(I4B), intent(in) :: jj + logical, intent(inout) :: found + ! -- local + integer(I4B) :: n1, n2 + ! + found = .true. + select case (obstypeid) + case ('RATE') + if (this%iboundpak(jj) /= 0) then + call this%mwe_rate_term(jj, n1, n2, v) + end if + case ('FW-RATE') + if (this%iboundpak(jj) /= 0 .and. this%idxbudfwrt > 0) then + call this%mwe_fwrt_term(jj, n1, n2, v) + end if + case ('RATE-TO-MVR') + if (this%iboundpak(jj) /= 0 .and. this%idxbudrtmv > 0) then + call this%mwe_rtmv_term(jj, n1, n2, v) + end if + case ('FW-RATE-TO-MVR') + if (this%iboundpak(jj) /= 0 .and. this%idxbudfrtm > 0) then + call this%mwe_frtm_term(jj, n1, n2, v) + end if + case default + found = .false. + end select + ! + ! -- Return + return + end subroutine mwe_bd_obs + + !> @brief Sets the stress period attributes for keyword use. + !< + subroutine mwe_set_stressperiod(this, itemno, keyword, found) + ! -- modules + use TimeSeriesManagerModule, only: read_value_or_time_series_adv + ! -- dummy + class(GweMweType), intent(inout) :: this + integer(I4B), intent(in) :: itemno + character(len=*), intent(in) :: keyword + logical, intent(inout) :: found + ! -- local + character(len=LINELENGTH) :: text + integer(I4B) :: ierr + integer(I4B) :: jj + real(DP), pointer :: bndElem => null() + ! + ! RATE + ! + found = .true. + select case (keyword) + case ('RATE') + ierr = this%apt_check_valid(itemno) + if (ierr /= 0) then + goto 999 + end if + call this%parser%GetString(text) + jj = 1 + bndElem => this%temprate(itemno) + call read_value_or_time_series_adv(text, itemno, jj, bndElem, & + this%packName, 'BND', this%tsManager, & + this%iprpak, 'RATE') + case default + ! + ! -- Keyword not recognized so return to caller with found = .false. + found = .false. + end select + ! +999 continue + ! + ! -- Return + return + end subroutine mwe_set_stressperiod + +end module GweMweModule diff --git a/src/Model/TransportModel/tsp1apt1.f90 b/src/Model/TransportModel/tsp1apt1.f90 index facc861b3bb..76fc718e033 100644 --- a/src/Model/TransportModel/tsp1apt1.f90 +++ b/src/Model/TransportModel/tsp1apt1.f90 @@ -2813,7 +2813,7 @@ subroutine apt_rp_obs(this) ' must be assigned to a feature with a unique boundname.' call store_error(errmsg) end if - case ('LKT', 'SFT', 'MWT', 'UZT', 'LKE', 'SFE') + case ('LKT', 'SFT', 'MWT', 'UZT', 'LKE', 'SFE', 'MWE') call this%rp_obs_budterm(obsrv, & this%flowbudptr%budterm(this%idxbudgwf)) case ('FLOW-JA-FACE') @@ -2898,7 +2898,7 @@ subroutine apt_bd_obs(this) if (this%iboundpak(jj) /= 0) then v = this%xnewpak(jj) end if - case ('LKT', 'SFT', 'MWT', 'UZT', 'LKE', 'SFE') + case ('LKT', 'SFT', 'MWT', 'UZT', 'LKE', 'SFE', 'MWE') n = this%flowbudptr%budterm(this%idxbudgwf)%id1(jj) if (this%iboundpak(n) /= 0) then igwfnode = this%flowbudptr%budterm(this%idxbudgwf)%id2(jj) diff --git a/src/meson.build b/src/meson.build index 28d973721a6..447ef97947c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -71,6 +71,7 @@ modflow_sources = files( 'Model' / 'GroundWaterEnergy' / 'gwe1ic1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1idm.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1lke1.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1mwe1.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1sfe1.f90', 'Model' / 'GroundWaterFlow' / 'gwf3.f90', 'Model' / 'GroundWaterFlow' / 'gwf3api8.f90', From eb57ea50ea45595cb733d8661ead661b5d93ab3c Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Thu, 8 Feb 2024 16:07:08 -0800 Subject: [PATCH 42/46] Adding unsaturated-zone energy transport (UZE) package. Includes 2 new autotests --- autotest/test_gwe_uze00.py | 612 ++++++++ autotest/test_gwe_uze00_flux.py | 753 +++++++++ doc/Common/gwe-uzeobs.tex | 20 +- doc/mf6io/gwe/gwe.tex | 4 + doc/mf6io/gwe/namefile.tex | 1 + doc/mf6io/gwe/uze.tex | 55 + doc/mf6io/mf6ivar/dfn/gwe-uze.dfn | 438 ++++++ .../mf6ivar/examples/gwe-uze-example-obs.dat | 12 + .../mf6ivar/examples/gwe-uze-example.dat | 24 + doc/mf6io/mf6ivar/md/mf6ivar.md | 34 + doc/mf6io/mf6ivar/mf6ivar.py | 1 + doc/mf6io/mf6ivar/tex/appendixA.tex | 4 + doc/mf6io/mf6ivar/tex/gwe-uze-desc.tex | 91 ++ doc/mf6io/mf6ivar/tex/gwe-uze-options.dat | 15 + doc/mf6io/mf6ivar/tex/gwe-uze-packagedata.dat | 5 + doc/mf6io/mf6ivar/tex/gwe-uze-period.dat | 5 + make/makefile | 1 + msvs/mf6core.vfproj | 3 +- src/Model/GroundWaterEnergy/gwe1.f90 | 10 +- src/Model/GroundWaterEnergy/gwe1uze1.f90 | 1395 +++++++++++++++++ src/Model/TransportModel/tsp1apt1.f90 | 4 +- src/meson.build | 1 + 22 files changed, 3470 insertions(+), 18 deletions(-) create mode 100644 autotest/test_gwe_uze00.py create mode 100644 autotest/test_gwe_uze00_flux.py create mode 100644 doc/mf6io/gwe/uze.tex create mode 100644 doc/mf6io/mf6ivar/dfn/gwe-uze.dfn create mode 100644 doc/mf6io/mf6ivar/examples/gwe-uze-example-obs.dat create mode 100644 doc/mf6io/mf6ivar/examples/gwe-uze-example.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-uze-desc.tex create mode 100644 doc/mf6io/mf6ivar/tex/gwe-uze-options.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-uze-packagedata.dat create mode 100644 doc/mf6io/mf6ivar/tex/gwe-uze-period.dat create mode 100644 src/Model/GroundWaterEnergy/gwe1uze1.f90 diff --git a/autotest/test_gwe_uze00.py b/autotest/test_gwe_uze00.py new file mode 100644 index 00000000000..5ef6a0e885e --- /dev/null +++ b/autotest/test_gwe_uze00.py @@ -0,0 +1,612 @@ +# +# - Outer columns not active for unsaturated zone, but are present to host +# constant head boundaries at the bottom of the model. +# +# +-------+ +# |///////| = Inactive cell +# +-------+ +# +# Model depiction: +# +# +-------+-------+-------+ +# |///////| |///////| Layer 1 +# +-------+-------+-------+ +# |///////| |///////| Layer 2 +# +-------+-------+-------+ +# |///////| |///////| Layer 3 +# +-------+-------+-------+ +# |///////| |///////| +# + -- -- + -- -- + -- -- + +# |///////| |///////| Layer x (Middle portion of model not shown) +# + -- -- + -- -- + -- -- + +# |///////| |///////| +# +-------+-------+-------+ +# | | | | Layer 99 +# +-------+-------+-------+ +# | | | | Layer 100 +# +-------+-------+-------+ + +import os + +import flopy +import numpy as np +import pytest +from framework import TestFramework + +import flopy.utils.binaryfile as bf +import math + +import matplotlib.pyplot as plt + + +# Analytical solution, from Barends (2010) Equation 5 +def temp_analyt(t, z, t0, tinfil, v, d): + if t == 0.0: + temp = t0 + else: + denom = 2.0 * math.sqrt(d * t) + ztermm = (z - v * t) / denom + ztermp = (z + v * t) / denom + vterm = v * z / d + if vterm < 100.0: + # might need to adjust this limit + temp = t0 + 0.5 * (tinfil - t0) * ( + math.erfc(ztermm) + math.exp(vterm) * math.erfc(ztermp) + ) + else: + zeta = 1.0 / (1.0 + 0.47047 * ztermp) + polyterm = zeta * ( + 0.3480242 + zeta * (-0.0958798 + zeta * 0.7478556) + ) + temp = t0 + 0.5 * (tinfil - t0) * ( + math.erfc(ztermm) + math.exp(vterm - ztermp ** 2) * polyterm + ) + + return temp + + +# Model units +length_units = "meters" +time_units = "days" + +nlay, nrow, ncol = 101, 1, 3 +nper = 2 +perlen = [1.0e9, 100.0] +nstp = [1, 100] +tsmult = len(perlen) * [1.0] + +delr = 1.0 +delc = 1.0 +delz = 0.1 # 10 cm +strt = 0.05 +top = 10.0005 +botm = [ + 9.9995 +] # Top layer is very thin for application of the boundary condition +for i in np.arange(1, nlay): + bot = 10.0 - (i * delz) + botm.append(round(bot, 1)) + +nouter, ninner = 100, 300 +hclose, rclose, relax = 1e-9, 1e-3, 0.97 +steady = {0: False, 1: False} +transient = {0: True, 1: True} + +idomain_u = [0, 1, 0] +idomain_l = [1, 1, 1] +idomain = [] +for i in np.arange(nlay): + if i < 99: + idomain.append(idomain_u) + else: + idomain.append(idomain_l) + +idomain = np.array(idomain) + +strt_temp = 10.0 +scheme = "UPSTREAM" +dispersivity = 0.0 +prsity = 0.2 + +# transient uzf info +# iuzno cellid landflg ivertcn surfdp vks thtr thts thti eps [bndnm] +uzf_pkdat = [[0, (0, 0, 1), 1, 1, 0.00001, 1, 0.0001, 0.20, 0.055, 4]] + +# Continue building the UZF list of objects +for iuzno in np.arange(1, 101, 1): + if iuzno < 99: + ivertconn = iuzno + 1 + else: + ivertconn = -1 + + uzf_pkdat.append( + [iuzno, (iuzno, 0, 1), 0, ivertconn, 0.01, 1, 0.0001, 0.20, 0.055, 4] + ) + +iuz_cell_dict = {} +cell_iuz_dict = {} +for i, itm in enumerate(uzf_pkdat): + iuz_cell_dict.update({itm[0]: (itm[1][0], itm[1][1], itm[1][2])}) + cell_iuz_dict.update({(itm[1][0], itm[1][1], itm[1][2]): itm[0]}) + +finf = 0.01 +extdp = 0.0 +pet = 0.0 +extwc = 0.0 +zero = 0.0 +uzf_spd = { + 0: [[0, finf, pet, extdp, extwc, zero, zero, zero]], + 1: [[0, finf, pet, extdp, extwc, zero, zero, zero]], +} + +cases = ["uze00"] + + +def build_models(idx, test): + name = cases[idx] + + # build MODFLOW 6 files + ws = test.workspace + sim = flopy.mf6.MFSimulation( + sim_name=name, version="mf6", exe_name="mf6", sim_ws=ws + ) + + # create tdis package + tdis_rc = [] + for i in range(nper): + tdis_rc.append((perlen[i], nstp[i], tsmult[i])) + + flopy.mf6.ModflowTdis( + sim, time_units=time_units, nper=nper, perioddata=tdis_rc + ) + + gwfname = "gwf_" + name + gwename = "gwe_" + name + + newtonoptions = ["NEWTON", "UNDER_RELAXATION"] + # create gwf model + gwf = flopy.mf6.ModflowGwf( + sim, + modelname=gwfname, + newtonoptions=newtonoptions, + save_flows=True, + ) + + # create iterative model solution and register the gwf model with it + ims = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + complexity="MODERATE", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="DBD", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename=f"{gwfname}.ims", + ) + sim.register_ims_package(ims, [gwf.name]) + + flopy.mf6.ModflowGwfdis( + gwf, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=idomain, + filename=f"{gwfname}.dis", + ) + + # initial conditions + flopy.mf6.ModflowGwfic( + gwf, + strt=strt, + filename=f"{gwfname}.ic", + ) + + # node property flow + flopy.mf6.ModflowGwfnpf( + gwf, + save_flows=True, + icelltype=1, + k=100.0, + k33=10, + filename=f"{gwfname}.npf", + ) + + # aquifer storage + flopy.mf6.ModflowGwfsto( + gwf, + iconvert=1, + ss=1e-5, + sy=prsity, + steady_state=steady, + transient=transient, + filename=f"{gwfname}.sto", + ) + + # chd files + chdval = 0.05 + chdspd = {0: [[(100, 0, 0), chdval, 10.0], [(100, 0, 2), chdval, 10.0]]} + + flopy.mf6.ModflowGwfchd( + gwf, + auxiliary=["TEMPERATURE"], + print_flows=True, + stress_period_data=chdspd, + pname="CHD-1", + filename=f"{gwfname}.chd", + ) + + # Unsaturated-zone flow package + flopy.mf6.ModflowGwfuzf( + gwf, + print_flows=True, + save_flows=True, + wc_filerecord=gwfname + ".uzfwc.bin", + simulate_et=False, + simulate_gwseep=False, + linear_gwet=False, + boundnames=False, + ntrailwaves=15, + nwavesets=40, + nuzfcells=len(uzf_pkdat), + packagedata=uzf_pkdat, + perioddata=uzf_spd, + budget_filerecord=f"{gwfname}.uzf.bud", + pname="UZF-1", + filename=f"{gwfname}.uzf", + ) + + # output control + flopy.mf6.ModflowGwfoc( + gwf, + budget_filerecord=f"{name}.cbc", + head_filerecord=f"{name}.hds", + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + printrecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + filename=f"{gwfname}.oc", + ) + + # ---------------------------------- + # Instantiating MODFLOW 6 GWE model + # ---------------------------------- + gwe = flopy.mf6.ModflowGwe( + sim, modelname=gwename, model_nam_file=f"{gwename}.nam" + ) + gwe.name_file.save_flows = True + + imsgwe = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwename), + ) + sim.register_ims_package(imsgwe, [gwe.name]) + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwedis( + gwe, + nogrb=True, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=idomain, + pname="DIS", + filename=f"{gwename}.dis", + ) + + # Instantiating MODFLOW 6 transport initial concentrations + flopy.mf6.ModflowGweic( + gwe, + strt=strt_temp, + pname="IC", + filename=f"{gwename}.ic", + ) + + # Instantiating MODFLOW 6 transport advection package + flopy.mf6.ModflowGweadv( + gwe, scheme=scheme, pname="ADV", filename="{}.adv".format(gwename) + ) + + # Instantiating MODFLOW 6 transport dispersion package + flopy.mf6.ModflowGwecnd( + gwe, + xt3d_off=False, + alh=dispersivity, + ath1=dispersivity, + ktw=0.5918 * 86400, + kts=0.2700 * 86400, + pname="DSP", + filename=f"{gwename}.dsp", + ) + + # Instantiating MODFLOW 6 transport mass storage package + rhow = 1000.0 + cpw = 4183.0 + lhv = 2500.0 + flopy.mf6.ModflowGweest( + gwe, + save_flows=True, + porosity=prsity, + cps=760.0, + rhos=1500.0, + packagedata=[cpw, rhow, lhv], + pname="MST", + filename=f"{gwename}.mst", + ) + + # Instantiating MODFLOW 6 constant temperature boundary condition at + ctpspd = {0: [[(0, 0, 1), 10.0]], 1: [[(0, 0, 1), 20.0]]} + + flopy.mf6.ModflowGwectp( + gwe, + save_flows=True, + print_flows=True, + stress_period_data=ctpspd, + pname="CTP", + filename="{}.ctp".format(gwename), + ) + + # Instantiating MODFLOW 6 transport source-sink mixing package + srctype = "AUX" + auxname = "TEMPERATURE" + pname = ["CHD-1"] + # Inpput to SSM is: + sources = [[itm, srctype, auxname] for itm in pname] + + flopy.mf6.ModflowGwessm( + gwe, + sources=sources, + pname="SSM", + filename=f"{gwename}.ssm", + ) + + # Instantiating MODFLOW 6 energy transport source-sink mixing package + uzepackagedata = [(iuz, 10.0) for iuz in range(nlay)] + uzeperioddata = { + 0: [[0, "INFILTRATION", 10.0]], + 1: [[0, "INFILTRATION", 20.0]], + } + + flopy.mf6.ModflowGweuze( + gwe, + flow_package_name="UZF-1", + boundnames=False, + save_flows=True, + print_input=True, + print_flows=True, + print_temperature=True, + temperature_filerecord=gwename + ".uze.bin", + budget_filerecord=gwename + ".uze.bud", + packagedata=uzepackagedata, + uzeperioddata=uzeperioddata, + pname="UZE-1", + filename=f"{gwename}.uze", + ) + + # Instantiate MODFLOW 6 heat transport output control package + flopy.mf6.ModflowGweoc( + gwe, + pname="OC", + budget_filerecord="{}.cbc".format(gwename), + temperature_filerecord="{}.ucn".format(gwename), + temperatureprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + printrecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + filename=f"{gwename}.oc", + ) + + # Instantiate Gwf-Gwe Exchange package + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename, + filename="{}.gwfgwe".format(gwename), + ) + + return sim, None + + +def check_output(idx, test): + print("evaluating flow...") + + name = cases[idx] + gwfname = "gwf_" + name + gwename = "gwe_" + name + ws = test.workspace + + # check some output... + wc_fl = gwfname + ".uzfwc.bin" + wcobj = flopy.utils.HeadFile(os.path.join(ws, wc_fl), text="water-content") + wc = wcobj.get_alldata() + + fl2 = gwename + ".uze.bin" + + uzeobj = flopy.utils.HeadFile(os.path.join(ws, fl2), text="TEMPERATURE") + temps = uzeobj.get_alldata() + + t = np.linspace(0.0, 100.0, 101) + z = np.arange(0.05, 10.0, 0.1) + z = np.insert(z, 0, 0.0) + + t0 = 10.0 + tinfil = 20.0 + + q = finf # infiltration rate + rhos = 1500.0 + Cps = 760.0 + rhow = 1000.0 + Cpw = 4183.0 + rhowCpw = Cpw * rhow + rhosCps = Cps * rhos + + Kts = 23328.0 + Ktw = 0.0 + + steady_wc = wc[1, 0, 0, 1] + Sw = steady_wc / prsity + + rhoCp_bulk = Sw * prsity * rhowCpw + (1 - prsity) * rhosCps + Kt_bulk = Sw * prsity * Ktw + (1 - prsity) * Kts + v = rhowCpw / rhoCp_bulk * q + D = Kt_bulk / rhoCp_bulk + + # Put analytical solution in place + analytical_sln = np.zeros((len(t), len(z))) + for i, tm in enumerate(t): + for j, depth in enumerate(z): + temp = temp_analyt(tm, depth, t0, tinfil, v, D) + analytical_sln[i, j] = temp + + # Run checks + msg0 = ( + "Simulated solution no longer falling within" + " default tolerance where it previously did" + ) + # Compare day 1. For layer 20 and below, the defaults of allclose should work + assert np.allclose(analytical_sln[1, 19:], temps[1, 0, 0, 19:]), msg0 + # Compare day 10. For layer 39 and below, the defaults of allclose should work + assert np.allclose(analytical_sln[10, 38:], temps[10, 0, 0, 38:]), msg0 + # Compare day 50. For layer 84 and below, the defaults of allclose should work + assert np.allclose(analytical_sln[50, 83:], temps[50, 0, 0, 83:]), msg0 + # Compare day 100, fits are generally good, but do not pass allclose default settings + + # Ensure that the differences in the 1st day fall within established bounds + msg1 = ( + "Simulated fits to analytical solution are " + "falling outside established bounds on day 1" + ) + assert ( + np.max(analytical_sln[1, :18] - temps[1, 0, 0, :18]) <= 1.52921097880 + ), msg1 + assert ( + np.min(analytical_sln[1, :18] - temps[1, 0, 0, :18]) >= -0.32260871278 + ), msg1 + + # Ensure that the differences on day 10 fall within established bounds + msg2 = ( + "Simulated fits to analytical solution are " + "falling outside established bounds on day 10" + ) + assert ( + np.max(analytical_sln[10, :37] - temps[10, 0, 0, :37]) <= 0.15993441016 + ), msg2 + assert ( + np.min(analytical_sln[10, :37] - temps[10, 0, 0, :37]) + >= -0.22298707253 + ), msg2 + + # Ensure that the differences on day 50 fall within established bounds + msg3 = ( + "Simulated fits to analytical solution are " + "falling outside established bounds on day 50" + ) + assert ( + np.max(analytical_sln[50, :82] - temps[50, 0, 0, :82]) <= 0.09327747258 + ), msg3 + assert ( + np.min(analytical_sln[50, :82] - temps[50, 0, 0, :82]) + >= -0.21182907402 + ), msg3 + + # Ensure that the differences on day 50 fall within established bounds + msg3 = ( + "Simulated fits to analytical solution are " + "falling outside established bounds on day 50" + ) + assert ( + np.max(analytical_sln[50, :82] - temps[50, 0, 0, :82]) <= 0.09327747258 + ), msg3 + assert ( + np.min(analytical_sln[50, :82] - temps[50, 0, 0, :82]) + >= -0.21182907402 + ), msg3 + + # Ensure that the differences on day 100 fall within established bounds + msg4 = ( + "Simulated fits to analytical solution are " + "falling outside established bounds on day 100" + ) + assert np.max(analytical_sln[100] - temps[100]) <= 0.10680304268, msg4 + assert np.min(analytical_sln[100] - temps[100]) >= -0.20763221276, msg4 + + # If a plot is needed for visual inspection, change following if statement to "True" + if False: + analytical_sln = np.zeros((len(t), len(z))) + for i, tm in enumerate(t): + for j, depth in enumerate(z): + temp = temp_analyt(tm, depth, t0, tinfil, v, D) + analytical_sln[i, j] = temp + + # first transient stress period + line1 = plt.plot( + analytical_sln[1], z, "-", color="red", label="Analytical" + ) + line2 = plt.plot( + temps[1, 0, 0], z, "-.", color="blue", label="MODFLOW 6" + ) + # 10th transient stress period + plt.plot(analytical_sln[10], z, "-", color="red") + plt.plot(temps[10, 0, 0], z, "-.", color="blue") + # 50th transient stress period + plt.plot(analytical_sln[50], z, "-", color="red") + plt.plot(temps[50, 0, 0], z, "-.", color="blue") + # last stress period + plt.plot(analytical_sln[100], z, "-", color="red") + plt.plot(temps[100, 0, 0], z, "-.", color="blue") + # add labels + plt.text(11.0, 0.85, "1 day", fontsize=10) + plt.text(12.0, 1.65, "10 days", fontsize=10) + plt.text(14.0, 2.90, "50 days", fontsize=10) + plt.text(16.0, 4.00, "100 days", fontsize=10) + + plt.gca().invert_yaxis() + plt.xlabel( + "$Temperature, C$" + ) # For latex replace with: '$Temperature, ^{\circ}C$' + plt.ylabel("$Depth, m$") + plt.minorticks_on() + plt.axhline(y=0.0) + plt.legend(loc="lower right", frameon=False) + plt.savefig(os.path.join(ws, "fit_view.png"), format="png") + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(cases)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t), + ) + test.run() diff --git a/autotest/test_gwe_uze00_flux.py b/autotest/test_gwe_uze00_flux.py new file mode 100644 index 00000000000..3873865d2a6 --- /dev/null +++ b/autotest/test_gwe_uze00_flux.py @@ -0,0 +1,753 @@ +# - Similar to test_gwe_uze00.py; however, this looks into whether the +# flux input is correct without pinning the temperature of the top-most +# cell to a specified value. +# +# - Outer columns not active for unsaturated zone, but are present to host +# constant head boundaries at the bottom of the model. +# +# +-------+ +# |///////| = Inactive cell +# +-------+ +# +# Model depiction: +# +# +-------+-------+-------+ +# |///////| |///////| Layer 1 +# +-------+-------+-------+ +# |///////| |///////| Layer 2 +# +-------+-------+-------+ +# |///////| |///////| Layer 3 +# +-------+-------+-------+ +# |///////| |///////| +# + -- -- + -- -- + -- -- + +# |///////| |///////| Layer x (Middle portion of model not shown) +# + -- -- + -- -- + -- -- + +# |///////| |///////| +# +-------+-------+-------+ +# | | | | Layer 99 +# +-------+-------+-------+ +# | | | | Layer 100 +# +-------+-------+-------+ + +import os + +import flopy +import numpy as np +import pytest +import math + +import flopy.utils.binaryfile as bf +from framework import TestFramework + + +# Analytical solution derived by Alden, similar in form to +# Barends (2010) Equation 5 - but remember that that solution +# pins the temperature of the top cell to a specified temperature +def flux_analyt(t, z, qt0, qtinfil, v, d): + if t == 0.0: + flux = qt0 + else: + denom = 2.0 * math.sqrt(d * t) + ztermm = (z - v * t) / denom + ztermp = (z + v * t) / denom + vterm = v * z / d + if vterm < 100.0: + # might need to adjust this limit + flux = qt0 + (qtinfil - qt0) * 0.5 * ( + math.erfc(ztermm) + math.exp(vterm) * math.erfc(ztermp) + ) + else: + zeta = 1.0 / (1.0 + 0.47047 * ztermp) + polyterm = zeta * ( + 0.3480242 + zeta * (-0.0958798 + zeta * 0.7478556) + ) + flux = qt0 + 0.5 * (qtinfil - qt0) * ( + math.erfc(ztermm) + math.exp(vterm - ztermp ** 2) * polyterm + ) + return flux + + +def temp_analyt(t, z, t0, tinfil, v, d): + if t == 0.0: + temp = t0 + else: + denom = 2.0 * math.sqrt(d * t) + ztermm = (z - v * t) / denom + ztermp = (z + v * t) / denom + vterm = v * z / d + if vterm < 100.0: + # might need to adjust this limit + temp = t0 + 0.5 * (tinfil - t0) * ( + math.erfc(ztermm) + math.exp(vterm) * math.erfc(ztermp) + ) + else: + zeta = 1.0 / (1.0 + 0.47047 * ztermp) + polyterm = zeta * ( + 0.3480242 + zeta * (-0.0958798 + zeta * 0.7478556) + ) + temp = t0 + 0.5 * (tinfil - t0) * ( + math.erfc(ztermm) + math.exp(vterm - ztermp ** 2) * polyterm + ) + return temp + + +# Model units +length_units = "meters" +time_units = "days" + +nlay, nrow, ncol = 101, 1, 3 +nper = 2 +perlen = [1.0e9, 100.0] +nstp = [1, 100] +tsmult = len(perlen) * [1.0] + +delr = 1.0 +delc = 1.0 +delz = 0.1 # 10 cm +strt = 0.05 +top = 10.0005 +botm = [ + 9.9995 +] # Top layer is very thin for application of the boundary condition +for i in np.arange(1, nlay): + bot = 10.0 - (i * delz) + botm.append(round(bot, 1)) + +nouter, ninner = 100, 300 +hclose, rclose, relax = 1e-9, 1e-3, 0.97 +steady = {0: False, 1: False} +transient = {0: True, 1: True} + +idomain_u = [0, 1, 0] +idomain_l = [1, 1, 1] +idomain = [] +for i in np.arange(nlay): + if i < 99: + idomain.append(idomain_u) + else: + idomain.append(idomain_l) + +idomain = np.array(idomain) + +strt_temp = 10.0 +scheme = "UPSTREAM" +dispersivity = 0.0 +prsity = 0.2 + +# transient uzf info +# iuzno cellid landflg ivertcn surfdp vks thtr thts thti eps [bndnm] +uzf_pkdat = [[0, (0, 0, 1), 1, 1, 0.00001, 1, 0.0001, 0.20, 0.055, 4]] + +# Continue building the UZF list of objects +for iuzno in np.arange(1, 101, 1): + if iuzno < nlay - 1: + ivertconn = iuzno + 1 + else: + ivertconn = -1 + + uzf_pkdat.append( + [iuzno, (iuzno, 0, 1), 0, ivertconn, 0.01, 1, 0.0001, 0.20, 0.055, 4] + ) + +iuz_cell_dict = {} +cell_iuz_dict = {} +for i, itm in enumerate(uzf_pkdat): + iuz_cell_dict.update({itm[0]: (itm[1][0], itm[1][1], itm[1][2])}) + cell_iuz_dict.update({(itm[1][0], itm[1][1], itm[1][2]): itm[0]}) + +finf = 0.01 +extdp = 0.0 +pet = 0.0 +extwc = 0.0 +zero = 0.0 +uzf_spd = { + 0: [[0, finf, pet, extdp, extwc, zero, zero, zero]], + 1: [[0, finf, pet, extdp, extwc, zero, zero, zero]], +} + +cases = ["uze00_flux"] + + +def build_models(idx, test): + name = cases[idx] + + # build MODFLOW 6 files + ws = test.workspace + sim = flopy.mf6.MFSimulation( + sim_name=name, version="mf6", exe_name="mf6", sim_ws=ws + ) + + # create tdis package + tdis_rc = [] + for i in range(nper): + tdis_rc.append((perlen[i], nstp[i], tsmult[i])) + + flopy.mf6.ModflowTdis( + sim, time_units=time_units, nper=nper, perioddata=tdis_rc + ) + + gwfname = "gwf_" + name + gwename = "gwe_" + name + + newtonoptions = ["NEWTON", "UNDER_RELAXATION"] + # create gwf model + gwf = flopy.mf6.ModflowGwf( + sim, + modelname=gwfname, + newtonoptions=newtonoptions, + save_flows=True, + ) + + # create iterative model solution and register the gwf model with it + ims = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + complexity="MODERATE", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="DBD", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename=f"{gwfname}.ims", + ) + sim.register_ims_package(ims, [gwf.name]) + + flopy.mf6.ModflowGwfdis( + gwf, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=idomain, + filename=f"{gwfname}.dis", + ) + + # initial conditions + flopy.mf6.ModflowGwfic( + gwf, + strt=strt, + filename=f"{gwfname}.ic", + ) + + # node property flow + flopy.mf6.ModflowGwfnpf( + gwf, + save_flows=True, + icelltype=1, + k=100.0, + k33=10, + filename=f"{gwfname}.npf", + ) + + # aquifer storage + flopy.mf6.ModflowGwfsto( + gwf, + iconvert=1, + ss=1e-5, + sy=prsity, + steady_state=steady, + transient=transient, + filename=f"{gwfname}.sto", + ) + + # chd files + chdval = 0.05 + chdspd = {0: [[(100, 0, 0), chdval, 10.0], [(100, 0, 2), chdval, 10.0]]} + + flopy.mf6.ModflowGwfchd( + gwf, + auxiliary=["TEMPERATURE"], + print_flows=True, + stress_period_data=chdspd, + pname="CHD-1", + filename=f"{gwfname}.chd", + ) + + # Unsaturated-zone flow package + flopy.mf6.ModflowGwfuzf( + gwf, + print_flows=True, + save_flows=True, + wc_filerecord=gwfname + ".uzfwc.bin", + simulate_et=False, + simulate_gwseep=False, + linear_gwet=False, + boundnames=False, + ntrailwaves=15, + nwavesets=40, + nuzfcells=len(uzf_pkdat), + packagedata=uzf_pkdat, + perioddata=uzf_spd, + budget_filerecord=f"{gwfname}.uzf.bud", + pname="UZF-1", + filename=f"{gwfname}.uzf", + ) + + # output control + flopy.mf6.ModflowGwfoc( + gwf, + budget_filerecord=f"{name}.cbc", + head_filerecord=f"{name}.hds", + headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], + saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + printrecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], + filename=f"{gwfname}.oc", + ) + + # ---------------------------------- + # Instantiating MODFLOW 6 GWE model + # ---------------------------------- + gwe = flopy.mf6.ModflowGwe( + sim, modelname=gwename, model_nam_file=f"{gwename}.nam" + ) + gwe.name_file.save_flows = True + + imsgwe = flopy.mf6.ModflowIms( + sim, + print_option="SUMMARY", + outer_dvclose=hclose, + outer_maximum=nouter, + under_relaxation="NONE", + inner_maximum=ninner, + inner_dvclose=hclose, + rcloserecord=rclose, + linear_acceleration="BICGSTAB", + scaling_method="NONE", + reordering_method="NONE", + relaxation_factor=relax, + filename="{}.ims".format(gwename), + ) + sim.register_ims_package(imsgwe, [gwe.name]) + + # Instantiating MODFLOW 6 transport discretization package + flopy.mf6.ModflowGwedis( + gwe, + nogrb=True, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=top, + botm=botm, + idomain=idomain, + pname="DIS", + filename=f"{gwename}.dis", + ) + + # Instantiating MODFLOW 6 transport initial concentrations + flopy.mf6.ModflowGweic( + gwe, + strt=strt_temp, + pname="IC", + filename=f"{gwename}.ic", + ) + + # Instantiating MODFLOW 6 transport advection package + flopy.mf6.ModflowGweadv( + gwe, scheme=scheme, pname="ADV", filename="{}.adv".format(gwename) + ) + + # Instantiating MODFLOW 6 transport dispersion package + flopy.mf6.ModflowGwecnd( + gwe, + xt3d_off=False, + alh=dispersivity, + ath1=dispersivity, + ktw=0.5918 * 86400, + kts=0.2700 * 86400, + pname="DSP", + filename=f"{gwename}.dsp", + ) + + # Instantiating MODFLOW 6 transport mass storage package + rhow = 1000.0 + cpw = 4183.0 + lhv = 2500.0 + flopy.mf6.ModflowGweest( + gwe, + save_flows=True, + porosity=prsity, + cps=760.0, + rhos=1500.0, + packagedata=[cpw, rhow, lhv], + pname="MST", + filename=f"{gwename}.mst", + ) + + # Instantiating MODFLOW 6 transport source-sink mixing package + srctype = "AUX" + auxname = "TEMPERATURE" + pname = ["CHD-1"] + # Inpput to SSM is: + sources = [[itm, srctype, auxname] for itm in pname] + + flopy.mf6.ModflowGwessm( + gwe, + sources=sources, + pname="SSM", + filename=f"{gwename}.ssm", + ) + + # Instantiating MODFLOW 6 energy transport source-sink mixing package + uzepackagedata = [(iuz, 10.0) for iuz in range(nlay)] + uzeperioddata = { + 0: [[0, "INFILTRATION", 10.0]], + 1: [[0, "INFILTRATION", 20.0]], + } + + flopy.mf6.ModflowGweuze( + gwe, + flow_package_name="UZF-1", + boundnames=False, + save_flows=True, + print_input=True, + print_flows=True, + print_temperature=True, + temperature_filerecord=gwename + ".uze.bin", + budget_filerecord=gwename + ".uze.bud", + packagedata=uzepackagedata, + uzeperioddata=uzeperioddata, + pname="UZE-1", + filename=f"{gwename}.uze", + ) + + # Instantiate MODFLOW 6 heat transport output control package + flopy.mf6.ModflowGweoc( + gwe, + pname="OC", + budget_filerecord="{}.cbc".format(gwename), + temperature_filerecord="{}.ucn".format(gwename), + temperatureprintrecord=[ + ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") + ], + saverecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + printrecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], + filename=f"{gwename}.oc", + ) + + # Instantiate Gwf-Gwe Exchange package + flopy.mf6.ModflowGwfgwe( + sim, + exgtype="GWF6-GWE6", + exgmnamea=gwfname, + exgmnameb=gwename, + filename="{}.gwfgwe".format(gwename), + ) + + return sim, None + + +def check_output(idx, test): + print("evaluating flow...") + + name = cases[idx] + gwfname = "gwf_" + name + gwename = "gwe_" + name + ws = test.workspace + + # check some output... + wc_fl = gwfname + ".uzfwc.bin" + wcobj = flopy.utils.HeadFile(os.path.join(ws, wc_fl), text="water-content") + wc = wcobj.get_alldata() + + # temperature output + fl2 = gwename + ".uze.bin" + uzeobj = flopy.utils.HeadFile(os.path.join(ws, fl2), text="TEMPERATURE") + temps = uzeobj.get_alldata() + + # Cell flows output + qfile = gwename + ".cbc" + gweflowsobj = flopy.utils.CellBudgetFile(os.path.join(ws, qfile)) + + # Binary grid file needed for post-processing + fgrb = gwfname + ".dis.grb" + grb_file = os.path.join(ws, fgrb) + + # UZE flows + fuzebud = gwename + ".uze.bud" + uzeflowsobj = flopy.utils.CellBudgetFile(os.path.join(ws, fuzebud)) + flowsadv = uzeflowsobj.get_data(text="FLOW-JA-FACE") + + t = np.linspace(0.0, 100.0, 101) + z = np.linspace(0.0, 9.9, 99) + + q = finf # infiltration rate + area = delr * delc + rhos = 1500.0 + Cps = 760.0 + rhow = 1000.0 + Cpw = 4183.0 + rhowCpw = Cpw * rhow + rhosCps = Cps * rhos + + Kts = 23328.0 + Ktw = 0.0 + + steady_wc = wc[1, 0, 0, 1] + Sw = steady_wc / prsity + + rhoCp_bulk = Sw * prsity * rhowCpw + (1 - prsity) * rhosCps + Kt_bulk = Sw * prsity * Ktw + (1 - prsity) * Kts + v = rhowCpw / rhoCp_bulk * q + D = Kt_bulk / rhoCp_bulk + + t0 = 10.0 + tinfil = 20.0 + qt0 = q * t0 + qtinfil = q * tinfil + + # for converting from J/day to W + unitadj = 1 / 86400 + + # Get analytical solution + conv10 = [] + cond10 = [] + conv50 = [] + cond50 = [] + conv100 = [] + cond100 = [] + analytical_sln = np.zeros((len(t), len(z))) + simulated_sln = np.zeros((len(t), len(z))) + for i, tm in enumerate(t): + if i == 0: + gweflowjaface = gweflowsobj.get_data( + text="FLOW-JA-FACE", kstpkper=(0, 0) + ) + else: + gweflowjaface = gweflowsobj.get_data( + text="FLOW-JA-FACE", kstpkper=(i - 1, 1) + ) + flowscond = flopy.mf6.utils.postprocessing.get_structured_faceflows( + gweflowjaface[0][0], grb_file=grb_file + ) + for j, depth in enumerate(z): + fluxa = flux_analyt(tm, depth, qt0, qtinfil, v, D) + analytical_sln[i, j] = fluxa * rhowCpw * unitadj + + (uze1, uze2, floadv) = flowsadv[i][2 * j + 1] + (fjunk1, flocond, fjunk2) = flowscond[1][j][0] + flo = floadv * rhowCpw * unitadj + flocond * rhowCpw * unitadj + if i == 10: + conv10.append(floadv * rhowCpw * unitadj) + cond10.append(flocond * rhowCpw * unitadj) + elif i == 50: + conv50.append(floadv * rhowCpw * unitadj) + cond50.append(flocond * rhowCpw * unitadj) + elif i == 100: + conv100.append(floadv * rhowCpw * unitadj) + cond100.append(flocond * rhowCpw * unitadj) + + flux = flo / area + simulated_sln[i, j] = flux + + # Run checks + msg0 = ( + "Simulated solution has deviated too far from the analytical solution" + ) + # Following values are calculated as "percent differences" when determining if fits are acceptable + # Day 10 + assert ( + np.max( + ((analytical_sln[10] * rhowCpw) - simulated_sln[10]) + / (analytical_sln[10] * rhowCpw) + * 100 + ) + <= 0.51091366512 + ), msg0 + assert ( + np.min( + ((analytical_sln[10] * rhowCpw) - simulated_sln[10]) + / (analytical_sln[10] * rhowCpw) + * 100 + ) + >= -2.62119104308 + ), msg0 + + # Day 50 + assert ( + np.max( + ((analytical_sln[50] * rhowCpw) - simulated_sln[50]) + / (analytical_sln[50] * rhowCpw) + * 100 + ) + <= 0.3171034702 + ), msg0 + assert ( + np.min( + ((analytical_sln[50] * rhowCpw) - simulated_sln[50]) + / (analytical_sln[50] * rhowCpw) + * 100 + ) + >= -2.52020856408 + ), msg0 + + # Day 100 + assert ( + np.max( + ((analytical_sln[100] * rhowCpw) - simulated_sln[100]) + / (analytical_sln[100] * rhowCpw) + * 100 + ) + <= 0.37655443171 + ), msg0 + assert ( + np.min( + ((analytical_sln[100] * rhowCpw) - simulated_sln[100]) + / (analytical_sln[100] * rhowCpw) + * 100 + ) + >= -2.56004275226 + ), msg0 + + # If plot is needed, change next statement to "if True:" + if False: + import matplotlib.pyplot as plt + from matplotlib import transforms + from matplotlib.collections import PathCollection + from matplotlib.patches import Patch + from matplotlib.lines import Line2D + + fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(10, 5)) + # 10 days + # ------- + polys1 = ax1.stackplot( + z, + conv10, + cond10, + labels=["Convection", "Conduction"], + colors=["lightseagreen", "lightgreen"], + ) + ax1.set_xlim((-0.05, 10.05)) + xlims = ax1.get_xlim() + for poly in polys1: + for path in poly.get_paths(): + path.vertices = path.vertices[:, ::-1] + ax1.set_xlim(0.095 * rhowCpw * unitadj, 0.205 * rhowCpw * unitadj) + ax1.set_ylim(xlims[::-1]) + ax1.plot(simulated_sln[10], z, "-", color="blue", linewidth=1) + ax1.plot(analytical_sln[10], z, "-.", color="red") + ax1.text(4.9, 0.4, "10 Days") + + legend_elements = [ + Line2D( + [0], + [0], + linestyle="-", + color="blue", + lw=1, + label="MODFLOW 6 Total Heat Flux", + ), + Line2D( + [0], [0], linestyle="-.", color="red", lw=1, label="Analytical" + ), + Patch( + facecolor="lightseagreen", + edgecolor="lightseagreen", + label="Convection", + ), + Patch( + facecolor="lightgreen", + edgecolor="lightgreen", + label="Conduction", + ), + ] + + ax1.legend(handles=legend_elements, loc="lower right", frameon=False) + ax1.set_xlabel("Energy Flux, $\dfrac{Watts}{m^2}$") + ax1.set_ylabel("Depth, m") + + # 50 days + # ------- + polys2 = ax2.stackplot( + z, + conv50, + cond50, + labels=["Convection", "Conduction"], + colors=["lightseagreen", "lightgreen"], + ) + ax2.set_xlim((-0.05, 10.05)) + xlims = ax2.get_xlim() + for poly in polys2: + for path in poly.get_paths(): + path.vertices = path.vertices[:, ::-1] + ax2.set_xlim(0.095 * rhowCpw * unitadj, 0.205 * rhowCpw * unitadj) + ax2.set_ylim(xlims[::-1]) + ax2.plot(simulated_sln[50], z, "-", color="blue", linewidth=1) + ax2.plot(analytical_sln[50], z, "-.", color="red") + ax2.set_xlabel("Energy Flux, $\dfrac{Watts}{m^2}$") + ax2.text(4.9, 0.4, "50 Days") + + # 100 days + # ------- + polys3 = ax3.stackplot( + z, + conv100, + cond100, + labels=["Convection", "Conduction"], + colors=["lightseagreen", "lightgreen"], + ) + ax3.set_xlim((-0.05, 10.05)) + xlims = ax3.get_xlim() + for poly in polys3: + for path in poly.get_paths(): + path.vertices = path.vertices[:, ::-1] + ax3.set_xlim(0.095 * rhowCpw * unitadj, 0.205 * rhowCpw * unitadj) + ax3.set_ylim(xlims[::-1]) + ax3.plot(simulated_sln[100], z, "-", color="blue", linewidth=1) + ax3.plot(analytical_sln[100], z, "-.", color="red") + ax3.set_xlabel("Energy Flux, $\dfrac{Watts}{m^2}$") + ax3.text(4.9, 0.4, "100 Days") + + plt.tight_layout() + plt.savefig(os.path.join(ws, "dual_view.png"), format="png") + + line1 = plt.plot( + analytical_sln[10], z, "-", color="red", label="Analytical" + ) + line2 = plt.plot( + simulated_sln[10], z, "-.", color="blue", label="MODFLOW 6" + ) + # 50th transient stress period + plt.plot(analytical_sln[50], z, "-", color="red") + plt.plot(simulated_sln[50], z, "-.", color="blue") + # last stress period + plt.plot(analytical_sln[100], z, "-", color="red") + plt.plot(simulated_sln[100], z, "-.", color="blue") + # add labels + plt.text(11.0, 0.85, "1 day", fontsize=10) + plt.text(12.0, 1.65, "10 days", fontsize=10) + plt.text(14.0, 2.90, "50 days", fontsize=10) + plt.text(16.0, 4.00, "100 days", fontsize=10) + + plt.gca().invert_yaxis() + plt.xlabel("$Energy Flux, -$") + plt.ylabel("$Depth, m$") + plt.minorticks_on() + plt.axhline(y=0.0) + plt.legend(loc="lower right", frameon=False) + plt.savefig(os.path.join(ws, "fit_view.png"), format="png") + + +# - No need to change any code below +@pytest.mark.parametrize( + "idx, name", + list(enumerate(cases)), +) +def test_mf6model(idx, name, function_tmpdir, targets): + test = TestFramework( + name=name, + workspace=function_tmpdir, + targets=targets, + build=lambda t: build_models(idx, t), + check=lambda t: check_output(idx, t), + ) + test.run() diff --git a/doc/Common/gwe-uzeobs.tex b/doc/Common/gwe-uzeobs.tex index f9a6aa1f2ba..241c86ef653 100644 --- a/doc/Common/gwe-uzeobs.tex +++ b/doc/Common/gwe-uzeobs.tex @@ -1,14 +1,14 @@ % general APT observations -UZE & temperature & ifno or boundname & -- & uze cell temperature. If boundname is specified, boundname must be unique for each uze cell. \\ -UZE & flow-ja-face & ifno or boundname & ifno or -- & Energy flow between two uze cells. If a boundname is specified for ID1, then the result is the total energy flow for all uze cells. If a boundname is specified for ID1 then ID2 is not used.\\ -UZE & storage & ifno or boundname & -- & Simulated energy storage flow rate for a uze cell or group of uze cells. \\ -UZE & constant & ifno or boundname & -- & Simulated energy constant-flow rate for a uze cell or a group of uze cells. \\ -UZE & from-mvr & ifno or boundname & -- & Simulated energy inflow into a uze cell or group of uze cells from the MVE package. Energy inflow is calculated as the product of provider temperature and the mover flow rate. \\ -UZE & uze & ifno or boundname & -- & Energy flow rate for a uze cell or group of uze cells and its aquifer connection(s). \\ +UZE & temperature & uzeno or boundname & -- & uze cell temperature. If boundname is specified, boundname must be unique for each uze cell. \\ +UZE & flow-ja-face & uzeno or boundname & uzeno or -- & Energy flow between two uze cells. If a boundname is specified for ID1, then the result is the total energy flow for all uze cells. If a boundname is specified for ID1 then ID2 is not used.\\ +UZE & storage & uzeno or boundname & -- & Simulated energy storage flow rate for a uze cell or group of uze cells. \\ +UZE & constant & uzeno or boundname & -- & Simulated energy constant-flow rate for a uze cell or a group of uze cells. \\ +UZE & from-mvr & uzeno or boundname & -- & Simulated energy inflow into a uze cell or group of uze cells from the MVE package. Energy inflow is calculated as the product of provider temperature and the mover flow rate. \\ +UZE & uze & uzeno or boundname & -- & Energy flow rate for a uze cell or group of uze cells and its aquifer connection(s). \\ %observations specific to the uze package % infiltration rej-inf uzet rej-inf-to-mvr -UZE & infiltration & ifno or boundname & -- & Infiltration rate applied to a uze cell or group of uze cells multiplied by the infiltration temperature. \\ -UZE & rej-inf & ifno or boundname & -- & Rejected infiltration rate applied to a uze cell or group of uze cells multiplied by the infiltration temperature. \\ -UZE & uzet & ifno or boundname & -- & Unsaturated zone evapotranspiration rate applied to a uze cell or group of uze cells multiplied by the latent heat of vaporization, heat capacity of the simulated fluid, and density of the simulated flued. \\ -UZE & rej-inf-to-mvr & ifno or boundname & -- & Rejected infiltration rate applied to a uze cell or group of uze cells multiplied by the infiltration temperature that is sent to the mover package. \\ +UZE & infiltration & uzeno or boundname & -- & Infiltration rate applied to a uze cell or group of uze cells multiplied by the infiltration temperature. \\ +UZE & rej-inf & uzeno or boundname & -- & Rejected infiltration rate applied to a uze cell or group of uze cells multiplied by the infiltration temperature. \\ +UZE & uzet & uzeno or boundname & -- & Unsaturated zone evapotranspiration rate applied to a uze cell or group of uze cells multiplied by the uze cell temperature. \\ +UZE & rej-inf-to-mvr & uzeno or boundname & -- & Rejected infiltration rate applied to a uze cell or group of uze cells multiplied by the infiltration temperature that is sent to the mover package. \\ diff --git a/doc/mf6io/gwe/gwe.tex b/doc/mf6io/gwe/gwe.tex index 0e7e30211bc..c4ab64fe833 100644 --- a/doc/mf6io/gwe/gwe.tex +++ b/doc/mf6io/gwe/gwe.tex @@ -137,6 +137,10 @@ \subsection{Lake Energy Transport (LKE) Package} \subsection{Multi-Aquifer Well Energy Transport (MWE) Package} \input{gwe/mwe} +\newpage +\subsection{Unsaturated-Zone Energy Transport (UZE) Package} +\input{gwe/uze} + \newpage \subsection{Flow Model Interface (FMI) Package} \input{gwe/fmi} diff --git a/doc/mf6io/gwe/namefile.tex b/doc/mf6io/gwe/namefile.tex index 4419af99530..d8cc1d18fec 100644 --- a/doc/mf6io/gwe/namefile.tex +++ b/doc/mf6io/gwe/namefile.tex @@ -37,6 +37,7 @@ \subsubsection{Explanation of Variables} SFE6 & Streamflow Energy Transport Package & * \\ LKE6 & Lake Energy Transport Package & * \\ MWE6 & Multi-Aquifer Well Energy Transport Package & * \\ +UZE6 & Unsaturated-Zone Energy Transport Package & * \\ OBS6 & Observations Option \\ \hline \end{tabular*} diff --git a/doc/mf6io/gwe/uze.tex b/doc/mf6io/gwe/uze.tex new file mode 100644 index 00000000000..1e65d5bbd11 --- /dev/null +++ b/doc/mf6io/gwe/uze.tex @@ -0,0 +1,55 @@ +Unsaturated Zone Energy Transport (UZE) Package information is read from the file that is specified by ``UZE6'' as the file type. There can be as many UZE Packages as necessary for a GWE model. Each UZE Package is designed to work with flows from a corresponding GWF UZF Package. By default \mf uses the UZE package name to determine which UZF Package corresponds to the UZE Package. Therefore, the package name of the UZE Package (as specified in the GWE name file) must match with the name of the corresponding UZF Package (as specified in the GWF name file). Alternatively, the name of the flow package can be specified using the FLOW\_PACKAGE\_NAME keyword in the options block. The GWE UZE Package cannot be used without a corresponding GWF UZF Package. + +The UZE Package does not have a dimensions block; instead, dimensions for the UZE Package are set using the dimensions from the corresponding UZF Package. For example, the UZF Package requires specification of the number of cells (NUZFCELLS). UZE sets the number of UZE cells equal to NUZFCELLS. Therefore, the PACKAGEDATA block below must have NUZFCELLS entries in it. + +\vspace{5mm} +\subsubsection{Structure of Blocks} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-uze-options.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-uze-packagedata.dat} +\lstinputlisting[style=blockdefinition]{./mf6ivar/tex/gwe-uze-period.dat} + +\vspace{5mm} +\subsubsection{Explanation of Variables} +\begin{description} +\input{./mf6ivar/tex/gwe-uze-desc.tex} +\end{description} + +\vspace{5mm} +\subsubsection{Example Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-uze-example.dat} + +\vspace{5mm} +\subsubsection{Available observation types} +Unsaturated Zone Energy Transport Package observations include UZF cell temperature and all of the terms that contribute to the continuity equation for each UZF cell. Additional UZE Package observations include energy flow rates for individual UZF cells, or groups of UZF cells. The data required for each UZE Package observation type is defined in table~\ref{table:gwe-uzeobstype}. Negative and positive values for \texttt{uzt} observations represent a loss from and gain to the GWE model, respectively. For all other flow terms, negative and positive values represent a loss from and gain from the UZE package, respectively. + +\begin{longtable}{p{2cm} p{2.75cm} p{2cm} p{1.25cm} p{7cm}} +\caption{Available UZE Package observation types} \tabularnewline + +\hline +\hline +\textbf{Stress Package} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endfirsthead + +\captionsetup{textformat=simple} +\caption*{\textbf{Table \arabic{table}.}{\quad}Available UZE Package observation types.---Continued} \tabularnewline + +\hline +\hline +\textbf{Stress Package} & \textbf{Observation type} & \textbf{ID} & \textbf{ID2} & \textbf{Description} \\ +\hline +\endhead + + +\hline +\endfoot + +\input{../Common/gwe-uzeobs.tex} +\label{table:gwe-uzeobstype} +\end{longtable} + +\vspace{5mm} +\subsubsection{Example Observation Input File} +\lstinputlisting[style=inputfile]{./mf6ivar/examples/gwe-uze-example-obs.dat} + + diff --git a/doc/mf6io/mf6ivar/dfn/gwe-uze.dfn b/doc/mf6io/mf6ivar/dfn/gwe-uze.dfn new file mode 100644 index 00000000000..1f272617b73 --- /dev/null +++ b/doc/mf6io/mf6ivar/dfn/gwe-uze.dfn @@ -0,0 +1,438 @@ +# --------------------- gwe uze options --------------------- +# flopy multi-package + +block options +name flow_package_name +type string +shape +reader urword +optional true +longname keyword to specify name of corresponding flow package +description keyword to specify the name of the corresponding flow package. If not specified, then the corresponding flow package must have the same name as this advanced transport package (the name associated with this package in the GWE name file). + +block options +name auxiliary +type string +shape (naux) +reader urword +optional true +longname keyword to specify aux variables +description REPLACE auxnames {'{#1}': 'Groundwater Energy Transport'} + +block options +name flow_package_auxiliary_name +type string +shape +reader urword +optional true +longname keyword to specify name of concentration auxiliary variable in flow package +description keyword to specify the name of an auxiliary variable in the corresponding flow package. If specified, then the simulated concentrations from this advanced transport package will be copied into the auxiliary variable specified with this name. Note that the flow package must have an auxiliary variable with this name or the program will terminate with an error. If the flows for this advanced transport package are read from a file, then this option will have no effect. + +block options +name boundnames +type keyword +shape +reader urword +optional true +longname +description REPLACE boundnames {'{#1}': 'unsaturated zone flow'} + +block options +name print_input +type keyword +reader urword +optional true +longname print input to listing file +description REPLACE print_input {'{#1}': 'unsaturated zone flow'} + +block options +name print_temperature +type keyword +reader urword +optional true +longname print calculated temperatures to listing file +description REPLACE print_temperature {'{#1}': 'UZF cell', '{#2}': 'temperatures', '{#3}': 'TEMPERATURE'} + +block options +name print_flows +type keyword +reader urword +optional true +longname print calculated flows to listing file +description REPLACE print_flows {'{#1}': 'unsaturated zone'} + +block options +name save_flows +type keyword +reader urword +optional true +longname save UZE cell flows to budget file +description REPLACE save_flows {'{#1}': 'unsaturated zone'} + +block options +name temperature_filerecord +type record temperature fileout tempfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name temperature +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname stage keyword +description keyword to specify that record corresponds to temperature. + +block options +name tempfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the binary output file to write temperature information. + +block options +name budget_filerecord +type record budget fileout budgetfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name budget +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname budget keyword +description keyword to specify that record corresponds to the budget. + +block options +name fileout +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname file keyword +description keyword to specify that an output filename is expected next. + +block options +name budgetfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the binary output file to write budget information. + +block options +name budgetcsv_filerecord +type record budgetcsv fileout budgetcsvfile +shape +reader urword +tagged true +optional true +longname +description + +block options +name budgetcsv +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname budget keyword +description keyword to specify that record corresponds to the budget CSV. + +block options +name budgetcsvfile +type string +preserve_case true +shape +in_record true +reader urword +tagged false +optional false +longname file keyword +description name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. + +block options +name ts_filerecord +type record ts6 filein ts6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name ts6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname head keyword +description keyword to specify that record corresponds to a time-series file. + +block options +name filein +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname file keyword +description keyword to specify that an input filename is expected next. + +block options +name ts6_filename +type string +preserve_case true +in_record true +reader urword +optional false +tagged false +longname file name of time series information +description REPLACE timeseriesfile {} + +block options +name obs_filerecord +type record obs6 filein obs6_filename +shape +reader urword +tagged true +optional true +longname +description + +block options +name obs6 +type keyword +shape +in_record true +reader urword +tagged true +optional false +longname obs keyword +description keyword to specify that record corresponds to an observations file. + +block options +name obs6_filename +type string +preserve_case true +in_record true +tagged false +reader urword +optional false +longname obs6 input filename +description REPLACE obs6_filename {'{#1}': 'UZE'} + + +# --------------------- gwe uze packagedata --------------------- + +block packagedata +name packagedata +type recarray uzfno strt aux boundname +shape (maxbound) +reader urword +longname +description + +block packagedata +name uzfno +type integer +shape +tagged false +in_record true +reader urword +longname UZF cell number for this entry +description integer value that defines the UZF cell number associated with the specified PACKAGEDATA data on the line. UZFNO must be greater than zero and less than or equal to NUZFCELLS. Unsaturated zone flow information must be specified for every UZF cell or the program will terminate with an error. The program also will terminate with an error if information for a UZF cell is specified more than once. +numeric_index true + +block packagedata +name strt +type double precision +shape +tagged false +in_record true +reader urword +longname starting UZF cell temperature +description real value that defines the starting temperature for the unsaturated zone flow cell. + +block packagedata +name aux +type double precision +in_record true +tagged false +shape (naux) +reader urword +time_series true +optional true +longname auxiliary variables +description REPLACE aux {'{#1}': 'unsaturated zone flow'} + +block packagedata +name boundname +type string +shape +tagged false +in_record true +reader urword +optional true +longname UZF cell name +description REPLACE boundname {'{#1}': 'unsaturated zone flow'} + + +# --------------------- gwe uze period --------------------- + +block period +name iper +type integer +block_variable True +in_record true +tagged false +shape +valid +reader urword +optional false +longname stress period number +description REPLACE iper {} + +block period +name uzeperioddata +type recarray uzfno uzesetting +shape +reader urword +longname +description + +block period +name uzfno +type integer +shape +tagged false +in_record true +reader urword +longname unsaturated zone flow cell number for this entry +description integer value that defines the UZF cell number associated with the specified PERIOD data on the line. UZFNO must be greater than zero and less than or equal to NUZFCELLS. +numeric_index true + +block period +name uzesetting +type keystring status temperature infiltration uzet auxiliaryrecord +shape +tagged false +in_record true +reader urword +longname +description line of information that is parsed into a keyword and values. Keyword values that can be used to start the UZESETTING string include: STATUS, TEMPERATURE, INFILTRATION, UZET, and AUXILIARY. These settings are used to assign the temperature associated with the corresponding flow terms. Temperatures cannot be specified for all flow terms. + +block period +name status +type string +shape +tagged true +in_record true +reader urword +longname unsaturated zone flow cell temperature status +description keyword option to define UZF cell status. STATUS can be ACTIVE, INACTIVE, or CONSTANT. By default, STATUS is ACTIVE, which means that temperature will be calculated for the UZF cell. If a UZF cell is inactive, then there will be no energy fluxes into or out of the UZF cell and the inactive value will be written for the UZF cell temperature. If a UZF cell is constant, then the temperature for the UZF cell will be fixed at the user specified value. + +block period +name temperature +type string +shape +tagged true +in_record true +time_series true +reader urword +longname unsaturated zone flow cell temperature +description real or character value that defines the temperature for the unsaturated zone flow cell. The specified TEMPERATURE is only applied if the unsaturated zone flow cell is a constant temperature cell. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name infiltration +type string +shape +tagged true +in_record true +reader urword +time_series true +longname infiltration temperature +description real or character value that defines the temperature of the infiltration $(^\circ C)$ for the UZF cell. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name uzet +type string +shape +tagged true +in_record true +reader urword +time_series true +longname unsaturated zone et temperature +description real or character value that states what fraction of the simulated unsaturated zone evapotranspiration is associated with evaporation. The evaporative losses from the unsaturated zone moisture content will have an evaporative cooling effect on the GWE cell from which the evaporation originated. If this value is larger than 1, then it will be reset to 1. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. + +block period +name auxiliaryrecord +type record auxiliary auxname auxval +shape +tagged +in_record true +reader urword +longname +description + +block period +name auxiliary +type keyword +shape +in_record true +reader urword +longname +description keyword for specifying auxiliary variable. + +block period +name auxname +type string +shape +tagged false +in_record true +reader urword +longname +description name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. + +block period +name auxval +type double precision +shape +tagged false +in_record true +reader urword +time_series true +longname auxiliary variable value +description value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. diff --git a/doc/mf6io/mf6ivar/examples/gwe-uze-example-obs.dat b/doc/mf6io/mf6ivar/examples/gwe-uze-example-obs.dat new file mode 100644 index 00000000000..3859fd40ff1 --- /dev/null +++ b/doc/mf6io/mf6ivar/examples/gwe-uze-example-obs.dat @@ -0,0 +1,12 @@ +BEGIN options + DIGITS 7 + PRINT_INPUT +END options + +BEGIN continuous FILEOUT gwe_02.uze.obs.csv + mwe-1-temp TEMPERATURE 1 + mwe-1-stor STORAGE 1 + mwe-1-gwe1 UZE 1 + mwe-1-gwe2 UZE 2 + mwe-2-gwe1 UZE 3 +END continuous diff --git a/doc/mf6io/mf6ivar/examples/gwe-uze-example.dat b/doc/mf6io/mf6ivar/examples/gwe-uze-example.dat new file mode 100644 index 00000000000..e6e29baac43 --- /dev/null +++ b/doc/mf6io/mf6ivar/examples/gwe-uze-example.dat @@ -0,0 +1,24 @@ +BEGIN OPTIONS + AUXILIARY aux1 aux2 + BOUNDNAMES + PRINT_INPUT + PRINT_TEMPERATURE + PRINT_FLOWS + SAVE_FLOWS + TEMPERATURE FILEOUT gwe_02.uze.bin + BUDGET FILEOUT gwe_02.uze.bud + OBS6 FILEIN gwe_02.uze.obs +END OPTIONS + +BEGIN PACKAGEDATA +# L STRT aux1 aux2 bname + 1 0.0 99.0 999.0 MYUZFCELL1 + 2 0.0 99.0 999.0 MYUZFCELL2 + 3 0.0 99.0 999.0 MYUZFCELL3 +END PACKAGEDATA + +BEGIN PERIOD 1 + 1 STATUS ACTIVE + 2 STATUS ACTIVE + 3 STATUS ACTIVE +END PERIOD 1 diff --git a/doc/mf6io/mf6ivar/md/mf6ivar.md b/doc/mf6io/mf6ivar/md/mf6ivar.md index aeb29f13a33..adb9fde7379 100644 --- a/doc/mf6io/mf6ivar/md/mf6ivar.md +++ b/doc/mf6io/mf6ivar/md/mf6ivar.md @@ -1448,6 +1448,40 @@ | GWE | SFE | PERIOD | AUXILIARY | KEYWORD | keyword for specifying auxiliary variable. | | GWE | SFE | PERIOD | AUXNAME | STRING | name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. | | GWE | SFE | PERIOD | AUXVAL | DOUBLE PRECISION | value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | UZE | OPTIONS | FLOW_PACKAGE_NAME | STRING | keyword to specify the name of the corresponding flow package. If not specified, then the corresponding flow package must have the same name as this advanced transport package (the name associated with this package in the GWE name file). | +| GWE | UZE | OPTIONS | AUXILIARY | STRING (NAUX) | defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. | +| GWE | UZE | OPTIONS | FLOW_PACKAGE_AUXILIARY_NAME | STRING | keyword to specify the name of an auxiliary variable in the corresponding flow package. If specified, then the simulated concentrations from this advanced transport package will be copied into the auxiliary variable specified with this name. Note that the flow package must have an auxiliary variable with this name or the program will terminate with an error. If the flows for this advanced transport package are read from a file, then this option will have no effect. | +| GWE | UZE | OPTIONS | BOUNDNAMES | KEYWORD | keyword to indicate that boundary names may be provided with the list of unsaturated zone flow cells. | +| GWE | UZE | OPTIONS | PRINT_INPUT | KEYWORD | keyword to indicate that the list of unsaturated zone flow information will be written to the listing file immediately after it is read. | +| GWE | UZE | OPTIONS | PRINT_TEMPERATURE | KEYWORD | keyword to indicate that the list of UZF cell temperatures will be printed to the listing file for every stress period in which ``TEMPERATURE PRINT'' is specified in Output Control. If there is no Output Control option and PRINT\_TEMPERATURE is specified, then temperatures are printed for the last time step of each stress period. | +| GWE | UZE | OPTIONS | PRINT_FLOWS | KEYWORD | keyword to indicate that the list of unsaturated zone flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. | +| GWE | UZE | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that unsaturated zone flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | +| GWE | UZE | OPTIONS | TEMPERATURE | KEYWORD | keyword to specify that record corresponds to temperature. | +| GWE | UZE | OPTIONS | TEMPFILE | STRING | name of the binary output file to write temperature information. | +| GWE | UZE | OPTIONS | BUDGET | KEYWORD | keyword to specify that record corresponds to the budget. | +| GWE | UZE | OPTIONS | FILEOUT | KEYWORD | keyword to specify that an output filename is expected next. | +| GWE | UZE | OPTIONS | BUDGETFILE | STRING | name of the binary output file to write budget information. | +| GWE | UZE | OPTIONS | BUDGETCSV | KEYWORD | keyword to specify that record corresponds to the budget CSV. | +| GWE | UZE | OPTIONS | BUDGETCSVFILE | STRING | name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. | +| GWE | UZE | OPTIONS | TS6 | KEYWORD | keyword to specify that record corresponds to a time-series file. | +| GWE | UZE | OPTIONS | FILEIN | KEYWORD | keyword to specify that an input filename is expected next. | +| GWE | UZE | OPTIONS | TS6_FILENAME | STRING | defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. | +| GWE | UZE | OPTIONS | OBS6 | KEYWORD | keyword to specify that record corresponds to an observations file. | +| GWE | UZE | OPTIONS | OBS6_FILENAME | STRING | name of input file to define observations for the UZE package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the UZE package. | +| GWE | UZE | PACKAGEDATA | UZFNO | INTEGER | integer value that defines the UZF cell number associated with the specified PACKAGEDATA data on the line. UZFNO must be greater than zero and less than or equal to NUZFCELLS. Unsaturated zone flow information must be specified for every UZF cell or the program will terminate with an error. The program also will terminate with an error if information for a UZF cell is specified more than once. | +| GWE | UZE | PACKAGEDATA | STRT | DOUBLE PRECISION | real value that defines the starting temperature for the unsaturated zone flow cell. | +| GWE | UZE | PACKAGEDATA | AUX | DOUBLE PRECISION (NAUX) | represents the values of the auxiliary variables for each unsaturated zone flow. The values of auxiliary variables must be present for each unsaturated zone flow. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | UZE | PACKAGEDATA | BOUNDNAME | STRING | name of the unsaturated zone flow cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. | +| GWE | UZE | PERIOD | IPER | INTEGER | integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. | +| GWE | UZE | PERIOD | UZFNO | INTEGER | integer value that defines the UZF cell number associated with the specified PERIOD data on the line. UZFNO must be greater than zero and less than or equal to NUZFCELLS. | +| GWE | UZE | PERIOD | UZESETTING | KEYSTRING | line of information that is parsed into a keyword and values. Keyword values that can be used to start the UZESETTING string include: STATUS, TEMPERATURE, INFILTRATION, UZET, and AUXILIARY. These settings are used to assign the temperature associated with the corresponding flow terms. Temperatures cannot be specified for all flow terms. | +| GWE | UZE | PERIOD | STATUS | STRING | keyword option to define UZF cell status. STATUS can be ACTIVE, INACTIVE, or CONSTANT. By default, STATUS is ACTIVE, which means that temperature will be calculated for the UZF cell. If a UZF cell is inactive, then there will be no energy fluxes into or out of the UZF cell and the inactive value will be written for the UZF cell temperature. If a UZF cell is constant, then the temperature for the UZF cell will be fixed at the user specified value. | +| GWE | UZE | PERIOD | TEMPERATURE | STRING | real or character value that defines the temperature for the unsaturated zone flow cell. The specified TEMPERATURE is only applied if the unsaturated zone flow cell is a constant temperature cell. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | UZE | PERIOD | INFILTRATION | STRING | real or character value that defines the temperature of the infiltration $(^\circ C)$ for the UZF cell. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | UZE | PERIOD | UZET | STRING | real or character value that states what fraction of the simulated unsaturated zone evapotranspiration is associated with evaporation. The evaporative losses from the unsaturated zone moisture content will have an evaporative cooling effect on the GWE cell from which the evaporation originated. If this value is larger than 1, then it will be reset to 1. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | +| GWE | UZE | PERIOD | AUXILIARY | KEYWORD | keyword for specifying auxiliary variable. | +| GWE | UZE | PERIOD | AUXNAME | STRING | name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. | +| GWE | UZE | PERIOD | AUXVAL | DOUBLE PRECISION | value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value. | | GWE | FMI | OPTIONS | SAVE_FLOWS | KEYWORD | keyword to indicate that FMI flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. | | GWE | FMI | OPTIONS | FLOW_IMBALANCE_CORRECTION | KEYWORD | correct for an imbalance in flows by assuming that any residual flow error comes in or leaves at the temperature of the cell. When this option is activated, the GWE Model budget written to the listing file will contain two additional entries: FLOW-ERROR and FLOW-CORRECTION. These two entries will be equal but opposite in sign. The FLOW-CORRECTION term is a mass flow that is added to offset the error caused by an imprecise flow balance. If these terms are not relatively small, the flow model should be rerun with stricter convergence tolerances. | | GWE | FMI | PACKAGEDATA | FLOWTYPE | STRING | is the word GWFBUDGET, GWFHEAD, GWFMOVER or the name of an advanced GWF stress package. If GWFBUDGET is specified, then the corresponding file must be a budget file from a previous GWF Model run. If an advanced GWF stress package name appears then the corresponding file must be the budget file saved by a LAK, SFR, MAW or UZF Package. | diff --git a/doc/mf6io/mf6ivar/mf6ivar.py b/doc/mf6io/mf6ivar/mf6ivar.py index 1170f4a7428..a968c2c0ff0 100644 --- a/doc/mf6io/mf6ivar/mf6ivar.py +++ b/doc/mf6io/mf6ivar/mf6ivar.py @@ -754,6 +754,7 @@ def write_appendix(texdir, allblocks): "gwe-oc", "gwe-ssm", "gwe-sfe", + "gwe-uze", "gwe-fmi", "utl-spc", "utl-spca", diff --git a/doc/mf6io/mf6ivar/tex/appendixA.tex b/doc/mf6io/mf6ivar/tex/appendixA.tex index cf214f3156f..b9581283c5e 100644 --- a/doc/mf6io/mf6ivar/tex/appendixA.tex +++ b/doc/mf6io/mf6ivar/tex/appendixA.tex @@ -302,6 +302,10 @@ GWE & SFE & PACKAGEDATA & yes \\ GWE & SFE & PERIOD & yes \\ \hline +GWE & UZE & OPTIONS & yes \\ +GWE & UZE & PACKAGEDATA & yes \\ +GWE & UZE & PERIOD & yes \\ +\hline GWE & FMI & OPTIONS & yes \\ GWE & FMI & PACKAGEDATA & yes \\ \hline diff --git a/doc/mf6io/mf6ivar/tex/gwe-uze-desc.tex b/doc/mf6io/mf6ivar/tex/gwe-uze-desc.tex new file mode 100644 index 00000000000..791b8dd9404 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-uze-desc.tex @@ -0,0 +1,91 @@ +% DO NOT MODIFY THIS FILE DIRECTLY. IT IS CREATED BY mf6ivar.py + +\item \textbf{Block: OPTIONS} + +\begin{description} +\item \texttt{flow\_package\_name}---keyword to specify the name of the corresponding flow package. If not specified, then the corresponding flow package must have the same name as this advanced transport package (the name associated with this package in the GWE name file). + +\item \texttt{auxiliary}---defines an array of one or more auxiliary variable names. There is no limit on the number of auxiliary variables that can be provided on this line; however, lists of information provided in subsequent blocks must have a column of data for each auxiliary variable name defined here. The number of auxiliary variables detected on this line determines the value for naux. Comments cannot be provided anywhere on this line as they will be interpreted as auxiliary variable names. Auxiliary variables may not be used by the package, but they will be available for use by other parts of the program. The program will terminate with an error if auxiliary variables are specified on more than one line in the options block. + +\item \texttt{flow\_package\_auxiliary\_name}---keyword to specify the name of an auxiliary variable in the corresponding flow package. If specified, then the simulated concentrations from this advanced transport package will be copied into the auxiliary variable specified with this name. Note that the flow package must have an auxiliary variable with this name or the program will terminate with an error. If the flows for this advanced transport package are read from a file, then this option will have no effect. + +\item \texttt{BOUNDNAMES}---keyword to indicate that boundary names may be provided with the list of unsaturated zone flow cells. + +\item \texttt{PRINT\_INPUT}---keyword to indicate that the list of unsaturated zone flow information will be written to the listing file immediately after it is read. + +\item \texttt{PRINT\_TEMPERATURE}---keyword to indicate that the list of UZF cell temperatures will be printed to the listing file for every stress period in which ``TEMPERATURE PRINT'' is specified in Output Control. If there is no Output Control option and PRINT\_TEMPERATURE is specified, then temperatures are printed for the last time step of each stress period. + +\item \texttt{PRINT\_FLOWS}---keyword to indicate that the list of unsaturated zone flow rates will be printed to the listing file for every stress period time step in which ``BUDGET PRINT'' is specified in Output Control. If there is no Output Control option and ``PRINT\_FLOWS'' is specified, then flow rates are printed for the last time step of each stress period. + +\item \texttt{SAVE\_FLOWS}---keyword to indicate that unsaturated zone flow terms will be written to the file specified with ``BUDGET FILEOUT'' in Output Control. + +\item \texttt{TEMPERATURE}---keyword to specify that record corresponds to temperature. + +\item \texttt{tempfile}---name of the binary output file to write temperature information. + +\item \texttt{BUDGET}---keyword to specify that record corresponds to the budget. + +\item \texttt{FILEOUT}---keyword to specify that an output filename is expected next. + +\item \texttt{budgetfile}---name of the binary output file to write budget information. + +\item \texttt{BUDGETCSV}---keyword to specify that record corresponds to the budget CSV. + +\item \texttt{budgetcsvfile}---name of the comma-separated value (CSV) output file to write budget summary information. A budget summary record will be written to this file for each time step of the simulation. + +\item \texttt{TS6}---keyword to specify that record corresponds to a time-series file. + +\item \texttt{FILEIN}---keyword to specify that an input filename is expected next. + +\item \texttt{ts6\_filename}---defines a time-series file defining time series that can be used to assign time-varying values. See the ``Time-Variable Input'' section for instructions on using the time-series capability. + +\item \texttt{OBS6}---keyword to specify that record corresponds to an observations file. + +\item \texttt{obs6\_filename}---name of input file to define observations for the UZE package. See the ``Observation utility'' section for instructions for preparing observation input files. Tables \ref{table:gwf-obstypetable} and \ref{table:gwt-obstypetable} lists observation type(s) supported by the UZE package. + +\end{description} +\item \textbf{Block: PACKAGEDATA} + +\begin{description} +\item \texttt{uzfno}---integer value that defines the UZF cell number associated with the specified PACKAGEDATA data on the line. UZFNO must be greater than zero and less than or equal to NUZFCELLS. Unsaturated zone flow information must be specified for every UZF cell or the program will terminate with an error. The program also will terminate with an error if information for a UZF cell is specified more than once. + +\item \texttt{strt}---real value that defines the starting temperature for the unsaturated zone flow cell. + +\item \textcolor{blue}{\texttt{aux}---represents the values of the auxiliary variables for each unsaturated zone flow. The values of auxiliary variables must be present for each unsaturated zone flow. The values must be specified in the order of the auxiliary variables specified in the OPTIONS block. If the package supports time series and the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \texttt{boundname}---name of the unsaturated zone flow cell. BOUNDNAME is an ASCII character variable that can contain as many as 40 characters. If BOUNDNAME contains spaces in it, then the entire name must be enclosed within single quotes. + +\end{description} +\item \textbf{Block: PERIOD} + +\begin{description} +\item \texttt{iper}---integer value specifying the starting stress period number for which the data specified in the PERIOD block apply. IPER must be less than or equal to NPER in the TDIS Package and greater than zero. The IPER value assigned to a stress period block must be greater than the IPER value assigned for the previous PERIOD block. The information specified in the PERIOD block will continue to apply for all subsequent stress periods, unless the program encounters another PERIOD block. + +\item \texttt{uzfno}---integer value that defines the UZF cell number associated with the specified PERIOD data on the line. UZFNO must be greater than zero and less than or equal to NUZFCELLS. + +\item \texttt{uzesetting}---line of information that is parsed into a keyword and values. Keyword values that can be used to start the UZESETTING string include: STATUS, TEMPERATURE, INFILTRATION, UZET, and AUXILIARY. These settings are used to assign the temperature associated with the corresponding flow terms. Temperatures cannot be specified for all flow terms. + +\begin{lstlisting}[style=blockdefinition] +STATUS +TEMPERATURE <@temperature@> +INFILTRATION <@infiltration@> +UZET <@uzet@> +AUXILIARY <@auxval@> +\end{lstlisting} + +\item \texttt{status}---keyword option to define UZF cell status. STATUS can be ACTIVE, INACTIVE, or CONSTANT. By default, STATUS is ACTIVE, which means that temperature will be calculated for the UZF cell. If a UZF cell is inactive, then there will be no energy fluxes into or out of the UZF cell and the inactive value will be written for the UZF cell temperature. If a UZF cell is constant, then the temperature for the UZF cell will be fixed at the user specified value. + +\item \textcolor{blue}{\texttt{temperature}---real or character value that defines the temperature for the unsaturated zone flow cell. The specified TEMPERATURE is only applied if the unsaturated zone flow cell is a constant temperature cell. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{infiltration}---real or character value that defines the temperature of the infiltration $(^\circ C)$ for the UZF cell. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \textcolor{blue}{\texttt{uzet}---real or character value that states what fraction of the simulated unsaturated zone evapotranspiration is associated with evaporation. The evaporative losses from the unsaturated zone moisture content will have an evaporative cooling effect on the GWE cell from which the evaporation originated. If this value is larger than 1, then it will be reset to 1. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\item \texttt{AUXILIARY}---keyword for specifying auxiliary variable. + +\item \texttt{auxname}---name for the auxiliary variable to be assigned AUXVAL. AUXNAME must match one of the auxiliary variable names defined in the OPTIONS block. If AUXNAME does not match one of the auxiliary variable names defined in the OPTIONS block the data are ignored. + +\item \textcolor{blue}{\texttt{auxval}---value for the auxiliary variable. If the Options block includes a TIMESERIESFILE entry (see the ``Time-Variable Input'' section), values can be obtained from a time series by entering the time-series name in place of a numeric value.} + +\end{description} + diff --git a/doc/mf6io/mf6ivar/tex/gwe-uze-options.dat b/doc/mf6io/mf6ivar/tex/gwe-uze-options.dat new file mode 100644 index 00000000000..ef83c7fa718 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-uze-options.dat @@ -0,0 +1,15 @@ +BEGIN OPTIONS + [FLOW_PACKAGE_NAME ] + [AUXILIARY ] + [FLOW_PACKAGE_AUXILIARY_NAME ] + [BOUNDNAMES] + [PRINT_INPUT] + [PRINT_TEMPERATURE] + [PRINT_FLOWS] + [SAVE_FLOWS] + [TEMPERATURE FILEOUT ] + [BUDGET FILEOUT ] + [BUDGETCSV FILEOUT ] + [TS6 FILEIN ] + [OBS6 FILEIN ] +END OPTIONS diff --git a/doc/mf6io/mf6ivar/tex/gwe-uze-packagedata.dat b/doc/mf6io/mf6ivar/tex/gwe-uze-packagedata.dat new file mode 100644 index 00000000000..b6b04c298fe --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-uze-packagedata.dat @@ -0,0 +1,5 @@ +BEGIN PACKAGEDATA + [<@aux(naux)@>] [] + [<@aux(naux)@>] [] + ... +END PACKAGEDATA diff --git a/doc/mf6io/mf6ivar/tex/gwe-uze-period.dat b/doc/mf6io/mf6ivar/tex/gwe-uze-period.dat new file mode 100644 index 00000000000..b06edb21028 --- /dev/null +++ b/doc/mf6io/mf6ivar/tex/gwe-uze-period.dat @@ -0,0 +1,5 @@ +BEGIN PERIOD + + + ... +END PERIOD diff --git a/make/makefile b/make/makefile index 99010bb3e1a..d7d5d3cef71 100644 --- a/make/makefile +++ b/make/makefile @@ -280,6 +280,7 @@ $(OBJDIR)/gwf3buy8.o \ $(OBJDIR)/GhostNode.o \ $(OBJDIR)/gwf3evt8.o \ $(OBJDIR)/gwf3chd8.o \ +$(OBJDIR)/gwe1uze1.o \ $(OBJDIR)/gwe1sfe1.o \ $(OBJDIR)/gwe1mwe1.o \ $(OBJDIR)/gwe1lke1.o \ diff --git a/msvs/mf6core.vfproj b/msvs/mf6core.vfproj index afc7f577759..b9cbf1a7366 100644 --- a/msvs/mf6core.vfproj +++ b/msvs/mf6core.vfproj @@ -154,7 +154,8 @@ - + + diff --git a/src/Model/GroundWaterEnergy/gwe1.f90 b/src/Model/GroundWaterEnergy/gwe1.f90 index dd5536dba78..fafde6d3101 100644 --- a/src/Model/GroundWaterEnergy/gwe1.f90 +++ b/src/Model/GroundWaterEnergy/gwe1.f90 @@ -765,7 +765,7 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & use GweLkeModule, only: lke_create use GweSfeModule, only: sfe_create use GweMweModule, only: mwe_create - !use GweUzeModule, only: uze_create + use GweUzeModule, only: uze_create use ApiModule, only: api_create ! -- dummy class(GweModelType) :: this @@ -802,10 +802,10 @@ subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, & call mwe_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & pakname, this%fmi, this%eqnsclfac, this%gwecommon, & this%depvartype, this%depvarunit, this%depvarunitabbrev) - !case ('UZE6') - ! call uze_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & - ! pakname, this%fmi, this%tsplab, this%eqnsclfac, & - ! this%gwecommon) + case ('UZE6') + call uze_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & + pakname, this%fmi, this%eqnsclfac, this%gwecommon, & + this%depvartype, this%depvarunit, this%depvarunitabbrev) !case('API6') ! call api_create(packobj, ipakid, ipaknum, inunit, iout, this%name, & ! pakname) diff --git a/src/Model/GroundWaterEnergy/gwe1uze1.f90 b/src/Model/GroundWaterEnergy/gwe1uze1.f90 new file mode 100644 index 00000000000..64231abc2ff --- /dev/null +++ b/src/Model/GroundWaterEnergy/gwe1uze1.f90 @@ -0,0 +1,1395 @@ +! -- Unsaturated Zone Flow Energy Transport Module +! -- todo: save the uze temperature into the uze aux variable? +! -- todo: calculate the uzf DENSE aux variable using temperature? +! -- todo: GWD and GWD-TO-MVR do not seem to be included; prob in UZF? +! +! UZF flows (flowbudptr) index var UZE term Transport Type +!--------------------------------------------------------------------------------- + +! -- terms from UZF that will be handled by parent APT Package +! FLOW-JA-FACE idxbudfjf FLOW-JA-FACE cv2cv +! GWF (aux FLOW-AREA) idxbudgwf GWF uzf2gwf +! STORAGE (aux VOLUME) idxbudsto none used for water volumes +! FROM-MVR idxbudfmvr FROM-MVR q * cext = this%qfrommvr(:) +! AUXILIARY none none none +! none none STORAGE (aux MASS) +! none none AUXILIARY none + +! -- terms from UZF that need to be handled here +! INFILTRATION idxbudinfl INFILTRATION q < 0: q * cwell, else q * cuser +! REJ-INF idxbudrinf REJ-INF q * cuze +! UZET idxbuduzet UZET q * cet +! REJ-INF-TO-MVR idxbudritm REJ-INF-TO-MVR q * cinfil? +! THERMAL-EQUIL idxbudtheq THERMAL-EQUIL residual + +! -- terms from UZF that should be skipped + +module GweUzeModule + + use KindModule, only: DP, I4B + use ConstantsModule, only: DZERO, DONE, LINELENGTH + use SimModule, only: store_error + use BndModule, only: BndType, GetBndFromList + use TspFmiModule, only: TspFmiType + use UzfModule, only: UzfType + use ObserveModule, only: ObserveType + use TspAptModule, only: TspAptType, apt_process_obsID, & + apt_process_obsID12 + use GweInputDataModule, only: GweInputDataType + use MatrixBaseModule + + implicit none + + public uze_create + + character(len=*), parameter :: ftype = 'UZE' + character(len=*), parameter :: flowtype = 'UZF' + character(len=16) :: text = ' UZE' + + type, extends(TspAptType) :: GweUzeType + + type(GweInputDataType), pointer :: gwecommon => null() !< pointer to shared gwe data used by multiple packages but set in mst + + integer(I4B), pointer :: idxbudinfl => null() !< index of uzf infiltration terms in flowbudptr + integer(I4B), pointer :: idxbudrinf => null() !< index of rejected infiltration terms in flowbudptr + integer(I4B), pointer :: idxbuduzet => null() !< index of unsat et terms in flowbudptr + integer(I4B), pointer :: idxbudritm => null() !< index of rej infil to mover rate to mover terms in flowbudptr + integer(I4B), pointer :: idxbudtheq => null() !< index of thermal equilibration terms in flowbudptr + + real(DP), dimension(:), pointer, contiguous :: tempinfl => null() !< infiltration temperature + real(DP), dimension(:), pointer, contiguous :: tempuzet => null() !< unsat et temperature + + contains + + procedure :: bnd_da => uze_da + procedure :: allocate_scalars + procedure :: apt_allocate_arrays => uze_allocate_arrays + procedure :: find_apt_package => find_uze_package + procedure :: apt_fc_expanded => uze_fc_expanded + procedure :: pak_solve => uze_solve + procedure :: pak_get_nbudterms => uze_get_nbudterms + procedure :: pak_setup_budobj => uze_setup_budobj + procedure :: pak_fill_budobj => uze_fill_budobj + procedure :: uze_infl_term + procedure :: uze_rinf_term + procedure :: uze_uzet_term + procedure :: uze_ritm_term + procedure :: uze_theq_term + procedure :: pak_df_obs => uze_df_obs + procedure :: pak_rp_obs => uze_rp_obs + procedure :: pak_bd_obs => uze_bd_obs + procedure :: pak_set_stressperiod => uze_set_stressperiod + procedure :: bnd_ac => uze_ac + procedure :: bnd_mc => uze_mc + + end type GweUzeType + +contains + + !> @breif Create a new UZE package + !< + subroutine uze_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, & + fmi, eqnsclfac, gwecommon, dvt, dvu, dvua) + ! -- dummy + class(BndType), pointer :: packobj + integer(I4B), intent(in) :: id + integer(I4B), intent(in) :: ibcnum + integer(I4B), intent(in) :: inunit + integer(I4B), intent(in) :: iout + character(len=*), intent(in) :: namemodel + character(len=*), intent(in) :: pakname + type(TspFmiType), pointer :: fmi + real(DP), intent(in), pointer :: eqnsclfac !< governing equation scale factor + type(GweInputDataType), intent(in), target :: gwecommon !< shared data container for use by multiple GWE packages + character(len=*), intent(in) :: dvt !< For GWE, set to "TEMPERATURE" in TspAptType + character(len=*), intent(in) :: dvu !< For GWE, set to "energy" in TspAptType + character(len=*), intent(in) :: dvua !< For GWE, set to "E" in TspAptType + ! -- local + type(GweUzeType), pointer :: uzeobj + ! + ! -- Allocate the object and assign values to object variables + allocate (uzeobj) + packobj => uzeobj + ! + ! -- Create name and memory path + call packobj%set_names(ibcnum, namemodel, pakname, ftype) + packobj%text = text + ! + ! -- Allocate scalars + call uzeobj%allocate_scalars() + ! + ! -- Initialize package + call packobj%pack_initialize() + ! + packobj%inunit = inunit + packobj%iout = iout + packobj%id = id + packobj%ibcnum = ibcnum + packobj%ncolbnd = 1 + packobj%iscloc = 1 + + ! -- Store pointer to flow model interface. When the GwfGwt exchange is + ! created, it sets fmi%bndlist so that the GWT model has access to all + ! the flow packages + uzeobj%fmi => fmi + ! + ! -- Store pointer to governing equation scale factor + uzeobj%eqnsclfac => eqnsclfac + ! + ! -- Store pointer to shared data module for accessing cpw, rhow + ! for the budget calculations, and for accessing the latent heat of + ! vaporization + uzeobj%gwecommon => gwecommon + ! + ! -- Set labels that will be used in generalized APT class + uzeobj%depvartype = dvt + uzeobj%depvarunit = dvu + uzeobj%depvarunitabbrev = dvua + ! + ! -- Return + return + end subroutine uze_create + + !> @brief Find corresponding uze package + !< + subroutine find_uze_package(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweUzeType) :: this + ! -- local + character(len=LINELENGTH) :: errmsg + class(BndType), pointer :: packobj + integer(I4B) :: ip, icount + integer(I4B) :: nbudterm + logical :: found + ! + ! -- Initialize found to false, and error later if flow package cannot + ! be found + found = .false. + ! + ! -- If user is specifying flows in a binary budget file, then set up + ! the budget file reader, otherwise set a pointer to the flow package + ! budobj + if (this%fmi%flows_from_file) then + call this%fmi%set_aptbudobj_pointer(this%flowpackagename, this%flowbudptr) + if (associated(this%flowbudptr)) found = .true. + ! + else + if (associated(this%fmi%gwfbndlist)) then + ! -- Look through gwfbndlist for a flow package with the same name as + ! this transport package name + do ip = 1, this%fmi%gwfbndlist%Count() + packobj => GetBndFromList(this%fmi%gwfbndlist, ip) + if (packobj%packName == this%flowpackagename) then + found = .true. + ! + ! -- Store BndType pointer to packobj, and then + ! use the select type to point to the budobj in flow package + this%flowpackagebnd => packobj + select type (packobj) + type is (UzfType) + this%flowbudptr => packobj%budobj + end select + end if + if (found) exit + end do + end if + end if + ! + ! -- Error if flow package not found + if (.not. found) then + write (errmsg, '(a)') 'COULD NOT FIND FLOW PACKAGE WITH NAME '& + &//trim(adjustl(this%flowpackagename))//'.' + call store_error(errmsg) + call this%parser%StoreErrorUnit() + end if + ! + ! -- Allocate space for idxbudssm, which indicates whether this is a + ! special budget term or one that is a general source and sink + nbudterm = this%flowbudptr%nbudterm + call mem_allocate(this%idxbudssm, nbudterm, 'IDXBUDSSM', this%memoryPath) + ! + ! -- Process budget terms and identify special budget terms + write (this%iout, '(/, a, a)') & + 'PROCESSING '//ftype//' INFORMATION FOR ', this%packName + write (this%iout, '(a)') ' IDENTIFYING FLOW TERMS IN '//flowtype//' PACKAGE' + write (this%iout, '(a, i0)') & + ' NUMBER OF '//flowtype//' = ', this%flowbudptr%ncv + icount = 1 + do ip = 1, this%flowbudptr%nbudterm + select case (trim(adjustl(this%flowbudptr%budterm(ip)%flowtype))) + case ('FLOW-JA-FACE') + this%idxbudfjf = ip + this%idxbudssm(ip) = 0 + case ('GWF') + this%idxbudgwf = ip + this%idxbudssm(ip) = 0 + case ('STORAGE') + this%idxbudsto = ip + this%idxbudssm(ip) = 0 + case ('INFILTRATION') + this%idxbudinfl = ip + this%idxbudssm(ip) = 0 + case ('REJ-INF') + this%idxbudrinf = ip + this%idxbudssm(ip) = 0 + case ('UZET') + this%idxbuduzet = ip + this%idxbudssm(ip) = 0 + case ('REJ-INF-TO-MVR') + this%idxbudritm = ip + this%idxbudssm(ip) = 0 + case ('TO-MVR') + this%idxbudtmvr = ip + this%idxbudssm(ip) = 0 + case ('FROM-MVR') + this%idxbudfmvr = ip + this%idxbudssm(ip) = 0 + case ('AUXILIARY') + this%idxbudaux = ip + this%idxbudssm(ip) = 0 + case default + ! + ! -- Set idxbudssm equal to a column index for where the temperatures + ! are stored in the tempbud(nbudssm, ncv) array + this%idxbudssm(ip) = icount + icount = icount + 1 + end select + ! + write (this%iout, '(a, i0, " = ", a,/, a, i0)') & + ' TERM ', ip, trim(adjustl(this%flowbudptr%budterm(ip)%flowtype)), & + ' MAX NO. OF ENTRIES = ', this%flowbudptr%budterm(ip)%maxlist + end do + write (this%iout, '(a, //)') 'DONE PROCESSING '//ftype//' INFORMATION' + ! + ! -- Thermal equilibration term + this%idxbudtheq = this%flowbudptr%nbudterm + 1 + ! + ! -- Return + return + end subroutine find_uze_package + + !> @brief Add package connection to matrix. + !! + !! Overrides apt_ac to fold the UZE heat balance terms into the row + !! corresponding to the host cell and enforce thermal equilibrium between + !! UZE and the GWE cell. + !< + subroutine uze_ac(this, moffset, sparse) + use MemoryManagerModule, only: mem_setptr + use SparseModule, only: sparsematrix + ! -- dummy + class(GweUzeType), intent(inout) :: this + integer(I4B), intent(in) :: moffset !< current models starting position in global matrix + type(sparsematrix), intent(inout) :: sparse + ! -- local + integer(I4B) :: i, ii + integer(I4B) :: n !< index of a uze object within the complete list of uze objects + integer(I4B) :: jj !< + integer(I4B) :: nglo !< index of uze object in global matrix + integer(I4B) :: jglo !< host cell's position in global matrix for a uze object + integer(I4B) :: idxn !< used for cross-check + integer(I4B) :: idxjj !< used for cross-check + integer(I4B) :: idxnglo !< used for cross-check + integer(I4B) :: idxjglo !< used for cross-check + ! + ! -- Add package rows to sparse + if (this%imatrows /= 0) then + ! + ! -- Diagonal on the row assoc. with the uze feature + do n = 1, this%ncv + nglo = moffset + this%dis%nodes + this%ioffset + n + call sparse%addconnection(nglo, nglo, 1) + end do + ! + ! -- Add uze-to-gwe connections. For uze, this particular do loop + ! is the same as its counterpart in apt_ac. + ! nlist: number of gwe cells with a connection to at least one uze object + do i = 1, this%flowbudptr%budterm(this%idxbudgwf)%nlist + n = this%flowbudptr%budterm(this%idxbudgwf)%id1(i) !< uze object position within uze object list + jj = this%flowbudptr%budterm(this%idxbudgwf)%id2(i) !< position of gwe cell to which uze feature is connected + nglo = moffset + this%dis%nodes + this%ioffset + n !< uze feature position + jglo = moffset + jj !< gwe cell position + call sparse%addconnection(nglo, jglo, 1) + call sparse%addconnection(jglo, nglo, 1) + end do + ! + ! -- For uze, add feature-to-feature connections (i.e., + ! vertically stacked UZ objects) to row corresponding + ! to the host cell. Terms added to the row associated with host + ! cell are added to columns associated with other uze features. + ! This approach deviates from the approach taken in apt_ac. + if (this%idxbudfjf /= 0) then + do i = 1, this%flowbudptr%budterm(this%idxbudfjf)%maxlist + n = this%flowbudptr%budterm(this%idxbudfjf)%id1(i) !< position of currently considered uze feature + jj = this%flowbudptr%budterm(this%idxbudfjf)%id2(i) !< position of connected uze feature + nglo = moffset + this%dis%nodes + this%ioffset + n !< global position of currently considered uze feature + jglo = moffset + this%dis%nodes + this%ioffset + jj !< global position of connected uze feature + ! -- If connected uze feature is upstream, find cell that hosts currently + ! considered uze feature and add connection to that cell's row + do ii = 1, this%flowbudptr%budterm(this%idxbudgwf)%nlist !< uze object id among uze objects + idxn = this%flowbudptr%budterm(this%idxbudgwf)%id1(ii) !< uze object position within uze object list + idxjj = this%flowbudptr%budterm(this%idxbudgwf)%id2(ii) !< position of gwe cell to which uze feature is connected + idxnglo = moffset + this%dis%nodes + this%ioffset + idxn !< uze feature global position + idxjglo = moffset + idxjj !< gwe cell global position + if (nglo == idxnglo) exit + end do + call sparse%addconnection(idxjglo, jglo, 1) + end do + end if + end if + ! + ! -- Return + return + end subroutine uze_ac + + !> @brief Map package connection to matrix + !< + subroutine uze_mc(this, moffset, matrix_sln) + use SparseModule, only: sparsematrix + ! -- dummy + class(GweUzeType), intent(inout) :: this + integer(I4B), intent(in) :: moffset + class(MatrixBaseType), pointer :: matrix_sln + ! -- local + integer(I4B) :: n, j, iglo, jglo + integer(I4B) :: idxn, idxj, idxiglo, idxjglo + integer(I4B) :: ipos, idxpos + ! + ! -- Allocate memory for index arrays + call this%apt_allocate_index_arrays() + ! + ! -- Store index positions + if (this%imatrows /= 0) then + ! + ! -- Find the position of each connection in the global ia, ja structure + ! and store them in idxglo. idxglo allows this model to insert or + ! retrieve values into or from the global A matrix + ! apt rows + ! + ! -- Feature diagonal in global matrix + do n = 1, this%ncv + iglo = moffset + this%dis%nodes + this%ioffset + n + this%idxpakdiag(n) = matrix_sln%get_position_diag(iglo) + end do + ! + ! -- Cell to feature connection in global matrix + do ipos = 1, this%flowbudptr%budterm(this%idxbudgwf)%nlist + n = this%flowbudptr%budterm(this%idxbudgwf)%id1(ipos) !< feature number + j = this%flowbudptr%budterm(this%idxbudgwf)%id2(ipos) !< cell number + iglo = moffset + this%dis%nodes + this%ioffset + n !< feature row index + jglo = j + moffset !< cell row index + ! -- Note that this is where idxlocnode is set for uze; it is set + ! to the host cell local row index rather than the feature local + ! row index + this%idxlocnode(n) = j ! kluge note: do we want to introduce a new array instead of co-opting idxlocnode??? + ! -- For connection ipos in list of feature-cell connections, + ! global positions of feature-row diagonal and off-diagonal + ! corresponding to the cell + this%idxdglo(ipos) = matrix_sln%get_position_diag(iglo) + this%idxoffdglo(ipos) = matrix_sln%get_position(iglo, jglo) + end do + ! + ! -- Feature to cell connection in global matrix + do ipos = 1, this%flowbudptr%budterm(this%idxbudgwf)%nlist + n = this%flowbudptr%budterm(this%idxbudgwf)%id1(ipos) !< feature number + j = this%flowbudptr%budterm(this%idxbudgwf)%id2(ipos) !< cell number + iglo = j + moffset !< cell row index + jglo = moffset + this%dis%nodes + this%ioffset + n !< feature row index + ! -- For connection ipos in list of feature-cell connections, + ! global positions of cell-row diagonal and off-diagonal + ! corresponding to the feature + this%idxsymdglo(ipos) = matrix_sln%get_position_diag(iglo) + this%idxsymoffdglo(ipos) = matrix_sln%get_position(iglo, jglo) + end do + ! + ! -- Feature to feature connection in global matrix + if (this%idxbudfjf /= 0) then + do ipos = 1, this%flowbudptr%budterm(this%idxbudfjf)%nlist + n = this%flowbudptr%budterm(this%idxbudfjf)%id1(ipos) !< number of currently considered uze feature + j = this%flowbudptr%budterm(this%idxbudfjf)%id2(ipos) !< number of connected uze feature + iglo = moffset + this%dis%nodes + this%ioffset + n !< global position of currently considered uze feature + jglo = moffset + this%dis%nodes + this%ioffset + j !< global position of connected uze feature + ! -- If connected uze feature is upstream, find cell that hosts currently + ! considered uze feature and map connection to that cell's row + do idxpos = 1, this%flowbudptr%budterm(this%idxbudgwf)%nlist + idxn = this%flowbudptr%budterm(this%idxbudgwf)%id1(idxpos) !< feature number + idxj = this%flowbudptr%budterm(this%idxbudgwf)%id2(idxpos) !< cell number) + idxjglo = moffset + this%dis%nodes + this%ioffset + idxn !< feature row index + idxiglo = moffset + idxj !< cell row index + if (idxjglo == iglo) exit + end do + ! -- For connection ipos in list of feature-feature connections, + ! global positions of host-cell-row entries corresponding to + ! (in the same columns as) the feature-id1-row diagonal and the + ! feature-id1-row off-diagonal corresponding to feature id2 + this%idxfjfdglo(ipos) = matrix_sln%get_position_diag(idxiglo) + this%idxfjfoffdglo(ipos) = matrix_sln%get_position(idxiglo, jglo) + end do + end if + end if + ! + ! -- Return + return + end subroutine uze_mc + + !> @brief Add matrix terms related to UZE + !! + !! This will be called from TspAptType%apt_fc_expanded() + !! in order to add matrix terms specifically for this package + !< + subroutine uze_fc_expanded(this, rhs, ia, idxglo, matrix_sln) + ! -- dummy + class(GweUzeType) :: this + real(DP), dimension(:), intent(inout) :: rhs + integer(I4B), dimension(:), intent(in) :: ia + integer(I4B), dimension(:), intent(in) :: idxglo + class(MatrixBaseType), pointer :: matrix_sln + ! -- local + integer(I4B) :: j, n, n1, n2 + integer(I4B) :: iloc + integer(I4B) :: iposd, iposoffd + integer(I4B) :: ipossymoffd + real(DP) :: cold + real(DP) :: qbnd + real(DP) :: omega + real(DP) :: rrate + real(DP) :: rhsval + real(DP) :: hcofval + ! + ! -- Add infiltration contribution + ! uze does not put feature balance coefficients in the row + ! associated with the feature. Instead, these coefficients are + ! moved into the row associated with cell hosting the uze feature + if (this%idxbudinfl /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudinfl)%nlist + call this%uze_infl_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) !< for uze idxlocnode stores the host cell local row index + ipossymoffd = this%idxsymoffdglo(j) + call matrix_sln%add_value_pos(ipossymoffd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add rejected infiltration contribution + if (this%idxbudrinf /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudrinf)%nlist + call this%uze_rinf_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) ! for uze idxlocnode stores the host cell local row index + ipossymoffd = this%idxsymoffdglo(j) + call matrix_sln%add_value_pos(ipossymoffd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add unsaturated et contribution + if (this%idxbuduzet /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbuduzet)%nlist + call this%uze_uzet_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) ! for uze idxlocnode stores the host cell local row index + ipossymoffd = this%idxsymoffdglo(j) + call matrix_sln%add_value_pos(ipossymoffd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add rejected infiltration to mover contribution + if (this%idxbudritm /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudritm)%nlist + call this%uze_ritm_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) ! for uze idxlocnode stores the host cell local row index + ipossymoffd = this%idxsymoffdglo(j) + call matrix_sln%add_value_pos(ipossymoffd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- For UZE, content of apt_fc_expanded placed here as the approach is to + ! completely override apt_fc_expanded() with what follows + ! + ! -- Mass (or energy) storage in features + do n = 1, this%ncv + cold = this%xoldpak(n) + iloc = this%idxlocnode(n) ! for uze idxlocnode stores the host cell local row index + ipossymoffd = this%idxsymoffdglo(n) + call this%apt_stor_term(n, n1, n2, rrate, rhsval, hcofval) + call matrix_sln%add_value_pos(ipossymoffd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + ! + ! -- Add to mover contribution + if (this%idxbudtmvr /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudtmvr)%nlist + call this%apt_tmvr_term(j, n1, n2, rrate, rhsval, hcofval) + iloc = this%idxlocnode(n1) ! for uze, idxlocnode stores the host cell local row index + ipossymoffd = this%idxsymoffdglo(j) + call matrix_sln%add_value_pos(ipossymoffd, hcofval) + rhs(iloc) = rhs(iloc) + rhsval + end do + end if + ! + ! -- Add from mover contribution + if (this%idxbudfmvr /= 0) then + do n = 1, this%ncv + rhsval = this%qmfrommvr(n) ! kluge note: presumably already in terms of energy + iloc = this%idxlocnode(n) ! for uze idxlocnode stores the host cell local row index + rhs(iloc) = rhs(iloc) - rhsval + end do + end if + ! + ! -- Go through each apt-gwf connection + do j = 1, this%flowbudptr%budterm(this%idxbudgwf)%nlist + ! + ! -- Set n to feature number and process if active feature + n = this%flowbudptr%budterm(this%idxbudgwf)%id1(j) + if (this%iboundpak(n) /= 0) then + ! + ! -- This code altered from its counterpart appearing in apt; this equates + ! uze temperature to cell temperature using the feature's row + iposd = this%idxdglo(j) + iposoffd = this%idxoffdglo(j) + call matrix_sln%add_value_pos(iposd, DONE) + call matrix_sln%add_value_pos(iposoffd, -DONE) + end if + end do + ! + ! -- Go through each apt-apt connection + if (this%idxbudfjf /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudfjf)%nlist + n1 = this%flowbudptr%budterm(this%idxbudfjf)%id1(j) + n2 = this%flowbudptr%budterm(this%idxbudfjf)%id2(j) + qbnd = this%flowbudptr%budterm(this%idxbudfjf)%flow(j) + if (qbnd <= DZERO) then + omega = DONE + else + omega = DZERO + end if + iposd = this%idxfjfdglo(j) !< position of feature-id1 column in feature id1's host-cell row + iposoffd = this%idxfjfoffdglo(j) !< position of feature-id2 column in feature id1's host-cell row + call matrix_sln%add_value_pos(iposd, omega * qbnd * this%eqnsclfac) + call matrix_sln%add_value_pos(iposoffd, & + (DONE - omega) * qbnd * this%eqnsclfac) + end do + end if + ! + ! -- Return + return + end subroutine uze_fc_expanded + + !> @brief Explicit solve + !! + !! There should be no explicit solve for uze. However, if there were, then + !! this subroutine would add terms specific to the unsaturated zone to the + !! explicit unsaturated-zone solve + subroutine uze_solve(this) + ! -- dummy + class(GweUzeType) :: this + ! -- local + integer(I4B) :: j + integer(I4B) :: n1, n2 + real(DP) :: rrate + ! + ! -- Add infiltration contribution + if (this%idxbudinfl /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudinfl)%nlist + call this%uze_infl_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add rejected infiltration contribution + if (this%idxbudrinf /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudrinf)%nlist + call this%uze_rinf_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add unsaturated et contribution + if (this%idxbuduzet /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbuduzet)%nlist + call this%uze_uzet_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Add rejected infiltration to mover contribution + if (this%idxbudritm /= 0) then + do j = 1, this%flowbudptr%budterm(this%idxbudritm)%nlist + call this%uze_ritm_term(j, n1, n2, rrate) + this%dbuff(n1) = this%dbuff(n1) + rrate + end do + end if + ! + ! -- Return + return + end subroutine uze_solve + + !> @brief Return the number of UZE-specific budget terms + !! + !! Function to return the number of budget terms just for this package. + !! This overrides function in parent. + !< + function uze_get_nbudterms(this) result(nbudterms) + ! -- dummy + class(GweUzeType) :: this + ! -- Return + integer(I4B) :: nbudterms + ! + ! -- Number of budget terms is 5 + nbudterms = 0 + if (this%idxbudinfl /= 0) nbudterms = nbudterms + 1 + if (this%idxbudrinf /= 0) nbudterms = nbudterms + 1 + if (this%idxbuduzet /= 0) nbudterms = nbudterms + 1 + if (this%idxbudritm /= 0) nbudterms = nbudterms + 1 + if (this%idxbudtheq /= 0) nbudterms = nbudterms + 1 + ! + ! -- Return + return + end function uze_get_nbudterms + + !> @brief Setup budget object + !! + !! Set up the budget object that stores all the unsaturated-zone + !! flows + !< + subroutine uze_setup_budobj(this, idx) + ! -- modules + use ConstantsModule, only: LENBUDTXT + ! -- dummy + class(GweUzeType) :: this + integer(I4B), intent(inout) :: idx + ! -- local + integer(I4B) :: maxlist, naux + character(len=LENBUDTXT) :: text + ! + ! -- Infiltration + text = ' INFILTRATION' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudinfl)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- Rejected infiltration (Hortonian flow) + if (this%idxbudrinf /= 0) then + text = ' REJ-INF' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudrinf)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + end if + ! + ! -- Evapotranspiration from the unsaturated zone + if (this%idxbuduzet /= 0) then + text = ' UZET' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbuduzet)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + end if + ! + ! -- Rejected infiltration that is subsequently transferred by MVR + if (this%idxbudritm /= 0) then + text = ' INF-REJ-TO-MVR' + idx = idx + 1 + maxlist = this%flowbudptr%budterm(this%idxbudritm)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + end if + ! + ! -- Energy transferred to solid phase by the thermal equilibrium assumption + text = ' THERMAL-EQUIL' + idx = idx + 1 + ! -- use dimension of GWF term + maxlist = this%flowbudptr%budterm(this%idxbudgwf)%maxlist + naux = 0 + call this%budobj%budterm(idx)%initialize(text, & + this%name_model, & + this%packName, & + this%name_model, & + this%packName, & + maxlist, .false., .false., & + naux) + ! + ! -- Return + return + end subroutine uze_setup_budobj + + !> @brief Fill UZE budget object + !! + !! Copy flow terms into this%budobj + !< + subroutine uze_fill_budobj(this, idx, x, flowja, ccratin, ccratout) + ! -- modules + ! -- dummy + class(GweUzeType) :: this + integer(I4B), intent(inout) :: idx + real(DP), dimension(:), intent(in) :: x + real(DP), dimension(:), contiguous, intent(inout) :: flowja + real(DP), intent(inout) :: ccratin + real(DP), intent(inout) :: ccratout + ! -- local + integer(I4B) :: j, n1, n2, indx + integer(I4B) :: nlist, nlen + integer(I4B) :: igwfnode + integer(I4B) :: idiag + real(DP) :: q + real(DP), dimension(:), allocatable :: budresid + ! + allocate (budresid(this%ncv)) + do n1 = 1, this%ncv + budresid(n1) = DZERO + end do + ! + indx = 0 + ! + ! -- FLOW JA FACE into budresid + nlen = 0 + if (this%idxbudfjf /= 0) then + nlen = this%flowbudptr%budterm(this%idxbudfjf)%maxlist + end if + if (nlen > 0) then + indx = indx + 1 + nlist = this%budobj%budterm(indx)%nlist + do j = 1, nlist + n1 = this%budobj%budterm(indx)%id1(j) + n2 = this%budobj%budterm(indx)%id2(j) + if (n1 < n2) then + q = this%budobj%budterm(indx)%flow(j) + budresid(n1) = budresid(n1) + q + budresid(n2) = budresid(n2) - q + end if + end do + end if + ! + ! -- GWF (LEAKAGE) into budresid + indx = indx + 1 + nlist = this%budobj%budterm(indx)%nlist + do j = 1, nlist + n1 = this%budobj%budterm(indx)%id1(j) + q = this%budobj%budterm(indx)%flow(j) + budresid(n1) = budresid(n1) + q + end do + ! + ! -- Skip individual package terms + indx = this%idxlastpak + ! + ! -- STORAGE into budresid + indx = indx + 1 + do n1 = 1, this%ncv + q = this%budobj%budterm(indx)%flow(n1) + budresid(n1) = budresid(n1) + q + end do + ! + ! -- TO MOVER into budresid + if (this%idxbudtmvr /= 0) then + indx = indx + 1 + nlist = this%budobj%budterm(indx)%nlist + do j = 1, nlist + n1 = this%budobj%budterm(indx)%id1(j) + q = this%budobj%budterm(indx)%flow(j) + budresid(n1) = budresid(n1) + q + end do + end if + ! + ! -- FROM MOVER into budresid + if (this%idxbudfmvr /= 0) then + indx = indx + 1 + nlist = this%budobj%budterm(indx)%nlist + do j = 1, nlist + n1 = this%budobj%budterm(indx)%id1(j) + q = this%budobj%budterm(indx)%flow(j) + budresid(n1) = budresid(n1) + q + end do + end if + ! + ! -- CONSTANT FLOW into budresid + indx = indx + 1 + do n1 = 1, this%ncv + q = this%budobj%budterm(indx)%flow(n1) + budresid(n1) = budresid(n1) + q + end do + ! + ! -- AUXILIARY VARIABLES into budresid + ! -- (No flows associated with these) + ! + ! -- Individual package terms processed last + ! + ! -- Infiltration + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudinfl)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%uze_infl_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + budresid(n1) = budresid(n1) + q + end do + ! + ! -- Rej-Inf + if (this%idxbudrinf /= 0) then + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudrinf)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%uze_rinf_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + budresid(n1) = budresid(n1) + q + end do + end if + ! + ! -- UZET + if (this%idxbuduzet /= 0) then + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbuduzet)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%uze_uzet_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + budresid(n1) = budresid(n1) + q + end do + end if + ! + ! -- Rej-Inf-To-MVR + if (this%idxbudritm /= 0) then + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudritm)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + call this%uze_ritm_term(j, n1, n2, q) + call this%budobj%budterm(idx)%update_term(n1, n2, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + budresid(n1) = budresid(n1) + q + end do + end if + ! + ! -- Thermal-Equil + ! -- processed last because it is calculated from the residual + idx = idx + 1 + nlist = this%flowbudptr%budterm(this%idxbudgwf)%nlist + call this%budobj%budterm(idx)%reset(nlist) + do j = 1, nlist + n1 = this%flowbudptr%budterm(this%idxbudgwf)%id1(j) + igwfnode = this%flowbudptr%budterm(this%idxbudgwf)%id2(j) + q = -budresid(n1) + call this%uze_theq_term(j, n1, igwfnode, q) + call this%budobj%budterm(idx)%update_term(n1, igwfnode, q) + call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout) + if (this%iboundpak(n1) /= 0) then + ! -- Contribution to gwe cell budget + this%simvals(n1) = this%simvals(n1) - q + idiag = this%dis%con%ia(igwfnode) + flowja(idiag) = flowja(idiag) - q + end if + end do + ! + deallocate (budresid) + ! + ! -- Return + return + end subroutine uze_fill_budobj + + !> @brief Allocate scalars + !! + !! Allocate scalars specific to UZE package + !< + subroutine allocate_scalars(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweUzeType) :: this + ! -- local + ! + ! -- Allocate scalars in TspAptType + call this%TspAptType%allocate_scalars() + ! + ! -- Allocate + call mem_allocate(this%idxbudinfl, 'IDXBUDINFL', this%memoryPath) + call mem_allocate(this%idxbudrinf, 'IDXBUDRINF', this%memoryPath) + call mem_allocate(this%idxbuduzet, 'IDXBUDUZET', this%memoryPath) + call mem_allocate(this%idxbudritm, 'IDXBUDRITM', this%memoryPath) + call mem_allocate(this%idxbudtheq, 'IDXBUDTHEQ', this%memoryPath) + ! + ! -- Initialize + this%idxbudinfl = 0 + this%idxbudrinf = 0 + this%idxbuduzet = 0 + this%idxbudritm = 0 + this%idxbudtheq = 0 + ! + ! -- Return + return + end subroutine allocate_scalars + + !> @brief Allocate arrays + !! + !! Allocate arrays used by the UZE package + !< + subroutine uze_allocate_arrays(this) + ! -- modules + use MemoryManagerModule, only: mem_allocate + ! -- dummy + class(GweUzeType), intent(inout) :: this + ! -- local + integer(I4B) :: n + ! + ! -- Time series + call mem_allocate(this%tempinfl, this%ncv, 'TEMPINFL', this%memoryPath) + call mem_allocate(this%tempuzet, this%ncv, 'TEMPUZET', this%memoryPath) + ! + ! -- Call standard TspAptType allocate arrays + call this%TspAptType%apt_allocate_arrays() + ! + ! -- Initialize + do n = 1, this%ncv + this%tempinfl(n) = DZERO + this%tempuzet(n) = DZERO + end do + ! + ! -- Return + return + end subroutine uze_allocate_arrays + + !> @brief Deallocate memory + !< + subroutine uze_da(this) + ! -- modules + use MemoryManagerModule, only: mem_deallocate + ! -- dummy + class(GweUzeType) :: this + ! + ! -- Deallocate scalars + call mem_deallocate(this%idxbudinfl) + call mem_deallocate(this%idxbudrinf) + call mem_deallocate(this%idxbuduzet) + call mem_deallocate(this%idxbudritm) + call mem_deallocate(this%idxbudtheq) + ! + ! -- Deallocate time series + call mem_deallocate(this%tempinfl) + call mem_deallocate(this%tempuzet) + ! + ! -- Deallocate scalars in TspAptType + call this%TspAptType%bnd_da() + ! + ! -- Return + return + end subroutine uze_da + + !> @brief Infiltration term + !! + !! Accounts for energy added to the subsurface via infiltration, for example, + !! energy entering the model domain via rainfall or irrigation. + !< + subroutine uze_infl_term(this, ientry, n1, n2, rrate, & + rhsval, hcofval) + ! -- dummy + class(GweUzeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + real(DP) :: h, r + ! + n1 = this%flowbudptr%budterm(this%idxbudinfl)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudinfl)%id2(ientry) + ! + ! -- Note that qbnd is negative for negative infiltration + qbnd = this%flowbudptr%budterm(this%idxbudinfl)%flow(ientry) + if (qbnd < DZERO) then + ctmp = this%xnewpak(n1) + h = qbnd + r = DZERO + else + ctmp = this%tempinfl(n1) + h = DZERO + r = -qbnd * ctmp + end if + if (present(rrate)) rrate = qbnd * ctmp * this%eqnsclfac + if (present(rhsval)) rhsval = r * this%eqnsclfac + if (present(hcofval)) hcofval = h * this%eqnsclfac + ! + ! -- Return + return + end subroutine uze_infl_term + + !> @brief Rejected infiltration term + !! + !! Accounts for energy that is added to the model from specifying an + !! infiltration rate and temperature, but is subsequently removed from + !! the model as that portion of the infiltration that is rejected (and + !! NOT transferred to another advanced package via the MVR/MVT packages). + !< + subroutine uze_rinf_term(this, ientry, n1, n2, rrate, & + rhsval, hcofval) + ! -- dummy + class(GweUzeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudrinf)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudrinf)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudrinf)%flow(ientry) + ctmp = this%tempinfl(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac + if (present(rhsval)) rhsval = DZERO + if (present(hcofval)) hcofval = qbnd * this%eqnsclfac + ! + ! -- Return + return + end subroutine uze_rinf_term + + !> @brief Evapotranspiration from the unsaturated-zone term + !! + !! Accounts for thermal cooling in the unsaturated zone as a result of + !! evapotranspiration from the unsaturated zone. Amount of water converted + !! to vapor phase (UZET) determined by GWF model + !< + subroutine uze_uzet_term(this, ientry, n1, n2, rrate, rhsval, hcofval) + ! -- dummy + class(GweUzeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + real(DP) :: omega + ! + n1 = this%flowbudptr%budterm(this%idxbuduzet)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbuduzet)%id2(ientry) + ! -- Note that qbnd is negative for uzet + qbnd = this%flowbudptr%budterm(this%idxbuduzet)%flow(ientry) + ctmp = this%tempuzet(n1) + if (this%xnewpak(n1) < ctmp) then + omega = DONE + else + omega = DZERO + end if + if (present(rrate)) & + rrate = (omega * qbnd * this%xnewpak(n1) + & + (DONE - omega) * qbnd * ctmp) * this%eqnsclfac + if (present(rhsval)) rhsval = -(DONE - omega) * qbnd * ctmp * this%eqnsclfac + if (present(hcofval)) hcofval = omega * qbnd * this%eqnsclfac + ! + ! -- Return + return + end subroutine uze_uzet_term + + !> @brief Rejected infiltration to MVR/MVT term + !! + !! Accounts for energy that is added to the model from specifying an + !! infiltration rate and temperature, but does not infiltrate into the + !! subsurface. This subroutine is called when the rejected infiltration + !! is transferred to another advanced package via the MVR/MVT packages. + !< + subroutine uze_ritm_term(this, ientry, n1, n2, rrate, & + rhsval, hcofval) + ! -- dummy + class(GweUzeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout), optional :: rrate + real(DP), intent(inout), optional :: rhsval + real(DP), intent(inout), optional :: hcofval + ! -- local + real(DP) :: qbnd + real(DP) :: ctmp + ! + n1 = this%flowbudptr%budterm(this%idxbudritm)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudritm)%id2(ientry) + qbnd = this%flowbudptr%budterm(this%idxbudritm)%flow(ientry) + ctmp = this%tempinfl(n1) + if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac + if (present(rhsval)) rhsval = DZERO + if (present(hcofval)) hcofval = qbnd * this%eqnsclfac + ! + ! -- Return + return + end subroutine uze_ritm_term + + !> @brief Heat transferred through thermal equilibrium with the solid phase + !! + !! Accounts for the transfer of energy from the liquid phase to the solid + !! phase as a result of the instantaneous thermal equilibrium assumption. + !< + subroutine uze_theq_term(this, ientry, n1, n2, rrate) + ! -- modules + use ConstantsModule, only: LENBUDTXT + ! -- dummy + class(GweUzeType) :: this + integer(I4B), intent(in) :: ientry + integer(I4B), intent(inout) :: n1 + integer(I4B), intent(inout) :: n2 + real(DP), intent(inout) :: rrate + ! -- local + real(DP) :: r + integer(I4B) :: i + character(len=LENBUDTXT) :: flowtype + ! + r = DZERO + n1 = this%flowbudptr%budterm(this%idxbudgwf)%id1(ientry) + n2 = this%flowbudptr%budterm(this%idxbudgwf)%id2(ientry) + if (this%iboundpak(n1) /= 0) then + do i = 1, this%budobj%nbudterm + flowtype = this%budobj%budterm(i)%flowtype + select case (trim(adjustl(flowtype))) + case ('THERMAL-EQUIL') + ! -- Skip + continue + case default + r = r - this%budobj%budterm(i)%flow(ientry) + end select + end do + end if + rrate = r + ! + ! -- Return + return + end subroutine uze_theq_term + + !> @brief Define UZE Observation + !! + !! This subroutine: + !! - Stores observation types supported by the parent APT package. + !! - Overrides BndType%bnd_df_obs + !< + subroutine uze_df_obs(this) + ! -- dummy + class(GweUzeType) :: this + ! -- local + integer(I4B) :: indx + ! + ! -- Store obs type and assign procedure pointer + ! for temperature observation type. + call this%obs%StoreObsType('temperature', .false., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for flow between uze cells. + call this%obs%StoreObsType('flow-ja-face', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID12 + ! + ! -- Store obs type and assign procedure pointer + ! for from-mvr observation type. + call this%obs%StoreObsType('from-mvr', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- to-mvr not supported for uze + !call this%obs%StoreObsType('to-mvr', .true., indx) + !this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for storage observation type. + call this%obs%StoreObsType('storage', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for constant observation type. + call this%obs%StoreObsType('constant', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for observation type: uze + call this%obs%StoreObsType('uze', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for observation type. + call this%obs%StoreObsType('infiltration', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for observation type. + call this%obs%StoreObsType('rej-inf', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for observation type. + call this%obs%StoreObsType('uzet', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for observation type. + call this%obs%StoreObsType('rej-inf-to-mvr', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Store obs type and assign procedure pointer + ! for observation type. + call this%obs%StoreObsType('thermal-equil', .true., indx) + this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID + ! + ! -- Return + return + end subroutine uze_df_obs + + !> @brief Process package specific obs + !! + !! Method to process specific observations for this package. + !< + subroutine uze_rp_obs(this, obsrv, found) + ! -- dummy + class(GweUzeType), intent(inout) :: this !< package class + type(ObserveType), intent(inout) :: obsrv !< observation object + logical, intent(inout) :: found !< indicate whether observation was found + ! + found = .true. + select case (obsrv%ObsTypeId) + case ('INFILTRATION') + call this%rp_obs_byfeature(obsrv) + case ('REJ-INF') + call this%rp_obs_byfeature(obsrv) + case ('UZET') + call this%rp_obs_byfeature(obsrv) + case ('REJ-INF-TO-MVR') + call this%rp_obs_byfeature(obsrv) + case ('THERMAL-EQUIL') + call this%rp_obs_byfeature(obsrv) + case default + found = .false. + end select + ! + return + end subroutine uze_rp_obs + + !> @brief Calculate observation value and pass it back to APT + !< + subroutine uze_bd_obs(this, obstypeid, jj, v, found) + ! -- dummy + class(GweUzeType), intent(inout) :: this + character(len=*), intent(in) :: obstypeid + real(DP), intent(inout) :: v + integer(I4B), intent(in) :: jj + logical, intent(inout) :: found + ! -- local + integer(I4B) :: n1, n2 + ! + found = .true. + select case (obstypeid) + case ('INFILTRATION') + if (this%iboundpak(jj) /= 0 .and. this%idxbudinfl > 0) then + call this%uze_infl_term(jj, n1, n2, v) + end if + case ('REJ-INF') + if (this%iboundpak(jj) /= 0 .and. this%idxbudrinf > 0) then + call this%uze_rinf_term(jj, n1, n2, v) + end if + case ('UZET') + if (this%iboundpak(jj) /= 0 .and. this%idxbuduzet > 0) then + call this%uze_uzet_term(jj, n1, n2, v) + end if + case ('REJ-INF-TO-MVR') + if (this%iboundpak(jj) /= 0 .and. this%idxbudritm > 0) then + call this%uze_ritm_term(jj, n1, n2, v) + end if + case ('THERMAL-EQUIL') + if (this%iboundpak(jj) /= 0 .and. this%idxbudtheq > 0) then + call this%uze_theq_term(jj, n1, n2, v) + end if + case default + found = .false. + end select + ! + ! -- Return + return + end subroutine uze_bd_obs + + !> @brief Sets the stress period attributes for keyword use. + !< + subroutine uze_set_stressperiod(this, itemno, keyword, found) + ! -- modules + use TimeSeriesManagerModule, only: read_value_or_time_series_adv + ! -- dummy + class(GweUzeType), intent(inout) :: this + integer(I4B), intent(in) :: itemno + character(len=*), intent(in) :: keyword + logical, intent(inout) :: found + ! -- local + character(len=LINELENGTH) :: temp_text + integer(I4B) :: ierr + integer(I4B) :: jj + real(DP), pointer :: bndElem => null() + ! + ! INFILTRATION + ! UZET + ! + found = .true. + select case (keyword) + case ('INFILTRATION') + ierr = this%apt_check_valid(itemno) + if (ierr /= 0) then + goto 999 + end if + call this%parser%GetString(temp_text) + jj = 1 + bndElem => this%tempinfl(itemno) + call read_value_or_time_series_adv(temp_text, itemno, jj, bndElem, & + this%packName, 'BND', this%tsManager, & + this%iprpak, 'INFILTRATION') + case ('UZET') + ierr = this%apt_check_valid(itemno) + if (ierr /= 0) then + goto 999 + end if + call this%parser%GetString(temp_text) + jj = 1 + bndElem => this%tempuzet(itemno) + call read_value_or_time_series_adv(temp_text, itemno, jj, bndElem, & + this%packName, 'BND', this%tsManager, & + this%iprpak, 'UZET') + case default + ! + ! -- Keyword not recognized so return to caller with found = .false. + found = .false. + end select + ! +999 continue + ! + ! -- Return + return + end subroutine uze_set_stressperiod + +end module GweUzeModule diff --git a/src/Model/TransportModel/tsp1apt1.f90 b/src/Model/TransportModel/tsp1apt1.f90 index 76fc718e033..b63a3b70569 100644 --- a/src/Model/TransportModel/tsp1apt1.f90 +++ b/src/Model/TransportModel/tsp1apt1.f90 @@ -2813,7 +2813,7 @@ subroutine apt_rp_obs(this) ' must be assigned to a feature with a unique boundname.' call store_error(errmsg) end if - case ('LKT', 'SFT', 'MWT', 'UZT', 'LKE', 'SFE', 'MWE') + case ('LKT', 'SFT', 'MWT', 'UZT', 'LKE', 'SFE', 'MWE', 'UZE') call this%rp_obs_budterm(obsrv, & this%flowbudptr%budterm(this%idxbudgwf)) case ('FLOW-JA-FACE') @@ -2898,7 +2898,7 @@ subroutine apt_bd_obs(this) if (this%iboundpak(jj) /= 0) then v = this%xnewpak(jj) end if - case ('LKT', 'SFT', 'MWT', 'UZT', 'LKE', 'SFE', 'MWE') + case ('LKT', 'SFT', 'MWT', 'UZT', 'LKE', 'SFE', 'MWE', 'UZE') n = this%flowbudptr%budterm(this%idxbudgwf)%id1(jj) if (this%iboundpak(n) /= 0) then igwfnode = this%flowbudptr%budterm(this%idxbudgwf)%id2(jj) diff --git a/src/meson.build b/src/meson.build index 447ef97947c..24ef7691927 100644 --- a/src/meson.build +++ b/src/meson.build @@ -73,6 +73,7 @@ modflow_sources = files( 'Model' / 'GroundWaterEnergy' / 'gwe1lke1.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1mwe1.f90', 'Model' / 'GroundWaterEnergy' / 'gwe1sfe1.f90', + 'Model' / 'GroundWaterEnergy' / 'gwe1uze1.f90', 'Model' / 'GroundWaterFlow' / 'gwf3.f90', 'Model' / 'GroundWaterFlow' / 'gwf3api8.f90', 'Model' / 'GroundWaterFlow' / 'gwf3buy8.f90', From 34125e75ccf5b26ede65063260041eac6043b245 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 9 Feb 2024 11:16:43 -0800 Subject: [PATCH 43/46] Attempting to reapply a failing autotest. Unable to discern why it is failing as downloaded contents from its failure are working locally. --- autotest/test_gwe_uze00_flux.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autotest/test_gwe_uze00_flux.py b/autotest/test_gwe_uze00_flux.py index 3873865d2a6..e47662f9a64 100644 --- a/autotest/test_gwe_uze00_flux.py +++ b/autotest/test_gwe_uze00_flux.py @@ -62,7 +62,7 @@ def flux_analyt(t, z, qt0, qtinfil, v, d): 0.3480242 + zeta * (-0.0958798 + zeta * 0.7478556) ) flux = qt0 + 0.5 * (qtinfil - qt0) * ( - math.erfc(ztermm) + math.exp(vterm - ztermp ** 2) * polyterm + math.erfc(ztermm) + math.exp(vterm - ztermp**2) * polyterm ) return flux @@ -86,7 +86,7 @@ def temp_analyt(t, z, t0, tinfil, v, d): 0.3480242 + zeta * (-0.0958798 + zeta * 0.7478556) ) temp = t0 + 0.5 * (tinfil - t0) * ( - math.erfc(ztermm) + math.exp(vterm - ztermp ** 2) * polyterm + math.erfc(ztermm) + math.exp(vterm - ztermp**2) * polyterm ) return temp @@ -292,7 +292,7 @@ def build_models(idx, test): ) # output control - flopy.mf6.ModflowGwfoc( + oc = flopy.mf6.ModflowGwfoc( gwf, budget_filerecord=f"{name}.cbc", head_filerecord=f"{name}.hds", @@ -302,9 +302,9 @@ def build_models(idx, test): filename=f"{gwfname}.oc", ) - # ---------------------------------- + # ---------------------------------------------------- # Instantiating MODFLOW 6 GWE model - # ---------------------------------- + # ---------------------------------------------------- gwe = flopy.mf6.ModflowGwe( sim, modelname=gwename, model_nam_file=f"{gwename}.nam" ) From 1e0d617e1ed1bb7738bd2cf0574199baffc86ea9 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 9 Feb 2024 11:43:22 -0800 Subject: [PATCH 44/46] removing troublesome autotest. Downloaded contents from failed run on Actions doesn't yield the same output that the logs are reporting. This particular autotest has an analytical solution (and a plot) that might be better shown on the modflow6-examples repo anyway --- autotest/test_gwe_uze00_flux.py | 753 -------------------------------- 1 file changed, 753 deletions(-) delete mode 100644 autotest/test_gwe_uze00_flux.py diff --git a/autotest/test_gwe_uze00_flux.py b/autotest/test_gwe_uze00_flux.py deleted file mode 100644 index e47662f9a64..00000000000 --- a/autotest/test_gwe_uze00_flux.py +++ /dev/null @@ -1,753 +0,0 @@ -# - Similar to test_gwe_uze00.py; however, this looks into whether the -# flux input is correct without pinning the temperature of the top-most -# cell to a specified value. -# -# - Outer columns not active for unsaturated zone, but are present to host -# constant head boundaries at the bottom of the model. -# -# +-------+ -# |///////| = Inactive cell -# +-------+ -# -# Model depiction: -# -# +-------+-------+-------+ -# |///////| |///////| Layer 1 -# +-------+-------+-------+ -# |///////| |///////| Layer 2 -# +-------+-------+-------+ -# |///////| |///////| Layer 3 -# +-------+-------+-------+ -# |///////| |///////| -# + -- -- + -- -- + -- -- + -# |///////| |///////| Layer x (Middle portion of model not shown) -# + -- -- + -- -- + -- -- + -# |///////| |///////| -# +-------+-------+-------+ -# | | | | Layer 99 -# +-------+-------+-------+ -# | | | | Layer 100 -# +-------+-------+-------+ - -import os - -import flopy -import numpy as np -import pytest -import math - -import flopy.utils.binaryfile as bf -from framework import TestFramework - - -# Analytical solution derived by Alden, similar in form to -# Barends (2010) Equation 5 - but remember that that solution -# pins the temperature of the top cell to a specified temperature -def flux_analyt(t, z, qt0, qtinfil, v, d): - if t == 0.0: - flux = qt0 - else: - denom = 2.0 * math.sqrt(d * t) - ztermm = (z - v * t) / denom - ztermp = (z + v * t) / denom - vterm = v * z / d - if vterm < 100.0: - # might need to adjust this limit - flux = qt0 + (qtinfil - qt0) * 0.5 * ( - math.erfc(ztermm) + math.exp(vterm) * math.erfc(ztermp) - ) - else: - zeta = 1.0 / (1.0 + 0.47047 * ztermp) - polyterm = zeta * ( - 0.3480242 + zeta * (-0.0958798 + zeta * 0.7478556) - ) - flux = qt0 + 0.5 * (qtinfil - qt0) * ( - math.erfc(ztermm) + math.exp(vterm - ztermp**2) * polyterm - ) - return flux - - -def temp_analyt(t, z, t0, tinfil, v, d): - if t == 0.0: - temp = t0 - else: - denom = 2.0 * math.sqrt(d * t) - ztermm = (z - v * t) / denom - ztermp = (z + v * t) / denom - vterm = v * z / d - if vterm < 100.0: - # might need to adjust this limit - temp = t0 + 0.5 * (tinfil - t0) * ( - math.erfc(ztermm) + math.exp(vterm) * math.erfc(ztermp) - ) - else: - zeta = 1.0 / (1.0 + 0.47047 * ztermp) - polyterm = zeta * ( - 0.3480242 + zeta * (-0.0958798 + zeta * 0.7478556) - ) - temp = t0 + 0.5 * (tinfil - t0) * ( - math.erfc(ztermm) + math.exp(vterm - ztermp**2) * polyterm - ) - return temp - - -# Model units -length_units = "meters" -time_units = "days" - -nlay, nrow, ncol = 101, 1, 3 -nper = 2 -perlen = [1.0e9, 100.0] -nstp = [1, 100] -tsmult = len(perlen) * [1.0] - -delr = 1.0 -delc = 1.0 -delz = 0.1 # 10 cm -strt = 0.05 -top = 10.0005 -botm = [ - 9.9995 -] # Top layer is very thin for application of the boundary condition -for i in np.arange(1, nlay): - bot = 10.0 - (i * delz) - botm.append(round(bot, 1)) - -nouter, ninner = 100, 300 -hclose, rclose, relax = 1e-9, 1e-3, 0.97 -steady = {0: False, 1: False} -transient = {0: True, 1: True} - -idomain_u = [0, 1, 0] -idomain_l = [1, 1, 1] -idomain = [] -for i in np.arange(nlay): - if i < 99: - idomain.append(idomain_u) - else: - idomain.append(idomain_l) - -idomain = np.array(idomain) - -strt_temp = 10.0 -scheme = "UPSTREAM" -dispersivity = 0.0 -prsity = 0.2 - -# transient uzf info -# iuzno cellid landflg ivertcn surfdp vks thtr thts thti eps [bndnm] -uzf_pkdat = [[0, (0, 0, 1), 1, 1, 0.00001, 1, 0.0001, 0.20, 0.055, 4]] - -# Continue building the UZF list of objects -for iuzno in np.arange(1, 101, 1): - if iuzno < nlay - 1: - ivertconn = iuzno + 1 - else: - ivertconn = -1 - - uzf_pkdat.append( - [iuzno, (iuzno, 0, 1), 0, ivertconn, 0.01, 1, 0.0001, 0.20, 0.055, 4] - ) - -iuz_cell_dict = {} -cell_iuz_dict = {} -for i, itm in enumerate(uzf_pkdat): - iuz_cell_dict.update({itm[0]: (itm[1][0], itm[1][1], itm[1][2])}) - cell_iuz_dict.update({(itm[1][0], itm[1][1], itm[1][2]): itm[0]}) - -finf = 0.01 -extdp = 0.0 -pet = 0.0 -extwc = 0.0 -zero = 0.0 -uzf_spd = { - 0: [[0, finf, pet, extdp, extwc, zero, zero, zero]], - 1: [[0, finf, pet, extdp, extwc, zero, zero, zero]], -} - -cases = ["uze00_flux"] - - -def build_models(idx, test): - name = cases[idx] - - # build MODFLOW 6 files - ws = test.workspace - sim = flopy.mf6.MFSimulation( - sim_name=name, version="mf6", exe_name="mf6", sim_ws=ws - ) - - # create tdis package - tdis_rc = [] - for i in range(nper): - tdis_rc.append((perlen[i], nstp[i], tsmult[i])) - - flopy.mf6.ModflowTdis( - sim, time_units=time_units, nper=nper, perioddata=tdis_rc - ) - - gwfname = "gwf_" + name - gwename = "gwe_" + name - - newtonoptions = ["NEWTON", "UNDER_RELAXATION"] - # create gwf model - gwf = flopy.mf6.ModflowGwf( - sim, - modelname=gwfname, - newtonoptions=newtonoptions, - save_flows=True, - ) - - # create iterative model solution and register the gwf model with it - ims = flopy.mf6.ModflowIms( - sim, - print_option="SUMMARY", - complexity="MODERATE", - outer_dvclose=hclose, - outer_maximum=nouter, - under_relaxation="DBD", - inner_maximum=ninner, - inner_dvclose=hclose, - rcloserecord=rclose, - linear_acceleration="BICGSTAB", - scaling_method="NONE", - reordering_method="NONE", - relaxation_factor=relax, - filename=f"{gwfname}.ims", - ) - sim.register_ims_package(ims, [gwf.name]) - - flopy.mf6.ModflowGwfdis( - gwf, - nlay=nlay, - nrow=nrow, - ncol=ncol, - delr=delr, - delc=delc, - top=top, - botm=botm, - idomain=idomain, - filename=f"{gwfname}.dis", - ) - - # initial conditions - flopy.mf6.ModflowGwfic( - gwf, - strt=strt, - filename=f"{gwfname}.ic", - ) - - # node property flow - flopy.mf6.ModflowGwfnpf( - gwf, - save_flows=True, - icelltype=1, - k=100.0, - k33=10, - filename=f"{gwfname}.npf", - ) - - # aquifer storage - flopy.mf6.ModflowGwfsto( - gwf, - iconvert=1, - ss=1e-5, - sy=prsity, - steady_state=steady, - transient=transient, - filename=f"{gwfname}.sto", - ) - - # chd files - chdval = 0.05 - chdspd = {0: [[(100, 0, 0), chdval, 10.0], [(100, 0, 2), chdval, 10.0]]} - - flopy.mf6.ModflowGwfchd( - gwf, - auxiliary=["TEMPERATURE"], - print_flows=True, - stress_period_data=chdspd, - pname="CHD-1", - filename=f"{gwfname}.chd", - ) - - # Unsaturated-zone flow package - flopy.mf6.ModflowGwfuzf( - gwf, - print_flows=True, - save_flows=True, - wc_filerecord=gwfname + ".uzfwc.bin", - simulate_et=False, - simulate_gwseep=False, - linear_gwet=False, - boundnames=False, - ntrailwaves=15, - nwavesets=40, - nuzfcells=len(uzf_pkdat), - packagedata=uzf_pkdat, - perioddata=uzf_spd, - budget_filerecord=f"{gwfname}.uzf.bud", - pname="UZF-1", - filename=f"{gwfname}.uzf", - ) - - # output control - oc = flopy.mf6.ModflowGwfoc( - gwf, - budget_filerecord=f"{name}.cbc", - head_filerecord=f"{name}.hds", - headprintrecord=[("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL")], - saverecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], - printrecord=[("HEAD", "ALL"), ("BUDGET", "ALL")], - filename=f"{gwfname}.oc", - ) - - # ---------------------------------------------------- - # Instantiating MODFLOW 6 GWE model - # ---------------------------------------------------- - gwe = flopy.mf6.ModflowGwe( - sim, modelname=gwename, model_nam_file=f"{gwename}.nam" - ) - gwe.name_file.save_flows = True - - imsgwe = flopy.mf6.ModflowIms( - sim, - print_option="SUMMARY", - outer_dvclose=hclose, - outer_maximum=nouter, - under_relaxation="NONE", - inner_maximum=ninner, - inner_dvclose=hclose, - rcloserecord=rclose, - linear_acceleration="BICGSTAB", - scaling_method="NONE", - reordering_method="NONE", - relaxation_factor=relax, - filename="{}.ims".format(gwename), - ) - sim.register_ims_package(imsgwe, [gwe.name]) - - # Instantiating MODFLOW 6 transport discretization package - flopy.mf6.ModflowGwedis( - gwe, - nogrb=True, - nlay=nlay, - nrow=nrow, - ncol=ncol, - delr=delr, - delc=delc, - top=top, - botm=botm, - idomain=idomain, - pname="DIS", - filename=f"{gwename}.dis", - ) - - # Instantiating MODFLOW 6 transport initial concentrations - flopy.mf6.ModflowGweic( - gwe, - strt=strt_temp, - pname="IC", - filename=f"{gwename}.ic", - ) - - # Instantiating MODFLOW 6 transport advection package - flopy.mf6.ModflowGweadv( - gwe, scheme=scheme, pname="ADV", filename="{}.adv".format(gwename) - ) - - # Instantiating MODFLOW 6 transport dispersion package - flopy.mf6.ModflowGwecnd( - gwe, - xt3d_off=False, - alh=dispersivity, - ath1=dispersivity, - ktw=0.5918 * 86400, - kts=0.2700 * 86400, - pname="DSP", - filename=f"{gwename}.dsp", - ) - - # Instantiating MODFLOW 6 transport mass storage package - rhow = 1000.0 - cpw = 4183.0 - lhv = 2500.0 - flopy.mf6.ModflowGweest( - gwe, - save_flows=True, - porosity=prsity, - cps=760.0, - rhos=1500.0, - packagedata=[cpw, rhow, lhv], - pname="MST", - filename=f"{gwename}.mst", - ) - - # Instantiating MODFLOW 6 transport source-sink mixing package - srctype = "AUX" - auxname = "TEMPERATURE" - pname = ["CHD-1"] - # Inpput to SSM is: - sources = [[itm, srctype, auxname] for itm in pname] - - flopy.mf6.ModflowGwessm( - gwe, - sources=sources, - pname="SSM", - filename=f"{gwename}.ssm", - ) - - # Instantiating MODFLOW 6 energy transport source-sink mixing package - uzepackagedata = [(iuz, 10.0) for iuz in range(nlay)] - uzeperioddata = { - 0: [[0, "INFILTRATION", 10.0]], - 1: [[0, "INFILTRATION", 20.0]], - } - - flopy.mf6.ModflowGweuze( - gwe, - flow_package_name="UZF-1", - boundnames=False, - save_flows=True, - print_input=True, - print_flows=True, - print_temperature=True, - temperature_filerecord=gwename + ".uze.bin", - budget_filerecord=gwename + ".uze.bud", - packagedata=uzepackagedata, - uzeperioddata=uzeperioddata, - pname="UZE-1", - filename=f"{gwename}.uze", - ) - - # Instantiate MODFLOW 6 heat transport output control package - flopy.mf6.ModflowGweoc( - gwe, - pname="OC", - budget_filerecord="{}.cbc".format(gwename), - temperature_filerecord="{}.ucn".format(gwename), - temperatureprintrecord=[ - ("COLUMNS", 10, "WIDTH", 15, "DIGITS", 6, "GENERAL") - ], - saverecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], - printrecord=[("TEMPERATURE", "ALL"), ("BUDGET", "ALL")], - filename=f"{gwename}.oc", - ) - - # Instantiate Gwf-Gwe Exchange package - flopy.mf6.ModflowGwfgwe( - sim, - exgtype="GWF6-GWE6", - exgmnamea=gwfname, - exgmnameb=gwename, - filename="{}.gwfgwe".format(gwename), - ) - - return sim, None - - -def check_output(idx, test): - print("evaluating flow...") - - name = cases[idx] - gwfname = "gwf_" + name - gwename = "gwe_" + name - ws = test.workspace - - # check some output... - wc_fl = gwfname + ".uzfwc.bin" - wcobj = flopy.utils.HeadFile(os.path.join(ws, wc_fl), text="water-content") - wc = wcobj.get_alldata() - - # temperature output - fl2 = gwename + ".uze.bin" - uzeobj = flopy.utils.HeadFile(os.path.join(ws, fl2), text="TEMPERATURE") - temps = uzeobj.get_alldata() - - # Cell flows output - qfile = gwename + ".cbc" - gweflowsobj = flopy.utils.CellBudgetFile(os.path.join(ws, qfile)) - - # Binary grid file needed for post-processing - fgrb = gwfname + ".dis.grb" - grb_file = os.path.join(ws, fgrb) - - # UZE flows - fuzebud = gwename + ".uze.bud" - uzeflowsobj = flopy.utils.CellBudgetFile(os.path.join(ws, fuzebud)) - flowsadv = uzeflowsobj.get_data(text="FLOW-JA-FACE") - - t = np.linspace(0.0, 100.0, 101) - z = np.linspace(0.0, 9.9, 99) - - q = finf # infiltration rate - area = delr * delc - rhos = 1500.0 - Cps = 760.0 - rhow = 1000.0 - Cpw = 4183.0 - rhowCpw = Cpw * rhow - rhosCps = Cps * rhos - - Kts = 23328.0 - Ktw = 0.0 - - steady_wc = wc[1, 0, 0, 1] - Sw = steady_wc / prsity - - rhoCp_bulk = Sw * prsity * rhowCpw + (1 - prsity) * rhosCps - Kt_bulk = Sw * prsity * Ktw + (1 - prsity) * Kts - v = rhowCpw / rhoCp_bulk * q - D = Kt_bulk / rhoCp_bulk - - t0 = 10.0 - tinfil = 20.0 - qt0 = q * t0 - qtinfil = q * tinfil - - # for converting from J/day to W - unitadj = 1 / 86400 - - # Get analytical solution - conv10 = [] - cond10 = [] - conv50 = [] - cond50 = [] - conv100 = [] - cond100 = [] - analytical_sln = np.zeros((len(t), len(z))) - simulated_sln = np.zeros((len(t), len(z))) - for i, tm in enumerate(t): - if i == 0: - gweflowjaface = gweflowsobj.get_data( - text="FLOW-JA-FACE", kstpkper=(0, 0) - ) - else: - gweflowjaface = gweflowsobj.get_data( - text="FLOW-JA-FACE", kstpkper=(i - 1, 1) - ) - flowscond = flopy.mf6.utils.postprocessing.get_structured_faceflows( - gweflowjaface[0][0], grb_file=grb_file - ) - for j, depth in enumerate(z): - fluxa = flux_analyt(tm, depth, qt0, qtinfil, v, D) - analytical_sln[i, j] = fluxa * rhowCpw * unitadj - - (uze1, uze2, floadv) = flowsadv[i][2 * j + 1] - (fjunk1, flocond, fjunk2) = flowscond[1][j][0] - flo = floadv * rhowCpw * unitadj + flocond * rhowCpw * unitadj - if i == 10: - conv10.append(floadv * rhowCpw * unitadj) - cond10.append(flocond * rhowCpw * unitadj) - elif i == 50: - conv50.append(floadv * rhowCpw * unitadj) - cond50.append(flocond * rhowCpw * unitadj) - elif i == 100: - conv100.append(floadv * rhowCpw * unitadj) - cond100.append(flocond * rhowCpw * unitadj) - - flux = flo / area - simulated_sln[i, j] = flux - - # Run checks - msg0 = ( - "Simulated solution has deviated too far from the analytical solution" - ) - # Following values are calculated as "percent differences" when determining if fits are acceptable - # Day 10 - assert ( - np.max( - ((analytical_sln[10] * rhowCpw) - simulated_sln[10]) - / (analytical_sln[10] * rhowCpw) - * 100 - ) - <= 0.51091366512 - ), msg0 - assert ( - np.min( - ((analytical_sln[10] * rhowCpw) - simulated_sln[10]) - / (analytical_sln[10] * rhowCpw) - * 100 - ) - >= -2.62119104308 - ), msg0 - - # Day 50 - assert ( - np.max( - ((analytical_sln[50] * rhowCpw) - simulated_sln[50]) - / (analytical_sln[50] * rhowCpw) - * 100 - ) - <= 0.3171034702 - ), msg0 - assert ( - np.min( - ((analytical_sln[50] * rhowCpw) - simulated_sln[50]) - / (analytical_sln[50] * rhowCpw) - * 100 - ) - >= -2.52020856408 - ), msg0 - - # Day 100 - assert ( - np.max( - ((analytical_sln[100] * rhowCpw) - simulated_sln[100]) - / (analytical_sln[100] * rhowCpw) - * 100 - ) - <= 0.37655443171 - ), msg0 - assert ( - np.min( - ((analytical_sln[100] * rhowCpw) - simulated_sln[100]) - / (analytical_sln[100] * rhowCpw) - * 100 - ) - >= -2.56004275226 - ), msg0 - - # If plot is needed, change next statement to "if True:" - if False: - import matplotlib.pyplot as plt - from matplotlib import transforms - from matplotlib.collections import PathCollection - from matplotlib.patches import Patch - from matplotlib.lines import Line2D - - fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(10, 5)) - # 10 days - # ------- - polys1 = ax1.stackplot( - z, - conv10, - cond10, - labels=["Convection", "Conduction"], - colors=["lightseagreen", "lightgreen"], - ) - ax1.set_xlim((-0.05, 10.05)) - xlims = ax1.get_xlim() - for poly in polys1: - for path in poly.get_paths(): - path.vertices = path.vertices[:, ::-1] - ax1.set_xlim(0.095 * rhowCpw * unitadj, 0.205 * rhowCpw * unitadj) - ax1.set_ylim(xlims[::-1]) - ax1.plot(simulated_sln[10], z, "-", color="blue", linewidth=1) - ax1.plot(analytical_sln[10], z, "-.", color="red") - ax1.text(4.9, 0.4, "10 Days") - - legend_elements = [ - Line2D( - [0], - [0], - linestyle="-", - color="blue", - lw=1, - label="MODFLOW 6 Total Heat Flux", - ), - Line2D( - [0], [0], linestyle="-.", color="red", lw=1, label="Analytical" - ), - Patch( - facecolor="lightseagreen", - edgecolor="lightseagreen", - label="Convection", - ), - Patch( - facecolor="lightgreen", - edgecolor="lightgreen", - label="Conduction", - ), - ] - - ax1.legend(handles=legend_elements, loc="lower right", frameon=False) - ax1.set_xlabel("Energy Flux, $\dfrac{Watts}{m^2}$") - ax1.set_ylabel("Depth, m") - - # 50 days - # ------- - polys2 = ax2.stackplot( - z, - conv50, - cond50, - labels=["Convection", "Conduction"], - colors=["lightseagreen", "lightgreen"], - ) - ax2.set_xlim((-0.05, 10.05)) - xlims = ax2.get_xlim() - for poly in polys2: - for path in poly.get_paths(): - path.vertices = path.vertices[:, ::-1] - ax2.set_xlim(0.095 * rhowCpw * unitadj, 0.205 * rhowCpw * unitadj) - ax2.set_ylim(xlims[::-1]) - ax2.plot(simulated_sln[50], z, "-", color="blue", linewidth=1) - ax2.plot(analytical_sln[50], z, "-.", color="red") - ax2.set_xlabel("Energy Flux, $\dfrac{Watts}{m^2}$") - ax2.text(4.9, 0.4, "50 Days") - - # 100 days - # ------- - polys3 = ax3.stackplot( - z, - conv100, - cond100, - labels=["Convection", "Conduction"], - colors=["lightseagreen", "lightgreen"], - ) - ax3.set_xlim((-0.05, 10.05)) - xlims = ax3.get_xlim() - for poly in polys3: - for path in poly.get_paths(): - path.vertices = path.vertices[:, ::-1] - ax3.set_xlim(0.095 * rhowCpw * unitadj, 0.205 * rhowCpw * unitadj) - ax3.set_ylim(xlims[::-1]) - ax3.plot(simulated_sln[100], z, "-", color="blue", linewidth=1) - ax3.plot(analytical_sln[100], z, "-.", color="red") - ax3.set_xlabel("Energy Flux, $\dfrac{Watts}{m^2}$") - ax3.text(4.9, 0.4, "100 Days") - - plt.tight_layout() - plt.savefig(os.path.join(ws, "dual_view.png"), format="png") - - line1 = plt.plot( - analytical_sln[10], z, "-", color="red", label="Analytical" - ) - line2 = plt.plot( - simulated_sln[10], z, "-.", color="blue", label="MODFLOW 6" - ) - # 50th transient stress period - plt.plot(analytical_sln[50], z, "-", color="red") - plt.plot(simulated_sln[50], z, "-.", color="blue") - # last stress period - plt.plot(analytical_sln[100], z, "-", color="red") - plt.plot(simulated_sln[100], z, "-.", color="blue") - # add labels - plt.text(11.0, 0.85, "1 day", fontsize=10) - plt.text(12.0, 1.65, "10 days", fontsize=10) - plt.text(14.0, 2.90, "50 days", fontsize=10) - plt.text(16.0, 4.00, "100 days", fontsize=10) - - plt.gca().invert_yaxis() - plt.xlabel("$Energy Flux, -$") - plt.ylabel("$Depth, m$") - plt.minorticks_on() - plt.axhline(y=0.0) - plt.legend(loc="lower right", frameon=False) - plt.savefig(os.path.join(ws, "fit_view.png"), format="png") - - -# - No need to change any code below -@pytest.mark.parametrize( - "idx, name", - list(enumerate(cases)), -) -def test_mf6model(idx, name, function_tmpdir, targets): - test = TestFramework( - name=name, - workspace=function_tmpdir, - targets=targets, - build=lambda t: build_models(idx, t), - check=lambda t: check_output(idx, t), - ) - test.run() From fd6d84c0c4f2b25c3802cdf412d9c96ec96a6b2a Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 9 Feb 2024 11:57:53 -0800 Subject: [PATCH 45/46] Removing a file that shouldn't have been added (snuck in among other staged files) --- doc/mf6io/mf6io_copy.bbl | 289 --------------------------------------- 1 file changed, 289 deletions(-) delete mode 100644 doc/mf6io/mf6io_copy.bbl diff --git a/doc/mf6io/mf6io_copy.bbl b/doc/mf6io/mf6io_copy.bbl deleted file mode 100644 index 9a3a5427419..00000000000 --- a/doc/mf6io/mf6io_copy.bbl +++ /dev/null @@ -1,289 +0,0 @@ -\begin{thebibliography}{41} -\providecommand{\natexlab}[1]{#1} -\expandafter\ifx\csname urlstyle\endcsname\relax - \providecommand{\doi}[1]{doi:\discretionary{}{}{}#1}\else - \providecommand{\doi}{doi:\discretionary{}{}{}\begingroup - \urlstyle{rm}\Url}\fi - -\bibitem[{Anderman and Hill(2000)}]{anderman2000modflow} -Anderman, E.R., and Hill, M.C., 2000, MODFLOW-2000, the U.S. Geological Survey - modular ground-water model-documentation of the Hydrogeologic-Unit Flow (HUF) - Package: {U.S. Geological Survey Open-File Report 2000--342, 89 p.} - -\bibitem[{Anderman and Hill(2003)}]{anderman2003modflow} -Anderman, E.R., and Hill, M.C., 2003, MODFLOW-2000, the U.S. Geological Survey - modular ground-water model---Three additions to the Hydrogeologic-Unit Flow - (HUF) Package: Alternative storage for the uppermost active cells, flows in - hydrogeologic units, and the hydraulic-conductivity depth-dependence (KDEP) - capability: {U.S. Geological Survey Open-File Report 2003--347, 36 p.} - -\bibitem[{Bakker and others(2013)Bakker, Schaars, Hughes, Langevin, and - Dausman}]{bakker2013documentation} -Bakker, Mark, Schaars, Frans, Hughes, J.D., Langevin, C.D., and Dausman, A.M., - 2013, Documentation of the seawater intrusion (SWI2) package for MODFLOW: - {U.S. Geological Survey Techniques and Methods, book 6, chap. A46, 47 p.}, - accessed June 27, 2017, at \url{https://pubs.er.usgs.gov/publication/tm6A46}. - -\bibitem[{Banta(2000)}]{modflowdrtpack} -Banta, E.R., 2000, MODFLOW-2000, the U.S. Geological Survey Modular - Ground-Water Model; documentation of packages for simulating - evapotranspiration with a segmented function (ETS1) and drains with return - flow (DRT1): {U.S. Geological Survey Open File Report 2000--466, 127 p}. - -\bibitem[{Banta(2011)}]{banta2011modflow} -Banta, E.R., 2011, MODFLOW-CDSS, a version of MODFLOW-2005 with modifications - for Colorado Decision Support Systems: {U.S. Geological Survey Open-File - Report 2011--1213, 19 p.}, accessed June 27, 2017, at - \url{https://pubs.er.usgs.gov/publication/ofr20111213}. - -\bibitem[{Bedekar and others(2016)Bedekar, Morway, Langevin, and - Tonkin}]{mt3dusgs} -Bedekar, Vivek, Morway, E.D., Langevin, C.D., and Tonkin, M.J., 2016, MT3D-USGS - version 1: A U.S. Geological Survey release of MT3DMS updated with new and - expanded transport capabilities for use with MODFLOW: {U.S. Geological Survey - Techniques and Methods, book 6, chap. A53, 69 p.}, - \url{https://doi.org/10.3133/tm6a53}, \url{http://dx.doi.org/10.3133/tm6A53}. - -\bibitem[{Fenske and others(1996)Fenske, Leake, and - Prudic}]{fenske1996documentation} -Fenske, J.P., Leake, S.A., and Prudic, D.E., 1996, Documentation of a computer - program (RES1) to simulate leakage from reservoirs using the modular - finite-difference ground-water flow model (MODFLOW): {U.S. Geological Survey - Open-File Report 96--364, 51 p.}, accessed June 27, 2017, at - \url{https://pubs.er.usgs.gov/publication/ofr96364}. - -\bibitem[{Halford and Hanson(2002)}]{halford2002} -Halford, K.J., and Hanson, R.T., 2002, User guide for the drawdown-limited, - multi-node well (MNW) package for the U.S. Geological Survey's modular - three-dimensional finite-difference ground-water flow model, versions - MODFLOW-96 and MODFLOW-2000: {U.S. Geological Survey Open-File Report - 02--293, 33 p.} - -\bibitem[{Hanson and Leake(1999)}]{hanson1999documentation} -Hanson, R.T., and Leake, S.A., 1999, Documentation for HYDMOD---A program for - extracting and processing time-series data from the U.S. Geological Survey's - modular three-dimensional finite-difference ground-water flow model: {U.S. - Geological Survey Open-File Report 98--564, 57 p.}, accessed June 27, 2017, - at \url{https://pubs.er.usgs.gov/publication/ofr98564}. - -\bibitem[{Harbaugh(2005)}]{modflow2005} -Harbaugh, A.W., 2005, MODFLOW-2005, the U.S. Geological Survey modular - ground-water model---the Ground-Water Flow Process: {U.S. Geological Survey - Techniques and Methods, book 6, chap. A16, variously paged}, accessed June - 27, 2017, at \url{https://pubs.usgs.gov/tm/2005/tm6A16/}. - -\bibitem[{Healy and Ronan(1996)}]{healy1996} -Healy, R.W., and Ronan, A.D., 1996, Documentation of Computer Program VS2DH for - Simulation of Energy Transport in Variably Saturated Porous Media: - Modification of the U.S. Geological Survey's Computer Program VS2DT: {U.S. - Geological Survey Water-Resources Investigation Report 96-4230, 36 p.}, - accessed September 27, 2022, at \url{https://doi.org/10.3133/wri964230}, at - \url{https://pubs.usgs.gov/wri/1996/4230/report.pdf}. - -\bibitem[{Hecht-Mendez and others(2010)Hecht-Mendez, Molina-Giraldo, Blum, and - Bayer}]{hechtmendez} -Hecht-Mendez, J., Molina-Giraldo, N., Blum, P., and Bayer, P., 2010, Evaluating - mt3dms for heat transport simulation of closed geothermal systems: - Groundwater, v.~48, no.~5, p.~741--756, - \url{https://doi.org/10.1111/j.1745-6584.2010.00678.x}. - -\bibitem[{Hill(1990)}]{hill1990preconditioned} -Hill, M.C., 1990, Preconditioned Conjugate-Gradient 2 (PCG2), a computer - program for solving ground-water flow equations: {U.S. Geological Survey - Water-Resources Investigations Report 90--4048, 25 p.}, accessed June 27, - 2017, at \url{https://pubs.usgs.gov/wri/wrir_90-4048}. - -\bibitem[{Hill and others(2000)Hill, Banta, Harbaugh, and - Anderman}]{hill2000modflow} -Hill, M.C., Banta, E.R., Harbaugh, A.W., and Anderman, E.R., 2000, - MODFLOW-2000, the U.S. Geological Survey modular ground-water model---User - guide to the observation, sensitivity, and parameter-estimation processes and - three post-processing programs: {U.S. Geological Survey Open-File Report - 00--184, 210 p.} - -\bibitem[{Hoffmann and others(2003)Hoffmann, Leake, Galloway, and - Wilson}]{hoffmann2003modflow} -Hoffmann, J{\"o}rn, Leake, S.A., Galloway, D.L., and Wilson, A.M., 2003, - MODFLOW-2000 Ground-Water Model---User Guide to the Subsidence and - Aquifer-System Compaction (SUB) Package: {U.S. Geological Survey Open-File - Report 03--233, 44 p.}, accessed June 27, 2017, at - \url{https://pubs.usgs.gov/of/2003/ofr03-233/}. - -\bibitem[{Hsieh and Freckleton(1993)}]{hsieh1993hfb} -Hsieh, P.A., and Freckleton, J.R., 1993, Documentation of a computer program to - simulate horizontal-flow barriers using the U.S. Geological Survey's modular - three-dimensional finite-difference ground-water flow model: {U.S. Geological - Survey Open-File Report 92--477, 32 p.}, accessed June 27, 2017, at - \url{https://pubs.er.usgs.gov/publication/ofr92477}. - -\bibitem[{Hughes and others(2012)Hughes, Langevin, Chartier, and - White}]{hughes2012documentation} -Hughes, J.D., Langevin, C.D., Chartier, K.L., and White, J.T., 2012, - Documentation of the Surface-Water Routing (SWR1) Process for modeling - surface-water flow with the U.S. Geological Survey modular groundwater model - (MODFLOW-2005): {U.S. Geological Survey Techniques and Methods, book 6, chap. - A40 (Version 1.0), 113 p.}, accessed June 27, 2017, at - \url{https://pubs.usgs.gov/tm/6a40/}. - -\bibitem[{Hughes and others(2017)Hughes, Langevin, and - Banta}]{modflow6framework} -Hughes, J.D., Langevin, C.D., and Banta, E.R., 2017, Documentation for the - MODFLOW 6 framework: {U.S. Geological Survey Techniques and Methods, book 6, - chap. A57, 36 p.}, \url{https://doi.org/10.3133/tm6A57}. - -\bibitem[{Hughes and others(2022{\natexlab{a}})Hughes, Russcher, Langevin, - Morway, and McDonald}]{modflow6api} -Hughes, J.D., Russcher, M.J., Langevin, C.D., Morway, E.D., and McDonald, R.R., - 2022{\natexlab{a}}, The {MODFLOW Application Programming Interface} for - simulation control and software interoperability: Environmental Modelling \& - Software, v. 148, 105257, - \url{https://doi.org/10.1016/j.envsoft.2021.105257}. - -\bibitem[{Hughes and others(2022{\natexlab{b}})Hughes, Leake, Galloway, and - White}]{modflow6csub} -Hughes, J.D., Leake, S.A., Galloway, D.L., and White, J.T., 2022{\natexlab{b}}, - Documentation for the Skeletal Storage, Compaction, and Subsidence (CSUB) - Package of MODFLOW 6: {U.S. Geological Survey Techniques and Methods, book 6, - chap. A62, 57 p.}, \url{https://doi.org/10.3133/tm6A62}. - -\bibitem[{Kipp(1987)}]{kipp1987} -Kipp, K.L., 1987, HST3D: A Computer Code for Simulation of Heat and Solute - Transport in Three-Dimensional Ground-Water Flow Systems: {U.S. Geological - Survey Water-Resources Investigation Report 86-4095, 517 p.}, accessed - September 27, 2022, at \url{https://pubs.usgs.gov/wri/1986/4095/report.pdf}. - -\bibitem[{Konikow and others(2009)Konikow, Hornberger, Halford, and - Hanson}]{konikow2009} -Konikow, L.F., Hornberger, G.Z., Halford, K.J., and Hanson, R.T., 2009, Revised - multi-node well (MNW2) package for MODFLOW ground-water flow model: {U.S. - Geological Survey Techniques and Methods, book 6, chap. A30, 67 p.}, accessed - June 27, 2017, at \url{https://pubs.usgs.gov/tm/tm6a30/}. - -\bibitem[{Langevin and others(2008)Langevin, Thorne~Jr, Dausman, Sukop, and - Guo}]{langevin2008seawat} -Langevin, C.D., Thorne~Jr, D.T., Dausman, A.M., Sukop, M.C., and Guo, Weixing, - 2008, {SEAWAT} Version 4---A computer program for simulation of multi-species - solute and heat transport: {U.S. Geological Survey Techniques and Methods, - book 6, chap. A22, 39 p.}, accessed June 27, 2017, at - \url{https://pubs.er.usgs.gov/publication/tm6A22}. - -\bibitem[{Langevin and others(2017)Langevin, Hughes, Provost, Banta, Niswonger, - and Panday}]{modflow6gwf} -Langevin, C.D., Hughes, J.D., Provost, A.M., Banta, E.R., Niswonger, R.G., and - Panday, Sorab, 2017, Documentation for the MODFLOW 6 Groundwater Flow (GWF) - Model: {U.S. Geological Survey Techniques and Methods, book 6, chap. A55, 197 - p.}, \url{https://doi.org/10.3133/tm6A55}. - -\bibitem[{Langevin and others(2020)Langevin, Panday, and - Provost}]{langevin2020hydraulic} -Langevin, C.D., Panday, Sorab, and Provost, A.M., 2020, Hydraulic-head - formulation for density-dependent flow and transport: Groundwater, v.~58, - no.~3, p.~349--362. - -\bibitem[{Langevin and others(2022)Langevin, Provost, Panday, and - Hughes}]{modflow6gwt} -Langevin, C.D., Provost, A.M., Panday, Sorab, and Hughes, J.D., 2022, - Documentation for the MODFLOW 6 Groundwater Transport (GWT) Model: {U.S. - Geological Survey Techniques and Methods, book 6, chap. A61, 56 p.}, - \url{https://doi.org/10.3133/tm6A61}. - -\bibitem[{Leake and Galloway(2007)}]{leake2007modflow} -Leake, S.A., and Galloway, D.L., 2007, MODFLOW Ground-water model---User guide - to the Subsidence and Aquifer-System Compaction Package (SUB-WT) for - Water-Table Aquifers: {U.S. Geological Survey Techniques and Methods, book 6, - chap. A23, 42 p.}, accessed June 27, 2017, at - \url{https://pubs.er.usgs.gov/publication/tm6A23}. - -\bibitem[{Leake and Lilly(1997)}]{leake1997documentation} -Leake, S.A., and Lilly, M.R., 1997, Documentation of computer program (FHB1) - for assignment of transient specified-flow and specified-head boundaries in - applications of the modular finite-diference ground-water flow model - (MODFLOW): {U.S. Geological Survey Open-File Report 97--571, 50 p.}, accessed - June 27, 2017, at \url{https://pubs.er.usgs.gov/publication/ofr97571}. - -\bibitem[{Ma and Zheng(2010)}]{mazheng2010} -Ma, Rui, and Zheng, Chunmiao, 2010, Effects of density and viscosity in - modeling heat as a groundwater tracer: Groundwater, v.~48, no.~3, - p.~380--389, \url{https://doi.org/10.1111/j.1745-6584.2009.00660.x}. - -\bibitem[{Maddock and others(2012)Maddock, Baird, Hanson, Schmid, and - Ajami}]{modflowripetpack} -Maddock, Thomas, III, Baird, K.J., Hanson, R.T., Schmid, Wolfgang, and Ajami, - Hoori, 2012, RIP-ET---A Riparian Evapotranspiration Package for MODFLOW-2005: - {U.S. Geological Survey Techniques and Methods, book 6, chap. A39, 76 p.}, - accessed June 27, 2017, at \url{https://pubs.usgs.gov/tm/tm6a39/}. - -\bibitem[{Merritt and Konikow(2000)}]{modflowlak3pack} -Merritt, M.L., and Konikow, L.F., 2000, Documentation of a computer program to - simulate lake-aquifer interaction using the MODFLOW ground-water flow model - and the MOC3D solute-transport model: {U.S. Geological Survey Water-Resources - Investigations Report 00--4167, 146 p.}, accessed June 27, 2017, at - \url{https://pubs.er.usgs.gov/publication/wri004167}. - -\bibitem[{Niswonger and Prudic(2005)}]{modflowsfr2pack} -Niswonger, R.G., and Prudic, D.E., 2005, Documentation of the - Streamflow-Routing (SFR2) Package to include unsaturated flow beneath - streams---A modification to SFR1: {U.S. Geological Survey Techniques and - Methods, book 6, chap. A13, 50 p.}, accessed June 27, 2017, at - \url{https://pubs.er.usgs.gov/publication/tm6A13}. - -\bibitem[{Niswonger and others(2006)Niswonger, Prudic, and Regan}]{UZF} -Niswonger, R.G., Prudic, D.E., and Regan, R.S., 2006, Documentation of the - Unsaturated-Zone Flow (UZF1) Package for modeling unsaturated flow between - the land surface and the water table with {MODFLOW}-2005: {U.S. Geological - Survey Techniques and Methods, book 6, chap. A19, 62 p.}, accessed June 27, - 2017, at \url{https://pubs.usgs.gov/tm/2006/tm6a19/}. - -\bibitem[{Panday and others(2013)Panday, Langevin, Niswonger, Ibaraki, and - Hughes}]{modflowusg} -Panday, Sorab, Langevin, C.D., Niswonger, R.G., Ibaraki, Motomu, and Hughes, - J.D., 2013, MODFLOW-USG version 1---An unstructured grid version of MODFLOW - for simulating groundwater flow and tightly coupled processes using a control - volume finite-difference formulation: {U.S. Geological Survey Techniques and - Methods, book 6, chap. A45, 66 p.}, accessed June 27, 2017, at - \url{https://pubs.usgs.gov/tm/06/a45/}. - -\bibitem[{Provost and others(2017)Provost, Langevin, and Hughes}]{modflow6xt3d} -Provost, A.M., Langevin, C.D., and Hughes, J.D., 2017, Documentation for the - ``XT3D'' Option in the Node Property Flow (NPF) Package of MODFLOW 6: {U.S. - Geological Survey Techniques and Methods, book 6, chap. A56, 46 p.}, - \url{https://doi.org/10.3133/tm6A56}. - -\bibitem[{Prudic(1989)}]{prudic1989str} -Prudic, D.E., 1989, Documentation of a computer program to simulate - stream-aquifer relations using a modular, finite-difference, ground-water - flow model: {U.S. Geological Survey Open-File Report 88--729, 113 p.}, - accessed June 27, 2017, at - \url{https://pubs.er.usgs.gov/publication/ofr88729}. - -\bibitem[{Prudic and others(2004)Prudic, Konikow, and Banta}]{modflowsfr1pack} -Prudic, D.E., Konikow, L.F., and Banta, E.R., 2004, A New Streamflow-Routing - (SFR1) Package to simulate stream-aquifer interaction with MODFLOW-2000: - {U.S. Geological Survey Open File Report 2004--1042, 104 p.}, accessed June - 27, 2017, at \url{https://pubs.er.usgs.gov/publication/ofr20041042}. - -\bibitem[{Voss(1984)}]{Voss1984sutra} -Voss, C.I., 1984, SUTRA---A finite-element simulation model for - saturated-unsaturated fluid-density-dependent ground-water flow with energy - transport or chemically-reactive single-species solute transport: {U.S. - Geological Survey Water-Resources Investigations Report 84--4369, 409 p.} - -\bibitem[{Zheng(2010)}]{zheng2010supplemental} -Zheng, Chunmiao, 2010, MT3DMS v5.3, Supplemental User's Guide: {Technical - Report Prepared for the U.S. Army Corps of Engineers, 51 p.} - -\bibitem[{Zheng and Wang(1999)}]{zheng1999mt3dms} -Zheng, Chunmiao, and Wang, P.P., 1999, MT3DMS---A modular three-dimensional - multi-species transport model for simulation of advection, dispersion and - chemical reactions of contaminants in groundwater systems; Documentation and - user's guide: {Contract report SERDP--99--1: Vicksburg, Miss., U.S. Army - Engineer Research and Development Center, 169 p.} - -\bibitem[{Zheng and others(2001)Zheng, Hill, and Hsieh}]{zheng2001modflow} -Zheng, Chunmiao, Hill, M.C., and Hsieh, P.A., 2001, MODFLOW-2000, the U.S. - Geological Survey Modular Ground-Water Model---User guide to the LMT6 - package, the linkage with MT3DMS for multi-species mass transport modeling: - {U.S. Geological Survey Open-File Report 01--82, 43 p.}, accessed June 27, - 2017, at \url{https://pubs.er.usgs.gov/publication/ofr0182}. - -\end{thebibliography} From fa190fd79c219c48a7bd3b94126a735340e5a123 Mon Sep 17 00:00:00 2001 From: Eric Morway Date: Fri, 9 Feb 2024 12:23:24 -0800 Subject: [PATCH 46/46] Update release notes --- doc/ReleaseNotes/develop.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/ReleaseNotes/develop.tex b/doc/ReleaseNotes/develop.tex index f4813a50b54..11ac03ea128 100644 --- a/doc/ReleaseNotes/develop.tex +++ b/doc/ReleaseNotes/develop.tex @@ -3,12 +3,12 @@ \item \currentmodflowversion - %\underline{NEW FUNCTIONALITY} - %\begin{itemize} - % \item xxx + \underline{NEW FUNCTIONALITY} + \begin{itemize} + \item A new Groundwater Energy (GWE) transport model is introduced to the code base for simulating heat transport in the subsurface. Additional information for activating the GWE model type within a MODFLOW 6 simulation is available within the mf6io.pdf document. New example problems have been developed for testing and demonstrating GWE capabilities (in addition to other internal tests that help verify the accuracy of GWE); however, additional changes to the code and input may be necessary in response to user needs and further testing. % \item xxx % \item xxx - %\end{itemize} + \end{itemize} %\underline{EXAMPLES} %\begin{itemize}