def test_get_water_table(): nodata = -9999. hds = np.ones ((3, 3, 3), dtype=float) * nodata hds[-1, :, :] = 2. hds[1, 1, 1] = 1. wt = get_water_table(hds, nodata=nodata) assert wt.shape == (3, 3) assert wt[1, 1] == 1. assert np.sum(wt) == 17. hds2 = np.array([hds, hds]) wt = get_water_table(hds2, nodata=nodata) assert wt.shape == (2, 3, 3) assert np.sum(wt[:, 1, 1]) == 2. assert np.sum(wt) == 34. wt = get_water_table(hds2, nodata=nodata, per_idx=0) assert wt.shape == (3, 3) assert wt[1, 1] == 1. assert np.sum(wt) == 17.
def test_get_water_table(): nodata = -9999. hds = np.ones((3, 3, 3), dtype=float) * nodata hds[-1, :, :] = 2. hds[1, 1, 1] = 1. wt = get_water_table(hds, nodata=nodata) assert wt.shape == (3, 3) assert wt[1, 1] == 1. assert np.sum(wt) == 17. hds2 = np.array([hds, hds]) wt = get_water_table(hds2, nodata=nodata) assert wt.shape == (2, 3, 3) assert np.sum(wt[:, 1, 1]) == 2. assert np.sum(wt) == 34. wt = get_water_table(hds2, nodata=nodata, per_idx=0) assert wt.shape == (3, 3) assert wt[1, 1] == 1. assert np.sum(wt) == 17.
def get_inset_boundary_fluxes(self, kstpkper=(0, 0)): """Get all boundary fluxes for a stress period. Parameters ---------- kstpkper : tuple or list of tuples zero-based (timestep, stress period) Returns ------- df : DataFrame of all pfl_nwt model boundary fluxes With columns k, i, j, flux, and per """ assert 'UPW' in self.inset.get_package_list( ), "need UPW package to get boundary fluxes" assert 'DIS' in self.inset.get_package_list( ), "need DIS package to get boundary fluxes" if not isinstance(kstpkper, list): kstpkper = [kstpkper] t0 = time.time() print('getting boundary fluxes from {}...'.format(self.cpth)) dfs = [] for kp in kstpkper: hdsobj = bf.HeadFile(self.hpth) hds = hdsobj.get_data(kstpkper=kp) hdry = -9999 self.wt = get_water_table(hds, nodata=hdry) self.read_parent_cbc_per(kstpkper=kp) for side in ['top', 'left', 'bottom', 'right']: print(side) Qside = self.get_inset_boundary_flux_side(side) Qside['per'] = kp[1] dfs.append(Qside) df = pd.concat(dfs) # check that Qnet out of the parent model equals # the derived fluxes on the pfl_nwt side tol = 0.01 for per, dfp in df.groupby('per'): Qnet_parent = self.get_parent_boundary_net_flux(kstpkper=per) Qnet_inset = dfp.flux.sum() assert np.abs(Qnet_parent - Qnet_inset) < tol print("finished in {:.2f}s\n".format(time.time() - t0)) return df
def export_drawdown(heads_file, grid, hdry, hnflo, kstpkper0=None, kstpkper1=None, levels=None, interval=None, output_path='postproc', suffix=''): """Export MODFLOW binary head output to rasters and shapefiles. Parameters ---------- modelname : str model base name grid : rOpen.modflow.grid instance hdry : hdry value from UPW package hnflo : hnflo value from BAS package levels : 1D numpy array Values of equal interval contours to write. shps_outfolder : where to write shapefiles rasters_outfolder : where to write rasters Writes ------ * A raster of heads for each layer and a raster of the water table elevation * Shapefiles of head contours for each layer and the water table. """ print('Exporting drawdown...') print('file: {}'.format(heads_file)) if kstpkper0 is not None: print( 'from stress period {}, timestep {}'.format(*reversed(kstpkper0))) if kstpkper1 is not None: print('to stress period {}, timestep {}'.format(*reversed(kstpkper1))) print('\n') if kstpkper1 == (0, 0): print('kstpkper == (0, 0, no drawdown to export') return kstp, kper = kstpkper1 pdfs_dir, rasters_dir, shps_dir = make_output_folders(output_path) # Heads output hdsobj = bf.HeadFile(heads_file) hds0 = hdsobj.get_data(kstpkper=kstpkper0) wt0 = get_water_table(hds0, nodata=hdry) hds1 = hdsobj.get_data(kstpkper=kstpkper1) wt1 = get_water_table(hds1, nodata=hdry) hds0[(hds0 > 9999) & (hds0 < 0)] = np.nan hds1[(hds1 > 9999) & (hds1 < 0)] = np.nan ddn = hds0 - hds1 wt_ddn = wt0 - wt1 outfiles = [] outfile = '{}/wt-ddn_per{}_stp{}{}.tif'.format(rasters_dir, kper, kstp, suffix) ctr_outfile = '{}/wt-ddn_ctr_per{}_stp{}{}.shp'.format( shps_dir, kper, kstp, suffix) export_array(outfile, wt_ddn, grid, nodata=hnflo) export_array_contours( ctr_outfile, wt_ddn, grid, levels=levels, interval=interval, ) outfiles += [outfile, ctr_outfile] for k, d in enumerate(ddn): outfile = '{}/ddn_lay{}_per{}_stp{}{}.tif'.format( rasters_dir, k, kper, kstp, suffix) ctr_outfile = '{}/ddn_ctr_lay{}_per{}_stp{}{}.shp'.format( shps_dir, k, kper, kstp, suffix) export_array(outfile, d, grid, nodata=hnflo) export_array_contours(ctr_outfile, d, grid, levels=levels) outfiles += [outfile, ctr_outfile] return outfiles
def export_heads(heads_file, grid, hdry, hnflo, kstpkper=(0, 0), levels=None, interval=None, output_path='postproc', suffix=''): """Export MODFLOW binary head output to rasters and shapefiles. Parameters ---------- modelname : str model base name grid : rOpen.modflow.grid instance hdry : hdry value from UPW package hnflo : hnflo value from BAS package levels : 1D numpy array Values of equal interval contours to write. shps_outfolder : where to write shapefiles rasters_outfolder : where to write rasters Writes ------ * A raster of heads for each layer and a raster of the water table elevation * Shapefiles of head contours for each layer and the water table. """ if np.isscalar(kstpkper[0]): kstpkper = [kstpkper] print('Exporting heads...') print('file: {}'.format(heads_file)) pdfs_dir, rasters_dir, shps_dir = make_output_folders(output_path) outfiles = [] for kstp, kper in kstpkper: print('stress period {}, timestep {}'.format(kper, kstp)) # Heads output hdsobj = bf.HeadFile(heads_file) hds = hdsobj.get_data(kstpkper=(kstp, kper)) wt = get_water_table(hds, nodata=hdry) wt[(wt > 9999) | (wt < 0)] = np.nan outfile = '{}/wt_per{}_stp{}{}.tif'.format(rasters_dir, kper, kstp, suffix) ctr_outfile = '{}/wt_ctr_per{}_stp{}{}.shp'.format( shps_dir, kper, kstp, suffix) export_array(outfile, wt, grid, nodata=hnflo) export_array_contours(ctr_outfile, wt, grid, levels=levels, interval=interval) outfiles += [outfile, ctr_outfile] hds[(hds > 9999) | (hds < 0)] = np.nan for k, h in enumerate(hds): outfile = '{}/hds_lay{}_per{}_stp{}{}.tif'.format( rasters_dir, k, kper, kstp, suffix) ctr_outfile = '{}/hds_ctr_lay{}_per{}_stp{}{}.shp'.format( shps_dir, k, kper, kstp, suffix) export_array(outfile, h, grid, nodata=hnflo) export_array_contours( ctr_outfile, h, grid, levels=levels, interval=interval, ) outfiles += [outfile, ctr_outfile] return outfiles
def export_heads(heads_file, grid, hdry, hnflo, kstpkper=(0, 0), levels=None, interval=None, export_water_table=True, export_depth_to_water=True, export_layers=False, land_surface_elevations=None, output_path='postproc', suffix=''): """Export MODFLOW binary head output to rasters and shapefiles. Parameters ---------- modelname : str model base name grid : rOpen.modflow.grid instance hdry : hdry value from UPW package hnflo : hnflo value from BAS package levels : 1D numpy array Values of equal interval contours to write. shps_outfolder : where to write shapefiles rasters_outfolder : where to write rasters Writes ------ * A raster of heads for each layer and a raster of the water table elevation * Shapefiles of head contours for each layer and the water table. """ if np.isscalar(kstpkper[0]): kstpkper = [kstpkper] print('Exporting heads...') print('file: {}'.format(heads_file)) pdfs_dir, rasters_dir, shps_dir = make_output_folders(output_path) outfiles = [] for kstp, kper in kstpkper: print('stress period {}, timestep {}'.format(kper, kstp)) # Heads output hdsobj = bf.HeadFile(heads_file) hds = hdsobj.get_data(kstpkper=(kstp, kper)) if export_water_table or export_depth_to_water: wt = get_water_table(hds, nodata=hdry) wt[(wt > 9999) | (wt < 0)] = np.nan outfile = '{}/wt_per{}_stp{}{}.tif'.format(rasters_dir, kper, kstp, suffix) ctr_outfile = '{}/wt_ctr_per{}_stp{}{}.shp'.format(shps_dir, kper, kstp, suffix) export_array(outfile, wt, grid, nodata=hnflo) export_array_contours(ctr_outfile, wt, grid, levels=levels, interval=interval) outfiles += [outfile, ctr_outfile] if export_depth_to_water: if land_surface_elevations is None: raise ValueError(('export_heads: export_depth_to_water option ' 'requires specification of the land surface')) if not isinstance(land_surface_elevations, np.ndarray): land_surface_elevations = np.loadtxt(land_surface_elevations) # Depth to water dtw = land_surface_elevations - wt # Overpressurization op = dtw.copy() # For DTW, mask areas of overpressurization; # For Overpressurization, mask areas where water table is below land surface op = np.ma.masked_array(op, mask=op > 0) dtw = np.ma.masked_array(dtw, mask=dtw < 0) if np.max(dtw) > 0: #dtw_levels = None #if interval is not None: # dtw_levels = np.linspace(0, np.nanmax(dtw), interval) outfile = '{}/dtw_per{}_stp{}{}.tif'.format(rasters_dir, kper, kstp, suffix) ctr_outfile = '{}/dtw_ctr_per{}_stp{}{}.shp'.format(shps_dir, kper, kstp, suffix) export_array(outfile, dtw, grid, nodata=hnflo) export_array_contours(ctr_outfile, dtw, grid, interval=interval) outfiles += [outfile, ctr_outfile] else: print('Water table is above land surface everywhere, skipping depth to water.') if np.nanmin(op) < 0: #op_levels = None #if interval is not None: # op_levels = np.linspace(0, np.nanmin(op), interval) outfile = '{}/op_per{}_stp{}{}.tif'.format(rasters_dir, kper, kstp, suffix) ctr_outfile = '{}/op_ctr_per{}_stp{}{}.shp'.format(shps_dir, kper, kstp, suffix) export_array(outfile, op, grid, nodata=hnflo) export_array_contours(ctr_outfile, op, grid, interval=interval) outfiles += [outfile, ctr_outfile] else: print('No overpressurization, skipping.') hds[(hds > 9999) | (hds < 0)] = np.nan if export_layers: for k, h in enumerate(hds): outfile = '{}/hds_lay{}_per{}_stp{}{}.tif'.format(rasters_dir, k, kper, kstp, suffix) ctr_outfile = '{}/hds_ctr_lay{}_per{}_stp{}{}.shp'.format(shps_dir, k, kper, kstp, suffix) export_array(outfile, h, grid, nodata=hnflo) export_array_contours(ctr_outfile, h, grid, levels=levels, interval=interval, ) outfiles += [outfile, ctr_outfile] return outfiles
time = 1 ## head output # Create the headfile object h = bf.HeadFile(os.path.join(model_ws, modelname_NoPump+'.hds'), text='head') h_NoPump = bf.HeadFile(os.path.join(model_ws_NoPump, modelname_NoPump+'.hds'), text='head') # extract data matrix head = h.get_data(totim=time) head[head <= mf.bas6.hnoflo] = np.nan head_NoPump = h_NoPump.get_data(totim=time) head_NoPump[head_NoPump <= mf.bas6.hnoflo] = np.nan # calculate WTE and DDN wte = pp.get_water_table(head, nodata=mf.bas6.hnoflo) wte_NoPump = pp.get_water_table(head_NoPump, nodata=mf.bas6.hnoflo) ddn = wte_NoPump - wte ## load MNW output mnwout = bf.CellBudgetFile(os.path.join(model_ws, modelname_NoPump+'.mnw2.out'), verbose=False) mnwout_data = mnwout.get_data(totim=time, text='MNW2', full3D=True)[0] mnwout.close() # well of interest row_wel = 410 # Well 493 col_wel = 360 # Well 493 mnwout_data[:,row_wel,col_wel] # well
success, mfoutput = mf.run_model() if not success: raise Exception('MODFLOW did not terminate normally.') # output rivout = bf.CellBudgetFile(modelname + '.riv.out', verbose=False) rivout_3D = rivout.get_data(totim=1, text='RIVER LEAKAGE') leakage_L_pump_10lay = rivout_3D[0][0][1] leakage_R_pump_10lay = rivout_3D[0][1][1] rivout.close() h = bf.HeadFile(modelname + '.hds', text='head') head_pump_10lay = h.get_data(totim=1) h.close() # calculate WTEs wte_noPump = pp.get_water_table(head_noPump, nodata=-9999) wte_noPump_10lay = pp.get_water_table(head_noPump_10lay, nodata=-9999) wte_pump = pp.get_water_table(head_pump, nodata=-9999) wte_pump_10lay = pp.get_water_table(head_pump_10lay, nodata=-9999) ## plots # water table plt.plot(xcoord, wte_noPump, 'b') plt.plot(xcoord, wte_pump, 'r') plt.plot(xcoord, wte_noPump_10lay, 'b--') plt.plot(xcoord, wte_pump_10lay, 'r--') plt.xlabel('position [m]') plt.ylabel('water table elevation [m]') #plt.axis([0, 1010, 88, 100]) plt.title( 'blue=no pumping, red=pumping;\nsolid=1 layer, dashed=5 layer\nLeft/Right Capture Fraction='
gage = flopy.modflow.ModflowGage(mf, numgage=numgage, gage_data=gage_data, unitnumber=90) ## write inputs and run model (the first time - will be run again with MNW2 package) mf.write_input() success, mfoutput = mf.run_model() if not success: raise Exception('MODFLOW did not terminate normally.') ## need to figure out steady-state WTE to define wells # use head output from the SS situation without boreholes time = perlen[0] h = bf.HeadFile(os.path.join(mf.model_ws, modelname+'.hds'), text='head') head = h.get_data(totim=time) wte = pp.get_water_table(head, nodata=bas.hnoflo) ## create MNW2 package # Based on: https://github.com/modflowpy/flopy/blob/develop/examples/Notebooks/flopy3_mnw2package_example.ipynb iwel = pd.read_table(os.path.join('modflow', 'input', 'iwel.txt'), delimiter=' ') # define well parameters losstype = 'THIEM' pumploc = 0 # 0=intake location assumed to occur above first active node qlimit = 0 # 0=do not constrain pumping rate based on head ppflag = 1 # 1=adjust head for partial penetration pumpcap = 0 # 0=do not adjust pumping rate for changes in lift rw = 0.25 screen_length = 50 # [m] - will start at SS WTE start_flag = True