Пример #1
0
def test_cell_budget_export(model):
    m, grid, output_path = model
    precision = 'single'
    binary_grid_file = None
    skip = []
    if m.version == 'mf6':
        precision = 'double'
        binary_grid_file = os.path.join(m.model_ws,
                                        '{}.dis.grb'.format(m.name))
        skip = ['WEL']
    file = os.path.join(m.model_ws, '{}.cbc'.format(m.name))
    #file = 'Examples/data/lpr/lpr_inset.cbc'
    assert os.path.exists(file)
    cbobj = bf.CellBudgetFile(file, precision=precision)
    layers = list(range(cbobj.nlay))
    kstpkper = cbobj.get_kstpkper()[0]
    variables = [
        bs.decode().strip() for bs in cbobj.textlist
        if bs.decode().strip() not in skip
    ]
    nrow, ncol = cbobj.nrow, cbobj.ncol
    cbobj.close()
    outfiles = export_cell_budget(file,
                                  grid,
                                  binary_grid_file=binary_grid_file,
                                  kstpkper=kstpkper,
                                  precision=precision,
                                  output_path=output_path)
    check_files(outfiles, variables, kstpkper)
    tifs = [f for f in outfiles if f.endswith('.tif')]
    for f in tifs:
        with rasterio.open(f) as src:
            assert src.width == ncol
            assert src.height == nrow
            compare_polygons(grid.bbox, box(*src.bounds))
Пример #2
0
def get_stress_budget_textlist(mf6_stress_budget_output):
    """Get list of available variable names in a binary budget output file.
    """
    cbobj = bf.CellBudgetFile(mf6_stress_budget_output,
                              precision='double'
                              )
    textlist = [t.strip().decode() for t in cbobj.textlist]
    return textlist
Пример #3
0
 def read_parent_cbc_per(self, kstpkper=(0, 0)):
     cbbobj = bf.CellBudgetFile(self.cpth)
     text = {'FLOW RIGHT FACE': 'frf',
             'FLOW FRONT FACE': 'fff'}
     self.cbc = {}
     for fulltxt, shorttxt in text.items():
         self.cbc[shorttxt] = get_surface_bc_flux(cbbobj, fulltxt,
                                                  kstpkper=kstpkper, idx=0)
Пример #4
0
    def get_output_objects(self):
        headfile = tuple()
        cellfile = tuple()

        # Find output files we want to process.  These are the defaults if
        # no specific file is specified in the configuration
        for u, f, b in zip(self.mf.external_units, self.mf.external_fnames, self.mf.external_binflag):
            _, ext = os.path.splitext(f)
            if ext == ".bud":
                cellfile = (u, f, b)
            elif ext == ".bhd":
                headfile = (u, f, b)
            else:
                pass

        # Headfile
        head_obj = None
        with LoggingTimer("Loading head file", logger.info):
            try:
                if self.head_file:
                    head_obj = flopy_binary.HeadFile(self.head_file, precision=self.precision)
                elif headfile:
                    head_obj = flopy_binary.HeadFile(headfile[1], precision=self.precision)
                else:
                    logger.warning("No Headfile found")
            except BaseException:
                logger.exception("Exception occured when trying to load the HeadFile into flopy. Skipping!")

        # Cell budget file
        cell_obj = None
        with LoggingTimer("Loading cell budget file", logger.info):
            try:
                if self.cbud_file:
                    cell_obj = flopy_binary.CellBudgetFile(self.cbud_file, precision=self.precision)
                elif cellfile:
                    cell_obj = flopy_binary.CellBudgetFile(cellfile[1], precision=self.precision)
                else:
                    logger.warning("No CellBudget file found")
            except BaseException:
                logger.exception("Exception occured when trying to load the CellBudgetFile into flopy. Skipping!")

        return dict(head_obj=head_obj,
                    cell_obj=cell_obj)
Пример #5
0
def read_mf6_stress_budget_output(mf6_stress_budget_output,
                                  text='FLOW-JA-FACE',
                                  kstpkper=None):
    """Reads budget output from any package that follows the imeth=6
    structure (e.g. LAK, MAW, SFR, and UZF package(s); for example,
    output from BUDGET FILEOUT in the options block of the .sfr6 file).

    Parameters
    ----------
    mf6_stress_budget_output : file path
        Binary output file
    text : str
        Text identifying flow term (e.g. 'FLOW-JA-FACE')

    Returns
    -------
    df : DataFrame
        Table with flow results. Columns:
        node : node number (e.g. stream reach; 1-based)
        node2 : connecting node (e.g. up or downstream reach; 1-based)
        q : flow values
        FLOW-AREA : area of JA-FACE?
        kstpkper : (timestep, stress period)
        time : total time in model units
    """
    print('reading {} from\n{}...'.format(text, mf6_stress_budget_output))
    ta = time.time()
    cbobj = bf.CellBudgetFile(mf6_stress_budget_output,
                              precision='double'
                              )
    times = cbobj.get_times()
    dfs = []
    if kstpkper is None:
        kstpkper = cbobj.get_kstpkper()
        # returns a list of recarrays (length: nnodes);
        # one for each timestep, stress period
        records = cbobj.get_data(text=text)
    else:
        # otherwise, just get the results
        # for specified timestep, stress periods
        if not isinstance(kstpkper, list):
            kstpkper = [kstpkper]
        records = []
        for ksp in kstpkper:
            records += cbobj.get_data(text=text, kstpkper=ksp)

    for i, rec in enumerate(records):
        df = pd.DataFrame(rec)
        df['kstpkper'] = [kstpkper[i]] * len(df)
        df['time'] = [times[i]] * len(df)
        dfs.append(df.copy())
    df = pd.concat(dfs)
    print("finished in {:.2f}s\n".format(time.time() - ta))
    return df.sort_values(by=['time', 'node'])
Пример #6
0
def convert_uzf_to_rch(mf, issue=None, alpha=None):
    """

    Parameters
    ----------
    mf: Modflow model object with UZF

    Returns
    -------
    mf: Modflow model object with RCH, in place of UZF
    """
    # update user
    print('Converting UZF to Recharge.')
    # IMPORTS
    import os
    import flopy
    import numpy as np
    import flopy.utils.binaryfile as bf
    # data from original model run - recharge
    orig_cbc_file = bf.CellBudgetFile(
        os.path.join(mf.model_ws, mf.name + '.cbc'))
    orch_data = orig_cbc_file.get_data(text='uzf recharge')
    orig_cbc_file.close()

    # determine cell areas
    spacex, spacey = np.meshgrid(mf.modelgrid.delr, mf.modelgrid.delc)
    gridA = spacex * spacey

    # remove the uzf package
    mf.remove_package('UZF')
    mf.remove_package('LMT6')

    # address issues?
    if issue is not None:
        for i in issue:
            t = i[0]
            idx = (i[1], i[2], i[3])
            orch_data[t][idx] *= 0.9

    # recreate stress_period_data dictionary
    rch_spd = {}
    print('    >> Creating new stress period data...')
    if alpha is None:
        alpha = np.ones((mf.nper, ))
    for sp in range(mf.nper):
        rch_spd[sp] = (orch_data[sp][0, ...] / gridA
                       ) * alpha[sp]  # translate volumetric/sp to flow rate/d

    # instantiate the recharge package
    flopy.modflow.ModflowRch(mf, ipakcb=1, rech=rch_spd)
    # re-instantiate the LMT package
    flopy.modflow.ModflowLmt(mf, extension='lmt')
    return mf
Пример #7
0
def test_specific_discharge_default():
    # load and postprocess
    mf = flopy.modflow.Modflow.load(namfile_mf2005, check=False)
    cbc = bf.CellBudgetFile(cbcfile_mf2005)
    keys = ["FLOW RIGHT FACE", "FLOW FRONT FACE", "FLOW LOWER FACE"]
    vectors = [cbc.get_data(text=t)[0] for t in keys]
    qx, qy, qz = flopy.utils.postprocessing.get_specific_discharge(vectors, mf)

    # overall check
    overall = np.sum(qx) + np.sum(qy) + np.sum(qz)
    assert np.allclose(overall, -1.7959892749786377)
    return
Пример #8
0
 def uzf_arrays(self):
     """
     Make 3d numpy arrays of shape (74*51*549)
     """
     varnames = ['surf_leak', 'uzf_rch', 'uzf_et', 'uzf_run']
     variables = ['SURFACE LEAKAGE', 'UZF RECHARGE', 'GW ET', 'HORT+DUNN']
     for scenario in self.scenarios:
         slr_name = op.basename(scenario)
         slr = slr_name[4:7]
         uzf_file = op.join(scenario, '{}.uzfcb2.bin'.format(slr_name))
         try:
             uzfobj = bf.CellBudgetFile(uzf_file, precision='single')
         except:
             uzfobj = bf.CellBudgetFile(uzf_file, precision='double')
         for i, variable in enumerate(variables):
             uzf_data = uzfobj.get_data(text=variable)
             sys_mat = np.zeros([len(self.ts_day), 74, 51])
             for j in range(len(self.ts_day)):
                 sys_mat[j, :, :] = uzf_data[j]
             # save separately so can load separately and faster
             path_res = op.join(self.path_picks,
                                '{}_{}.npy'.format(varnames[i], slr))
             np.save(path_res, sys_mat)
     print('UZF arrays pickled to: {}'.format(self.path_picks))
