Ejemplo n.º 1
0
    def accumulate_flow(self, update_flow_director=True):
        """
        Function to make FlowAccumulator calculate drainage area and discharge.

        Running run_one_step() results in the following to occur:
            1. Flow directions are updated (unless update_flow_director is set
            as False).
            2. Intermediate steps that analyse the drainage network topology
            and create datastructures for efficient drainage area and discharge
            calculations.
            3. Calculation of drainage area and discharge.
            4. Depression finding and mapping, which updates drainage area and
            discharge.
        """
        # step 1. Find flow directions by specified method
        if update_flow_director == True:
            self.flow_director.run_one_step()

        # further steps vary depending on how many recievers are present
        # one set of steps is for route to one (D8, Steepest/D4)
        if self.flow_director.to_n_receivers == 'one':

            # step 3. Run depression finder if passed
            # Depression finder reaccumulates flow at the end of its routine.
            if self.depression_finder_provided is not None:

                self.depression_finder.map_depressions()

                a = self._grid['node']['drainage_area']
                q = self._grid['node']['surface_water__discharge']

            else:
                # step 2. Get r
                r = self._grid['node']['flow__receiver_node']

                # step 2. Stack, D, delta construction
                nd = flow_accum_bw._make_number_of_donors_array(r)
                delta = flow_accum_bw._make_delta_array(nd)
                D = flow_accum_bw._make_array_of_donors(r, delta)
                s = flow_accum_bw.make_ordered_node_array(r)

                # put theese in grid so that depression finder can use it.
                # store the generated data in the grid
                self._grid['node']['flow__data_structure_delta'][:] = delta[1:]
                self._grid['link']['flow__data_structure_D'][:len(D)] = D
                self._grid['node']['flow__upstream_node_order'][:] = s

                # step 4. Accumulate (to one or to N depending on direction method. )
                a, q = flow_accum_bw.find_drainage_area_and_discharge(s,
                                                                      r,
                                                                      self.node_cell_area,
                                                                      self._grid.at_node['water__unit_flux_in'])
                self._grid['node']['drainage_area'][:] = a
                self._grid['node']['surface_water__discharge'][:] = q

        else:
            # step 2. Get r and p
            r = self._grid['node']['flow__receiver_nodes']
            p = self._grid['node']['flow__receiver_proportions']

            # step 2. Stack, D, delta construction
            nd = flow_accum_to_n._make_number_of_donors_array_to_n(r, p)
            delta = flow_accum_to_n._make_delta_array_to_n(nd)
            D = flow_accum_to_n._make_array_of_donors_to_n(r, p, delta)
            s = flow_accum_to_n.make_ordered_node_array_to_n(r, p)

            # put theese in grid so that depression finder can use it.
            # store the generated data in the grid
            self._grid['node']['flow__data_structure_delta'][:] = delta[1:]

            if self._is_raster:
                tempD = BAD_INDEX_VALUE * np.ones((self._grid.number_of_links*2))
                tempD[:len(D)] = D
                self._grid['link']['flow__data_structure_D'][:] = tempD.reshape((self._grid.number_of_links, 2))
            else:
                self._grid['link']['flow__data_structure_D'][:len(D)] = D
            self._grid['node']['flow__upstream_node_order'][:] = s

            # step 3. Run depression finder if passed
            # at present this must go at the end.

            # step 4. Accumulate (to one or to N depending on direction method. )
            a, q = flow_accum_to_n.find_drainage_area_and_discharge_to_n(s,
                                                                         r,
                                                                         p,
                                                                         self.node_cell_area,
                                                                         self._grid.at_node['water__unit_flux_in'])
            # store drainage area and discharge.
            self._grid['node']['drainage_area'][:] = a
            self._grid['node']['surface_water__discharge'][:] = q

            # at the moment, this is where the depression finder needs to live.
            if self.depression_finder_provided is not None:
                self.depression_finder.map_depressions()

        return (a, q)
