Beispiel #1
0
def test_setup_lake_info(get_pleasant_mf6_with_dis):

    m = get_pleasant_mf6_with_dis
    result = setup_lake_info(m)
    for id in result.lak_id:
        loc = m._lakarr_2d == id
        strt = result.loc[result.lak_id == id, 'strt'].values[0]
        assert np.allclose(strt, m.dis.top.array[loc].min())

    # test setting up lake info without any lake package
    del m.cfg['lak']
    result = setup_lake_info(m)
    assert result is None
    assert m.lake_recharge is None
Beispiel #2
0
    def setup_lak(self):

        print('setting up LAKE package...')
        t0 = time.time()
        # if shapefile of lakes was included,
        # lakarr should be automatically built by property method
        if self.lakarr.sum() == 0:
            print("lakes_shapefile not specified, or no lakes in model area")
            return

        # source data
        source_data = self.cfg['lak']['source_data']
        self.lake_info = setup_lake_info(self)
        nlakes = len(self.lake_info)

        # set up the tab files, if any
        tab_files_argument = None
        tab_units = None
        start_tab_units_at = 150  # default starting number for iunittab
        if 'stage_area_volume_file' in source_data:

            tab_files = setup_lake_tablefiles(
                self, source_data['stage_area_volume_file'])
            tab_units = list(
                range(start_tab_units_at, start_tab_units_at + len(tab_files)))

            # tabfiles aren't rewritten by flopy on package write
            self.cfg['lak']['tab_files'] = tab_files
            # kludge to deal with ugliness of lake package external file handling
            # (need to give path relative to model_ws, not folder that flopy is working in)
            tab_files_argument = [os.path.relpath(f) for f in tab_files]

        self.setup_external_filepaths(
            'lak', 'lakzones',
            self.cfg['lak']['{}_filename_fmt'.format('lakzones')])
        self.setup_external_filepaths(
            'lak',
            'bdlknc',
            self.cfg['lak']['{}_filename_fmt'.format('bdlknc')],
            file_numbers=list(range(self.nlay)))

        # make the arrays or load them
        lakzones = make_bdlknc_zones(self.modelgrid,
                                     self.lake_info,
                                     include_ids=self.lake_info['feat_id'])
        save_array(self.cfg['intermediate_data']['lakzones'][0],
                   lakzones,
                   fmt='%d')

        bdlknc = np.zeros((self.nlay, self.nrow, self.ncol))
        # make the areal footprint of lakebed leakance from the zones (layer 1)
        bdlknc[0] = make_bdlknc2d(
            lakzones, self.cfg['lak']['source_data']['littoral_leakance'],
            self.cfg['lak']['source_data']['profundal_leakance'])
        for k in range(self.nlay):
            if k > 0:
                # for each underlying layer, assign profundal leakance to cells were isbc == 1
                bdlknc[k][self.isbc[k] == 1] = self.cfg['lak']['source_data'][
                    'profundal_leakance']
            save_array(self.cfg['intermediate_data']['bdlknc'][0][k],
                       bdlknc[k],
                       fmt='%.6e')

        # get estimates of stage from model top, for specifying ranges
        stages = []
        for lakid in self.lake_info['lak_id']:
            loc = self.lakarr[0] == lakid
            est_stage = self.dis.top.array[loc].min()
            stages.append(est_stage)
        stages = np.array(stages)

        # setup stress period data
        tol = 5  # specify lake stage range as +/- this value
        ssmn, ssmx = stages - tol, stages + tol
        stage_range = list(zip(ssmn, ssmx))

        # set up dataset 9
        # ssmn and ssmx values only required for steady-state periods > 0
        self.lake_fluxes = setup_lake_fluxes(self)
        precip = self.lake_fluxes['precipitation'].tolist()
        evap = self.lake_fluxes['evaporation'].tolist()
        flux_data = {}
        for i, steady in enumerate(self.dis.steady.array):
            if i > 0 and steady:
                flux_data_i = []
                for lake_ssmn, lake_ssmx in zip(ssmn, ssmx):
                    flux_data_i.append(
                        [precip[i], evap[i], 0, 0, lake_ssmn, lake_ssmx])
            else:
                flux_data_i = [[precip[i], evap[i], 0, 0]] * nlakes
            flux_data[i] = flux_data_i
        options = ['tableinput'] if tab_files_argument is not None else None

        kwargs = self.cfg['lak']
        kwargs['nlakes'] = len(self.lake_info)
        kwargs['stages'] = stages
        kwargs['stage_range'] = stage_range
        kwargs['flux_data'] = flux_data
        kwargs[
            'tab_files'] = tab_files_argument  #This needs to be in the order of the lake IDs!
        kwargs['tab_units'] = tab_units
        kwargs['options'] = options
        kwargs['ipakcb'] = self.ipakcb
        kwargs['lwrt'] = 0
        kwargs = get_input_arguments(kwargs, fm.mflak.ModflowLak)
        lak = fm.ModflowLak(self, **kwargs)
        print("finished in {:.2f}s\n".format(time.time() - t0))
        return lak
