Exemple #1
0
                        delr=swt_delr, delc=swt_delc, laycbd=0, top=swt_top, botm=swt_botm,
                        nper=nper, perlen=perlen, nstp=1, steady=False)
bas = mf.ModflowBas(ml, ibound=swt_ibound, strt=0.05)
lpf = mf.ModflowLpf(ml, hk=2.0, vka=2.0, ss=0.0, sy=0.0, laytyp=0, layavg=0)
oc = mf.ModflowOc88(ml, save_head_every=1, item2=[[0, 1, 0, 0]])
pcg = mf.ModflowPcg(ml)
ml.write_input()
# Create the basic MT3DMS model structure
mt = mt3.Mt3dms(modelname, 'nam_mt3dms', modflowmodel=ml, 
                model_ws=dirs[1])  # Coupled to modflow model 'mf'
adv = mt3.Mt3dAdv(mt, mixelm=-1,  #-1 is TVD
                  percel=0.05,
                  nadvfd=0,  #0 or 1 is upstream; 2 is central in space
                  #particle based methods
                  nplane=4,
                  mxpart=1e7,
                  itrack=2,
                  dceps=1e-4,
                  npl=16,
                  nph=16,
                  npmin=8,
                  npmax=256)
btn = mt3.Mt3dBtn(mt, icbund=1, prsity=ssz, sconc=sconc, ifmtcn=-1,
                  chkmas=False, nprobs=10, nprmas=10, dt0=0.0, ttsmult=1.2, ttsmax=100.0,
                  ncomp=1, nprs=nprs, timprs=timprs, mxstrn=1e8)
dsp = mt3.Mt3dDsp(mt, al=0., trpt=1., trpv=1., dmcoef=0.)
gcg = mt3.Mt3dGcg(mt, mxiter=1, iter1=50, isolve=3, cclose=1e-6, iprgcg=5)
ssm = mt3.Mt3dSsm(mt, stress_period_data=ssm_data)
mt.write_input()
# Create the SEAWAT model structure
mswtf = swt.Seawat(modelname, 'nam_swt', modflowmodel=ml, mt3dmodel=mt,
                   exe_name=swtexe_name, model_ws=dirs[1])  # Coupled to modflow model mf and mt3dms model mt
Exemple #2
0
     rclose=0.001,
     relax=1.0,
     nbpol=0)
 ml.write_input()
 '''Initialize MT3DMS packages'''
 mt = mt3.Mt3dms(name,
                 'nam_mt3dms',
                 exe_name=swtexe_name,
                 modflowmodel=ml,
                 model_ws=dirs[0])
 adv = mt3.Mt3dAdv(
     mt,
     mixelm=0,
     percel=0.8,
     nadvfd=1,  #Particle based methods
     nplane=0,
     mxpart=250000,
     dceps=1e-4,
     npl=5,
     nph=8,
     npmin=1,
     npmax=16)
 btn = mt3.Mt3dBtn(
     mt,
     cinact=-100.,
     icbund=grid_obj.ICBUND,
     prsity=grid_obj.PEFF,
     sconc=grid_obj.temp,  #sconc2=grid_obj.salinity,
     ifmtcn=-1,
     chkmas=False,
     nprobs=0,
     nprmas=1,
Exemple #3
0
 def get_package(self, _mt):
     content = self.merge()
     return mt.Mt3dAdv(
         _mt,
         **content
     )
    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()