示例#1
0
    def run(self):
        """Perform a full simulation
        including infiltration, surface flow etc.,
        recording of data and mass_balance calculation
        """
        # dict of next time-step (datetime object)
        self.next_ts = {
            'end': self.end_time,
            'rec': self.start_time + self.record_step
        }
        for k in ['hyd', 'surf', 'drain']:
            self.next_ts[k] = self.start_time

        # First time-step is forced
        self.nextstep = self.sim_time + self.dt
        self.surf_sim.dt = self.dt
        self.rast_domain.update_input_arrays(self.sim_time)
        self.surf_sim.solve_q()
        # case if no drainage simulation
        if not self.drainage:
            self.next_ts['drain'] = self.end_time
            self.rast_domain.isnew['n_drain'] = False
        else:
            self.drainage.set_linkable()
            self.rast_domain.isnew['n_drain'] = True
            self.drainage.solve_dt()
        # record initial state

        self.report.step(self.sim_time)
        self.rast_domain.reset_stats(self.sim_time)
        sim_start_time = datetime.now()

        msgr.verbose(u"Starting time-stepping...")
        while self.sim_time < self.end_time:
            # display advance of simulation
            msgr.percent(self.start_time, self.end_time, self.sim_time,
                         sim_start_time)

            # recalculate the flow direction if DEM changed
            if self.rast_domain.isnew['z']:
                self.surf_sim.update_flow_dir()
            # step models
            self.step()
            # update simulation time
            self.sim_time += self.dt
            # update input arrays
            self.rast_domain.update_input_arrays(self.sim_time)
        # write final report
        self.report.end(self.sim_time)
        return self
示例#2
0
 def run(self):
     """Perform a full simulation
     including infiltration, surface flow etc.,
     recording of data and mass_balance calculation
     """
     sim_start_time = datetime.now()
     msgr.verbose(u"Starting time-stepping...")
     while self.sim_time < self.end_time:
         # display advance of simulation
         msgr.percent(self.start_time, self.end_time, self.sim_time,
                      sim_start_time)
         # step models
         self.step()
     return self
示例#3
0
    def update_input_arrays(self, sim_time):
        """Get new array using TimedArray
        First update the DEM and mask if needed
        Replace the NULL values (mask)
        """
        # make sure DEM is treated first
        if not self.tarr['z'].is_valid(sim_time):
            self.arr['z'][:] = self.tarr['z'].get(sim_time)
            self.isnew['z'] = True
            # note: must run update_flow_dir() in SuperficialSimulation
            self.update_mask(self.arr['z'])
            self.mask_array(self.arr['z'], np.finfo(self.dtype).max)
        else:
            self.isnew['z'] = False
        # loop through the arrays
        for k, ta in self.tarr.iteritems():
            if not ta.is_valid(sim_time):
                # z is done before
                if k == 'z':
                    continue
                # calculate statistics before updating array
                if k in ['in_q', 'rain']:
                    self.populate_stat_array(k, sim_time)

                # update array
                msgr.verbose(u"{}: update input array <{}>".format(
                    sim_time, k))
                self.arr[k][:] = ta.get(sim_time)
                self.isnew[k] = True

                if k == 'n':
                    fill_value = 1
                else:
                    fill_value = 0
                # mask arrays

                self.mask_array(self.arr[k], fill_value)
            else:
                self.isnew[k] = False

        # calculate water volume at the beginning of the simulation
        if self.isnew['h']:
            self.start_volume = self.asum('h')
        return self
示例#4
0
    def initialize(self):
        """Set-up the simulation.
        """
        # instantiate simulation objects
        gis_kwargs = dict(start_time=self.start_time,
                          end_time=self.end_time,
                          dtype=self.dtype,
                          mkeys=self.in_map_names.keys(),
                          region_id=self.region_id,
                          raster_mask_id=self.raster_mask_id)
        self.igis = gis.Igis(**gis_kwargs)
        msgr.verbose(u"Setting up models...")
        self.__set_models(self.igis)
        msgr.verbose(u"Models set up")
        msgr.verbose(u"Reading maps information from GIS...")
        self.igis.read(self.in_map_names)

        # dict of next time-step (datetime object)
        self.next_ts = {
            'end': self.end_time,
            'rec': self.start_time + self.record_step
        }
        for k in ['hyd', 'surf', 'drain']:
            self.next_ts[k] = self.start_time
        # case if no drainage simulation
        if not self.drainage:
            self.next_ts['drain'] = self.end_time
        # First time-step is forced
        self.nextstep = self.sim_time + self.dt
        # record initial state
        self.rast_domain.update_input_arrays(self.sim_time)
        self.report.step(self.sim_time)
        self.rast_domain.reset_stats(self.sim_time)
        return self
