import os
from ..mbase import BaseModel
from ..pakbase import Package
from ..modflow import Modflow
from ..mt3d import Mt3dms
from .swtvdf import SeawatVdf
from .swtvsc import SeawatVsc
from ..discretization.structuredgrid import StructuredGrid
from flopy.discretization.modeltime import ModelTime
[docs]class SeawatList(Package):
"""
List Package class
"""
def __init__(self, model, extension="list", listunit=7):
Package.__init__(self, model, extension, "LIST", listunit)
return
def __repr__(self):
return "List package class"
[docs] def write_file(self):
# Not implemented for list class
return
[docs]class Seawat(BaseModel):
"""
SEAWAT Model Class.
Parameters
----------
modelname : string, optional
Name of model. This string will be used to name the SEAWAT input
that are created with write_model. (the default is 'swttest')
namefile_ext : string, optional
Extension for the namefile (the default is 'nam')
version : string, optional
Version of SEAWAT to use (the default is 'seawat').
exe_name : string, optional
The name of the executable to use (the default is
'swtv4.exe').
listunit : integer, optional
Unit number for the list file (the default is 2).
model_ws : string, optional
model workspace. Directory name to create model data sets.
(default is the present working directory).
external_path : string
Location for external files (default is None).
verbose : boolean, optional
Print additional information to the screen (default is False).
load : boolean, optional
(default is True).
silent : integer
(default is 0)
Attributes
----------
Methods
-------
See Also
--------
Notes
-----
Examples
--------
>>> import flopy
>>> m = flopy.seawat.swt.Seawat()
"""
def __init__(
self,
modelname="swttest",
namefile_ext="nam",
modflowmodel=None,
mt3dmodel=None,
version="seawat",
exe_name="swtv4",
structured=True,
listunit=2,
model_ws=".",
external_path=None,
verbose=False,
load=True,
silent=0,
):
# Call constructor for parent object
BaseModel.__init__(
self,
modelname,
namefile_ext,
exe_name,
model_ws,
structured=structured,
verbose=verbose,
)
# Set attributes
self.version_types = {"seawat": "SEAWAT"}
self.set_version(version)
self.lst = SeawatList(self, listunit=listunit)
self.glo = None
self._mf = None
self._mt = None
# If a MODFLOW model was passed in, then add its packages
self.mf = self
if modflowmodel is not None:
for p in modflowmodel.packagelist:
self.packagelist.append(p)
self._modelgrid = modflowmodel.modelgrid
else:
modflowmodel = Modflow()
# If a MT3D model was passed in, then add its packages
if mt3dmodel is not None:
for p in mt3dmodel.packagelist:
self.packagelist.append(p)
else:
mt3dmodel = Mt3dms()
# external option stuff
self.array_free_format = False
self.array_format = "mt3d"
self.external_fnames = []
self.external_units = []
self.external_binflag = []
self.external = False
self.load = load
# the starting external data unit number
self._next_ext_unit = 3000
if external_path is not None:
assert model_ws == ".", (
"ERROR: external cannot be used " + "with model_ws"
)
# external_path = os.path.join(model_ws, external_path)
if os.path.exists(external_path):
print(
"Note: external_path "
+ str(external_path)
+ " already exists"
)
# assert os.path.exists(external_path),'external_path does not exist'
else:
os.mkdir(external_path)
self.external = True
self.external_path = external_path
self.verbose = verbose
self.silent = silent
# Create a dictionary to map package with package object.
# This is used for loading models.
self.mfnam_packages = {}
for k, v in modflowmodel.mfnam_packages.items():
self.mfnam_packages[k] = v
for k, v in mt3dmodel.mfnam_packages.items():
self.mfnam_packages[k] = v
self.mfnam_packages["vdf"] = SeawatVdf
self.mfnam_packages["vsc"] = SeawatVsc
return
@property
def modeltime(self):
# build model time
data_frame = {
"perlen": self.dis.perlen.array,
"nstp": self.dis.nstp.array,
"tsmult": self.dis.tsmult.array,
}
self._model_time = ModelTime(
data_frame,
self.dis.itmuni_dict[self.dis.itmuni],
self.dis.start_datetime,
self.dis.steady.array,
)
return self._model_time
@property
def modelgrid(self):
if not self._mg_resync:
return self._modelgrid
if self.has_package("bas6"):
ibound = self.bas6.ibound.array
else:
ibound = None
# build grid
# self.dis should exist if modflow model passed
self._modelgrid = StructuredGrid(
self.dis.delc.array,
self.dis.delr.array,
self.dis.top.array,
self.dis.botm.array,
idomain=ibound,
lenuni=self.dis.lenuni,
proj4=self._modelgrid.proj4,
epsg=self._modelgrid.epsg,
xoff=self._modelgrid.xoffset,
yoff=self._modelgrid.yoffset,
angrot=self._modelgrid.angrot,
nlay=self.dis.nlay,
)
# resolve offsets
xoff = self._modelgrid.xoffset
if xoff is None:
if self._xul is not None:
xoff = self._modelgrid._xul_to_xll(self._xul)
else:
xoff = 0.0
yoff = self._modelgrid.yoffset
if yoff is None:
if self._yul is not None:
yoff = self._modelgrid._yul_to_yll(self._yul)
else:
yoff = 0.0
self._modelgrid.set_coord_info(
xoff,
yoff,
self._modelgrid.angrot,
self._modelgrid.epsg,
self._modelgrid.proj4,
)
self._mg_resync = not self._modelgrid.is_complete
return self._modelgrid
@property
def nlay(self):
if self.dis:
return self.dis.nlay
else:
return 0
@property
def nrow(self):
if self.dis:
return self.dis.nrow
else:
return 0
@property
def ncol(self):
if self.dis:
return self.dis.ncol
else:
return 0
@property
def nper(self):
if self.dis:
return self.dis.nper
else:
return 0
@property
def nrow_ncol_nlay_nper(self):
dis = self.get_package("DIS")
if dis:
return dis.nrow, dis.ncol, dis.nlay, dis.nper
else:
return 0, 0, 0, 0
[docs] def get_nrow_ncol_nlay_nper(self):
return self.nrow_ncol_nlay_nper
[docs] def get_ifrefm(self):
bas = self.get_package("BAS6")
if bas:
return bas.ifrefm
else:
return False
@property
def ncomp(self):
if self.btn:
return self.btn.ncomp
else:
return 1
@property
def mcomp(self):
if self.btn:
return self.btn.mcomp
else:
return 1
def _set_name(self, value):
# Overrides BaseModel's setter for name property
BaseModel._set_name(self, value)
# for i in range(len(self.lst.extension)):
# self.lst.file_name[i] = self.name + '.' + self.lst.extension[i]
# return
[docs] def change_model_ws(self, new_pth=None, reset_external=False):
# if hasattr(self,"_mf"):
if self._mf is not None:
self._mf.change_model_ws(
new_pth=new_pth, reset_external=reset_external
)
# if hasattr(self,"_mt"):
if self._mt is not None:
self._mt.change_model_ws(
new_pth=new_pth, reset_external=reset_external
)
super(Seawat, self).change_model_ws(
new_pth=new_pth, reset_external=reset_external
)
[docs] def write_name_file(self):
"""
Write the name file
Returns
-------
None
"""
# open and write header
fn_path = os.path.join(self.model_ws, self.namefile)
f_nam = open(fn_path, "w")
f_nam.write("{}\n".format(self.heading))
# Write global file entry
if self.glo is not None:
if self.glo.unit_number[0] > 0:
f_nam.write(
"{:14s} {:5d} {}\n".format(
self.glo.name[0],
self.glo.unit_number[0],
self.glo.file_name[0],
)
)
# Write list file entry
f_nam.write(
"{:14s} {:5d} {}\n".format(
self.lst.name[0],
self.lst.unit_number[0],
self.lst.file_name[0],
)
)
# Write SEAWAT entries and close
f_nam.write("{}".format(self.get_name_file_entries()))
if self._mf is not None:
# write the external files
for b, u, f in zip(
self._mf.external_binflag,
self._mf.external_units,
self._mf.external_fnames,
):
tag = "DATA"
if b:
tag = "DATA(BINARY)"
f_nam.write("{0:14s} {1:5d} {2}\n".format(tag, u, f))
# write the output files
for u, f, b in zip(
self._mf.output_units,
self._mf.output_fnames,
self._mf.output_binflag,
):
if u == 0:
continue
if b:
f_nam.write(
"DATA(BINARY) {0:5d} ".format(u) + f + " REPLACE\n"
)
else:
f_nam.write("DATA {0:5d} ".format(u) + f + "\n")
if self._mt is not None:
# write the external files
for b, u, f in zip(
self._mt.external_binflag,
self._mt.external_units,
self._mt.external_fnames,
):
tag = "DATA"
if b:
tag = "DATA(BINARY)"
f_nam.write("{0:14s} {1:5d} {2}\n".format(tag, u, f))
# write the output files
for u, f, b in zip(
self._mt.output_units,
self._mt.output_fnames,
self._mt.output_binflag,
):
if u == 0:
continue
if b:
f_nam.write(
"DATA(BINARY) {0:5d} ".format(u) + f + " REPLACE\n"
)
else:
f_nam.write("DATA {0:5d} ".format(u) + f + "\n")
# write the external files
for b, u, f in zip(
self.external_binflag, self.external_units, self.external_fnames
):
tag = "DATA"
if b:
tag = "DATA(BINARY)"
f_nam.write("{0:14s} {1:5d} {2}\n".format(tag, u, f))
# write the output files
for u, f, b in zip(
self.output_units, self.output_fnames, self.output_binflag
):
if u == 0:
continue
if b:
f_nam.write(
"DATA(BINARY) {0:5d} ".format(u) + f + " REPLACE\n"
)
else:
f_nam.write("DATA {0:5d} ".format(u) + f + "\n")
f_nam.close()
return
[docs] @classmethod
def load(
cls,
f,
version="seawat",
exe_name="swtv4",
verbose=False,
model_ws=".",
load_only=None,
):
"""
Load an existing model.
Parameters
----------
f : string
Full path and name of SEAWAT name file.
version : string
The version of SEAWAT (seawat)
(default is seawat)
exe_name : string
The name of the executable to use if this loaded model is run.
(default is swtv4.exe)
verbose : bool
Write information on the load process if True.
(default is False)
model_ws : string
The path for the model workspace.
(default is the current working directory '.')
load_only : list of strings
Filetype(s) to load (e.g. ['lpf', 'adv'])
(default is None, which means that all will be loaded)
Returns
-------
m : flopy.seawat.swt.Seawat
flopy Seawat model object
Examples
--------
>>> import flopy
>>> m = flopy.seawat.swt.Seawat.load(f)
"""
# test if name file is passed with extension (i.e., is a valid file)
if os.path.isfile(os.path.join(model_ws, f)):
modelname = f.rpartition(".")[0]
else:
modelname = f
# create instance of a seawat model and load modflow and mt3dms models
ms = cls(
modelname=modelname,
namefile_ext="nam",
modflowmodel=None,
mt3dmodel=None,
version=version,
exe_name=exe_name,
model_ws=model_ws,
verbose=verbose,
)
mf = Modflow.load(
f,
version="mf2k",
exe_name=None,
verbose=verbose,
model_ws=model_ws,
load_only=load_only,
forgive=False,
check=False,
)
mt = Mt3dms.load(
f,
version="mt3dms",
exe_name=None,
verbose=verbose,
model_ws=model_ws,
forgive=False,
)
# set listing and global files using mf objects
ms.lst = mf.lst
ms.glo = mf.glo
for p in mf.packagelist:
p.parent = ms
ms.add_package(p)
ms._mt = None
if mt is not None:
for p in mt.packagelist:
p.parent = ms
ms.add_package(p)
mt.external_units = []
mt.external_binflag = []
mt.external_fnames = []
ms._mt = mt
ms._mf = mf
# return model object
return ms