Source code for flopy.mfusg.mfusgwel

"""
Mfusgwel module.

Contains the MfUsgWel class. Note that the user can access
the MfUsgWel class as `flopy.mfusg.MfUsgWel`.

Additional information for this MODFLOW package can be found at the `Online
MODFLOW Guide
<https://water.usgs.gov/ogw/modflow/MODFLOW-2005-Guide/wel.html>`_.
"""

from ..modflow.mfwel import ModflowWel
from ..utils import MfList
from .mfusg import MfUsg


[docs]class MfUsgWel(ModflowWel): """MODFLOW-USG Well Package Class. Parameters ---------- model : model object The model object (of type :class:`flopy.modflow.mf.Modflow`) to which this package will be added. ipakcb : int, optional Toggles whether cell-by-cell budget data should be saved. If None or zero, budget data will not be saved (default is None). stress_period_data : list of boundaries, or recarray of boundaries, or dictionary of boundaries For structured grid, each well is defined through definition of layer (int), row (int), column (int), flux (float). The simplest form is a dictionary with a lists of boundaries for each stress period, where each list of boundaries itself is a list of boundaries. Indices of the dictionary are the numbers of the stress period. This gives the form of: stress_period_data = {0: [ [lay, row, col, flux], [lay, row, col, flux], [lay, row, col, flux] ], 1: [ [lay, row, col, flux], [lay, row, col, flux], [lay, row, col, flux] ], ... kper: [ [lay, row, col, flux], [lay, row, col, flux], [lay, row, col, flux] ] } For unstructured grid, stress_period_data = {0: [ [node, flux], [node, flux], [node, flux] ], 1: [ [node, flux], [node, flux], [node, flux] ], ... kper: [ [node, flux], [node, flux], [node, flux] ] } Note that if the number of lists is smaller than the number of stress periods, then the last list of wells will apply until the end of the simulation. Full details of all options to specify stress_period_data can be found in the flopy3 boundaries Notebook in the basic subdirectory of the examples directory cln_stress_period_data : list of boundaries, or recarray of boundaries, or dictionary of boundaries Stress period data of wells simulated as Connected Linear Network (CLN) The simplest form is a dictionary with a lists of boundaries for each stress period, where each list of boundaries itself is a list of boundaries. Indices of the dictionary are the numbers of the stress period. This gives the form of: cln_stress_period_data = {0: [ [iclnnode, flux], [iclnnode, flux], [iclnnode, flux] ], 1: [ [iclnnode, flux], [iclnnode, flux], [iclnnode, flux] ], ... kper: [ [iclnnode, flux], [iclnnode, flux], [iclnnode, flux] ] } dtype : custom datatype of stress_period_data. If None the default well datatype will be applied (default is None). cln_dtype : custom datatype of cln_stress_period_data. If None the default well datatype will be applied (default is None). extension : string Filename extension (default is 'wel') options : list of strings Package options (default is None). unitnumber : int File unit number (default is None). filenames : str or list of str Filenames to use for the package and the output files. If filenames=None the package name will be created using the model name and package extension and the cbc output name will be created using the model name and .cbc extension (for example, modflowtest.cbc), if ipakcb is a number greater than zero. If a single string is passed the package will be set to the string and cbc output names will be created using the model name and .cbc extension, if ipakcb is a number greater than zero. To define the names for all package files (input and output) the length of the list of strings should be 2. Default is None. add_package : bool Flag to add the initialised package object to the parent model object. Default is True. Attributes ---------- mxactw : int Maximum number of wells for a stress period. This is calculated automatically by FloPy based on the information in stress_period_data. Methods ------- See Also -------- Notes ----- Parameters are not supported in FloPy. Examples -------- >>> import flopy >>> m = flopy.mfusg.MfUsg() >>> lrcq = {0:[[2, 3, 4, -100.]], 1:[[2, 3, 4, -100.]]} >>> wel = flopy.mfusg.MfUsgWel(m, stress_period_data=lrcq) """ def __init__( self, model, ipakcb=None, stress_period_data=None, cln_stress_period_data=None, dtype=None, cln_dtype=None, extension="wel", options=None, binary=False, unitnumber=None, filenames=None, add_package=True, ): """Package constructor.""" msg = ( "Model object must be of type flopy.mfusg.MfUsg\n" f"but received type: {type(model)}." ) assert isinstance(model, MfUsg), msg # set filenames filenames = self._prepare_filenames(filenames) super().__init__( model, ipakcb=ipakcb, stress_period_data=stress_period_data, dtype=dtype, extension=extension, options=options, binary=binary, unitnumber=unitnumber, filenames=filenames, add_package=False, ) self.autoflowreduce = False self.iunitafr = 0 for opt in self.options: if "autoflowreduce" in opt.lower(): self.autoflowreduce = True if "iunitafr" in opt.lower(): line_text = opt.strip().split() self.iunitafr = int(line_text[1]) if self.iunitafr > 0: model.add_output_file( self.iunitafr, fname=filenames[1], extension="afr", binflag=False, package=self._ftype(), ) # initialize CLN MfList # CLN WELs are always read as CLNNODE Q, so dtype must be of unstructured form if cln_dtype is None: cln_dtype = MfUsgWel.get_default_dtype(structured=False) self.dtype = cln_dtype # determine if any aux variables in cln_dtype options = self._check_for_aux(options, cln=True) self.cln_stress_period_data = MfList( self, cln_stress_period_data, binary=binary ) # reset self.dtype for cases where the model is structured but CLN WELs are used if dtype is not None: self.dtype = dtype else: self.dtype = self.get_default_dtype( structured=self.parent.structured ) # determine if any aux variables in dtype options = self._check_for_aux(options) self.options = options # initialize MfList self.stress_period_data = MfList( self, stress_period_data, binary=binary ) if add_package: self.parent.add_package(self) def _check_for_aux(self, options, cln=False): """Check dtype for auxiliary variables, and add to options. Parameters: ---------- options: (list) package options Returns ------- options: list Package options strings """ if cln: dt = self.get_default_dtype(structured=False) else: dt = self.get_default_dtype(structured=self.parent.structured) if len(self.dtype.names) > len(dt.names): for name in self.dtype.names[len(dt.names) :]: ladd = True for option in options: if name.lower() in option.lower(): ladd = False break if ladd: options.append(f"aux {name} ") return options
[docs] def write_file(self, f=None): """Write the package file. Parameters: ---------- f: (str) optional file name Returns ------- None """ if f is None: f_wel = open(self.fn_path, "w") elif isinstance(f, str): f_wel = open(f, "w") else: f_wel = f f_wel.write(f"{self.heading}\n") mxact = ( self.stress_period_data.mxact + self.cln_stress_period_data.mxact ) line = f" {mxact:9d} {self.ipakcb:9d} " if self.options is None: self.options = [] for opt in self.options: line += " " + str(opt) line += "\n" f_wel.write(line) # gwf wels (and possibly cln wells) self.stress_period_data.write_transient( f_wel, cln_data=self.cln_stress_period_data ) f_wel.close()