示例#5
0
    def __init__(self,
                 sim_times,
                 input_maps,
                 output_maps,
                 sim_param,
                 drainage_params,
                 dtype=np.float32,
                 dtmin=timedelta(seconds=0.01),
                 stats_file=None):

        # read time parameters
        self.start_time = sim_times.start
        self.end_time = sim_times.end
        self.duration = sim_times.duration
        self.record_step = sim_times.record_step
        self.temporal_type = sim_times.temporal_type

        # set simulation time to start_time
        self.sim_time = self.start_time
        # First time-step is forced
        self.dt = dtmin  # Global time-step
        self.dtinf = sim_param['dtinf']

        # dictionaries of map names
        self.in_map_names = input_maps
        self.out_map_names = output_maps

        # data type of arrays
        self.dtype = dtype
        # simulation parameters
        self.sim_param = sim_param
        self.inf_model = self.sim_param['inf_model']

        # drainage parameters
        self.drainage_params = drainage_params

        # statistic file name
        self.stats_file = stats_file

        # instantiate a Igis object
        self.gis = gis.Igis(start_time=self.start_time,
                            end_time=self.end_time,
                            dtype=self.dtype,
                            mkeys=self.in_map_names.keys())
        msgr.verbose(u"Reading maps information from GIS...")
        self.gis.read(self.in_map_names)

        # instantiate simulation objects
        msgr.verbose(u"Setting up models...")
        self.__set_models()
        msgr.verbose(u"Models set up")