Пример #9
0
 def __init__(self, cbbfile, model_ws, modelname, starting_locs, n, delt,
              ntimes):
     self.cbbobj = bf.CellBudgetFile(os.path.join(model_ws, cbbfile))
     self.times = self.cbbobj.get_times()
     self.mf = flopy.modflow.Modflow.load(
         os.path.join(model_ws, modelname + '.nam'))
     self.delr = self.mf.dis.delr.array
     self.delc = self.mf.dis.delc.array
     self.nlay = self.mf.dis.nlay
     self.nrow = self.mf.dis.nrow
     self.ncol = self.mf.dis.ncol
     self.starting_locs = starting_locs
     self.n = n
     self.delt = delt
     self.ntimes = ntimes
Пример #10
0
def get_sim_bc(budget_binary,text=None):
    '''Extracts a single boundary condition from the budget_binary and returns
    an (nper,nlay,nrow,ncol) array.'''
    
    cbc = bf.CellBudgetFile(budget_binary)
    bc = cbc.get_data(text=text,full3D=True)
    
    # Convert to a 4D numpy array
    nper = len(bc[0])
    nlay,nrow,ncol = np.shape(bc[0])
    
    bc_array = np.empty((nper,nlay,nrow,ncol))
    for i in range(nper):
        bc_array[i,:,:,:] = bc[i]

    return bc_array    
Пример #11
0
def get_flowja_face(cell_budget_file,
                    binary_grid_file,
                    kstpkper=(0, 0),
                    idx=0,
                    precision='double'):
    """Get FLOW-JA-FACE (cell by cell flows) from MODFLOW 6 budget
    output and binary grid file.
    TODO: need test for extracted flowja fluxes
    """
    if isinstance(cell_budget_file, str):
        cbb = bf.CellBudgetFile(cell_budget_file)
        if binary_grid_file is None:
            binary_grid_file = cell_budget_file[::-4] + '.dis.grb'
            if not os.path.exists(binary_grid_file):
                binary_grid_file = None
    else:
        cbb = cell_budget_file
    if binary_grid_file is None:
        print(
            "Couldn't get FLOW-JA-FACE, need binary grid file for connection information."
        )
        return
    bgf = MfGrdFile(binary_grid_file)
    # IA array maps cell number to connection number
    # (one-based index number of first connection at each cell)?
    # taking the forward difference then yields nconnections per cell
    ia = bgf._datadict['IA'] - 1
    # Connections in the JA array correspond directly with the
    # FLOW-JA-FACE record that is written to the budget file.
    ja = bgf._datadict['JA'] - 1  # cell connections
    flowja = cbb.get_data(text='FLOW-JA-FACE')[0][0, 0, :]
    df = get_intercell_connections(ia, ja, flowja)
    cols = ['n', 'm', 'q']

    # get the k, i, j locations for plotting the connections
    if isinstance(bgf.mg, StructuredGrid):
        nlay, nrow, ncol = bgf.mg.nlay, bgf.mg.nrow, bgf.mg.ncol
        k, i, j = get_kij_from_node3d(df['n'].values, nrow, ncol)
        df['kn'], df['in'], df['jn'] = k, i, j
        k, i, j = get_kij_from_node3d(df['m'].values, nrow, ncol)
        df['km'], df['im'], df['jm'] = k, i, j
        df.reset_index()
        cols += ['kn', 'in', 'jn', 'km', 'im', 'jm']
    return df[cols].copy()
Пример #12
0
    def __init__(self, workspace, modelname, ext='.cbc'):

        self.CBC = bf.CellBudgetFile(os.path.join(workspace, modelname + ext))

        # get active labels
        self.labels = [
            self.__class__.txt2lbl[txt] for txt in self.CBC.textlist
            if txt in self.__class__.txt2lbl.keys()
        ]

        kstpkper = self.CBC.get_kstpkper()
        nstp = len(kstpkper)

        # initialize budget for all labels, per label np.array(n, 2)
        # where np.array[:,0] = inflows and np.array[:,1] = outflows
        self.budget = {lbl: np.zeros((nstp, 2)) for lbl in self.labels}

        cbclbl = self.__class__.cbc_label  # shorthand

        for i, sp in enumerate(kstpkper):
            for label in self.labels:
                try:
                    rec = self.CBC.get_data(kstpkper=sp,
                                            text=cbclbl[label]['text'])[0]
                    if isinstance(rec, np.recarray):
                        self.budget[label][i,
                                           0] = np.sum(rec['q'][rec['q'] > 0])
                        self.budget[label][i,
                                           1] = np.sum(rec['q'][rec['q'] < 0])
                    elif label in ['RCH', 'EVT']:
                        self.budget[label][i, 0] = np.sum(rec[1][rec[1] > 0])
                        self.budget[label][i, 1] = np.sum(rec[1][rec[1] < 0])
                    else:  # 3D array
                        self.budget[label][i, 0] = np.sum(rec[rec > 0])
                        self.budget[label][i, 1] = np.sum(rec[rec < 0])
                except:
                    pass  # skips when label not avaiable for stress period
Пример #13
0
wells = [wel1,wel2,wel3,wel4]

wel_spd = {0: wells, 1: wells, 2: wells, 3: wells, 4: wells, 5: wells, 6: wells, 7: wells,
           8: wells, 9: wells}
wel = flopy.modflow.ModflowWel(mf,stress_period_data=wel_spd,ipakcb=53)

# wel.export(os.path.join('grid','wel.shp'))
# shutil.copy(os.path.join('grid','grid.prj'),os.path.join('grid','wel.prj'))

#write the modflow input files
mf.write_input()

# Run the MODFLOW model
success, buff = mf.run_model(silent=False)

cbbobj = bf.CellBudgetFile(os.path.join(model_ws,modelname+'.cbc'))
# print(cbbobj.get_)

# create contour shapefile
headobj = bf.HeadFile(os.path.join(model_ws,modelname+'.hds'))
times = headobj.get_times()
head = headobj.get_data(totim=times[-1])

levels = np.arange(45,100,5)
extent = [xul,xul+Lx,yul-Ly,yul]

fig, ax = plt.subplots()
plt.imshow(head[0],extent=extent)
plt.colorbar()
contour = plt.contour(np.flipud(head[0]),levels,extent=extent)
Пример #14
0
mf.write_input()

# Run the model
success, mfoutput = mf.run_model(silent=False, pause=False)
if not success:
    raise Exception('MODFLOW did not terminate normally.')


# Imports
import matplotlib.pyplot as plt
import flopy.utils.binaryfile as bf

# Create the headfile and budget file objects
headobj = bf.HeadFile(modelname+'.hds')
times = headobj.get_times()
cbb = bf.CellBudgetFile(modelname+'.cbc')

# Setup contour parameters
levels = np.linspace(0, 10, 11)
extent = (delr/2., Lx - delr/2., delc/2., Ly - delc/2.)
print('Levels: ', levels)
print('Extent: ', extent)

# Well point
wpt = ((float(ncol/2)-0.5)*delr, (float(nrow/2-1)+0.5)*delc)
wpt = (450., 550.)

# Make the plots
mytimes = [1.0, 101.0, 201.0]
for iplot, time in enumerate(mytimes):
    print('*****Processing time: ', time)
Пример #15
0
         int(dt2[k, 0]) - 1,
         int(dt2[k, 1]) - 1] = dt2[k, 4]

# Load River Cells ID
if feature_id == 1:
    rcid = np.loadtxt('river_cells.dat')  # river cell id
elif feature_id == 2:
    rcid = np.loadtxt('GHB_cells.dat')  # river cell id
elif feature_id == 3:
    rcid = np.loadtxt('river_n_GHB.dat')  # river cell id

#print rcid.shape[0]
nFeatureCells = rcid.shape[0]

## Read MODFLOW ccf file using flopy
cbb = bf.CellBudgetFile('Future_SS.ccf')
#cbb.list_records()
#list_unique_records_ = cbb.list_unique_records()  # Print all RECORDS
#print 'nrecords=',cbb.get_nrecords()
#print '[.] Extract flow rate data from MODFLOW CCF file ====='
#CHD = cbb.get_data(totim=1, text='CONSTANT HEAD',  full3D=True)[0]
FRF = cbb.get_data(text='FLOW RIGHT FACE', full3D=True)[0]
FFF = cbb.get_data(text='FLOW FRONT FACE', full3D=True)[0]
FLF = cbb.get_data(text='FLOW LOWER FACE', full3D=True)[0]
#FBF = cbb.get_data(totim=1, text='FLOW BACK FACE',full3D=True)[0]
RLK = cbb.get_data(text='RIVER LEAKAGE', full3D=True)[0]
HDB = cbb.get_data(text='HEAD DEP BOUNDS', full3D=True)[0]
RCH = cbb.get_data(text='RECHARGE', full3D=True)[0]
MNW = cbb.get_data(text='MNW2', full3D=True)[0]

