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
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
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