示例#6
0
    def step(self):
        """Step each of the models if needed
        """

        # HYDROLOGY MODEL - compute rainfall rates, losses rates, infiltration rates#
        #------------------------------------------------------------------------------
        if self.sim_time == self.next_ts['hyd']:
            self.hydrology.solve_dt()
            # calculate when will happen the next time-step
            self.next_ts['hyd'] += self.hydrology.dt
            self.hydrology.step()
            # update stat array
            self.rast_domain.populate_stat_array('inf', self.sim_time)
            self.rast_domain.populate_stat_array('capped_losses',
                                                 self.sim_time)

        #SWMM MODEL - Apply linkage flow to SWMM Model and STEP SWMM Model
        #------------------------------------------------------------------------------
        if self.sim_time == self.next_ts['drain'] and self.drainage:

            self.drainage.apply_drainage_flow()
            self.drainage.step()
            self.drainage.solve_dt()
            self.next_ts['drain'] += self.drainage.dt  #compute next 1D time

        # SURFACE FLOW SIM
        #------------------------------------------------------------------------------
        #calculate fluxes at cell interfaces
        self.surf_sim.solve_q()

        # calculate drainage flows and apply it to 2D Model at each 2D timestep
        if self.drainage:
            self.drainage.drainage_flow(
                self.dt.total_seconds())  #compute drainage flow
            self.rast_domain.update_ext_array()
            self.rast_domain.populate_stat_array('n_drain', self.sim_time)
        else:
            self.rast_domain.update_ext_array()

        self.surf_sim.apply_boundary_conditions()
        try:
            self.surf_sim.update_h()
            # in case of NaN/NULL cells, raisea NullError
            self.surf_sim.arr_err = np.isnan(self.rast_domain.get('h'))
            if np.any(self.surf_sim.arr_err):
                raise NullError
        except NullError:
            self.report.write_error_to_gis(self.surf_sim.arr_err)
            msgr.fatal(u"{}: Null value detected in simulation, "
                       u"terminating".format(self.sim_time))
        self.surf_sim.swap_flow_arrays()
        # calculate when should happen the next surface time-step
        self.surf_sim.solve_dt()
        # increment time when should happen next timestep
        if self.drainage:
            self.next_ts['surf'] += min(
                self.surf_sim.dt, self.drainage.dt2d
            )  #self.drainage.dt2d is the courant condition based on maximum node head.
        else:
            self.next_ts['surf'] += self.surf_sim.dt

        #REPORTING
        #------------------------------------------------------------------------------
        # send current time-step duration to mass balance object
        if self.massbal:
            self.massbal.add_value('tstep', self.dt.total_seconds())

        # Reporting #
        if self.sim_time == self.next_ts['rec']:
            msgr.verbose(u"{}: Writing output maps...".format(self.sim_time))
            self.report.step(self.sim_time)
            self.next_ts['rec'] += self.record_step
            # reset statistic maps
            self.rast_domain.reset_stats(self.sim_time)

        #GLOBAL STEP CALCULATION
        #------------------------------------------------------------------------------
        # find next step
        self.nextstep = min(self.next_ts.values())
        # force the surface time-step to the lowest time-step
        self.next_ts['surf'] = self.nextstep
        self.dt = self.nextstep - self.sim_time
        # force time-step to be the general time-step
        self.surf_sim.dt = self.dt
        return self
    def step(self):
        """Step each of the models if needed
        """

        # hydrology #
        if self.sim_time == self.next_ts['hyd']:
            self.hydrology.solve_dt()
            # calculate when will happen the next time-step
            self.next_ts['hyd'] += self.hydrology.dt
            self.hydrology.step()
            # update stat array
            self.rast_domain.populate_stat_array('inf', self.sim_time)
            self.rast_domain.populate_stat_array('capped_losses',
                                                 self.sim_time)

        # drainage #
        if self.sim_time == self.next_ts['drain'] and self.drainage:
            self.drainage.solve_dt()
            # calculate when will happen the next time-step
            self.next_ts['drain'] += self.drainage.dt
            self.drainage.step()
            self.drainage.apply_linkage(self.dt.total_seconds())
            self.rast_domain.isnew['n_drain'] = True
            # update stat array
            self.rast_domain.populate_stat_array('n_drain', self.sim_time)
        else:
            self.rast_domain.isnew['n_drain'] = False

        # surface flow #
        # update arrays of infiltration, rainfall etc.
        self.rast_domain.update_ext_array()
        # force time-step to be the general time-step
        self.surf_sim.dt = self.dt
        # surf_sim.step() raise NullError in case of NaN/NULL cell
        # if this happen, stop simulation and
        # output a map showing the errors
        try:
            self.surf_sim.step()
        except NullError:
            self.report.write_error_to_gis(self.surf_sim.arr_err)
            msgr.fatal(u"{}: Null value detected in simulation, "
                       u"terminating".format(self.sim_time))
        # calculate when should happen the next surface time-step
        self.surf_sim.solve_dt()
        self.next_ts['surf'] += self.surf_sim.dt

        # send current time-step duration to mass balance object
        if self.massbal:
            self.massbal.add_value('tstep', self.dt.total_seconds())

        # Reporting #
        if self.sim_time >= self.next_ts['rec']:
            msgr.verbose(u"{}: Writing output maps...".format(self.sim_time))
            self.report.step(self.sim_time)
            self.next_ts['rec'] += self.record_step
            # reset statistic maps
            self.rast_domain.reset_stats(self.sim_time)

        # find next step
        self.nextstep = min(self.next_ts.values())
        # force the surface time-step to the lowest time-step
        self.next_ts['surf'] = self.nextstep
        self.dt = self.nextstep - self.sim_time
        return self
示例#8
0
 def display_sim_param(self):
     """Display simulation parameters if verbose
     """
     inter_txt = u"#" * 50
     txt_template = u"{:<24s} {}"
     msgr.verbose(u"{}".format(inter_txt))
     msgr.verbose(u"Input maps:")
     for k, v in self.input_map_names.items():
         msgr.verbose(txt_template.format(k, v))
     msgr.verbose(u"{}".format(inter_txt))
     msgr.verbose(u"Output maps:")
     for k, v in self.output_map_names.items():
         msgr.verbose(txt_template.format(k, v))
     msgr.verbose(u"{}".format(inter_txt))
     msgr.verbose(u"Simulation parameters:")
     for k, v in self.sim_param.items():
         msgr.verbose(txt_template.format(k, v))
     # simulation times
     msgr.verbose(u"{}".format(inter_txt))
     msgr.verbose(u"Simulation times:")
     txt_start_time = self.sim_times.start.isoformat(" ").split(".")[0]
     txt_end_time = self.sim_times.end.isoformat(" ").split(".")[0]
     msgr.verbose(txt_template.format('start', txt_start_time))
     msgr.verbose(txt_template.format('end', txt_end_time))
     msgr.verbose(txt_template.format('duration', self.sim_times.duration))
     msgr.verbose(
         txt_template.format('record_step', self.sim_times.record_step))
     msgr.verbose(u"{}".format(inter_txt))