# Convert masked element to zero
Пример #16
0
def test006_2models_mvr():
    # init paths
    test_ex_name = 'test006_2models_mvr'
    sim_name = 'test006_2models_mvr'
    model_names = ['parent', 'child']

    pth = os.path.join('..', 'examples', 'data', 'mf6', test_ex_name)
    run_folder = os.path.join(cpth, test_ex_name)
    if not os.path.isdir(run_folder):
        os.makedirs(run_folder)
    save_folder = os.path.join(run_folder, 'temp')
    if not os.path.isdir(save_folder):
        os.makedirs(save_folder)

    expected_output_folder = os.path.join(pth, 'expected_output')
    expected_head_file_a = os.path.join(expected_output_folder,
                                        'model1_unch.hds')
    expected_head_file_aa = os.path.join(expected_output_folder,
                                         'model2_unch.hds')
    expected_cbc_file_a = os.path.join(expected_output_folder,
                                       'model1_unch.cbc')

    expected_head_file_b = os.path.join(expected_output_folder,
                                        'model1_adj.hds')
    expected_head_file_bb = os.path.join(expected_output_folder,
                                         'model2_adj.hds')

    # load simulation
    sim = MFSimulation.load(sim_name, 'mf6', exe_name, pth, verify_data=True)

    # make temp folder to save simulation
    sim.simulation_data.mfpath.set_sim_path(run_folder)

    # write simulation to new location
    sim.set_all_data_external()
    sim.write_simulation()

    if run:
        # run simulation
        sim.run_simulation()

        # compare output to expected results
        head_file = os.path.join(os.getcwd(), expected_head_file_a)
        head_new = os.path.join(run_folder, 'model1.hds')
        assert pymake.compare_heads(None,
                                    None,
                                    files1=head_file,
                                    files2=head_new)

        head_file = os.path.join(os.getcwd(), expected_head_file_aa)
        head_new = os.path.join(run_folder, 'model2.hds')
        assert pymake.compare_heads(None,
                                    None,
                                    files1=head_file,
                                    files2=head_new)

        budget_file = os.path.join(os.getcwd(), expected_cbc_file_a)
        budget_obj = bf.CellBudgetFile(budget_file, precision='double')
        budget_obj.list_records()

    # test getting models
    model_dict = sim.model_dict
    assert len(model_dict) == 2
    for model in model_dict.values():
        assert model.name in model_names
    names = sim.model_names
    assert len(names) == 2
    for name in names:
        assert name in model_names
        model = sim.get_model(name)
        assert model.model_type == 'gwf'
    models = sim.gwf
    assert len(models) == 2
    for model in models:
        assert model.name in model_names
        assert model.model_type == 'gwf'

    # change some settings
    parent_model = sim.get_model(model_names[0])
    maw_pkg = parent_model.get_package('maw')
    period_data = maw_pkg.perioddata.get_data()
    period_data[0][0][2] = -1.0
    maw_pkg.perioddata.set_data(period_data[0], 0)
    well_rec_data = maw_pkg.packagedata.get_data()
    assert (well_rec_data[0][0] == 0)

    exg_pkg = sim.get_exchange_file('simulation.exg')
    exg_data = exg_pkg.exchangedata.get_data()
    for index in range(0, len(exg_data)):
        exg_data[index][6] = 500.0
    exg_pkg.exchangedata.set_data(exg_data)

    # test getting packages
    pkg_dict = parent_model.package_dict
    assert len(pkg_dict) == 6
    pkg_names = parent_model.package_names
    assert len(pkg_names) == 6
    # confirm that this is a copy of the original dictionary with references
    # to the packages
    del pkg_dict[pkg_names[0]]
    assert len(pkg_dict) == 5
    pkg_dict = parent_model.package_dict
    assert len(pkg_dict) == 6

    old_val = pkg_dict['dis'].nlay.get_data()
    pkg_dict['dis'].nlay = 22
    pkg_dict = parent_model.package_dict
    assert pkg_dict['dis'].nlay.get_data() == 22
    pkg_dict['dis'].nlay = old_val

    # write simulation again
    sim.simulation_data.mfpath.set_sim_path(save_folder)
    sim.write_simulation()

    if run:
        # run simulation
        sim.run_simulation()

        # compare output to expected results
        head_file = os.path.join(os.getcwd(), expected_head_file_b)
        head_new = os.path.join(save_folder, 'model1.hds')
        assert pymake.compare_heads(None,
                                    None,
                                    files1=head_file,
                                    files2=head_new)

        head_file = os.path.join(os.getcwd(), expected_head_file_bb)
        head_new = os.path.join(save_folder, 'model2.hds')
        assert pymake.compare_heads(None,
                                    None,
                                    files1=head_file,
                                    files2=head_new)

        # clean up
        sim.delete_output_files()

    # test load_only
    model_package_check = ['ic', 'maw', 'npf', 'oc']
    load_only_lists = [['ic6', 'npf6', 'oc', 'gwf6-gwf6', 'ims'],
                       ['ic', 'maw', 'npf', 'gwf-gwf', 'ims'],
                       ['ic', 'maw6', 'npf']]
    for load_only in load_only_lists:
        sim = MFSimulation.load(sim_name,
                                'mf6',
                                exe_name,
                                pth,
                                load_only=load_only)
        for model_name in model_names:
            model = sim.get_model(model_name)
            for package in model_package_check:
                assert (package in model.package_type_dict or
                        package in sim.package_type_dict) == \
                       (package in load_only or '{}6'.format(package) in
                        load_only)
        assert (len(sim._exchange_files) > 0) == ('gwf6-gwf6' in load_only
                                                  or 'gwf-gwf' in load_only)
        assert (len(sim._ims_files) > 0) == ('ims6' in load_only
                                             or 'ims' in load_only)

    # load package by name
    load_only_list = ['ic6', 'maw', 'npf_p1', 'oc_p2', 'ims']
    sim = MFSimulation.load(sim_name,
                            'mf6',
                            exe_name,
                            pth,
                            load_only=load_only_list)
    model_parent = sim.get_model('parent')
    model_child = sim.get_model('child')
    assert 'oc' not in model_parent.package_type_dict
    assert 'oc' in model_child.package_type_dict
    assert 'npf' in model_parent.package_type_dict
    assert 'npf' not in model_child.package_type_dict

    if run:
        # test running a runnable load_only case
        sim = MFSimulation.load(sim_name,
                                'mf6',
                                exe_name,
                                pth,
                                load_only=load_only_lists[0])
        assert sim.run_simulation()[0]

    return
Пример #17
0
def test001a_tharmonic():
    # init paths
    test_ex_name = 'test001a_Tharmonic'
    model_name = 'flow15'

    pth = os.path.join('..', 'examples', 'data', 'mf6', test_ex_name)
    run_folder = os.path.join(cpth, test_ex_name)
    if not os.path.isdir(run_folder):
        os.makedirs(run_folder)
    save_folder = os.path.join(run_folder, 'temp')
    if not os.path.isdir(save_folder):
        os.makedirs(save_folder)

    expected_output_folder = os.path.join(pth, 'expected_output')
    expected_head_file_a = os.path.join(expected_output_folder,
                                        'flow15_flow_unch.hds')
    expected_head_file_b = os.path.join(expected_output_folder,
                                        'flow15_flow_adj.hds')
    expected_cbc_file_a = os.path.join(expected_output_folder,
                                       'flow15_flow_unch.cbc')
    expected_cbc_file_b = os.path.join(expected_output_folder,
                                       'flow15_flow_adj.cbc')

    array_util = PyListUtil()

    # load simulation
    sim = MFSimulation.load(model_name,
                            'mf6',
                            exe_name,
                            pth,
                            verbosity_level=0,
                            verify_data=True,
                            write_headers=False)
    sim.simulation_data.mfpath.set_sim_path(run_folder)

    # write simulation to new location
    sim.set_all_data_external()
    sim.write_simulation(silent=True)

    model = sim.get_model(model_name)
    model.export('{}/tharmonic.nc'.format(model.model_ws))
    model.export('{}/tharmonic.shp'.format(model.model_ws))
    model.dis.botm.export('{}/botm.shp'.format(model.model_ws))

    mg = model.modelgrid

    if run:
        # run simulation
        sim.run_simulation()

        # get expected results
        budget_file = os.path.join(os.getcwd(), expected_cbc_file_a)
        budget_obj = bf.CellBudgetFile(budget_file, precision='auto')
        budget_obj.list_records()
        budget_frf_valid = np.array(
            budget_obj.get_data(text='    FLOW JA FACE', full3D=True))

        # compare output to expected results
        head_file = os.path.join(os.getcwd(), expected_head_file_a)
        head_new = os.path.join(run_folder, 'flow15_flow.hds')
        assert pymake.compare_heads(None,
                                    None,
                                    files1=head_file,
                                    files2=head_new)

        budget_frf = sim.simulation_data.mfdata[(model_name, 'CBC',
                                                 'FLOW-JA-FACE')]
        assert array_util.array_comp(budget_frf_valid, budget_frf)

    # change some settings
    hk_data = sim.simulation_data.mfdata[(model_name, 'npf', 'griddata', 'k')]
    hk_array = hk_data.get_data()
    hk_array[0, 0, 1] = 20.0
    hk_data.set_data(hk_array)

    model = sim.get_model(model_name)
    ic = model.get_package('ic')
    ic_data = ic.strt
    ic_array = ic_data.get_data()
    ic_array[0, 0, 0] = 1.0
    ic_array[0, 0, 9] = 1.0
    ic_data.set_data(ic_array)

    get_test = hk_data[0, 0, 0]
    assert (get_test == 10.0)
    get_test = hk_data.array
    assert (array_util.array_comp(
        get_test,
        [[10.0, 20.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0]]))
    get_test = hk_data[:]
    assert (array_util.array_comp(
        get_test,
        [[[10.0, 20.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0]]]))

    # write simulation again
    sim.simulation_data.mfpath.set_sim_path(save_folder)
    sim.write_simulation()

    if run:
        # run simulation
        sim.run_simulation()

        # get expected results
        budget_file = os.path.join(os.getcwd(), expected_cbc_file_b)
        budget_obj = bf.CellBudgetFile(budget_file, precision='auto')
        budget_frf_valid = np.array(
            budget_obj.get_data(text='    FLOW JA FACE', full3D=True))

        # compare output to expected results
        head_file = os.path.join(os.getcwd(), expected_head_file_b)
        head_new = os.path.join(save_folder, 'flow15_flow.hds')
        assert pymake.compare_heads(None,
                                    None,
                                    files1=head_file,
                                    files2=head_new)

        budget_frf = sim.simulation_data.mfdata[(model_name, 'CBC',
                                                 'FLOW-JA-FACE')]
        assert array_util.array_comp(budget_frf_valid, budget_frf)

        # clean up
        sim.delete_output_files()

    return