Ejemplo n.º 2
0
    def accumulate_flow(self, update_flow_director=True):
        """
        Function to make FlowAccumulator calculate drainage area and discharge.

        Running run_one_step() results in the following to occur:
            1. Flow directions are updated (unless update_flow_director is set
            as False).
            2. Intermediate steps that analyse the drainage network topology
            and create datastructures for efficient drainage area and discharge
            calculations.
            3. Calculation of drainage area and discharge.
            4. Depression finding and mapping, which updates drainage area and
            discharge.
        """
        # set a couple of aliases
        a = self._grid["node"]["drainage_area"]
        q = self._grid["node"]["surface_water__discharge"]

        # step 1. Find flow directions by specified method
        if update_flow_director:
            self.flow_director.run_one_step()

        # further steps vary depending on how many recievers are present
        # one set of steps is for route to one (D8, Steepest/D4)

        # step 2. Get r
        r = self._grid["node"]["flow__receiver_node"]

        if self.flow_director.to_n_receivers == "one":

            # step 2b. Run depression finder if passed
            # Depression finder reaccumulates flow at the end of its routine.
            # At the moment, no depression finders work with to-many, so it
            # lives here
            if self.depression_finder_provided is not None:
                self.depression_finder.map_depressions()

            # step 3. Stack, D, delta construction
            nd = flow_accum_bw._make_number_of_donors_array(r)
            delta = flow_accum_bw._make_delta_array(nd)
            D = flow_accum_bw._make_array_of_donors(r, delta)
            s = flow_accum_bw.make_ordered_node_array(r)

            # put these in grid so that depression finder can use it.
            # store the generated data in the grid
            self._grid["node"]["flow__data_structure_delta"][:] = delta[1:]
            self._grid["link"]["flow__data_structure_D"][:len(D)] = D
            self._grid["node"]["flow__upstream_node_order"][:] = s

            # step 4. Accumulate (to one or to N depending on direction method)
            a[:], q[:] = self._accumulate_A_Q_to_one(s, r)

        else:
            # Get p
            p = self._grid["node"]["flow__receiver_proportions"]

            # step 3. Stack, D, delta construction
            nd = flow_accum_to_n._make_number_of_donors_array_to_n(r, p)
            delta = flow_accum_to_n._make_delta_array_to_n(nd)
            D = flow_accum_to_n._make_array_of_donors_to_n(r, p, delta)
            s = flow_accum_to_n.make_ordered_node_array_to_n(r, p)

            # put theese in grid so that depression finder can use it.
            # store the generated data in the grid
            self._grid["node"]["flow__data_structure_delta"][:] = delta[1:]

            if self._is_raster:
                tempD = BAD_INDEX_VALUE * np.ones(
                    (self._grid.number_of_links * 2))
                tempD[:len(D)] = D
                self._grid["link"][
                    "flow__data_structure_D"][:] = tempD.reshape(
                        (self._grid.number_of_links, 2))
            else:
                self._grid["link"]["flow__data_structure_D"][:len(D)] = D
            self._grid["node"]["flow__upstream_node_order"][:] = s

            # step 4. Accumulate (to one or to N depending on direction method)
            a[:], q[:] = self._accumulate_A_Q_to_n(s, r, p)

        return (a, q)
