Source code for flopy.mfusg.mfusgdpf

"""
Mfusgdpf module.

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

import numpy as np

from ..pakbase import Package
from ..utils import Util2d, Util3d
from ..utils.utils_def import (
    get_open_file_object,
    get_unitnumber_from_ext_unit_dict,
    get_util2d_shape_for_layer,
)
from .mfusg import MfUsg


[docs]class MfUsgDpf(Package): """Dual Porosity Flow (dpf) Package Class for MODFLOW-USG Transport. Parameters ---------- model : model object The model object (of type :class:`flopy.modflow.Modflow`) to which this package will be added. ipakcb : int (0,1,-1), (default is 0) a flag and a unit number >0 for cell-by-cell mass flux terms. idpfhd : int, (default is 0) a flag and a unit number >0 for immobile domain heads. idpfdd : int, (default is 0) a flag and a unit number >0 for immobile domain drawdown. iuzontabim : int or array of ints, (default is 0) soil type index for all groundwater flow nodes in the immobile domain iboundim : int, (default is 0) boundary variable for the immobile domain (<0 constant head, =0 no flow) hnewim : float or array of floats initial (starting) head in the immobile domain phif : float or array of floats porosity of the mobile domain. ddftr : float or array of floats dual domain flow transfer rate sc1im : float or array of floats specific storage of the immobile domain sc2im : float or array of floats specific yield or porosity of the immobile domain alphaim : float or array of floats van Genuchten alpha coefficient of the immobile domain betaim : float or array of floats van Genuchten beta coefficient of the immobile domain srim : float or array of floats van Genuchten sr coefficient of the immobile domain brookim : float or array of floats Brooks-Corey exponent for the relative permeability of the immobile domain bpim : float or array of floats Bubble point or air entry pressure head of the immobile domain extension : string, (default is 'dpf'). unitnumber : int, default is 57. File unit number. filenames : str or list of str Filenames to use for the package and the output files. add_package : bool, default is True Flag to add the initialised package object to the parent model object. Methods ------- See Also -------- Notes ----- Examples -------- >>> import flopy >>> ml = flopy.mfusg.MfUsg() >>> disu = flopy.mfusg.MfUsgDisU(model=ml, nlay=1, nodes=1, iac=[1], njag=1,ja=np.array([0]), fahl=[1.0], cl12=[1.0]) >>> dpf = flopy.mfusg.MfUsgdpf(ml)""" def __init__( self, model, ipakcb=0, idpfhd=0, idpfdd=0, # iuzontabim=0, iboundim=0, hnewim=0.0, phif=0.0, ddftr=0.0, sc1im=0.0, sc2im=0.0, # alphaim=0.0, # betaim=0.0, # srim=0.0, # brookim=0.0, # bpim=0.0, extension="dpf", unitnumber=None, filenames=None, add_package=True, ): """Constructs the MfUsgdpf object.""" msg = ( "Model object must be of type flopy.mfusg.MfUsg\n" f"but received type: {type(model)}." ) assert isinstance(model, MfUsg), msg # set default unit number of one is not specified if unitnumber is None: self.unitnumber = self._defaultunit() super().__init__( model, extension, self._ftype(), unitnumber, self._prepare_filenames(filenames), ) self._generate_heading() self.ipakcb = ipakcb self.idpfhd = idpfhd self.idpfdd = idpfdd model.idpf = 0 nrow, ncol, nlay, nper = self.parent.nrow_ncol_nlay_nper # if self.parent.tabrich: # self.iuzontabim = Util3d( # model, (nlay, nrow, ncol), np.int32, iuzontabim, name="iuzontabim" # ) self.iboundim = Util3d( model, (nlay, nrow, ncol), np.float32, iboundim, name="iboundim" ) self.hnewim = Util3d( model, (nlay, nrow, ncol), np.float32, hnewim, name="hnewim" ) self.phif = Util3d(model, (nlay, nrow, ncol), np.float32, phif, name="phif") self.ddftr = Util3d(model, (nlay, nrow, ncol), np.float32, ddftr, name="ddftr") self.sc1im = Util3d(model, (nlay, nrow, ncol), np.float32, sc1im, name="sc1im") self.sc2im = Util3d(model, (nlay, nrow, ncol), np.float32, sc2im, name="sc2im") # self.alphaim = Util3d( # model, (nlay, nrow, ncol), np.float32, alphaim, name="alphaim" # ) # self.betaim = Util3d( # model, (nlay, nrow, ncol), np.float32, betaim, name="betaim" # ) # self.srim = Util3d( # model, (nlay, nrow, ncol), np.float32, srim, name="srim" # ) # self.brookim = Util3d( # model, (nlay, nrow, ncol), np.float32, brookim, name="brookim" # ) # self.bpim = Util3d( # model, (nlay, nrow, ncol), np.float32, bpim, name="bpim" # ) if add_package: self.parent.add_package(self)
[docs] def write_file(self, f=None): """ Write the dpf package file. Parameters ---------- f : open file object. Default is None, which will result in MfUsg.fn_path being opened for writing. """ # Open file for writing if f is None: f_obj = open(self.fn_path, "w") # f_obj.write(f"{self.heading}\n") # Item 0: IPAKCB, IdpfCON f_obj.write(f" {self.ipakcb:9d} {self.idpfhd:9d} {self.idpfdd:9d} \n") f_obj.write(self.iboundim.get_file_entry()) f_obj.write(self.hnewim.get_file_entry()) f_obj.write(self.phif.get_file_entry()) f_obj.write(self.ddftr.get_file_entry()) f_obj.write(self.sc1im.get_file_entry()) f_obj.write(self.sc2im.get_file_entry()) # close the file f_obj.close()
[docs] @classmethod def load(cls, f, model, ext_unit_dict=None): """ Load an existing package. Parameters ---------- f : filename or file handle File to load. 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 ------- dpf : MfUsgdpf object Examples -------- >>> import flopy >>> ml = flopy.mfusg.MfUsg() >>> dis = flopy.modflow.ModflowDis.load('Test1.dis', ml) >>> dpf = flopy.mfusg.MfUsgdpf.load('Test1.BTN', ml) """ msg = ( "Model object must be of type flopy.mfusg.MfUsg\n" f"but received type: {type(model)}." ) assert isinstance(model, MfUsg), msg if model.verbose: print("loading dpf package file...") nlay = model.nlay f_obj = get_open_file_object(f, "r") # item 0 line = f_obj.readline().upper() while line.startswith("#"): line = f_obj.readline().upper() t = line.split() kwargs = {} # item 1a vars = { "ipakcb": int, "idpfhd": int, "idpfdd": int, } for i, (v, c) in enumerate(vars.items()): kwargs[v] = c(t[i].strip()) # print(f"{v}={kwargs[v]}\n") # item 1b # if self.parent.tabrich: # kwargs["iuzontabim"] = cls._load_prop_arrays( # f_obj, model, nlay, np.int32, "iuzontabim", ext_unit_dict # ) kwargs["iboundim"] = cls._load_prop_arrays( f_obj, model, nlay, np.int32, "iboundim", ext_unit_dict ) kwargs["hnewim"] = cls._load_prop_arrays( f_obj, model, nlay, np.float32, "hnewim", ext_unit_dict ) kwargs["phif"] = cls._load_prop_arrays( f_obj, model, nlay, np.float32, "phif", ext_unit_dict ) kwargs["ddftr"] = cls._load_prop_arrays( f_obj, model, nlay, np.float32, "ddftr", ext_unit_dict ) kwargs["sc1im"] = cls._load_prop_arrays( f_obj, model, nlay, np.float32, "sc1im", ext_unit_dict ) kwargs["sc2im"] = cls._load_prop_arrays( f_obj, model, nlay, np.float32, "sc2im", ext_unit_dict ) f_obj.close() # set package unit number unitnumber, filenames = get_unitnumber_from_ext_unit_dict( model, cls, ext_unit_dict, kwargs["ipakcb"] ) return cls(model, unitnumber=unitnumber, filenames=filenames, **kwargs)
@staticmethod def _load_prop_arrays(f_obj, model, nlay, dtype, name, ext_unit_dict): if model.verbose: print(f" loading {name} ...") prop_array = [0] * nlay for layer in range(nlay): util2d_shape = get_util2d_shape_for_layer(model, layer=layer) prop_array[layer] = Util2d.load( f_obj, model, util2d_shape, dtype, name, ext_unit_dict ) return prop_array @staticmethod def _ftype(): return "DPF" @staticmethod def _defaultunit(): return 157