Пример #18
0
def test006_gwf3():
    # init paths
    test_ex_name = 'test006_gwf3'
    model_name = 'gwf_1'

    pth = os.path.join('..', 'examples', 'data', 'mf6', test_ex_name)
    run_folder = os.path.join(cpth, test_ex_name)
    if not os.path.isdir(run_folder):
        os.makedirs(run_folder)
    save_folder = os.path.join(run_folder, 'temp')
    if not os.path.isdir(save_folder):
        os.makedirs(save_folder)

    expected_output_folder = os.path.join(pth, 'expected_output')
    expected_head_file_a = os.path.join(expected_output_folder,
                                        'flow_unch.hds')
    expected_head_file_b = os.path.join(expected_output_folder, 'flow_adj.hds')
    expected_cbc_file_a = os.path.join(expected_output_folder, 'flow_unch.cbc')
    expected_cbc_file_b = os.path.join(expected_output_folder, 'flow_adj.cbc')

    array_util = PyListUtil()

    # load simulation
    sim = MFSimulation.load(model_name, 'mf6', exe_name, pth, verify_data=True)

    model = sim.get_model()
    disu = model.get_package('disu')
    # test switching disu array to internal array
    disu.ja = disu.ja.array
    # test writing hwva and cl12 arrays out to different locations
    disu.hwva = {
        'filename': 'flow.disu.hwva_new.dat',
        'factor': 1.0,
        'data': disu.hwva.array
    }
    disu.cl12 = {
        'filename': 'flow.disu.cl12_new.dat',
        'factor': 1.0,
        'data': disu.cl12.array
    }

    # make temp folder to save simulation
    sim.simulation_data.mfpath.set_sim_path(run_folder)
    # write simulation to new location
    sim.set_all_data_external()
    sim.write_simulation()

    if run:
        # run simulation
        sim.run_simulation()

        budget_file = os.path.join(os.getcwd(), expected_cbc_file_a)
        budget_obj = bf.CellBudgetFile(budget_file, precision='double')
        budget_fjf_valid = np.array(
            budget_obj.get_data(text='    FLOW JA FACE', full3D=True))
        jaentries = budget_fjf_valid.shape[-1]
        budget_fjf_valid.shape = (-1, jaentries)

        # compare output to expected results
        head_file = os.path.join(os.getcwd(), expected_head_file_a)
        head_new = os.path.join(run_folder, 'flow.hds')
        assert pymake.compare_heads(None,
                                    None,
                                    files1=head_file,
                                    files2=head_new)

        budget_fjf = np.array(sim.simulation_data.mfdata[(model_name, 'CBC',
                                                          'FLOW-JA-FACE')])
        assert array_util.array_comp(np.array(budget_fjf_valid),
                                     np.array(budget_fjf))

    # change some settings
    model = sim.get_model(model_name)
    hk = model.get_package('npf').k
    hk_data = hk.get_data()
    hk_data[2] = 3.5
    hk.set_data(hk_data)
    ex_happened = False
    try:
        hk.make_layered()
    except:
        ex_happened = True
    assert (ex_happened)

    # write simulation again
    sim.simulation_data.mfpath.set_sim_path(save_folder)
    sim.write_simulation()

    if run:
        # run simulation
        sim.run_simulation()

        # get expected results
        budget_file = os.path.join(os.getcwd(), expected_cbc_file_b)
        budget_obj = bf.CellBudgetFile(budget_file, precision='auto')
        budget_fjf_valid = np.array(
            budget_obj.get_data(text='    FLOW JA FACE', full3D=True))
        jaentries = budget_fjf_valid.shape[-1]
        budget_fjf_valid.shape = (-1, jaentries)

        # compare output to expected results
        head_file = os.path.join(os.getcwd(), expected_head_file_b)
        head_new = os.path.join(save_folder, 'flow.hds')
        assert pymake.compare_heads(None,
                                    None,
                                    files1=head_file,
                                    files2=head_new)

        budget_fjf = np.array(sim.simulation_data.mfdata[(model_name, 'CBC',
                                                          'FLOW-JA-FACE')])
        assert array_util.array_comp(np.array(budget_fjf_valid),
                                     np.array(budget_fjf))

    # confirm that files did move
    save_folder = os.path.join(run_folder, 'temp_two')
    sim.simulation_data.mfpath.set_sim_path(save_folder)

    # write with "copy_external_files" turned off so external files do not get copied to new location
    sim.write_simulation(
        ext_file_action=flopy.mf6.mfbase.ExtFileAction.copy_none)

    # store strt in an external binary file
    model = sim.get_model()
    ic = model.get_package('ic')
    ic.strt.store_as_external_file('initial_heads.bin', binary=True)

    strt_data = ic.strt.array
    # update packages
    sim.write_simulation()

    if run:
        # run simulation
        sim.run_simulation()

        # get expected results
        budget_file = os.path.join(os.getcwd(), expected_cbc_file_b)
        budget_obj = bf.CellBudgetFile(budget_file, precision='double')
        budget_fjf_valid = np.array(
            budget_obj.get_data(text='    FLOW JA FACE', full3D=True))
        jaentries = budget_fjf_valid.shape[-1]
        budget_fjf_valid.shape = (-1, jaentries)

        # compare output to expected results
        head_file = os.path.join(os.getcwd(), expected_head_file_b)
        head_new = os.path.join(save_folder, 'flow.hds')
        assert pymake.compare_heads(None,
                                    None,
                                    files1=head_file,
                                    files2=head_new)

        budget_fjf = np.array(sim.simulation_data.mfdata[(model_name, 'CBC',
                                                          'FLOW-JA-FACE')])
        assert array_util.array_comp(np.array(budget_fjf_valid),
                                     np.array(budget_fjf))

        # confirm that files did not move
        assert not os.path.isfile(os.path.join(save_folder,
                                               'flow.disu.ja.dat'))
        assert not os.path.isfile(
            os.path.join(save_folder, 'flow.disu.iac.dat'))
        assert not os.path.isfile(
            os.path.join(save_folder, 'flow.disu.cl12.dat'))
        assert not os.path.isfile(
            os.path.join(save_folder, 'flow.disu.area.dat'))
        assert not os.path.isfile(
            os.path.join(save_folder, 'flow.disu.hwva.dat'))
        # confirm external binary file was created
        assert os.path.isfile(os.path.join(save_folder, 'initial_heads.bin'))

        # clean up
        sim.delete_output_files()

    return
Пример #19
0
# output result as:
# TimeStep, Row, Column, Value

import sys
import flopy.utils.binaryfile as bf

# run paramters
n_stress_periods = 132  # ! remember 0 indexing !
idx_time_step = 4
parameter_name = "RIVER LEAKAGE"
idx_layer = 0
delim = "\t"

# supply a binary .cbb modflow output file
cbb_filename = "/Users/Maru/Desktop/MODFLOW_HUGE/V38_Temp_V9.cbb"
cbb = bf.CellBudgetFile(cbb_filename)

rc = []  # row-column tuples [(row,column),...(row,column)]
# supply a tab-delimited filename of zero indexed row and column positions:
# row   column
# 1     2
# 2     4

river_filename = "/Users/Maru/Dropbox/JKMB001_flopy/FA128_RIVER.txt"
# This block loads the row-column indexed values identifying river cells
fh = open(river_filename, "r")
fh.readline()  # skip header row
[rc.append([int(x) for x in line.strip().split(delim)]) for line in fh]