Ejemplo n.º 3
0
    def accumulate_flow(self, update_flow_director=True):
        """
        Function to make FlowAccumulator calculate drainage area and discharge.

        Running run_one_step() results in the following to occur:
            1. Flow directions are updated (unless update_flow_director is set
            as False).
            2. Intermediate steps that analyse the drainage network topology
            and create datastructures for efficient drainage area and discharge
            calculations.
            3. Calculation of drainage area and discharge.
            4. Depression finding and mapping, which updates drainage area and
            discharge.
        """
        # step 1. Find flow directions by specified method
        if update_flow_director == True:
            self.flow_director.run_one_step()

        # further steps vary depending on how many recievers are present
        # one set of steps is for route to one (D8, Steepest/D4)
        if self.flow_director.to_n_receivers == 'one':

            # step 2. Get r
            r = self._grid['node']['flow__receiver_node']

            # step 2. Stack, D, delta construction
            nd = flow_accum_bw._make_number_of_donors_array(r)
            delta = flow_accum_bw._make_delta_array(nd)
            D = flow_accum_bw._make_array_of_donors(r, delta)
            s = flow_accum_bw.make_ordered_node_array(r)

            # put theese in grid so that depression finder can use it.
            # store the generated data in the grid
            self._grid['node']['flow__data_structure_delta'][:] = delta[1:]
            self._grid['link']['flow__data_structure_D'][:len(D)] = D
            self._grid['node']['flow__upstream_node_order'][:] = s

            # step 3. Run depression finder if passed
            # at present this must go at the end.

            # step 4. Accumulate (to one or to N depending on direction method. )
            a, q = flow_accum_bw.find_drainage_area_and_discharge(
                s, r, self.node_cell_area,
                self._grid.at_node['water__unit_flux_in'])

        else:
            # step 2. Get r and p
            r = self._grid['node']['flow__receiver_nodes']
            p = self._grid['node']['flow__receiver_proportions']

            # step 2. Stack, D, delta construction
            nd = flow_accum_to_n._make_number_of_donors_array_to_n(r, p)
            delta = flow_accum_to_n._make_delta_array_to_n(nd)
            D = flow_accum_to_n._make_array_of_donors_to_n(r, p, delta)
            s = flow_accum_to_n.make_ordered_node_array_to_n(r, p)

            # put theese in grid so that depression finder can use it.
            # store the generated data in the grid
            self._grid['node']['flow__data_structure_delta'][:] = delta[1:]

            if self._is_raster:
                tempD = BAD_INDEX_VALUE * np.ones(
                    (self._grid.number_of_links * 2))
                tempD[:len(D)] = D
                self._grid['link'][
                    'flow__data_structure_D'][:] = tempD.reshape(
                        (self._grid.number_of_links, 2))
            else:
                self._grid['link']['flow__data_structure_D'][:len(D)] = D
            self._grid['node']['flow__upstream_node_order'][:] = s

            # step 3. Run depression finder if passed
            # at present this must go at the end.

            # step 4. Accumulate (to one or to N depending on direction method. )
            a, q = flow_accum_to_n.find_drainage_area_and_discharge_to_n(
                s, r, p, self.node_cell_area,
                self._grid.at_node['water__unit_flux_in'])
        # store drainage area and discharge.
        self._grid['node']['drainage_area'][:] = a
        self._grid['node']['surface_water__discharge'][:] = q

        # at the moment, this is where the depression finder needs to live.
        if self.depression_finder_provided is not None:
            self.depression_finder.map_depressions()

        return (a, q)
Ejemplo n.º 4
0
    def accumulate_flow(self, update_flow_director=True):
        """Function to make FlowAccumulator calculate drainage area and
        discharge.

        Running run_one_step() results in the following to occur:
            1. Flow directions are updated (unless update_flow_director is set
            as False).
            2. Intermediate steps that analyse the drainage network topology
            and create datastructures for efficient drainage area and discharge
            calculations.
            3. Calculation of drainage area and discharge.
            4. Depression finding and mapping, which updates drainage area and
            discharge.
        """
        # set a couple of aliases
        a = self._grid["node"]["drainage_area"]
        q = self._grid["node"]["surface_water__discharge"]

        # step 1. Find flow directions by specified method
        if update_flow_director:
            self.flow_director.run_one_step()

        # further steps vary depending on how many recievers are present
        # one set of steps is for route to one (D8, Steepest/D4)

        # step 2. Get r
        r = as_id_array(self._grid["node"]["flow__receiver_node"])

        if self.flow_director.to_n_receivers == "one":

            # step 2b. Run depression finder if passed
            # Depression finder reaccumulates flow at the end of its routine.
            # At the moment, no depression finders work with to-many, so it
            # lives here
            if self.depression_finder_provided is not None:
                self.depression_finder.map_depressions()

                # if FlowDirectorSteepest is used, update the link directions
                if self.flow_director._name == "FlowDirectorSteepest":
                    self.flow_director._determine_link_directions()

            # step 3. Stack, D, delta construction
            nd = as_id_array(flow_accum_bw._make_number_of_donors_array(r))
            delta = as_id_array(flow_accum_bw._make_delta_array(nd))
            D = as_id_array(flow_accum_bw._make_array_of_donors(r, delta))
            s = as_id_array(flow_accum_bw.make_ordered_node_array(r))

            # put these in grid so that depression finder can use it.
            # store the generated data in the grid
            self._grid["node"]["flow__data_structure_delta"][:] = delta[1:]
            self._grid["grid"]["flow__data_structure_D"] = np.array([D], dtype=object)
            self._grid["node"]["flow__upstream_node_order"][:] = s

            # step 4. Accumulate (to one or to N depending on direction method)
            a[:], q[:] = self._accumulate_A_Q_to_one(s, r)

        else:
            # Get p
            p = self._grid["node"]["flow__receiver_proportions"]

            # step 3. Stack, D, delta construction
            nd = as_id_array(flow_accum_to_n._make_number_of_donors_array_to_n(r, p))
            delta = as_id_array(flow_accum_to_n._make_delta_array_to_n(nd))
            D = as_id_array(flow_accum_to_n._make_array_of_donors_to_n(r, p, delta))
            s = as_id_array(flow_accum_to_n.make_ordered_node_array_to_n(r, p))

            # put theese in grid so that depression finder can use it.
            # store the generated data in the grid
            self._grid["node"]["flow__data_structure_delta"][:] = delta[1:]
            self._grid["grid"]["flow__data_structure_D"][0] = np.array(
                [D], dtype=object
            )
            self._grid["node"]["flow__upstream_node_order"][:] = s
            self._grid["node"]["flow__upstream_node_order"][:] = s

            # step 4. Accumulate (to one or to N depending on direction method)
            a[:], q[:] = self._accumulate_A_Q_to_n(s, r, p)

        return (a, q)
