Source code for flopy.modflow.mfpar

"""
mfpar module.  Contains the ModflowPar class. Note that the user can access
the ModflowPar class as `flopy.modflow.ModflowPar`.


"""

import numpy as np

from .mfmlt import ModflowMlt
from .mfpval import ModflowPval
from .mfzon import ModflowZon


[docs]class ModflowPar: """ Class for loading mult, zone, pval, and parameter data for MODFLOW packages that use array data (LPF, UPW, RCH, EVT). Class also includes methods to create data arrays using mult, zone, pval, and parameter data (not used for boundary conditions). Notes ----- Parameters are supported in Flopy only when reading in existing models. Parameter values are converted to native values in Flopy and the connection to "parameters" is thus nonexistent. """ def __init__(self): """ Package constructor. """ self.pval = None self.mult = None self.zone = None return
[docs] def set_zone(self, model, ext_unit_dict): """ Load an existing zone package and set zone data for a model. Parameters ---------- model : model object The model object (of type :class:`flopy.modflow.mf.Modflow`) to which this package will be added. ext_unit_dict : dictionary, optional If the arrays in the file are specified using EXTERNAL, or older style array control records, then `f` should be a file handle. In this case ext_unit_dict is required, which can be constructed using the function :class:`flopy.utils.mfreadnam.parsenamefile`. Returns ------- Examples -------- >>> ml.mfpar.set_zone(ml, ext_unit_dict) """ zone = None zone_key = None for key, item in ext_unit_dict.items(): if item.filetype.lower() == "zone": zone = item zone_key = key if zone_key is not None: try: self.zone = ModflowZon.load( zone.filename, model, ext_unit_dict=ext_unit_dict ) if model.verbose: print(f" {self.zone.name[0]} package load...success") ext_unit_dict.pop(zone_key) model.remove_package("ZONE") except BaseException as o: print(f" ZONE package load...failed\n {o!s}") return
[docs] def set_mult(self, model, ext_unit_dict): """ Load an existing mult package and set mult data for a model. Parameters ---------- model : model object The model object (of type :class:`flopy.modflow.mf.Modflow`) to which this package will be added. ext_unit_dict : dictionary, optional If the arrays in the file are specified using EXTERNAL, or older style array control records, then `f` should be a file handle. In this case ext_unit_dict is required, which can be constructed using the function :class:`flopy.utils.mfreadnam.parsenamefile`. Returns ------- Examples -------- >>> ml.mfpar.set_mult(ml, ext_unit_dict) """ mult = None mult_key = None for key, item in ext_unit_dict.items(): if item.filetype.lower() == "mult": mult = item mult_key = key if mult_key is not None: try: self.mult = ModflowMlt.load( mult.filename, model, ext_unit_dict=ext_unit_dict ) if model.verbose: print(f" {self.mult.name[0]} package load...success") ext_unit_dict.pop(mult_key) model.remove_package("MULT") except BaseException as o: print(f" MULT package load...failed\n {o!s}") return
[docs] def set_pval(self, model, ext_unit_dict): """ Load an existing pval package and set pval data for a model. Parameters ---------- model : model object The model object (of type :class:`flopy.modflow.mf.Modflow`) to which this package will be added. ext_unit_dict : dictionary, optional If the arrays in the file are specified using EXTERNAL, or older style array control records, then `f` should be a file handle. In this case ext_unit_dict is required, which can be constructed using the function :class:`flopy.utils.mfreadnam.parsenamefile`. Returns ------- Examples -------- >>> ml.mfpar.set_pval(ml, ext_unit_dict) """ pval = None pval_key = None for key, item in ext_unit_dict.items(): if item.filetype.lower() == "pval": pval = item pval_key = key if pval_key is not None: try: self.pval = ModflowPval.load( pval.filename, model, ext_unit_dict=ext_unit_dict ) if model.verbose: print(f" {self.pval.name[0]} package load...success") ext_unit_dict.pop(pval_key) model.remove_package("PVAL") except BaseException as o: print(f" PVAL package load...failed\n {o!s}") return
[docs] @staticmethod def load(f, npar, verbose=False): """ Load property parameters from an existing package. Parameters ---------- f : file handle npar : int The number of parameters. verbose : bool Boolean flag to control output. (default is False) Returns ------- list : list object of unique par_types in file f dictionary : dictionary object with parameters in file f Examples -------- >>>par_types, parm_dict = flopy.modflow.mfpar.ModflowPar.load(f, np) """ # read parameter data if npar > 0: parm_dict = {} par_types = [] for nprm in range(npar): line = f.readline() t = line.strip().split() parnam = t[0].lower() if verbose: print(f' loading parameter "{parnam}"...') partyp = t[1].lower() if partyp not in par_types: par_types.append(partyp) parval = float(t[2]) nclu = int(t[3]) clusters = [] for nc in range(nclu): line = f.readline() t = line.strip().split() lay = int(t[0]) s = t[1] if len(s) > 10: s = s[0:10] mltarr = s s = t[2] if len(s) > 10: s = s[0:10] zonarr = s iarr = [] for iv in t[3:]: try: iz = int(iv) if iz != 0: iarr.append(iz) except: break clusters.append([lay, mltarr, zonarr, iarr]) # add parnam to parm_dict parm_dict[parnam] = { "partyp": partyp, "parval": parval, "nclu": nclu, "clusters": clusters, } return par_types, parm_dict
[docs] @staticmethod def parameter_fill(model, shape, findkey, parm_dict, findlayer=None): """ Fill an array with parameters using zone, mult, and pval data. Parameters ---------- model : model object The model object (of type :class:`flopy.modflow.mf.Modflow`) to which this package will be added. shape : tuple The shape of the returned data array. Typically shape is (nrow, ncol) findkey : string the parameter array to be constructed, parm_dict : dict dictionary that includes all of the parameter data for a package findlayer : int Layer that will be filled. Not required for array boundary condition data. Returns ------- data : numpy array Filled array resulting from applications of zone, mult, pval, and parameter data. Examples -------- for lpf and upw: >>> data = flopy.modflow.mfpar.ModflowPar.parameter_fill(m, (nrow, ncol), 'vkcb', >>> .....................................................parm_dict, findlayer=1) """ dtype = np.float32 data = np.zeros(shape, dtype=dtype) for key, tdict in parm_dict.items(): partyp, parval = tdict["partyp"], tdict["parval"] nclu, clusters = tdict["nclu"], tdict["clusters"] if model.mfpar.pval is None: pv = float(parval) else: try: pv = float(model.mfpar.pval.pval_dict[key.lower()]) except: pv = float(parval) # print partyp, parval, nclu, clusters if partyp == findkey: for [layer, mltarr, zonarr, izones] in clusters: # print layer, mltarr, zonarr, izones foundlayer = False if findlayer is None: foundlayer = True else: if layer == (findlayer + 1): foundlayer = True if foundlayer: model.parameter_load = True cluster_data = np.zeros(shape, dtype=dtype) if mltarr.lower() == "none": mult = np.ones(shape, dtype=dtype) else: mult = model.mfpar.mult.mult_dict[mltarr.lower()][ :, : ] if zonarr.lower() == "all": cluster_data = pv * mult else: mult_save = np.copy(mult) za = model.mfpar.zone.zone_dict[zonarr.lower()][ :, : ] # build a multiplier for all of the izones mult = np.zeros(shape, dtype=dtype) for iz in izones: filtarr = za == iz mult[filtarr] += np.copy(mult_save[filtarr]) # calculate parameter value for this cluster cluster_data = pv * mult # add data data += cluster_data return data