# This block loops through stress periods i to n_stress_periods, gets the data layer
for i in range(n_stress_periods):
Пример #20
0
def cbc_to_netcdf(cbcFile, disFile, locationFile, fileOutput):

    cbc = binaryfile.CellBudgetFile(cbcFile)
    variableNames = cbc.unique_record_names()

    fileHandle = open(disFile, 'r')
    for line in fileHandle:
        if "#" not in line.strip().split()[0]:
            values = line.split()
            break

    numberOfLayers = int(values[0])
    numberOfRows = int(values[1])
    numberOfColumns = int(values[2])
    numberOfHRUs = numberOfRows * numberOfColumns
    numberOfStressPeriods = int(values[3])

    timeStepForStressPeriods = []

    for index in range(numberOfStressPeriods, 0, -1):
        fileHandle = open(disFile, 'r')
        lineNumber = index * -1
        values = fileHandle.readlines()[lineNumber].split()
        numberOfTimeSteps = int(values[1])
        timeStepForStressPeriods.append(numberOfTimeSteps)

    fileHandle = open(locationFile, 'r')
    values = find_average_resolution(fileHandle, numberOfHRUs, numberOfRows,
                                     numberOfColumns)
    averageOfLatitudeValues = values[0]
    averageOfLongitudeValues = values[1]
    latitudeOfFirstHru = values[2]
    longitudeOfFirstHru = values[3]

    # Initialize new dataset
    ncfile = netCDF4.Dataset(fileOutput, mode='w')

    # Initialize dimensions
    lat_dim = ncfile.createDimension('lat', numberOfRows)
    lon_dim = ncfile.createDimension('lon', numberOfColumns)

    latList = []
    latList.append(latitudeOfFirstHru)
    previousValue = latitudeOfFirstHru
    lat = ncfile.createVariable('lat', 'f8', ('lat', ))
    lat.long_name = 'latitude'
    lat.units = 'degrees_north'
    for i in range(numberOfRows - 1):
        newValue = previousValue - averageOfLatitudeValues
        latList.append(newValue)
        previousValue = newValue
    lat[:] = latList

    lonList = []
    lonList.append(longitudeOfFirstHru)
    previousValue = longitudeOfFirstHru
    lon = ncfile.createVariable('lon', 'f8', ('lon', ))
    lon.long_name = 'longitude'
    lon.units = 'degrees_east'
    for i in range(numberOfColumns - 1):
        newValue = previousValue + averageOfLongitudeValues
        lonList.append(newValue)
        previousValue = newValue
    lon[:] = lonList

    sr = osr.SpatialReference()
    sr.ImportFromEPSG(4326)
    crs = ncfile.createVariable(
        'crs',
        'S1',
    )
    crs.spatial_ref = sr.ExportToWkt()

    variablePosition = 0

    for spIndex in range(numberOfStressPeriods):
        for tsIndex in range(timeStepForStressPeriods[spIndex]):
            for varName in variableNames:
                for layerIndex in range(numberOfLayers):
                    var = ncfile.createVariable(
                        varName.strip() + "_" + str(spIndex + 1) + "_" +
                        str(tsIndex + 1) + "_" + str(layerIndex + 1), 'f8',
                        ('lat', 'lon'))
                    var.layer_name = varName.strip() + "_" + str(
                        spIndex + 1) + "_" + str(tsIndex +
                                                 1) + "_" + str(layerIndex + 1)
                    var.layer_desc = "Variable " + varName.strip(
                    ) + ": Stress Period " + str(
                        spIndex + 1) + ", Time Step " + str(
                            tsIndex + 1) + ", Layer " + str(layerIndex + 1)
                    var.layer_units = "none"
                    var.grid_mapping = "crs"
                    values = find_values(cbc, variablePosition, layerIndex)
                    var[:] = values
                variablePosition += 1

    # Global attributes
    ncfile.title = 'Modflow Cell by Cell by Cell Budget Package'
    ncfile.bands = 1
    ncfile.bands_name = 'nsteps'
    ncfile.bands_desc = 'Variable information for ' + cbcFile

    # Close the 'ncfile' object
    ncfile.close()
Пример #21
0
def export_cell_budget(cell_budget_file,
                       grid,
                       binary_grid_file=None,
                       kstpkper=None,
                       text=None,
                       idx=0,
                       precision='single',
                       output_path='postproc',
                       suffix=''):
    """Read a flow component from MODFLOW binary cell budget output;
    write to raster.

    Parameters
    ----------
    cell_budget_file : modflow binary cell budget output
    grid : rOpen.modflow.grid instance
    text : cell budget record to read (e.g. 'STREAM LEAKAGE')
    kstpkper : tuple
        (timestep, stress period) to read
    idx : index of list returned by cbbobj (usually 0)
    outfolder : where to write raster
    """
    print('Exporting cell budget info...')
    print('file: {}'.format(cell_budget_file))
    print('binary grid file: {}'.format(binary_grid_file))

    cbbobj = bf.CellBudgetFile(cell_budget_file, precision=precision)
    if kstpkper is None:
        kstpkper = cbbobj.get_times()[idx]
    if np.isscalar(kstpkper[0]):
        kstpkper = [kstpkper]

    pdfs_dir, rasters_dir, shps_dir = make_output_folders(output_path)
    if text is not None and not isinstance(text, list):
        text = [text]

    names = [r.decode().strip() for r in cbbobj.get_unique_record_names()]
    if text is not None:
        names = list(set(text).intersection(names))
    if len(names) == 0:
        print('{} not found in {}'.format(' '.join(text), cell_budget_file))

    outfiles = []
    for kstp, kper in kstpkper:
        print('stress period {}, timestep {}'.format(kper, kstp))
        for variable in names:
            if variable == 'FLOW-JA-FACE':
                df = get_flowja_face(cbbobj,
                                     binary_grid_file=binary_grid_file,
                                     kstpkper=(kstp, kper),
                                     idx=idx,
                                     precision=precision)
                # export the vertical fluxes as rasters
                # (in the downward direction; so fluxes between 2 layers
                # would be represented in the upper layer)
                if df is not None and 'kn' in df.columns and np.any(
                        df['kn'] < df['km']):
                    vflux = df.loc[(df['kn'] < df['km'])]
                    nlay = vflux['km'].max()
                    _, nrow, ncol = grid.shape
                    vflux_array = np.zeros((nlay, nrow, ncol))
                    vflux_array[vflux['kn'].values, vflux['in'].values,
                                vflux['jn'].values] = vflux.q.values
                    data = vflux_array
            else:
                data = get_bc_flux(cbbobj,
                                   variable,
                                   kstpkper=(kstp, kper),
                                   idx=idx)
            if data is None:
                print('{} not exported.'.format(variable))
                continue
            outfile = '{}/{}_per{}_stp{}{}.tif'.format(rasters_dir, variable,
                                                       kper, kstp, suffix)
            export_array(outfile, data, grid, nodata=0)
            outfiles.append(outfile)
    return outfiles
Пример #22
0
mf.write_input()

# Run the model
success, mfoutput = mf.run_model(silent=True, pause=False, report=True)
if not success:
    raise Exception("MODFLOW did not terminate normally.")


# Imports
import matplotlib.pyplot as plt
import flopy.utils.binaryfile as bf

# Create the headfile and budget file objects
headobj = bf.HeadFile(modelname + ".hds")
times = headobj.get_times()
cbb = bf.CellBudgetFile(modelname + ".cbc")

# Setup contour parameters
levels = np.linspace(0, 10, 11)
extent = (delr / 2.0, Lx - delr / 2.0, delc / 2.0, Ly - delc / 2.0)
print("Levels: ", levels)
print("Extent: ", extent)

# Well point
wpt = ((float(ncol / 2) - 0.5) * delr, (float(nrow / 2 - 1) + 0.5) * delc)
wpt = (450.0, 550.0)

# Make the plots
mytimes = [1.0, 101.0, 201.0]
for iplot, time in enumerate(mytimes):
    print("*****Processing time: ", time)
