Note
Working with MODFLOW-NWT v 1.1 option blocks
In MODFLOW-NWT an option block is present for the WEL file, UZF file, and SFR file. This block takes keyword arguments that are supplied in an option line in other versions of MODFLOW.
The OptionBlock
class was created to provide combatibility with the MODFLOW-NWT option block and allow the user to easily edit values within the option block
[1]:
import os
import sys
from tempfile import TemporaryDirectory
try:
import flopy
except:
fpth = os.path.abspath(os.path.join("..", ".."))
sys.path.append(fpth)
import flopy
from flopy.utils import OptionBlock
print(sys.version)
print("flopy version: {}".format(flopy.__version__))
3.10.10 | packaged by conda-forge | (main, Mar 24 2023, 20:08:06) [GCC 11.3.0]
flopy version: 3.3.7
[2]:
load_ws = os.path.join("..", "..", "examples", "data", "options", "sagehen")
# temporary directory
temp_dir = TemporaryDirectory()
model_ws = os.path.join(temp_dir.name, "nwt_options", "output")
Loading a MODFLOW-NWT model that has option block options
It is critical to set the version
flag in flopy.modflow.Modflow.load()
to version='mfnwt'
We are going to load a modified version of the Sagehen test problem from GSFLOW to illustrate compatibility
[3]:
mfexe = "mfnwt"
ml = flopy.modflow.Modflow.load(
"sagehen.nam", model_ws=load_ws, exe_name=mfexe, version="mfnwt"
)
ml.change_model_ws(new_pth=model_ws)
ml.write_input()
loading iuzfbnd array...
loading vks array...
loading eps array...
loading thts array...
stress period 1:
loading finf array...
stress period 2:
creating model workspace...
../../../../../../../tmp/tmp6a64bhtb/nwt_options/output
Let’s look at the options attribute of the UZF object
The uzf.options
attribute is an OptionBlock
object. The representation of this object is the option block that will be written to output, which allows the user to easily check to make sure the block has the options they want.
[4]:
uzf = ml.get_package("UZF")
uzf.options
[4]:
OPTIONS
NOSURFLEAK
ETSQUARE 0.2
SAVEFINF
END
The OptionBlock
object also has attributes which correspond to the option names listed in the online guide to modflow
The user can call and edit the options within the option block
[5]:
print(uzf.options.nosurfleak)
print(uzf.options.savefinf)
True
True
[6]:
uzf.options.etsquare = False
uzf.options
[6]:
OPTIONS
NOSURFLEAK
SAVEFINF
END
[7]:
uzf.options.etsquare = True
uzf.options
[7]:
OPTIONS
NOSURFLEAK
ETSQUARE 0.2
SAVEFINF
END
The user can also see the single line representation of the options
[8]:
uzf.options.single_line_options
[8]:
'NOSURFLEAK ETSQUARE 0.2 SAVEFINF'
And the user can easily change to single line options writing
[9]:
uzf.options.block = False
# write out only the uzf file
uzf_name = "uzf_opt.uzf"
uzf.write_file(os.path.join(model_ws, uzf_name))
Now let’s examine the first few lines of the new UZF file
[10]:
f = open(os.path.join(model_ws, uzf_name))
for ix, line in enumerate(f):
if ix == 3:
break
else:
print(line)
# UZF package for MODFLOW-NWT generated by Flopy 3.3.7
NOSURFLEAK ETSQUARE 0.2 SAVEFINF
3 1 0 0 0 0 15 100 4 1.000000E+00 #NUZTOP IUZFOPT IRUNFLG IETFLG ipakcb IUZFCB2 NTRAIL NSETS NUZGAGES
And let’s load the new UZF file
[11]:
uzf2 = flopy.modflow.ModflowUzf1.load(
os.path.join(model_ws, uzf_name), ml, check=False
)
loading iuzfbnd array...
loading vks array...
loading eps array...
loading thts array...
stress period 1:
loading finf array...
stress period 2:
Now we can look at the options object, and check if it’s block or line format
block=False
indicates that options will be written as line format
[12]:
print(uzf2.options)
print(uzf2.options.block)
OPTIONS
NOSURFLEAK
ETSQUARE 0.2
SAVEFINF
END
False
Finally we can convert back to block format
[13]:
uzf2.options.block = True
uzf2.write_file(os.path.join(model_ws, uzf_name))
ml.remove_package("UZF")
uzf3 = flopy.modflow.ModflowUzf1.load(
os.path.join(model_ws, uzf_name), ml, check=False
)
print("\n")
print(uzf3.options)
print(uzf3.options.block)
loading iuzfbnd array...
loading vks array...
loading eps array...
loading thts array...
stress period 1:
loading finf array...
stress period 2:
OPTIONS
NOSURFLEAK
ETSQUARE 0.2
SAVEFINF
END
True
We can also look at the WEL object
[14]:
wel = ml.get_package("WEL")
wel.options
[14]:
OPTIONS
SPECIFY 0.1 90
END
Let’s write this out as a single line option block and examine the first few lines
[15]:
wel_name = "wel_opt.wel"
wel.options.block = False
wel.write_file(os.path.join(model_ws, wel_name))
f = open(os.path.join(model_ws, wel_name))
for ix, line in enumerate(f):
if ix == 4:
break
else:
print(line)
# WEL package for MODFLOW-NWT generated by Flopy 3.3.7
5 0 NOPRINT
SPECIFY 0.1 90
5 0 # stress period 1
And we can load the new single line options WEL file and confirm that it is being read as an option line
[16]:
ml.remove_package("WEL")
wel2 = flopy.modflow.ModflowWel.load(
os.path.join(model_ws, wel_name), ml, nper=ml.nper, check=False
)
wel2.options
wel2.options.block
[16]:
False
Building an OptionBlock from scratch
The user can also build an OptionBlock
object from scratch to add to a ModflowSfr2
, ModflowUzf1
, or ModflowWel
file.
The OptionBlock
class has two required parameters and one optional parameter
option_line
: a one line, string based representation of the options
package
: a modflow package object
block
: boolean flag for line based or block based options
[17]:
opt_line = "specify 0.1 20"
options = OptionBlock(opt_line, flopy.modflow.ModflowWel, block=True)
options
[17]:
OPTIONS
SPECIFY 0.1 20
END
from here we can set the noprint flag by using options.noprint
[18]:
options.noprint = True
and the user can also add auxillary variables by using options.auxillary
[19]:
options.auxillary = ["aux", "iface"]
and write it to output
[20]:
wel3 = flopy.modflow.ModflowWel(
ml,
stress_period_data=wel.stress_period_data,
options=options,
unitnumber=99,
)
wel3.write_file(os.path.join(model_ws, wel_name))
And now let’s examine the first few lines of the file
[21]:
f = open(os.path.join(model_ws, wel_name))
for ix, line in enumerate(f):
if ix == 8:
break
else:
print(line)
# WEL package for MODFLOW-NWT generated by Flopy 3.3.7
OPTIONS
SPECIFY 0.1 20
END
5 0 NOPRINT AUX IFACE
5 0 # stress period 1
1 35 12 20.0
1 36 13 21.0
We can see that everything that the OptionBlock class writes out options in the correct location.
[22]:
wel3.options.block = False
wel3.write_file(os.path.join(model_ws, wel_name))
f = open(os.path.join(model_ws, wel_name))
for ix, line in enumerate(f):
if ix == 6:
break
else:
print(line)
# WEL package for MODFLOW-NWT generated by Flopy 3.3.7
5 0 NOPRINT AUX IFACE
SPECIFY 0.1 20
5 0 # stress period 1
1 35 12 20.0
1 36 13 21.0
[23]:
try:
# ignore PermissionError on Windows
temp_dir.cleanup()
except:
pass