Beispiel #3
0
    def setup_lak(self):
        """
        Sets up the Lake package.

        Parameters
        ----------

        Notes
        -----

        """
        package = 'lak'
        print('\nSetting up {} package...'.format(package.upper()))
        t0 = time.time()
        if self.lakarr.sum() == 0:
            print("lakes_shapefile not specified, or no lakes in model area")
            return

        # option to write connectiondata to external file
        external_files = self.cfg['lak']['external_files']

        # source data
        source_data = self.cfg['lak']['source_data']

        # munge lake package input
        # returns dataframe with information for each lake
        self.lake_info = setup_lake_info(self)

        # returns dataframe with connection information
        connectiondata = setup_lake_connectiondata(self, for_external_file=external_files)
        # lakeno column will have # in front if for_external_file=True
        lakeno_col = [c for c in connectiondata.columns if 'lakeno' in c][0]
        nlakeconn = connectiondata.groupby(lakeno_col).count().iconn.to_dict()
        offset = 0 if external_files else 1
        self.lake_info['nlakeconn'] = [nlakeconn[id - offset] for id in self.lake_info['lak_id']]

        # set up the tab files
        if 'stage_area_volume_file' in source_data:
            tab_files = setup_lake_tablefiles(self, source_data['stage_area_volume_file'])

            # tabfiles aren't rewritten by flopy on package write
            self.cfg['lak']['tab_files'] = tab_files
            # kludge to deal with ugliness of lake package external file handling
            # (need to give path relative to model_ws, not folder that flopy is working in)
            tab_files_argument = [os.path.relpath(f) for f in tab_files]

        # todo: implement lake outlets with SFR

        # perioddata
        self.lake_fluxes = setup_lake_fluxes(self)
        lakeperioddata = get_lakeperioddata(self.lake_fluxes)

        # set up external files
        connectiondata_cols = [lakeno_col, 'iconn', 'k', 'i', 'j', 'claktype', 'bedleak',
                               'belev', 'telev', 'connlen', 'connwidth']
        if external_files:
            # get the file path (allowing for different external file locations, specified name format, etc.)
            filepath = self.setup_external_filepaths(package, 'connectiondata',
                                                     self.cfg[package]['connectiondata_filename_fmt'])
            connectiondata[connectiondata_cols].to_csv(filepath[0]['filename'], index=False, sep=' ')
            # make a copy for the intermediate data folder, for consistency with mf-2005
            shutil.copy(filepath[0]['filename'], self.cfg['intermediate_data']['output_folder'])
        else:
            connectiondata_cols = connectiondata_cols[:2] + ['cellid'] + connectiondata_cols[5:]
            self.cfg[package]['connectiondata'] = connectiondata[connectiondata_cols].values.tolist()

        # set up input arguments
        kwargs = self.cfg[package].copy()
        options = self.cfg[package]['options'].copy()
        renames = {'budget_fileout': 'budget_filerecord',
                   'stage_fileout': 'stage_filerecord'}
        for k, v in renames.items():
            if k in options:
                options[v] = options.pop(k)
        kwargs.update(self.cfg[package]['options'])
        kwargs['time_conversion'] = convert_time_units(self.time_units, 'seconds')
        kwargs['length_conversion'] = convert_time_units(self.length_units, 'meters')
        kwargs['nlakes'] = len(self.lake_info)
        kwargs['noutlets'] = 0  # not implemented
        # [lakeno, strt, nlakeconn, aux, boundname]
        packagedata_cols = ['lak_id', 'strt', 'nlakeconn']
        if kwargs.get('boundnames'):
            packagedata_cols.append('name')
        packagedata = self.lake_info[packagedata_cols]
        packagedata['lak_id'] -= 1  # convert to zero-based
        kwargs['packagedata'] = packagedata.values.tolist()
        kwargs['ntables'] = len(tab_files)
        kwargs['tables'] = [(i, f, 'junk', 'junk') for i, f in enumerate(tab_files)]
        kwargs['outlets'] = None  # not implemented
        #kwargs['outletperioddata'] = None  # not implemented
        kwargs['perioddata'] = lakeperioddata

        # observations
        kwargs['observations'] = setup_mf6_lake_obs(kwargs)

        kwargs = get_input_arguments(kwargs, mf6.ModflowGwflak)
        lak = mf6.ModflowGwflak(self, **kwargs)
        print("finished in {:.2f}s\n".format(time.time() - t0))
        return lak