Пример #23
0
def get_extended_budget(
    cbcfile,
    precision="single",
    idx=None,
    kstpkper=None,
    totim=None,
    boundary_ifaces=None,
    hdsfile=None,
    model=None,
):
    """
    Get the flow rate across cell faces including potential stresses applied
    along boundaries at a given time. Only implemented for "classical" MODFLOW
    versions where the budget is recorded as FLOW RIGHT FACE, FLOW FRONT FACE
    and FLOW LOWER FACE arrays.

    Parameters
    ----------
    cbcfile : str
        Cell by cell file produced by Modflow.
    precision : str
        Binary file precision, default is 'single'.
    idx : int or list
            The zero-based record number.
    kstpkper : tuple of ints
        A tuple containing the time step and stress period (kstp, kper).
        The kstp and kper values are zero based.
    totim : float
        The simulation time.
    boundary_ifaces : dictionary {str: int or list}
        A dictionary defining how to treat stress flows at boundary cells.
        The keys are budget terms corresponding to stress packages (same term
        as in the overall volumetric budget printed in the listing file).
        The values are either a single iface number to be applied to all cells
        for the stress package, or a list of lists describing individual
        boundary cells in the same way as in the package input plus the iface
        number appended. The iface number indicates the face to which the
        stress flow is assigned, following the MODPATH convention (see MODPATH
        user guide).
        Example:
        boundary_ifaces = {
        'RECHARGE': 6,
        'RIVER LEAKAGE': 6,
        'CONSTANT HEAD': [[lay, row, col, iface], ...],
        'WELLS': [[lay, row, col, flux, iface], ...],
        'HEAD DEP BOUNDS': [[lay, row, col, head, cond, iface], ...]}.
        Note: stresses that are not informed in boundary_ifaces are implicitly
        treated as internally-distributed sinks/sources.
    hdsfile : str
        Head file produced by MODFLOW (only required if boundary_ifaces is
        used).
    model : flopy.modflow.Modflow object
        Modflow model instance (only required if boundary_ifaces is used).

    Returns
    -------
    (Qx_ext, Qy_ext, Qz_ext) : tuple
        Flow rates across cell faces.
        Qx_ext is a ndarray of size (nlay, nrow, ncol + 1).
        Qy_ext is a ndarray of size (nlay, nrow + 1, ncol). The sign is such
        that the y axis is considered to increase in the north direction.
        Qz_ext is a ndarray of size (nlay + 1, nrow, ncol). The sign is such
        that the z axis is considered to increase in the upward direction.
    """
    import flopy.utils.binaryfile as bf

    # define useful stuff
    cbf = bf.CellBudgetFile(cbcfile, precision=precision)
    nlay, nrow, ncol = cbf.nlay, cbf.nrow, cbf.ncol
    rec_names = cbf.get_unique_record_names(decode=True)
    err_msg = " not found in the budget file."

    # get flow across right face
    Qx_ext = np.zeros((nlay, nrow, ncol + 1), dtype=np.float32)
    if ncol > 1:
        budget_term = "FLOW RIGHT FACE"
        matched_name = [s for s in rec_names if budget_term in s]
        if not matched_name:
            raise RuntimeError(budget_term + err_msg)
        frf = cbf.get_data(idx=idx,
                           kstpkper=kstpkper,
                           totim=totim,
                           text=budget_term)
        Qx_ext[:, :, 1:] = frf[0]
        # SWI2 package
        budget_term_swi = "SWIADDTOFRF"
        matched_name_swi = [s for s in rec_names if budget_term_swi in s]
        if matched_name_swi:
            frf_swi = cbf.get_data(idx=idx,
                                   kstpkper=kstpkper,
                                   totim=totim,
                                   text=budget_term_swi)
            Qx_ext[:, :, 1:] += frf_swi[0]

    # get flow across front face
    Qy_ext = np.zeros((nlay, nrow + 1, ncol), dtype=np.float32)
    if nrow > 1:
        budget_term = "FLOW FRONT FACE"
        matched_name = [s for s in rec_names if budget_term in s]
        if not matched_name:
            raise RuntimeError(budget_term + err_msg)
        fff = cbf.get_data(idx=idx,
                           kstpkper=kstpkper,
                           totim=totim,
                           text=budget_term)
        Qy_ext[:, 1:, :] = -fff[0]
        # SWI2 package
        budget_term_swi = "SWIADDTOFFF"
        matched_name_swi = [s for s in rec_names if budget_term_swi in s]
        if matched_name_swi:
            fff_swi = cbf.get_data(idx=idx,
                                   kstpkper=kstpkper,
                                   totim=totim,
                                   text=budget_term_swi)
            Qy_ext[:, 1:, :] -= fff_swi[0]

    # get flow across lower face
    Qz_ext = np.zeros((nlay + 1, nrow, ncol), dtype=np.float32)
    if nlay > 1:
        budget_term = "FLOW LOWER FACE"
        matched_name = [s for s in rec_names if budget_term in s]
        if not matched_name:
            raise RuntimeError(budget_term + err_msg)
        flf = cbf.get_data(idx=idx,
                           kstpkper=kstpkper,
                           totim=totim,
                           text=budget_term)
        Qz_ext[1:, :, :] = -flf[0]
        # SWI2 package
        budget_term_swi = "SWIADDTOFLF"
        matched_name_swi = [s for s in rec_names if budget_term_swi in s]
        if matched_name_swi:
            flf_swi = cbf.get_data(idx=idx,
                                   kstpkper=kstpkper,
                                   totim=totim,
                                   text=budget_term_swi)
            Qz_ext[1:, :, :] -= flf_swi[0]

    # deal with boundary cells
    if boundary_ifaces is not None:
        # need calculated heads for some stresses and to check hnoflo and hdry
        if hdsfile is None:
            raise ValueError("hdsfile must be provided when using "
                             "boundary_ifaces")
        hds = bf.HeadFile(hdsfile, precision=precision)
        head = hds.get_data(idx=idx, kstpkper=kstpkper, totim=totim)

        # get hnoflo and hdry values
        if model is None:
            raise ValueError("model must be provided when using "
                             "boundary_ifaces")
        noflo_or_dry = np.logical_or(head == model.hnoflo, head == model.hdry)

        for budget_term, iface_info in boundary_ifaces.items():
            # look for budget term in budget file
            matched_name = [s for s in rec_names if budget_term in s]
            if not matched_name:
                raise RuntimeError("Budget term " + budget_term + " not found"
                                   ' in "' + cbcfile + '" file.')
            if len(matched_name) > 1:
                raise RuntimeError("Budget term " + budget_term + " found"
                                   " in several record names. Use a more "
                                   " precise name.")
            Q_stress = cbf.get_data(
                idx=idx,
                kstpkper=kstpkper,
                totim=totim,
                text=matched_name[0],
                full3D=True,
            )[0]

            # remove potential leading and trailing spaces
            budget_term = budget_term.strip()

            # weirdly, MODFLOW puts recharge in all potential recharge cells
            # and not only the actual cells; thus, correct this by putting 0
            # away from water table cells
            if budget_term == "RECHARGE":
                # find the water table as the first active cell in each column
                water_table = np.full((nlay, nrow, ncol), False)
                water_table[0, :, :] = np.logical_not(noflo_or_dry[0, :, :])
                already_found = water_table[0, :, :]
                for lay in range(1, nlay):
                    if np.sum(already_found) == nrow * ncol:
                        break
                    water_table[lay, :, :] = np.logical_and(
                        np.logical_not(noflo_or_dry[lay, :, :]),
                        np.logical_not(already_found),
                    )
                    already_found = np.logical_or(already_found,
                                                  water_table[lay, :, :])
                Q_stress[np.logical_not(water_table)] = 0.0

            # case where the same iface is assigned to all cells
            if isinstance(iface_info, int):
                if iface_info == 1:
                    Qx_ext[:, :, :-1] += Q_stress
                elif iface_info == 2:
                    Qx_ext[:, :, 1:] -= Q_stress
                elif iface_info == 3:
                    Qy_ext[:, 1:, :] += Q_stress
                elif iface_info == 4:
                    Qy_ext[:, :-1, :] -= Q_stress
                elif iface_info == 5:
                    Qz_ext[1:, :, :] += Q_stress
                elif iface_info == 6:
                    Qz_ext[:-1, :, :] -= Q_stress

            # case where iface is assigned individually per cell
            elif isinstance(iface_info, list):
                # impose a unique iface (normally = 6) for some stresses
                # (note: UZF RECHARGE, GW ET and SURFACE LEAKAGE are all
                # related to the UZF package)
                if (budget_term == "RECHARGE" or budget_term == "ET"
                        or budget_term == "UZF RECHARGE"
                        or budget_term == "GW ET"
                        or budget_term == "SURFACE LEAKAGE"):
                    raise ValueError("This function imposes the use of a "
                                     "unique iface (normally = 6) for the " +
                                     budget_term + " budget term.")

                # loop through boundary cells
                for cell_info in iface_info:
                    lay, row, col = cell_info[0], cell_info[1], cell_info[2]
                    if noflo_or_dry[lay, row, col]:
                        continue
                    iface = cell_info[-1]
                    # Here, where appropriate, we recalculate Q_stress_cell
                    # using package input. This gives more flexibility than
                    # directly taking the value saved by MODFLOW. Indeed, it
                    # allows for a same type of stress to be applied several
                    # times to the same cell but to different faces
                    # (whereas MODFLOW only saves one lumped  value per
                    # stress type per cell).
                    # Note: this flexibility is not supported for:
                    # - FHB package (we would need to interpolate inputs
                    #   across time steps as done in the package; complicated)
                    # - RES package (we would need to interpolate inputs
                    #   across time steps as done in the package; complicated)
                    # - STR package (we would need first to retrieve river
                    #   stage from model outputs; complicated)
                    # - SFR1 package (we would need to retrieve river
                    #   stage and conductance from model outputs; complicated)
                    # - SFR2 package (even more complicated than SFR1)
                    # - LAK3 package (we would need to retrieve lake
                    #   stage and conductance from model outputs; complicated)
                    # - MNW1 package (we would need to retrieve well head and
                    #   conductance from model outputs; complicated)
                    # - MNW2 package (even more complicated than MNW1)
                    if budget_term == "WELLS":
                        Q_stress_cell = cell_info[3]
                    elif budget_term == "HEAD DEP BOUNDS":
                        ghb_head = cell_info[3]
                        ghb_cond = cell_info[4]
                        model_head = head[lay, row, col]
                        Q_stress_cell = ghb_cond * (ghb_head - model_head)
                    elif budget_term == "RIVER LEAKAGE":
                        riv_stage = cell_info[3]
                        riv_cond = cell_info[4]
                        riv_rbot = cell_info[5]
                        model_head = head[lay, row, col]
                        if model_head > riv_rbot:
                            Q_stress_cell = riv_cond * (riv_stage - model_head)
                        else:
                            Q_stress_cell = riv_cond * (riv_stage - riv_rbot)
                    elif budget_term == "DRAINS":
                        drn_stage = cell_info[3]
                        drn_cond = cell_info[4]
                        model_head = head[lay, row, col]
                        if model_head > drn_stage:
                            Q_stress_cell = drn_cond * (drn_stage - model_head)
                        else:
                            continue
                    # Else, take the value saved by MODFLOW.
                    # This includes the budget terms:
                    # - 'CONSTANT HEAD' for:
                    #      * head specified through -1 in IBOUND
                    #      * head specified in CHD package
                    #      * head specified in FHB package
                    # - 'SPECIFIED FLOWS' for flow specified in FHB package
                    # - 'RESERV. LEAKAGE' for RES package
                    # - 'STREAM LEAKAGE' for:
                    #      * STR package
                    #      * SFR1 package
                    #      * SFR2 package
                    #  - 'LAKE SEEPAGE' for LAK3 package
                    #  - 'MNW' for MNW1 package
                    #  - 'MNW2' for MNW2 package
                    #  - 'SWIADDTOCH' for SWI2 package
                    else:
                        Q_stress_cell = Q_stress[lay, row, col]

                    if iface == 1:
                        Qx_ext[lay, row, col] += Q_stress_cell
                    elif iface == 2:
                        Qx_ext[lay, row, col + 1] -= Q_stress_cell
                    elif iface == 3:
                        Qy_ext[lay, row + 1, col] += Q_stress_cell
                    elif iface == 4:
                        Qy_ext[lay, row, col] -= Q_stress_cell
                    elif iface == 5:
                        Qz_ext[lay + 1, row, col] += Q_stress_cell
                    elif iface == 6:
                        Qz_ext[lay, row, col] -= Q_stress_cell
            else:
                raise TypeError("boundary_ifaces value must be either "
                                "int or list.")

    return Qx_ext, Qy_ext, Qz_ext
