Source code for flopy.modflow.mfparbc

"""
mfparbc module.  Contains the ModflowParBc class. Note that the user can access
the ModflowParBc class as `flopy.modflow.ModflowParBc`.

"""

import numpy as np

from ..utils.flopy_io import line_strip, ulstrd


[docs]class ModflowParBc: """ Class for loading boundary condition parameter data for MODFLOW packages that use list data (WEL, GHB, DRN, etc.). This Class is also used to create hfb6 data from hfb parameters. Class also includes methods to create data arrays using pval and boundary condition parameter data. 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, bc_parms): """ Package constructor. """ self.bc_parms = bc_parms
[docs] def get(self, fkey): """ overload get to return a value from the bc_parms dictionary """ for key, value in self.bc_parms.items(): if fkey == key: return self.bc_parms[key] return None
[docs] @classmethod def load(cls, f, npar, dt, model, ext_unit_dict=None, verbose=False): """ Load bc property parameters from an existing bc package that uses list data (e.g. WEL, RIV, etc.). Parameters ---------- f : file handle npar : int The number of parameters. dt : numpy.dtype numpy.dtype for the particular list boundary condition. verbose : bool Boolean flag to control output. (default is False) Returns ------- dictionary : dictionary object with parameters in file f Examples -------- """ nitems = len(dt.names) # read parameter data if npar > 0: bc_parms = {} for idx in range(npar): line = f.readline() t = line_strip(line).split() parnam = t[0].lower() if parnam.startswith("'"): parnam = parnam[1:] if parnam.endswith("'"): parnam = parnam[:-1] if verbose: print(f' loading parameter "{parnam}"...') partyp = t[1].lower() parval = t[2] nlst = int(t[3]) numinst = 1 timeVarying = False if len(t) > 4: if "instances" in t[4].lower(): numinst = int(t[5]) timeVarying = True pinst = {} for inst in range(numinst): # read instance name if timeVarying: line = f.readline() t = line_strip(line).split() instnam = t[0].lower() else: instnam = "static" ra = np.zeros(nlst, dtype=dt) # todo: if sfac is used for parameter definition, then # the empty list on the next line needs to be the package # get_sfac_columns bcinst = ulstrd(f, nlst, ra, model, [], ext_unit_dict) pinst[instnam] = bcinst bc_parms[parnam] = [ { "partyp": partyp, "parval": parval, "nlst": nlst, "timevarying": timeVarying, }, pinst, ] return cls(bc_parms)
[docs] @staticmethod def loadarray(f, npar, verbose=False): """ Load bc property parameters from an existing bc package that uses array data (e.g. RCH, EVT). Parameters ---------- f : file handle npar : int The number of parameters. verbose : bool Boolean flag to control output. (default is False) Returns ------- dictionary : dictionary object with parameters in file f Examples -------- """ # read parameter data if npar > 0: bc_parms = {} for idx 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() parval = t[2] nclu = int(t[3]) numinst = 1 timeVarying = False if len(t) > 4: if "instances" in t[4].lower(): numinst = int(t[5]) timeVarying = True pinst = {} for inst in range(numinst): # read instance name if timeVarying: line = f.readline() t = line.strip().split() instnam = t[0].lower() else: instnam = "static" bcinst = [] for nc in range(nclu): line = f.readline() t = line.strip().split() bnd = [t[0], t[1]] if t[1].lower() == "all": bnd.append([]) else: iz = [] for jdx in range(2, len(t)): try: ival = int(t[jdx]) if ival > 0: iz.append(ival) except: break bnd.append(iz) bcinst.append(bnd) pinst[instnam] = bcinst bc_parms[parnam] = [ { "partyp": partyp, "parval": parval, "nclu": nclu, "timevarying": timeVarying, }, pinst, ] # print bc_parms bcpar = ModflowParBc(bc_parms) return bcpar
[docs] @staticmethod def parameter_bcfill(model, shape, parm_dict, pak_parms): """ 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) parm_dict : list dictionary of parameter instances pak_parms : dict dictionary that includes all of the parameter data for a package Returns ------- data : numpy array Filled array resulting from applications of zone, mult, pval, and parameter data. Examples -------- for rch and evt >>> data = flopy.modflow.mfparbc.ModflowParBc.parameter_bcfill(m, (nrow, ncol), >>> .......'rech', parm_dict, pak_parms) """ dtype = np.float32 data = np.zeros(shape, dtype=dtype) for key, value in parm_dict.items(): # print key, value pdict, idict = pak_parms.bc_parms[key] inst_data = idict[value] if model.mfpar.pval is None: pv = float(pdict["parval"]) else: try: pv = float(model.mfpar.pval.pval_dict[key.lower()]) except: pv = float(pdict["parval"]) for [mltarr, zonarr, izones] in inst_data: model.parameter_load = True # print mltarr, zonarr, izones if mltarr.lower() == "none": mult = np.ones(shape, dtype=dtype) else: mult = model.mfpar.mult.mult_dict[mltarr.lower()][:, :] if zonarr.lower() == "all": t = 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 instance t = pv * mult data += t return data