def test_mflist_reference(): import os import numpy as np import shapefile import flopy.modflow as fmf # model_ws = os.path.join('..', 'data', 'freyberg') # ml = fmf.Modflow.load('freyberg.nam', model_ws=model_ws) # make the model ml = fmf.Modflow() assert isinstance(ml, fmf.Modflow) perlen = np.arange(1, 20, 1) nstp = np.flipud(perlen) + 3 tsmult = 1.2 nlay = 10 nrow, ncol = 50, 40 botm = np.arange(0, -100, -10) hk = np.random.random((nrow, ncol)) dis = fmf.ModflowDis(ml, delr=100.0, delc=100.0, nrow=nrow, ncol=ncol, nlay=nlay, nper=perlen.shape[0], perlen=perlen, nstp=nstp, tsmult=tsmult, top=10, botm=botm, steady=False) assert isinstance(dis, fmf.ModflowDis) lpf = fmf.ModflowLpf(ml, hk=hk, vka=10.0, laytyp=1) assert isinstance(lpf, fmf.ModflowLpf) pcg = fmf.ModflowPcg(ml) assert isinstance(pcg, fmf.ModflowPcg) oc = fmf.ModflowOc(ml) assert isinstance(oc, fmf.ModflowOc) ibound = np.ones((nrow, ncol)) ibound[:, 0] = -1 ibound[25:30, 30:39] = 0 bas = fmf.ModflowBas(ml, strt=5.0, ibound=ibound) assert isinstance(bas, fmf.ModflowBas) rch = fmf.ModflowRch(ml, rech={0: 0.00001, 5: 0.0001, 6: 0.0}) assert isinstance(rch, fmf.ModflowRch) wel_dict = {} wel_data = [[9, 25, 20, -200], [0, 0, 0, -400], [5, 20, 32, 500]] wel_dict[0] = wel_data wel_data2 = [[45, 20, 200], [9, 49, 39, 400], [5, 20, 32, 500]] wel_dict[10] = wel_data2 wel = fmf.ModflowWel(ml, stress_period_data={0: wel_data}) assert isinstance(wel, fmf.ModflowWel) ghb_dict = {0: [1, 10, 10, 400, 300]} ghb = fmf.ModflowGhb(ml, stress_period_data=ghb_dict) assert isinstance(ghb, fmf.ModflowGhb) test = os.path.join('temp', 'test3.shp') ml.export(test, kper=0) shp = shapefile.Reader(test) assert shp.numRecords == nrow * ncol
def bas(self): """ self.mf must be initialized and discretized to right shape """ active = self.df_mf['IBND'].values.reshape(self.nrows, self.ncols) ibound = np.zeros((self.nlays, self.nrows, self.ncols), dtype=np.int32) + active bas = flomf.ModflowBas(self.mf, ibound=ibound, strt=self.params.get('strt', 1), ichflg=True) return bas
def create_package(self, name, content): if name == 'mf': model_ws = os.path.realpath(os.path.join(self._data_folder, self._model_id, content['model_ws'])) if not os.path.exists(model_ws): os.makedirs(model_ws) self._mf = mf.Modflow( modelname=content['modelname'], exe_name=content['exe_name'], version=content['version'], model_ws=model_ws ) if name == 'dis': mf.ModflowDis( self._mf, nlay=content['nlay'], nrow=content['nrow'], ncol=content['ncol'], nper=content['nper'], delr=content['delr'], delc=content['delc'], laycbd=content['laycbd'], top=content['top'], botm=content['botm'], perlen=content['perlen'], nstp=content['nstp'], tsmult=content['tsmult'], steady=content['steady'], itmuni=content['itmuni'], lenuni=content['lenuni'], extension=content['extension'], unitnumber=content['unitnumber'], xul=content['xul'], yul=content['yul'], rotation=content['rotation'], proj4_str=content['proj4_str'], start_datetime=content['start_datetime'] ) if name == 'bas': mf.ModflowBas( self._mf, ibound=content['ibound'], strt=content['strt'], ifrefm=content['ifrefm'], ixsec=content['ixsec'], ichflg=content['ichflg'], stoper=content['stoper'], hnoflo=content['hnoflo'], extension=content['extension'], unitnumber=content['unitnumber'] ) if name == 'lpf': mf.ModflowLpf( self._mf, laytyp=content['laytyp'], layavg=content['layavg'], chani=content['chani'], layvka=content['layvka'], laywet=content['laywet'], ipakcb=content['ipakcb'], hdry=content['hdry'], iwdflg=content['iwdflg'], wetfct=content['wetfct'], iwetit=content['iwetit'], ihdwet=content['ihdwet'], hk=content['hk'], hani=content['hani'], vka=content['vka'], ss=content['ss'], sy=content['sy'], vkcb=content['vkcb'], wetdry=content['wetdry'], storagecoefficient=content['storagecoefficient'], constantcv=content['constantcv'], thickstrt=content['thickstrt'], nocvcorrection=content['nocvcorrection'], novfc=content['novfc'], extension=content['extension'], unitnumber=content['unitnumber'] ) if name == 'pcg': mf.ModflowPcg( self._mf, mxiter=content['mxiter'], iter1=content['iter1'], npcond=content['npcond'], hclose=content['hclose'], rclose=content['rclose'], relax=content['relax'], nbpol=content['nbpol'], iprpcg=content['iprpcg'], mutpcg=content['mutpcg'], damp=content['damp'], dampt=content['dampt'], ihcofadd=content['ihcofadd'], extension=content['extension'], unitnumber=content['unitnumber'] ) if name == 'oc': mf.ModflowOc( self._mf, ihedfm=content['ihedfm'], iddnfm=content['iddnfm'], chedfm=content['chedfm'], cddnfm=content['cddnfm'], cboufm=content['cboufm'], compact=content['compact'], stress_period_data=self.get_stress_period_data(content['stress_period_data']), extension=content['extension'], unitnumber=content['unitnumber'] ) if name == 'risdlkfjlv': mf.ModflowRiv( self._mf, ipakcb=content['ipakcb'], stress_period_data=content['stress_period_data'], dtype=content['dtype'], extension=content['extension'], unitnumber=content['unitnumber'], options=content['options'], naux=content['naux'] ) if name == 'wel': mf.ModflowWel( self._mf, ipakcb=content['ipakcb'], stress_period_data=content['stress_period_data'], dtype=content['dtype'], extension=content['extension'], unitnumber=content['unitnumber'], options=content['options'] ) if name == 'rch': mf.ModflowRch( self._mf, ipakcb=content['ipakcb'], nrchop=content['nrchop'], rech=content['rech'], extension=content['extension'], unitnumber=content['unitnumber'] ) if name == 'chd': mf.ModflowChd( self._mf, stress_period_data=content['stress_period_data'], dtype=content['dtype'], options=content['options'], extension=content['extension'], unitnumber=content['unitnumber'] ) if name == 'ghb': mf.ModflowGhb( self._mf, ipakcb=content['ipakcb'], stress_period_data=content['stress_period_data'], dtype=content['dtype'], options=content['options'], extension=content['extension'], unitnumber=content['unitnumber'] )
z1[0, 0, 22:30] = np.arange(-2.5, -40, -5) z1[0, 0, 30:] = -40 z = [] z.append(z0) z.append(z1) ssz = 0.2 isource = np.ones((nrow, ncol), 'int') isource[0, 0] = 2 # stratified model modelname = 'swiex2_strat' print('creating...', modelname) ml = mf.Modflow(modelname, version='mf2005', exe_name=mf_name, model_ws=dirs[0]) discret = mf.ModflowDis(ml, nlay=1, ncol=ncol, nrow=nrow, delr=delr, delc=1, top=0, botm=[-40.0], nper=nper, perlen=perlen, nstp=nstp) bas = mf.ModflowBas(ml, ibound=ibound, strt=0.05) bcf = mf.ModflowBcf(ml, laycon=0, tran=2 * 40) swi = mf.ModflowSwi2(ml, nsrf=nsurf, istrat=1, toeslope=0.2, tipslope=0.2, nu=[0, 0.0125, 0.025], zeta=z, ssz=ssz, isource=isource, nsolver=1) oc = mf.ModflowOc88(ml, save_head_every=1000) pcg = mf.ModflowPcg(ml) ml.write_input() # run stratified model if not skipRuns: m = ml.run_model(silent=False) # read stratified results zetafile = os.path.join(dirs[0], '{}.zta'.format(modelname)) zobj = fu.CellBudgetFile(zetafile) zkstpkper = zobj.get_kstpkper() zeta = zobj.get_data(kstpkper=zkstpkper[-1], text=' ZETASRF 1')[0] zeta2 = zobj.get_data(kstpkper=zkstpkper[-1], text=' ZETASRF 2')[0]
ocdict = {} for idx in range(49, 200, 50): key = (0, idx) ocdict[key] = ['save head', 'save budget'] key = (0, idx+1) ocdict[key] = [] # create flopy modflow object ml = mf.Modflow(modelname, version='mf2005', exe_name=exe_name) # create flopy modflow package objects discret = mf.ModflowDis(ml, nlay=nlay, nrow=nrow, ncol=ncol, delr=delr, delc=delc, top=0, botm=[-40.0], perlen=400, nstp=200) bas = mf.ModflowBas(ml, ibound=ibound, strt=0.0) lpf = mf.ModflowLpf(ml, hk=2., vka=2.0, vkcb=0, laytyp=0, layavg=0) wel = mf.ModflowWel(ml, stress_period_data={0:[(0, 0, 0, 1)]}) swi = mf.ModflowSwi2(ml, npln=1, istrat=1, toeslope=0.2, tipslope=0.2, nu=[0, 0.025], zeta=z, ssz=0.2, isource=isource, nsolver=1) oc = mf.ModflowOc(ml, stress_period_data=ocdict) pcg = mf.ModflowPcg(ml) # create model files ml.write_input() # run the model m = ml.run_model(silent=False) # read model heads headfile = '{}.hds'.format(modelname) hdobj = fu.HeadFile(headfile) head = hdobj.get_alldata() head = np.array(head)
def main(): ''' This is the main function. ''' # Package all the required file paths into the Paths object mfPaths = Paths() # Package all the required framework specifications into the mfFrame object mfFrame = Frame(Paths=mfPaths, dx_dy=dx_dy) if build_from_gis: # Build the model framework ASCII files from the GIS layers. Note that this # requires a GDAL installation. If you don't want to get into that you # can skip this step and simply build the model from the ASCII files that I've # already created. mfFrame.build_frame(Paths=mfPaths) # --------------------------------------------- # --------------------------------------------- # Now use Flopy to build the MODFLOW model packages # --------------------------------------------- # --------------------------------------------- start_dir = os.getcwd() os.chdir(mfPaths.modflow_dir ) # This is simplest if done inside the MODFLOW directory # Initialize a Flopy model object. This is the base class around which the model # packages are built. Modflow = mf.Modflow(mfFrame.model_name, external_path='./', version=mfPaths.mf_version) # The .oc ('output control') package specifies how the model output is written. # This model includes a single steady state stress period. Save the # distribution of heads as well as the flow budget/mass balance to binaries. # These can be plotted or converted to rasters (the current version of the script # doesn't do any post-processing.) oc = mf.ModflowOc(Modflow, stress_period_data={ (0, 0): ['SAVE HEAD', 'SAVE BUDGET'] }) # The .dis and .bas packages define the model framework. I've already defined # the framework attributes using the mfFrame object and simply pass those # attributes to the constructor. dis = mf.ModflowDis(Modflow,mfFrame.nlay,mfFrame.nrow,mfFrame.ncol,\ delr=mfFrame.delr,delc=mfFrame.delc,\ top=mfFrame.top,botm=mfFrame.bottom) bas = mf.ModflowBas(Modflow, ibound=mfFrame.ibound, strt=mfFrame.top, hnoflo=mfFrame.hnoflo) # The .upw package describes the system properties (e.g., transmissivity/conductivity). # For this model I simply give it a constant hydraulic conductivity field. This model # converges but I have no idea how physically realistic it is. If you would # like to make it more physically realistic (e.g., try to fit head or discharge # data) you would need to estimate the hydraulic conductivity field via # calibration/inverse modeling hk = np.ones(np.shape(mfFrame.ibound)) upw = mf.ModflowUpw(Modflow, laytyp=mfFrame.laytyp, hk=hk, ipakcb=53) # The .nwt package defines the solver specs. Just use the defaults. nwt = mf.ModflowNwt(Modflow) # RECHARGE INPUTS TO THE SYSTEM # ----------------------------- # The .rch packages specifies recharge/precipitation inputs to the water table. # Remember that I have already generated an array from the GIS layer and attached # it to the mfFrame object. rch = mf.ModflowRch(Modflow, nrchop=3, rech={0: mfFrame.rch}, ipakcb=53) # BASEFLOW DISCHARGE FROM THE SYSTEM # ---------------------------------- # The .drn package is one method of simulating the discharge of groundwater as # base-flow in streams in rivers. Define every landsurface cell as a drain # in order to allow the discharge network to emerge from topography. drn_stages = mfFrame.top drn_stages[mfFrame.ibound.squeeze() <= 0] = np.nan drn_input = build_drain_input(mfFrame=mfFrame, stages=drn_stages) drn = mf.ModflowDrn(Modflow, stress_period_data=drn_input, ipakcb=53) # Now write the files. Flopy can also run the model if you tell it where the # binary is, but if I understood your method correctly you will be invoking something # from hydroshare. For convenience I am writing a windows .bat file that # can be used to run the model. Modflow.write_input() os.chdir(start_dir) with open(mfPaths.mf_bat_file, 'w') as fout: fout.write('%s %s' % (binary_path, os.path.basename(mfPaths.nam_file))) folder = mfPaths.scratch_dir for the_file in os.listdir(folder): file_path = os.path.join(folder, the_file) try: if os.path.isfile(file_path): os.unlink(file_path) except Exception as e: print(e) folder = mfPaths.model_frame_dir for the_file in os.listdir(folder): file_path = os.path.join(folder, the_file) try: if os.path.isfile(file_path): os.unlink(file_path) except Exception as e: print(e) folder = mfPaths.data_dir for the_file in os.listdir(folder): file_path = os.path.join(folder, the_file) try: if os.path.isfile(file_path): os.unlink(file_path) except Exception as e: print(e) return
if OutsideAirBound == 1: grid_obj.temp[0, :, :] = grid_obj.SurfaceT[ period] # sets temperature at surface level according to time of year if well_obj_list: # Create well and temperature lists following Modflow/MT3DMS format. Each timestep, flows and infiltration temp are assigned to the wells for i in well_obj_list: i.Q = i.flow[period] if temp_assigned == True: i.T_inj = i.T_inj_assigned[period] well_LRCQ_list = create_LRCQ_list( well_obj_list, grid_obj) # Set the settings of the wells for that timestep ssm_data = create_conc_list(well_obj_list, attrib='T_inj') '''Initialize MODFLOW Packages''' bas = mf.ModflowBas(ml, ibound=grid_obj.IBOUND, strt=grid_obj.head) # Basemodel Modflow wel = mf.ModflowWel(ml, stress_period_data=well_LRCQ_list) # Put in Wells words = ['head', 'drawdown', 'budget', 'phead', 'pbudget'] save_head_every = 1 #oc = mf.ModflowOc(ml) # Output control package class --> moved (p3.7 iso p3.6) pcg = mf.ModflowPcg( ml, mxiter=200, iter1=200, npcond= 1, # Preconditioned Conjugate-Gradient Package --> solves the finite differences equations hclose=0.001, rclose=0.001, relax=1.0, nbpol=0) ml.write_input()
twords.append('pbudget') if savehead == True: twords.append('head') savewords.append(twords) solver2params = {'mxiter': 100, 'iter1': 20, 'npcond': 1, 'zclose': 1.0e-6, 'rclose': 3e-3, 'relax': 1.0, 'nbpol': 2, 'damp': 1.0, 'dampt': 1.0} # --create model file and run model modelname = 'swi2ex5' mf_name = 'mf2005' if not skipRuns: ml = mf.Modflow(modelname, version='mf2005', exe_name=mf_name, model_ws=dirs[0]) discret = mf.ModflowDis(ml, nrow=nrow, ncol=ncol, nlay=nlay, delr=delr, delc=delc, top=0, botm=bot, laycbd=0, nper=nper, perlen=perlen, nstp=nstp, steady=steady) bas = mf.ModflowBas(ml, ibound=ibound, strt=ihead) lpf = mf.ModflowLpf(ml, hk=kh, vka=kv, ss=ss, sy=ssz, vkcb=0, laytyp=0, layavg=1) wel = mf.ModflowWel(ml, stress_period_data=well_data) swi = mf.ModflowSwi2(ml, npln=1, istrat=1, toeslope=0.025, tipslope=0.025, nu=[0, 0.025], \ zeta=z, ssz=ssz, isource=isource, nsolver=2, solver2params=solver2params) oc = mf.ModflowOc(ml, words=savewords) pcg = mf.ModflowPcg(ml, hclose=1.0e-6, rclose=3.0e-3, mxiter=100, iter1=50) # --write the modflow files ml.write_input() m = ml.run_model(silent=False) # --read model zeta get_stp = [364, 729, 1094, 1459, 364, 729, 1094, 1459] get_per = [0, 0, 0, 0, 1, 1, 1, 1] nswi_times = len(get_per) zetafile = os.path.join(dirs[0], '{}.zta'.format(modelname))
#be used to quickly initialize the ibound array with #values of 1, and then set the ibound value for the #first and last columns to -1. The numpy package #(and Python, in general) uses zero-based indexing and #supports negative indexing so that row 1 and column #1, and row 1 and column 201, can be referenced as [0, #0], and [0, -1], respectively. Although this simulation #is for steady flow, starting heads still need to be #specified. They are used as the head for fixed-head #cells (where ibound is negative), and as a starting #point to compute the saturated thickness for cases of #unconfined flow. ibound = np.ones((1, 201)) ibound[0, 0] = ibound[0, -1] = -1 fpm.ModflowBas(model, ibound=ibound, strt=20) #The hydraulic properties of the aquifer are specified #with the layer properties flow (LPF) package (alternatively, #the block centered flow (BCF) package may be #used). Only the hydraulic conductivity of the aquifer #and the layer type (laytyp) need to be specified. The #latter is set to 1, which means that MODFLOW will #calculate the saturated thickness differently depending #on whether or not the head is above the top of the #aquifer. fpm.ModflowLpf(model, hk=10, laytyp=1) #4. Aquifer recharge is simulated with the Recharge #package (RCH) and the extraction of water at the two
iso[:, :30] = -2 #--model objects ml = mf.Modflow(modelname, version='mf2005', exe_name=exe_name) discret = mf.ModflowDis(ml, nrow=nrow, ncol=ncol, nlay=3, delr=delr, delc=delc, laycbd=[0, 0, 0], top=-9.0, botm=[-29, -30, -50], nper=2, perlen=[365 * 1000, 1000 * 365], nstp=[500, 500]) bas = mf.ModflowBas(ml, ibound=1, strt=1.0) bcf = mf.ModflowBcf(ml, laycon=[0, 0, 0], tran=[40.0, 1, 80.0], vcont=[0.005, 0.005]) wel = mf.ModflowWel(ml, stress_period_data={0: lrcQ1, 1: lrcQ2}) ghb = mf.ModflowGhb(ml, stress_period_data={0: lrchc}) swi = mf.ModflowSwi2(ml, nsrf=1, istrat=1, toeslope=0.01, tipslope=0.04, nu=[0, 0.025], zeta=[zini, zini, zini], ssz=0.2, isource=iso,
def run_experiment(self, experiment): ''' Method for running an instantiated model structure. This method should always be implemented. :param case: keyword arguments for running the model. The case is a dict with the names of the uncertainties as key, and the values to which to set these uncertainties. ''' #NetLogo agent attributes to be passed to Python well objects #when new wells are created in NetLogo nl_read_sys_attribs = ['who', 'xcor', 'ycor'] nl_read_well_attribs = [ 'who', 'xcor', 'ycor', 'IsCold', 'z0', 'FilterLength', 'T_inj', 'Q' ] #NetLogo agent attributes to be updated by the Python objects after each period nl_update_well_attribs = ['T_modflow', 'H_modflow'] nl_update_globals = ['ztop', 'Laquifer'] self.netlogo.command('setup') for key, value in experiment.items(): if key in self.NetLogo_uncertainties: try: self.netlogo.command(self.command_format.format( key, value)) except jpype.JavaException as e: warning('Variable {0} throws exception: {}'.format( (key, str(e)))) logging.debug(self.netlogo.report(str(key))) if key in self.SEAWAT_uncertainties: setattr(self, key, value) #Set policy parameters if present if self.policy: for key, value in self.policy.items(): if (key in self.NetLogo_uncertainties and key != 'name'): self.netlogo.command(self.command_format.format( key, value)) elif key in self.SEAWAT_uncertainties: setattr(self, key, value) logging.info('Policy parameters set successfully') #Update NetLogo globals from input parameters for var in nl_update_globals: self.netlogo.command( self.command_format.format(var, getattr(self, var))) #Run the NetLogo setup routine, creating the agents #Create lists of Python objects based on the NetLogo agents self.netlogo.command('init-agents') sys_obj_list = update_runtime_objectlist(self.netlogo, [], nl_read_sys_attribs, breed='system', objclass=PySystem) well_obj_list, newgrid_flag = update_runtime_objectlist( self.netlogo, [], nl_read_well_attribs, breed='well', objclass=PyWell) #Assign values for uncertain NetLogo parameters logging.info('NetLogo parameters set successfully') #self.netlogo.command('init-agents') #Calculate geohydrological parameters linked to variable inputs rho_b = self.rho_solid * (1 - self.PEFF) kT_b = self.kT_s * (1 - self.PEFF) + self.kT_f * self.PEFF dmcoef = kT_b / (self.PEFF * self.rho_f * self.Cp_f) * 24 * 3600 trpt = self.al * self.trp_mult trpv = trpt #Initialize PyGrid object itype = mt3.Mt3dSsm.itype_dict() grid_obj = PyGrid() grid_obj.make_grid(well_obj_list, dmin=self.dmin, dmax=self.dmax, dz=self.dz, ztop=self.ztop, zbot=self.zbot, nstep=self.nstep, grid_extents=self.grid_extents) #Initial arrays for grid values (temperature, head) - for this case, assumes no groundwater flow #and uniform temperature grid_obj.ncol = len(grid_obj.XGR) - 1 grid_obj.delr = np.diff(grid_obj.XGR) grid_obj.nrow = len(grid_obj.YGR) - 1 grid_obj.delc = -np.diff(grid_obj.YGR) grid_obj.top = self.ztop * np.ones([grid_obj.nrow, grid_obj.ncol]) botm_range = np.arange(self.zbot, self.ztop, self.dz)[::-1] botm_2d = np.ones([grid_obj.nrow, grid_obj.ncol]) grid_obj.botm = botm_2d * botm_range[:, None, None] grid_obj.nlay = len(botm_range) grid_obj.IBOUND, grid_obj.ICBUND = boundaries( grid_obj) #Create grid boundaries #Initial arrays for grid values (temperature, head) init_grid = np.ones((grid_obj.nlay, grid_obj.nrow, grid_obj.ncol)) grid_obj.temp = 10. * init_grid grid_obj.HK = self.HK * init_grid grid_obj.VK = self.VK * init_grid #Set initial heads according to groundwater flow (based on mfLab Utrecht model) y_array = np.array([(grid_obj.YGR[:-1] - np.mean(grid_obj.YGR[:-1])) * self.PEFF * -self.gwflow_y / 365 / self.HK]) y_tile = np.array([np.tile(y_array.T, (1, grid_obj.ncol))]) x_array = (grid_obj.XGR[:-1] - np.mean( grid_obj.XGR[:-1])) * self.PEFF * -self.gwflow_x / 365 / self.HK y_tile += x_array grid_obj.head = np.tile(y_tile, (grid_obj.nlay, 1, 1)) #Set times at which to read SEAWAT output for each simulation period timprs = np.array([self.perlen]) nprs = len(timprs) logging.info('SEAWAT parameters set successfully') #Iterate the coupled model for period in range(self.run_length): #Set up the text output from NetLogo commands = [] self.fns = {} for outcome in self.outcomes: #if outcome.time: name = outcome.name fn = r'{0}{3}{1}{2}'.format(self._working_directory, name, '.txt', os.sep) self.fns[name] = fn fn = '"{}"'.format(fn) fn = fn.replace(os.sep, '/') if self.netlogo.report('is-agentset? {}'.format(name)): #If name is name of an agentset, we #assume that we should count the total number of agents nc = r'{2} {0} {3} {4} {1}'.format(fn, name, 'file-open', 'file-write', 'count') else: #It is not an agentset, so assume that it is #a reporter / global variable nc = r'{2} {0} {3} {1}'.format(fn, name, 'file-open', 'file-write') commands.append(nc) c_out = ' '.join(commands) self.netlogo.command(c_out) logging.info(' -- Simulating period {0} of {1}'.format( period, self.run_length)) #Run the NetLogo model for one tick self.netlogo.command('go') logging.debug('NetLogo step completed') #Create placeholder well list - required for MODFLOW WEL package if no wells active in NetLogo well_LRCQ_list = {} well_LRCQ_list[0] = [[0, 0, 0, 0]] ssm_data = {} ssm_data[0] = [[0, 0, 0, 0, itype['WEL']]] #Check the well agents which are active in NetLogo, and update the Python objects if required #The newgrid_flag indicates whether or not the grid should be recalculated to account for changes #in the list of active wells if well_obj_list: well_obj_list, newgrid_flag = update_runtime_objectlist( self.netlogo, well_obj_list, nl_read_well_attribs) if well_obj_list and newgrid_flag: #If the list of active wells has changed and if there are active wells, create a new grid object newgrid_obj = PyGrid() newgrid_obj.make_grid(well_obj_list, dmin=self.dmin, dmax=self.dmax, dz=self.dz, ztop=self.ztop, zbot=self.zbot, nstep=self.nstep, grid_extents=self.grid_extents) #Interpolate the temperature and head arrays to match the new grid newgrid_obj.temp = grid_interpolate(grid_obj.temp[0, :, :], grid_obj, newgrid_obj) newgrid_obj.head = grid_interpolate(grid_obj.head[0, :, :], grid_obj, newgrid_obj) #Use the new simulation grid grid_obj = newgrid_obj logging.debug('Python update completed') if well_obj_list: for i in well_obj_list: #Read well flows from NetLogo and locate each well in the simulation grid i.Q = read_NetLogo_attrib(self.netlogo, 'Q', i.who) i.calc_LRC(grid_obj) #Create well and temperature lists following MODFLOW/MT3DMS format well_LRCQ_list = create_LRCQ_list(well_obj_list, grid_obj) ssm_data = create_conc_list(well_obj_list) #Initialize MODFLOW packages using FloPy #ml = mf.Modflow(self.name, version='mf2005', exe_name=self.swtexe_name, model_ws=self.dirs[0]) swtm = swt.Seawat(self.name, exe_name=self.swtexe_name, model_ws=self.dirs[0]) discret = mf.ModflowDis(swtm, nrow=grid_obj.nrow, ncol=grid_obj.ncol, nlay=grid_obj.nlay, delr=grid_obj.delr, delc=grid_obj.delc, laycbd=0, top=self.ztop, botm=self.zbot, nper=self.nper, perlen=self.perlen, nstp=self.nstp, steady=self.steady) bas = mf.ModflowBas(swtm, ibound=grid_obj.IBOUND, strt=grid_obj.head) lpf = mf.ModflowLpf(swtm, hk=self.HK, vka=self.VK, ss=0.0, sy=0.0, laytyp=0, layavg=0) wel = mf.ModflowWel(swtm, stress_period_data=well_LRCQ_list) words = ['head', 'drawdown', 'budget', 'phead', 'pbudget'] save_head_every = 1 oc = mf.ModflowOc(swtm) pcg = mf.ModflowPcg(swtm, mxiter=200, iter1=200, npcond=1, hclose=0.001, rclose=0.001, relax=1.0, nbpol=0) #ml.write_input() #Initialize MT3DMS packages #mt = mt3.Mt3dms(self.name, 'nam_mt3dms', modflowmodel=ml, model_ws=self.dirs[0]) adv = mt3.Mt3dAdv( swtm, mixelm=0, #-1 is TVD percel=1, nadvfd=1, #Particle based methods nplane=0, mxpart=250000, itrack=3, dceps=1e-4, npl=5, nph=8, npmin=1, npmax=16) btn = mt3.Mt3dBtn(swtm, cinact=-100., icbund=grid_obj.ICBUND, prsity=self.PEFF, sconc=[grid_obj.temp][0], ifmtcn=-1, chkmas=False, nprobs=0, nprmas=1, dt0=0.0, ttsmult=1.5, ttsmax=20000., ncomp=1, nprs=nprs, timprs=timprs, mxstrn=9999) dsp = mt3.Mt3dDsp(swtm, al=self.al, trpt=trpt, trpv=trpv, dmcoef=dmcoef) rct = mt3.Mt3dRct(swtm, isothm=0, ireact=0, igetsc=0, rhob=rho_b) gcg = mt3.Mt3dGcg(swtm, mxiter=50, iter1=50, isolve=1, cclose=1e-3, iprgcg=0) ssm = mt3.Mt3dSsm(swtm, stress_period_data=ssm_data) #mt.write_input() #Initialize SEAWAT packages # mswtf = swt.Seawat(self.name, 'nam_swt', modflowmodel=ml, mt3dmsmodel=mt, # model_ws=self.dirs[0]) swtm.write_input() #Run SEAWAT #m = mswtf.run_model(silent=True) m = swtm.run_model(silent=True) logging.debug('SEAWAT step completed') #Copy Modflow/MT3DMS output to new files shutil.copyfile( os.path.join(self.dirs[0], self.name + '.hds'), os.path.join(self.dirs[0], self.name + str(period) + '.hds')) shutil.copyfile( os.path.join(self.dirs[0], 'MT3D001.UCN'), os.path.join(self.dirs[0], self.name + str(period) + '.UCN')) #Create head file object and read head array for next simulation period h_obj = bf.HeadFile( os.path.join(self.dirs[0], self.name + str(period) + '.hds')) grid_obj.head = h_obj.get_data(totim=self.perlen) #Create concentration file object and read temperature array for next simulation period t_obj = bf.UcnFile( os.path.join(self.dirs[0], self.name + str(period) + '.UCN')) grid_obj.temp = t_obj.get_data(totim=self.perlen) logging.debug('Output processed') if well_obj_list: for i in well_obj_list: #Update each active Python well object with the temperature and head at its grid location i.T_modflow = grid_obj.temp[i.L[0], i.R, i.C] i.H_modflow = grid_obj.head[i.L[0], i.R, i.C] #Update the NetLogo agents from the corresponding Python objects write_NetLogo_attriblist(self.netlogo, well_obj_list, nl_update_well_attribs) #As an example of data exchange, we can calculate the fraction of the simulated grid in which #the temperature change is significant, and send this value to a NetLogo global variable use = subsurface_use(grid_obj, grid_obj.temp) write_NetLogo_global(self.netlogo, 'SubsurfaceUse', use) logging.debug('NetLogo update completed') h_obj.file.close() t_obj.file.close() self.netlogo.command('file-close-all') self._handle_outcomes()
def calculate_model(z1_hk, z2_hk, z3_hk): # Z1_hk = 15 # 3<Z1_hk<15 # Z2_hk = 15 # 3<Z2_hk<15 # Z3_hk = 3 # 3<Z3_hk<15 hobs = [ [0, 20, 10, 69.52], [0, 40, 10, 71.44], [0, 60, 10, 72.99], [0, 80, 10, 73.86], [0, 20, 45, 58.73], [0, 40, 45, 50.57], [0, 60, 45, 54.31], [0, 80, 45, 58.06], [0, 20, 80, 56.31], [0, 40, 80, 52.32], [0, 60, 80, 46.35], [0, 80, 80, 29.01], [0, 20, 100, 57.24], [0, 40, 100, 54.24], [0, 60, 100, 39.48], [0, 80, 100, 48.47], ] model_path = os.path.join('_model') if os.path.exists(model_path): shutil.rmtree(model_path) modelname = 'parEstMod' version = 'mf2005' exe_name = 'mf2005' if platform.system() == 'Windows': exe_name = 'mf2005.exe' ml = mf.Modflow(modelname=modelname, exe_name=exe_name, version=version, model_ws=model_path) nlay = 1 nrow = 90 ncol = 120 area_width_y = 9000 area_width_x = 12000 delc = area_width_x / ncol delr = area_width_y / nrow nper = 1 top = 100 botm = 0 dis = mf.ModflowDis(ml, nlay=nlay, nrow=nrow, ncol=ncol, delr=delr, delc=delc, top=top, botm=botm, nper=nper, steady=True) ibound = 1 strt = 100 bas = mf.ModflowBas(ml, ibound=ibound, strt=strt) mask_arr = np.zeros((nlay, nrow, ncol)) mask_arr[:, :, 0] = 80 mask_arr[:, :, -1] = 60 ghb_spd = {0: []} for layer_id in range(nlay): for row_id in range(nrow): for col_id in range(ncol): if mask_arr[layer_id][row_id][col_id] > 0: ghb_spd[0].append([ layer_id, row_id, col_id, mask_arr[layer_id][row_id][col_id], 200 ]) ghb = mf.ModflowGhb(ml, stress_period_data=ghb_spd) rch = 0.0002 rech = {} rech[0] = rch rch = mf.ModflowRch(ml, rech=rech, nrchop=3) welSp = {} welSp[0] = [ [0, 20, 20, -20000], [0, 40, 40, -20000], [0, 60, 60, -20000], [0, 80, 80, -20000], [0, 60, 100, -20000], ] wel = mf.ModflowWel(ml, stress_period_data=welSp) hk = np.zeros((nlay, nrow, ncol)) hk[:, :, 0:40] = z1_hk hk[:, :, 40:80] = z2_hk hk[:, :, 80:120] = z3_hk lpf = mf.ModflowLpf(ml, hk=hk, layavg=0, layvka=0, sy=0.3, ipakcb=53) pcg = mf.ModflowPcg(ml, rclose=1e-1) oc = mf.ModflowOc(ml) ml.write_input() ml.run_model(silent=True) hds = fu.HeadFile(os.path.join(model_path, modelname + '.hds')) times = hds.get_times() response = [] for hob in hobs: observed = hob[3] calculated = hds.get_data(totim=times[-1])[hob[0]][hob[1]][hob[2]] response.append(observed - calculated) return json.dumps(response)
mf = fm.Modflow(modelname, exe_name=exe_name) dis = fm.ModflowDis(mf, Nlay, Ny, Nx, delr=dx, delc=dy, top=zTop, botm=zBot, laycbd=LAYCBD, nper=NPER, perlen=PERLEN, nstp=NSTP, steady=STEADY) bas = fm.ModflowBas(mf, ibound=IBOUND, strt=STRTHD) lpf = fm.ModflowLpf(mf, hk=HK, vka=VKA, sy=SY, ss=SS, laytyp=LAYTYP, vkcb=VKCB) ghb = fm.ModflowGhb(mf, stress_period_data=GHB) wel = fm.ModflowWel(mf, stress_period_data=WEL) rch = fm.ModflowRch(mf, nrchop=3, rech=RECH) evt = fm.ModflowEvt(mf, nevtop=3, evtr=EVTR) oc = fm.ModflowOc(mf, stress_period_data=OC, compact=True) pcg = fm.ModflowPcg(mf) #%% Write the model input files and running MODFLOW mf.write_input() success, mfoutput = mf.run_model(silent=False, pause=False) print('Running success = {}'.format(success))
start = h1 * np.ones((N, N)) start[Nhalf, Nhalf] = h2 # create external ibound array and starting head files files = [] hfile = '{}_strt.ref'.format(name) np.savetxt(hfile, start) hfiles = [] for kdx in range(Nlay): file = '{}_ib{:02d}.ref'.format(name, kdx + 1) files.append(file) hfiles.append(hfile) np.savetxt(file, ibound[kdx, :, :], fmt='%5d') bas = mf.ModflowBas(ml, ibound=files, strt=hfiles) # The aquifer properties (really only the hydraulic conductivity) are defined with the # LPF package. lpf = mf.ModflowLpf(ml, hk=Kh) # Finally, we need to specify the solver we want to use (PCG with default values), and the # output control (using the default values). Then we are ready to write all MODFLOW input # files and run MODFLOW. pcg = mf.ModflowPcg(ml) oc = mf.ModflowOc(ml) ml.write_input() ml.run_model() # change back to the starting directory os.chdir(cwdpth)
def get_package(self, _mf): content = self.merge() return mf.ModflowBas(_mf, **content)
# [-1., 1., 1., ..., 1., 1., -1.], # [-1., -1., -1., ..., -1., -1., -1.]]]) # set center cell in upper layer to constant head (-1) ibound[0, Nhalf, Nhalf] = -1 # defining the start-values # in the calculation only the -1 cells will be considered # # all values are set to h1 start = h1 * np.ones((N, N)) # and the center value is set to h2 start[Nhalf, Nhalf] = h2 # instantiate the modflow-basic package with iBound and startvalues bas = mf.ModflowBas(ml, ibound=ibound, strt=start) # set the aquifer properties with the lpf-package lpf = mf.ModflowLpf(ml, hk=k) # instantiation of the solver with default values pcg = mf.ModflowPcg(ml) # instantiation of the output control with default values oc = mf.ModflowOc(ml) rch = mf.ModflowRch(ml) ml.write_input() ml.run_model()
# what version of modflow to use? modflow_v = 'mfnwt' # 'mfnwt' or 'mf2005' # where is your MODFLOW executable? if (modflow_v == 'mf2005'): if platform.system() == 'Windows': path2mf = 'C:/Users/Sam/Dropbox/Work/Models/MODFLOW/MF2005.1_12/bin/mf2005.exe' else: path2mf = modflow_v elif (modflow_v == 'mfnwt'): if platform.system() == 'Windows': path2mf = 'C:/Users/Sam/Dropbox/Work/Models/MODFLOW/MODFLOW-NWT_1.1.4/bin/MODFLOW-NWT.exe' else: path2mf = modflow_v # set up super simple model ml = mf.Modflow(modelname="testmodel", exe_name=path2mf, version=modflow_v) dis = mf.ModflowDis(ml) bas = mf.ModflowBas(ml) oc = mf.ModflowOc(ml) # choose solver package depending on modflow version if (modflow_v == 'mf2005'): lpf = mf.ModflowLpf(ml) pcg = mf.ModflowPcg(ml) elif (modflow_v == 'mfnwt'): upw = mf.ModflowUpw(ml) nwt = mf.ModflowNwt(ml) ml.write_input() ml.run_model()