Пример #24
0
pcg = flopy.modflow.ModflowPcg(mf)

# Write the MODFLOW model input files
mf.write_input()

# Run the MODFLOW model
success, buff = mf.run_model()

# Post process the results
import matplotlib.pyplot as plt
import flopy.utils.binaryfile as bf
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(1, 1, 1, aspect='equal')

hds = bf.HeadFile(os.path.join('data', modelname + '.hds'))
times = hds.get_times()
head = hds.get_data(totim=times[-1])
levels = np.linspace(0, 10, 11)

cbb = bf.CellBudgetFile(os.path.join('data', modelname + '.cbc'))
kstpkper_list = cbb.get_kstpkper()
frf = cbb.get_data(text='FLOW RIGHT FACE', totim=times[-1])[0]
fff = cbb.get_data(text='FLOW FRONT FACE', totim=times[-1])[0]

modelmap = flopy.plot.ModelMap(model=mf, layer=0)
qm = modelmap.plot_ibound()
lc = modelmap.plot_grid()
cs = modelmap.contour_array(head, levels=levels)
quiver = modelmap.plot_discharge(frf, fff, head=head)
plt.show()
import numpy as np
import flopy.utils.binaryfile as bf
import pandas as pd
import glob

# set modelname
timeType = 'Transient'  # 'SteadyState' or 'Transient'
modelname = 'Navarro-'+timeType

## load RIV input
back_to_base_dir = os.path.join('..', '..', '..', '..', '..', '..', '..')
iriv = pd.read_table(os.path.join(back_to_base_dir, 'modflow', 'input', 'iriv.txt'), delimiter=' ')
iriv_ReachData = pd.read_table(os.path.join(back_to_base_dir, 'modflow', 'input', 'iriv_ReachData.txt'), delimiter=' ')

## load output files
rivout = bf.CellBudgetFile(modelname+'.riv.out', verbose=False)
mnwout = bf.CellBudgetFile(modelname+'.mnw2.out', verbose=False)
outputTimes = rivout.get_times()

# scroll through times
start_flag = True
for time in outputTimes:
    ## make a copy of iriv to avoid altering original
    iriv_copy = iriv.copy()
    
    # get riv output data
    rivout_3D = rivout.get_data(totim=time, text='RIVER LEAKAGE', full3D=True)
    iriv_copy['leakage'] = rivout_3D[0][iriv['lay'],iriv['row'],iriv['col']]
    
    ## join leakage to reach_data
    iriv_merge = pd.merge(iriv_ReachData[['SegNum', 'row', 'col','seg_proportion']], iriv_copy[['row', 'col', 'leakage']],
Пример #26
0
def test003_gwfs_disv():
    # init paths
    test_ex_name = 'test003_gwfs_disv'
    model_name = 'gwf_1'

    pth = os.path.join('..', 'examples', 'data', 'mf6', test_ex_name)
    run_folder = os.path.join(cpth, test_ex_name)
    if not os.path.isdir(run_folder):
        os.makedirs(run_folder)
    save_folder = os.path.join(run_folder, 'temp')
    if not os.path.isdir(save_folder):
        os.makedirs(save_folder)

    expected_output_folder = os.path.join(pth, 'expected_output')
    expected_head_file_a = os.path.join(expected_output_folder,
                                        'model_unch.hds')
    expected_head_file_b = os.path.join(expected_output_folder,
                                        'model_adj.hds')
    expected_cbc_file_a = os.path.join(expected_output_folder,
                                       'model_unch.cbc')
    expected_cbc_file_b = os.path.join(expected_output_folder, 'model_adj.cbc')

    array_util = PyListUtil()

    # load simulation
    sim = MFSimulation.load(model_name, 'mf6', exe_name, pth, verify_data=True)

    # make temp folder to save simulation
    sim.simulation_data.mfpath.set_sim_path(run_folder)

    # write simulation to new location
    sim.simulation_data.max_columns_of_data = 10
    sim.write_simulation()

    if run:
        # run simulation
        sim.run_simulation()

        # get expected results
        budget_file = os.path.join(os.getcwd(), expected_cbc_file_a)
        budget_obj = bf.CellBudgetFile(budget_file, precision='auto')
        budget_fjf_valid = np.array(
            budget_obj.get_data(text='    FLOW JA FACE', full3D=True))

        head_file = os.path.join(os.getcwd(), expected_head_file_a)
        head_new = os.path.join(run_folder, 'model.hds')
        assert pymake.compare_heads(None,
                                    None,
                                    files1=head_file,
                                    files2=head_new)

        budget_frf = sim.simulation_data.mfdata[(model_name, 'CBC',
                                                 'FLOW-JA-FACE')]
        assert array_util.array_comp(budget_fjf_valid, budget_frf)

    model = sim.get_model(model_name)
    if shapefile:
        model.export('{}/{}.shp'.format(pth, test_ex_name))

    # change some settings
    chd_head_left = model.get_package('CHD_LEFT')
    chd_left_period = chd_head_left.stress_period_data.get_data(0)
    chd_left_period[4][1] = 15.0
    chd_head_left.stress_period_data.set_data(chd_left_period, 0)

    chd_head_right = model.get_package('CHD_RIGHT')
    chd_right_period = chd_head_right.stress_period_data
    chd_right_data = chd_right_period.get_data(0)
    chd_right_data_slice = chd_right_data[3:10]
    chd_right_period.set_data(chd_right_data_slice, 0)

    # write simulation again
    sim.simulation_data.mfpath.set_sim_path(save_folder)
    sim.write_simulation()

    if run:
        # run simulation
        sim.run_simulation()

        # get expected results
        budget_file = os.path.join(os.getcwd(), expected_cbc_file_b)
        budget_obj = bf.CellBudgetFile(budget_file, precision='double')
        budget_fjf_valid = np.array(
            budget_obj.get_data(text='FLOW JA FACE', full3D=True))

        # compare output to expected results
        head_file = os.path.join(os.getcwd(), expected_head_file_b)
        head_new = os.path.join(save_folder, 'model.hds')
        assert pymake.compare_heads(None,
                                    None,
                                    files1=head_file,
                                    files2=head_new)

        budget_frf = sim.simulation_data.mfdata[(model_name, 'CBC',
                                                 'FLOW-JA-FACE')]
        assert array_util.array_comp(budget_fjf_valid, budget_frf)

        # clean up
        sim.delete_output_files()

    return
obs4_xcoord = 120
obs4_ycoord = 80
obs4_col = int(np.round(obs4_xcoord / delc))
obs4_row = int(np.round((Ly - obs4_ycoord) / delr))

# Plan view
fig = plt.figure(figsize=(10, 12))
ax = fig.add_subplot(1, 1, 1)

hds = bf.HeadFile(modelName + '.hds')
times = hds.get_times()
head = hds.get_data(totim=times[-1])
levels = np.linspace(-1, 2.1, 6)

cbb = bf.CellBudgetFile(modelName + '.cbc')  # read budget file
kstpkper_list = cbb.get_kstpkper()
# cbb.textlist to get a list of data texts
frf = cbb.get_data(text='FLOW RIGHT FACE', totim=times[-1])[0]
fff = cbb.get_data(text='FLOW FRONT FACE', totim=times[-1])[0]

# flopy plot object
pmv = flopy.plot.PlotMapView(model=mf, layer=0)

# plot grid
lc = pmv.plot_grid()  # grid

# plot contour
cs = pmv.contour_array(head, levels=np.linspace(-1, 3, 16))  # head contour
plt.clabel(cs, fontsize=fS, fmt='%1.1f')  # contour label
Пример #28
0
                               delimiter=' ')

## figure out which runs succeeded (output from CheckFailures script)
succ = pd.read_table(os.path.join(dir_runs, 'CheckFailure.csv'), delimiter=",")

## loop through and make output data frame
start_flag = True
for w in succ.WellNum:
    # check if model ran successfully
    converge = succ.Success.loc[(succ['WellNum'] == w)].bool()

    if converge:

        ## load output files
        rivout = bf.CellBudgetFile(os.path.join(dir_runs, prefix_runs + str(w),
                                                modelname + '.riv.out'),
                                   verbose=False)
        mnwout = bf.CellBudgetFile(os.path.join(dir_runs, prefix_runs + str(w),
                                                modelname + '.mnw2.out'),
                                   verbose=False)
        outputTimes = rivout.get_times()

        # scroll through times
        for time in outputTimes:
            ## make a copy of iriv to avoid altering original
            iriv_copy = iriv.copy()

            # get riv output data
            rivout_3D = rivout.get_data(totim=time,
                                        text='RIVER LEAKAGE',
                                        full3D=True)