Ejemplo n.º 5
0
    def accumulate_flow(self,
                        update_flow_director=True,
                        update_depression_finder=True):
        """Function to make FlowAccumulator calculate drainage area and
        discharge.

        Running accumulate_flow() results in the following to occur:

            1. Flow directions are updated (unless update_flow_director is set
               as False). This incluldes checking for updated boundary
               conditions.
            2. The depression finder, if present is updated (unless
               update_depression_finder is set as False).
            3. Intermediate steps that analyse the drainage network topology
               and create datastructures for efficient drainage area and
               discharge calculations.
            4. Calculation of drainage area and discharge.
            5. Return of drainage area and discharge.

        Parameters
        ----------
        update_flow_director : optional, bool
            Whether to update the flow director. Default is True.
        update_depression_finder : optional, bool
            Whether to update the depression finder, if present.
            Default is True.

        Returns
        -------
        drainage_area : array
            At node array which points to the field
            grid.at_node["drainage_area"].
        surface_water__discharge
            At node array which points to the field
            grid.at_node["surface_water__discharge"].
        """
        # set a couple of aliases
        a = self._grid["node"]["drainage_area"]
        q = self._grid["node"]["surface_water__discharge"]

        # step 1. Find flow directions by specified method
        if update_flow_director:
            self._flow_director.run_one_step()

        # further steps vary depending on how many recievers are present
        # one set of steps is for route to one (D8, Steepest/D4)

        # step 2. Get r
        r = as_id_array(self._grid["node"]["flow__receiver_node"])

        if self._flow_director._to_n_receivers == "one":

            # step 2b. Run depression finder if passed
            # Depression finder reaccumulates flow at the end of its routine.
            # At the moment, no depression finders work with to-many, so it
            # lives here
            if self._depression_finder_provided is not None:
                if update_depression_finder:
                    self._depression_finder.map_depressions()

                    # if FlowDirectorSteepest is used, update the link directions
                    if self._flow_director._name == "FlowDirectorSteepest":
                        self._flow_director._determine_link_directions()

            # step 3. Stack, D, delta construction
            nd = as_id_array(flow_accum_bw._make_number_of_donors_array(r))
            delta = as_id_array(flow_accum_bw._make_delta_array(nd))
            D = as_id_array(flow_accum_bw._make_array_of_donors(r, delta))
            s = as_id_array(flow_accum_bw.make_ordered_node_array(r))

            # put these in grid so that depression finder can use it.
            # store the generated data in the grid
            self._grid.at_node["flow__data_structure_delta"][:] = delta[1:]
            self._D_structure = D
            self._grid.at_node["flow__upstream_node_order"][:] = s

            # step 4. Accumulate (to one or to N depending on direction method)
            a[:], q[:] = self._accumulate_A_Q_to_one(s, r)

        else:
            # Get p
            p = self._grid["node"]["flow__receiver_proportions"]

            # step 3. Stack, D, delta construction
            nd = as_id_array(
                flow_accum_to_n._make_number_of_donors_array_to_n(r, p))
            delta = as_id_array(flow_accum_to_n._make_delta_array_to_n(nd))
            D = as_id_array(
                flow_accum_to_n._make_array_of_donors_to_n(r, p, delta))
            s = as_id_array(flow_accum_to_n.make_ordered_node_array_to_n(r, p))

            # put theese in grid so that depression finder can use it.
            # store the generated data in the grid
            self._grid["node"]["flow__data_structure_delta"][:] = delta[1:]
            self._D_structure = D

            self._grid["node"]["flow__upstream_node_order"][:] = s
            self._grid["node"]["flow__upstream_node_order"][:] = s

            # step 4. Accumulate (to one or to N depending on direction method)
            a[:], q[:] = self._accumulate_A_Q_to_n(s, r, p)

        return (a, q)