Пример #29
0
def get_specific_discharge(
    model,
    cbcfile,
    precision="single",
    idx=None,
    kstpkper=None,
    totim=None,
    boundary_ifaces=None,
    hdsfile=None,
    position="centers",
):
    """
    Get the discharge vector at cell centers at a given time. For "classical"
    MODFLOW versions, we calculate it from the flow rate across cell faces.
    For MODFLOW 6, we directly take it from MODFLOW output (this requires
    setting the option "save_specific_discharge" in the NPF package).

    Parameters
    ----------
    model : flopy.modflow.Modflow object
        Modflow model instance.
    cbcfile : str
        Cell by cell file produced by Modflow.
    precision : str
        Binary file precision, default is 'single'.
    idx : int or list
            The zero-based record number.
    kstpkper : tuple of ints
        A tuple containing the time step and stress period (kstp, kper).
        The kstp and kper values are zero based.
    totim : float
        The simulation time.
    boundary_ifaces : dictionary {str: int or list}
        A dictionary defining how to treat stress flows at boundary cells.
        Only implemented for "classical" MODFLOW versions where the budget is
        recorded as FLOW RIGHT FACE, FLOW FRONT FACE and FLOW LOWER FACE
        arrays.
        The keys are budget terms corresponding to stress packages (same term
        as in the overall volumetric budget printed in the listing file).
        The values are either a single iface number to be applied to all cells
        for the stress package, or a list of lists describing individual
        boundary cells in the same way as in the package input plus the iface
        number appended. The iface number indicates the face to which the
        stress flow is assigned, following the MODPATH convention (see MODPATH
        user guide).
        Example:
        boundary_ifaces = {
        'RECHARGE': 6,
        'RIVER LEAKAGE': 6,
        'WELLS': [[lay, row, col, flux, iface], ...],
        'HEAD DEP BOUNDS': [[lay, row, col, head, cond, iface], ...]}.
        Note: stresses that are not informed in boundary_ifaces are implicitly
        treated as internally-distributed sinks/sources.
    hdsfile : str
        Head file produced by MODFLOW. Head is used to calculate saturated
        thickness and to determine if a cell is inactive or dry. If not
        provided, all cells are considered fully saturated.
        hdsfile is also required if the budget term 'HEAD DEP BOUNDS',
        'RIVER LEAKAGE' or 'DRAINS' is present in boundary_ifaces and that the
        corresponding value is a list.
    position : str
        Position at which the specific discharge will be calculated. Possible
        values are "centers" (default), "faces" and "vertices".

    Returns
    -------
    (qx, qy, qz) : tuple
        Discharge vector.
        qx, qy, qz are ndarrays of size (nlay, nrow, ncol) for a structured
        grid or size (nlay, ncpl) for an unstructured grid.
        The sign of qy is such that the y axis is considered to increase
        in the north direction.
        The sign of qz is such that the z axis is considered to increase
        in the upward direction.
        Note: if hdsfile is provided, inactive and dry cells are set to NaN.
    """
    import flopy.utils.binaryfile as bf

    # check if budget file has classical budget terms
    cbf = bf.CellBudgetFile(cbcfile, precision=precision)
    rec_names = cbf.get_unique_record_names(decode=True)
    classical_budget_terms = [
        "FLOW RIGHT FACE",
        "FLOW FRONT FACE",
        "FLOW RIGHT FACE",
    ]
    classical_budget = False
    for budget_term in classical_budget_terms:
        matched_name = [s for s in rec_names if budget_term in s]
        if matched_name:
            classical_budget = True
            break

    if hdsfile is not None:
        hds = bf.HeadFile(hdsfile, precision=precision)
        head = hds.get_data(idx=idx, kstpkper=kstpkper, totim=totim)

    if classical_budget:
        # get extended budget
        Qx_ext, Qy_ext, Qz_ext = get_extended_budget(
            cbcfile,
            precision=precision,
            idx=idx,
            kstpkper=kstpkper,
            totim=totim,
            boundary_ifaces=boundary_ifaces,
            hdsfile=hdsfile,
            model=model,
        )

        # get saturated thickness (head - bottom elev for unconfined layer)
        if hdsfile is None:
            sat_thk = model.dis.thickness.array
        else:
            sat_thk = get_saturated_thickness(head, model, model.hdry)
            sat_thk = sat_thk.reshape(model.modelgrid.shape)

        # inform modelgrid of no-flow and dry cells
        modelgrid = model.modelgrid
        if modelgrid._idomain is None:
            modelgrid._idomain = model.dis.ibound
        if hdsfile is not None:
            noflo_or_dry = np.logical_or(head == model.hnoflo,
                                         head == model.hdry)
            modelgrid._idomain[noflo_or_dry] = 0

        # get cross section areas along x
        delc = np.reshape(modelgrid.delc, (1, modelgrid.nrow, 1))
        cross_area_x = np.empty(modelgrid.shape, dtype=float)
        cross_area_x = delc * sat_thk

        # get cross section areas along y
        delr = np.reshape(modelgrid.delr, (1, 1, modelgrid.ncol))
        cross_area_y = np.empty(modelgrid.shape, dtype=float)
        cross_area_y = delr * sat_thk

        # get cross section areas along z
        cross_area_z = np.ones(modelgrid.shape) * delc * delr

        # calculate qx, qy, qz
        if position == "centers":
            qx = 0.5 * (Qx_ext[:, :, 1:] + Qx_ext[:, :, :-1]) / cross_area_x
            qy = 0.5 * (Qy_ext[:, 1:, :] + Qy_ext[:, :-1, :]) / cross_area_y
            qz = 0.5 * (Qz_ext[1:, :, :] + Qz_ext[:-1, :, :]) / cross_area_z
        elif position == "faces" or position == "vertices":
            cross_area_x = modelgrid.array_at_faces(cross_area_x, "x")
            cross_area_y = modelgrid.array_at_faces(cross_area_y, "y")
            cross_area_z = modelgrid.array_at_faces(cross_area_z, "z")
            qx = Qx_ext / cross_area_x
            qy = Qy_ext / cross_area_y
            qz = Qz_ext / cross_area_z
        else:
            raise ValueError('"' + position + '" is not a valid value for '
                             "position")
        if position == "vertices":
            qx = modelgrid.array_at_verts(qx)
            qy = modelgrid.array_at_verts(qy)
            qz = modelgrid.array_at_verts(qz)

    else:
        # check valid options
        if boundary_ifaces is not None:
            import warnings

            warnings.warn(
                "the boundary_ifaces option is not implemented "
                'for "non-classical" MODFLOW versions where the '
                "budget is not recorded as FLOW RIGHT FACE, "
                "FLOW FRONT FACE and FLOW LOWER FACE; it will be "
                "ignored",
                UserWarning,
            )
        if position != "centers":
            raise NotImplementedError('position can only be "centers" for '
                                      '"non-classical" MODFLOW versions where '
                                      "the budget is not recorded as FLOW "
                                      "RIGHT FACE, FLOW FRONT FACE and FLOW "
                                      "LOWER FACE")

        is_spdis = [s for s in rec_names if "DATA-SPDIS" in s]
        if not is_spdis:
            err_msg = ("Could not find suitable records in the budget file "
                       "to construct the discharge vector.")
            raise RuntimeError(err_msg)
        spdis = cbf.get_data(text="DATA-SPDIS",
                             idx=idx,
                             kstpkper=kstpkper,
                             totim=totim)[0]
        nnodes = model.modelgrid.nnodes
        qx = np.full((nnodes), np.nan)
        qy = np.full((nnodes), np.nan)
        qz = np.full((nnodes), np.nan)
        idx = np.array(spdis["node"]) - 1
        qx[idx] = spdis["qx"]
        qy[idx] = spdis["qy"]
        qz[idx] = spdis["qz"]
        shape = model.modelgrid.shape
        qx.shape = shape
        qy.shape = shape
        qz.shape = shape

    # set no-flow and dry cells to NaN
    if hdsfile is not None and position == "centers":
        noflo_or_dry = np.logical_or(head == model.hnoflo, head == model.hdry)
        qx[noflo_or_dry] = np.nan
        qy[noflo_or_dry] = np.nan
        qz[noflo_or_dry] = np.nan

    return qx, qy, qz
Пример #30
0
        'STO_OUT': STO_OUT,
        'GHB_OUT': GHB_OUT,
        'DRT_OUT': DRT_OUT,
        'ET_OUT': ET_OUT,
        'Total_In': Total_In_NEW,
        'Total_Out': Total_Out_NEW,
        'WEL_IN': WEL_IN,
        'WEL_OUT': WEL_OUT
    })
    df.to_csv('budget.csv', index=None)

if read_ccf:  # Read ccf file to get simulated spring flows
    ifile = mname_prefix + '.ccf'
    fsize = os.path.getsize(ifile)
    if fsize > 4000000000:  # make sure model is converged (ccf > 4GB)
        cbb = bf.CellBudgetFile(ifile)
        # list_unique_records = cbb.list_unique_records()  # Print all RECORDS

        # ncols = 3  # make sure you change this
        #data_out = np.empty([n_stress_period, ncols])

        # Load data

        drt_cell = np.loadtxt(ifile_loc_spring_cells, delimiter=',',
                              dtype=int)  # use "" for python2
        n_drt_cells = len(drt_cell)
        drt_cell = drt_cell - 1  # IMPORTANT -  Python index is from 0
        Q_Bennetts = []
        Q_Manse = []
        #    fid = open('flow_at_cells.csv', 'w')
        for ts in range(n_stress_period):