示例#1
0
def test_get_watershed_masks_with_area_threshold():
    rmg = RasterModelGrid((7, 7), 200)

    z = np.array([
        -9999., -9999., -9999., -9999., -9999., -9999., -9999., -9999., 26.,
        0., 26., 30., 34., -9999., -9999., 28., 1., 28., 5., 32., -9999.,
        -9999., 30., 3., 30., 10., 34., -9999., -9999., 32., 11., 32., 15.,
        38., -9999., -9999., 34., 32., 34., 36., 40., -9999., -9999., -9999.,
        -9999., -9999., -9999., -9999., -9999.
    ])

    rmg.at_node['topographic__elevation'] = z

    rmg.set_closed_boundaries_at_grid_edges(True, True, True, False)

    # Route flow.
    fr = FlowRouter(rmg)
    fr.run_one_step()

    # Get the masks of watersheds greater than or equal to 80,000
    # square-meters.
    critical_area = 80000
    mask = get_watershed_masks_with_area_threshold(rmg, critical_area)

    # Assert that mask null nodes have a drainage area below critical area.
    null_nodes = np.where(mask == -1)[0]
    A = rmg.at_node['drainage_area'][null_nodes]
    below_critical_area_nodes = A < critical_area
    trues = np.ones(len(A), dtype=bool)

    np.testing.assert_equal(below_critical_area_nodes, trues)
    def __init__(self, input_file=None, params=None):
        """Initialize the StochasticDischargeHortonianModel."""

        # Call ErosionModel's init
        super(StochasticDischargeHortonianModel,
              self).__init__(input_file=input_file, params=params)

        # Instantiate components
        self.flow_router = FlowRouter(self.grid, **self.params)

        self.lake_filler = DepressionFinderAndRouter(self.grid, **self.params)

        self.rain_generator = \
            PrecipitationDistribution(delta_t=self.params['dt'],
                                      total_time=self.params['run_duration'],
                                      **self.params)

        # Add a field for discharge
        if 'surface_water__discharge' not in self.grid.at_node:
            self.grid.add_zeros('node', 'surface_water__discharge')
        self.discharge = self.grid.at_node['surface_water__discharge']                                    

        # Get the infiltration-capacity parameter
        self.infilt = self.params['infiltration_capacity']

        # Run flow routing and lake filler (only once, because we are not
        # not changing topography)
        self.flow_router.run_one_step()
        self.lake_filler.map_depressions()
def test_track_source():
    """Unit tests for track_source().
    """
    grid = RasterModelGrid((5, 5), spacing=(1., 1.))
    grid.at_node['topographic__elevation'] = np.array([5., 5., 5., 5., 5.,
                                                       5., 4., 5., 1., 5.,
                                                       0., 3., 5., 3., 0.,
                                                       5., 4., 5., 2., 5.,
                                                       5., 5., 5., 5., 5.])
    grid.status_at_node[10] = 0
    grid.status_at_node[14] = 0
    fr = FlowRouter(grid)
    fr.route_flow()
    r = grid.at_node['flow__receiver_node']
    assert_equal(r[6], 10)
    assert_equal(r[7], 8)
    assert_equal(r[18], 14)
    hsd_ids = np.empty(grid.number_of_nodes, dtype=int)
    hsd_ids[:] = 1
    hsd_ids[2:5] = 0
    hsd_ids[7:10] = 0
    (hsd_upstr, flow_accum) = track_source(grid, hsd_ids)
    assert_equal(hsd_upstr[8], [1, 0, 0])
    assert_equal(hsd_upstr[14], [1, 1, 1, 1, 0, 0, 1])
    assert_equal(flow_accum[14], 7)
示例#4
0
    def __init__(self, modern_dem_name, outlet_id, chi_mask_dem_name=None, from_file=None):
        """Initialize MetricCalculator with names of postglacial and modern
        DEMs."""


        if from_file is None:

            # Read and remember the modern DEM (whether data or model)
            (self.grid, self.z) = self.read_topography(modern_dem_name)
            #print self.grid.x_of_node
    
            self.grid.set_watershed_boundary_condition_outlet_id(outlet_id,
                                                                 self.z, nodata_value=-9999)
    
            # Instantiate and run a FlowRouter and lake filler, so we get
            # drainage area for cumulative-area statistic, and also fields for chi.
            fr = FlowRouter(self.grid)
            dfr = DepressionFinderAndRouter(self.grid)
            fr.route_flow()
            dfr.map_depressions()
    
            # Remember modern drainage area grid
            self.area = self.grid.at_node['drainage_area']
    
            # Instantiate a ChiFinder for chi-index
            self.chi_finder = ChiFinder(self.grid, min_drainage_area=10000.,
                                        reference_concavity=0.5)
            
            core_nodes = np.zeros(self.area.shape, dtype=bool)
            core_nodes[self.grid.core_nodes] = True
            # Read and remember the MASK, if provided
            if chi_mask_dem_name is None:
                 self.mask = (self.area>1e5)
                 self.till_mask = np.zeros(self.mask.shape, dtype=bool) 
                 self.till_mask[self.grid.core_nodes] = 1
            else:
                (self.mask_grid, zmask) = self.read_topography(chi_mask_dem_name)
                mask = (zmask>0)*1
                self.mask = (self.area>1e5)*(mask==1)
                
                mask_bool = (zmask>0)
                self.till_mask = np.zeros(self.mask.shape, dtype=bool) 
                self.till_mask[mask_bool*core_nodes] = 1
            # 
            
            # Create dictionary to contain metrics
            self.metric = {}
        
        else:
            with open(from_file, 'r') as f:
                metrics = load(f)
                self.modern_dem_name = metrics.pop('Topo file')

                self.metric = metrics
    
            fn_split = from_file.split('.')
            fn_split[-1] = 'chi'
            fn_split.append('txt')
            chi_filename = '.'.join(fn_split)
            self.density_chi = np.loadtxt(chi_filename)
示例#5
0
def test_get_watershed_nodes():
    grid = RasterModelGrid((7, 7), 1)

    z = np.array([
        -9999., -9999., -9999., -9999., -9999., -9999., -9999., -9999., 26.,
        0., 30., 32., 34., -9999., -9999., 28., 1., 25., 28., 32., -9999.,
        -9999., 30., 3., 3., 11., 34., -9999., -9999., 32., 11., 25., 18., 38.,
        -9999., -9999., 34., 32., 34., 36., 40., -9999., -9999., -9999.,
        -9999., -9999., -9999., -9999., -9999.
    ])

    grid.at_node['topographic__elevation'] = z

    outlet_id = 2

    grid.set_watershed_boundary_condition_outlet_id(outlet_id,
                                                    z,
                                                    nodata_value=-9999.)

    fr = FlowRouter(grid)
    fr.run_one_step()

    ws_nodes = get_watershed_nodes(grid, outlet_id)

    # Given the watershed boundary conditions, the number of watershed nodes
    # should be equal to the number of core nodes plus 1 for the outlet node.
    np.testing.assert_equal(len(ws_nodes), grid.number_of_core_nodes + 1)
    def __init__(self, input_file=None, params=None):
        """Initialize the LinearDiffusionModel."""

        # Call ErosionModel's init
        super(DrainageAreaModel, self).__init__(input_file=input_file,
                                                params=params)

        # Instantiate a FlowRouter and DepressionFinderAndRouter components
        self.flow_router = FlowRouter(self.grid, **self.params)
        self.lake_filler = DepressionFinderAndRouter(self.grid, **self.params)
示例#7
0
def plot_and_calc_concavities_final_run(directory='.'):
    """
    Plots S-A for final topo saved in folder "directory".

    Returns (k_s, concavity) for lin regression on log log trend.

    Concavity is defined as positive.
    """
    mg2 = deepcopy(mg)
    z2 = mg2.add_zeros('node', 'topographic__elevation', noclobber=False)
    fr2 = FlowRouter(mg2)
    # search for topo saves, to establish the num files, codes etc:
    prefixed_z = [
        filename for filename in os.listdir(directory)
        if filename.startswith('topographic__elevation')
    ]
    # grab the unique ID, so we can differentiate plots (if desired)
    unique_ID = prefixed_z[0][-14:-4]
    # work on first save to establish num digits
    _format = 0
    while True:
        char = prefixed_z[-1][-16 - _format]
        try:
            num = int(char)
        except ValueError:  # was a str
            break
        else:
            _format += 1

    # load the final topo:
    z2[:] = np.loadtxt(directory + '/' + prefixed_z[-1])
    # create a new flow map:
    fr2.run_one_step()
    profile_IDs = channel_nodes(mg2,
                                mg2.at_node['topographic__steepest_slope'],
                                mg2.at_node['drainage_area'],
                                mg2.at_node['flow__receiver_node'])
    ch_dists = get_distances_upstream(
        mg2, len(mg2.at_node['topographic__steepest_slope']), profile_IDs,
        mg2.at_node['flow__link_to_receiver_node'])
    slopes = mg2.at_node['topographic__steepest_slope'][profile_IDs[0]]
    areas = mg2.at_node['drainage_area'][profile_IDs[0]]
    logslopes = np.log(slopes)
    logareas = np.log(areas)
    goodvals = np.logical_and(np.isfinite(logslopes), np.isfinite(logareas))
    concavity, log_k_s, _, _, _ = linregress(logareas[goodvals],
                                             logslopes[goodvals])
    k_s = np.exp(log_k_s)

    loglog(areas, slopes, 'x')
    loglog(areas, k_s * areas**concavity, '-')
    xlabel('Drainage area (m**2)')
    ylabel('Slope (m/m)')

    return k_s, -concavity
示例#8
0
    def __init__(self, input_file=None, params=None):
        """Initialize the StreamPowerThresholdModel."""

        # Call ErosionModel's init
        super(StreamPowerThresholdModel, self).__init__(input_file=input_file,
                                                        params=params)

        # Instantiate a FlowRouter and DepressionFinderAndRouter components
        self.flow_router = FlowRouter(self.grid, **self.params)
        self.lake_filler = DepressionFinderAndRouter(self.grid, **self.params)

        # Instantiate a FastscapeEroder component
        self.eroder = StreamPowerSmoothThresholdEroder(
            self.grid,
            K_sp=self.params['K_sp'],
            threshold_sp=self.params['threshold_sp'])
示例#9
0
    def __init__(self, input_file=None, params=None):
        """Initialize the LinearDiffusionModel."""

        # Call ErosionModel's init
        super(EffectiveDrainageAreaModel, self).__init__(input_file=input_file,
                                                         params=params)

        # Instantiate a FlowRouter and DepressionFinderAndRouter components
        self.flow_router = FlowRouter(self.grid, **self.params)
        self.lake_filler = DepressionFinderAndRouter(self.grid, **self.params)

        # Add a field for effective drainage area
        self.eff_area = self.grid.add_zeros('node', 'effective_drainage_area')

        # Get the effective-area parameter
        self.sat_param = self.params['saturation_area_scale']
def test_find_unique_upstream_hsd_ids_and_fractions():
    """Unit tests find_unique_upstream_hsd_ids_and_fractions().
    """
    grid = RasterModelGrid((5, 5), spacing=(1., 1.))
    grid.at_node['topographic__elevation'] = np.array([
        5., 5., 5., 5., 5., 5., 4., 5., 1., 5., 0., 3., 5., 3., 0., 5., 4., 5.,
        2., 5., 5., 5., 5., 5., 5.
    ])
    grid.status_at_node[10] = 0
    grid.status_at_node[14] = 0
    fr = FlowRouter(grid)
    fr.route_flow()
    hsd_ids = np.empty(grid.number_of_nodes, dtype=int)
    hsd_ids[:] = 1
    hsd_ids[2:5] = 0
    hsd_ids[7:10] = 0
    (hsd_upstr, flow_accum) = track_source(grid, hsd_ids)
    (uniq_ids, coeff) = find_unique_upstream_hsd_ids_and_fractions(hsd_upstr)
    np.testing.assert_almost_equal(np.sort(np.array(coeff[8])),
                                   np.array([0.33333333, 0.66666667]))
class DrainageAreaModel(_ErosionModel):
    """
    A DrainageAreaModel simply computes drainage area on a raster-grid DEM.
    """
    def __init__(self, input_file=None, params=None):
        """Initialize the LinearDiffusionModel."""

        # Call ErosionModel's init
        super(DrainageAreaModel, self).__init__(input_file=input_file,
                                                params=params)

        # Instantiate a FlowRouter and DepressionFinderAndRouter components
        self.flow_router = FlowRouter(self.grid, **self.params)
        self.lake_filler = DepressionFinderAndRouter(self.grid, **self.params)

    def run_one_step(self, dt):
        """
        Advance model for one time-step of duration dt.
        """
        self.flow_router.run_one_step()

        # for debug
        from landlab.io import write_esri_ascii
        import numpy

        write_esri_ascii('test_dr_area_before_temp.txt',
                         self.grid,
                         names='drainage_area',
                         clobber=True)
        loga = self.grid.add_zeros('node', 'loga')
        loga[:] = numpy.log10(self.grid.at_node['drainage_area'] + 1)
        write_esri_ascii('test_logdr_area_before_temp.txt',
                         self.grid,
                         names='loga',
                         clobber=True)
        write_esri_ascii('test_sink_flag_before_temp.txt',
                         self.grid,
                         names='flow__sink_flag',
                         clobber=True)

        self.lake_filler.map_depressions()
    def __init__(self, input_file=None, params=None):
        """Initialize the HybridAlluviumModel."""

        # Call ErosionModel's init
        super(HybridAlluviumModel, self).__init__(input_file=input_file,
                                                  params=params)

        # Instantiate a FlowRouter and DepressionFinderAndRouter components
        self.flow_router = FlowRouter(self.grid, **self.params)
        self.lake_filler = DepressionFinderAndRouter(self.grid, **self.params)

        #make area_field and/or discharge_field depending on discharge_method
        if self.params['discharge_method'] is not None:
            if self.params['discharge_method'] == 'area_field':
                area_field = self.grid.at_node['drainage_area']
                discharge_field = None
            elif self.params['discharge_method'] == 'discharge_field':
                discharge_field = self.grid.at_node['surface_water__discharge']
                area_field = None
            else:
                raise (KeyError)
        else:
            area_field = None
            discharge_field = None

        # Instantiate a HybridAlluvium component
        self.eroder = Space(self.grid,
                            K_sed=self.params['K_sed'],
                            K_br=self.params['K_br'],
                            F_f=self.params['F_f'],
                            phi=self.params['phi'],
                            H_star=self.params['H_star'],
                            v_s=self.params['v_s'],
                            m_sp=self.params['m_sp'],
                            n_sp=self.params['n_sp'],
                            sp_crit_sed=self.params['sp_crit_sed'],
                            sp_crit_br=self.params['sp_crit_br'],
                            method=self.params['method'],
                            discharge_method=self.params['discharge_method'],
                            area_field=area_field,
                            discharge_field=discharge_field)
def test_find_unique_upstream_hsd_ids_and_fractions():
    """Unit tests find_unique_upstream_hsd_ids_and_fractions().
    """
    grid = RasterModelGrid((5, 5), spacing=(1., 1.))
    grid.at_node['topographic__elevation'] = np.array([5., 5., 5., 5., 5.,
                                                       5., 4., 5., 1., 5.,
                                                       0., 3., 5., 3., 0.,
                                                       5., 4., 5., 2., 5.,
                                                       5., 5., 5., 5., 5.])
    grid.status_at_node[10] = 0
    grid.status_at_node[14] = 0
    fr = FlowRouter(grid)
    fr.route_flow()
    hsd_ids = np.empty(grid.number_of_nodes, dtype=int)
    hsd_ids[:] = 1
    hsd_ids[2:5] = 0
    hsd_ids[7:10] = 0
    (hsd_upstr, flow_accum) = track_source(grid, hsd_ids)
    (uniq_ids, coeff) = find_unique_upstream_hsd_ids_and_fractions(hsd_upstr)
    np.testing.assert_almost_equal(
        np.sort(np.array(coeff[8])), np.array([0.33333333, 0.66666667]))
示例#14
0
class EffectiveDrainageAreaModel(_ErosionModel):
    """
    A DrainageAreaModel simply computes drainage area on a raster-grid DEM.
    """
    def __init__(self, input_file=None, params=None):
        """Initialize the LinearDiffusionModel."""

        # Call ErosionModel's init
        super(EffectiveDrainageAreaModel, self).__init__(input_file=input_file,
                                                         params=params)

        # Instantiate a FlowRouter and DepressionFinderAndRouter components
        self.flow_router = FlowRouter(self.grid, **self.params)
        self.lake_filler = DepressionFinderAndRouter(self.grid, **self.params)

        # Add a field for effective drainage area
        self.eff_area = self.grid.add_zeros('node', 'effective_drainage_area')

        # Get the effective-area parameter
        self.sat_param = self.params['saturation_area_scale']

    def run_one_step(self, dt):
        """
        Advance model for one time-step of duration dt.
        """

        # Run flow routing and lake filler
        self.flow_router.run_one_step()
        self.lake_filler.map_depressions()

        # Calculate effective area
        area = self.grid.at_node['drainage_area']
        slope = self.grid.at_node['topographic__steepest_slope']
        cores = self.grid.core_nodes
        self.eff_area[cores] = (
            area[cores] * np.exp(-self.sat_param * slope[cores] / area[cores]))

        # Lower outlet
        self.z[self.outlet_node] -= self.outlet_lowering_rate * dt
        print(('lowering outlet to ', self.z[self.outlet_node]))
示例#15
0
def test_get_watershed_outlet():
    grid = RasterModelGrid((7, 7), 1)

    z = np.array([
        -9999., -9999., -9999., -9999., -9999., -9999., -9999., -9999., 26.,
        0., 30., 32., 34., -9999., -9999., 28., 1., 25., 28., 32., -9999.,
        -9999., 30., 3., 3., 11., 34., -9999., -9999., 32., 11., 25., 18., 38.,
        -9999., -9999., 34., 32., 34., 36., 40., -9999., -9999., -9999.,
        -9999., -9999., -9999., -9999., -9999.
    ])

    grid.at_node['topographic__elevation'] = z

    imposed_outlet = 2

    grid.set_watershed_boundary_condition_outlet_id(imposed_outlet,
                                                    z,
                                                    nodata_value=-9999.)

    fr = FlowRouter(grid)
    fr.run_one_step()

    test_node = 32

    determined_outlet = get_watershed_outlet(grid, test_node)
    np.testing.assert_equal(determined_outlet, imposed_outlet)

    # Create a pit.
    pit_node = 38
    grid.at_node['topographic__elevation'][pit_node] -= 32
    fr.run_one_step()

    pit_outlet = get_watershed_outlet(grid, test_node)
    np.testing.assert_equal(pit_outlet, pit_node)
示例#16
0
    def __init__(self, input_file=None, params=None):
        """Initialize the StreamPowerVarThresholdModel."""

        # Call ErosionModel's init
        super(StreamPowerVarThresholdModel, self).__init__(input_file=input_file,
                                                params=params)

        # Instantiate a FlowRouter and DepressionFinderAndRouter components
        self.flow_router = FlowRouter(self.grid, **self.params)
        self.lake_filler = DepressionFinderAndRouter(self.grid, **self.params)
        
        # Create a field for the (initial) erosion threshold
        self.threshold = self.grid.add_zeros('node', 'erosion__threshold')
        self.threshold[:] = self.params['threshold_sp']
        
        # Instantiate a FastscapeEroder component
        self.eroder = StreamPowerSmoothThresholdEroder(
            self.grid,
            K_sp=self.params['K_sp'],
            threshold_sp=self.threshold)

        # Get the parameter for rate of threshold increase with erosion depth
        self.thresh_change_per_depth = self.params['thresh_change_per_depth']
示例#17
0
class StreamPowerThresholdModel(_ErosionModel):
    """
    A StreamPowerThresholdModel computes erosion using a form of the unit
    stream power model that represents a threshold using an exponential term.
    """
    def __init__(self, input_file=None, params=None):
        """Initialize the StreamPowerThresholdModel."""

        # Call ErosionModel's init
        super(StreamPowerThresholdModel, self).__init__(input_file=input_file,
                                                        params=params)

        # Instantiate a FlowRouter and DepressionFinderAndRouter components
        self.flow_router = FlowRouter(self.grid, **self.params)
        self.lake_filler = DepressionFinderAndRouter(self.grid, **self.params)

        # Instantiate a FastscapeEroder component
        self.eroder = StreamPowerSmoothThresholdEroder(
            self.grid,
            K_sp=self.params['K_sp'],
            threshold_sp=self.params['threshold_sp'])

    def run_one_step(self, dt):
        """
        Advance model for one time-step of duration dt.
        """

        # Route flow
        self.flow_router.run_one_step()
        self.lake_filler.map_depressions()

        # Get IDs of flooded nodes, if any
        flooded = np.where(self.lake_filler.flood_status == 3)[0]

        # Do some erosion (but not on the flooded nodes)
        self.eroder.run_one_step(dt, flooded_nodes=flooded)
def test_track_source():
    """Unit tests for track_source().
    """
    grid = RasterModelGrid((5, 5), spacing=(1., 1.))
    grid.at_node['topographic__elevation'] = np.array([
        5., 5., 5., 5., 5., 5., 4., 5., 1., 5., 0., 3., 5., 3., 0., 5., 4., 5.,
        2., 5., 5., 5., 5., 5., 5.
    ])
    grid.status_at_node[10] = 0
    grid.status_at_node[14] = 0
    fr = FlowRouter(grid)
    fr.route_flow()
    r = grid.at_node['flow__receiver_node']
    assert r[6] == 10
    assert r[7] == 8
    assert r[18] == 14
    hsd_ids = np.empty(grid.number_of_nodes, dtype=int)
    hsd_ids[:] = 1
    hsd_ids[2:5] = 0
    hsd_ids[7:10] = 0
    (hsd_upstr, flow_accum) = track_source(grid, hsd_ids)
    assert hsd_upstr[8] == [1, 0, 0]
    assert hsd_upstr[14] == [1, 1, 1, 1, 0, 0, 1]
    assert flow_accum[14] == 7
gridlist = []

# add initial noise to produce convergent flow from the initial conditions
np.random.seed(91) # so our figures are reproducible
mg_noise = np.random.rand(mg.number_of_nodes)/1000.

# set up the input fields
zr = mg.add_zeros('node', 'topographic__elevation')
zr += mg_noise

# Landlab sets fixed elevation boundary conditions by default. This is
# what we want, so we will not modify these here.

# instantiate the components:
frr = FlowRouter(mg) # water__unit_flux_in gets automatically ingested
spr = StreamPowerEroder(mg, K_sp=K_sp, m_sp=m_sp, n_sp=n_sp, threshold_sp=0,
                        use_Q=None)
lake = DepressionFinderAndRouter(mg)
    
# Hillslopes
dfn = LinearDiffuser(mg, linear_diffusivity=K_hs)

zr_last = -9999
keep_running = np.mean(np.abs(zr - zr_last)) >= end_thresh
ti = 0
while keep_running:
    zr_last = zr.copy()
    zr[mg.core_nodes] += uplift_rate*dt
    dfn.run_one_step(dt) # hillslopes always diffusive, even when dry
    frr.run_one_step()
示例#20
0
# make velocity profile and because the grid is discretized into pixels, we need to count how much
# deformation has occurred over a timestep and move a pixel after the
# accumulated deformation is larger than than the pixel length
v_profile = profile * vmax
accum_disp = profile * float(dxy)

# This is an array for counting how many pixels need to be moved
nshift = np.zeros(np.size(yLocation))
n_buff = 0  # optional extra buffer zone incase you only want to move a subset.

################################################################################
## Last, we instantiate landlab components that will evolve the landscape #####
################################################################################

fr = FlowRouter(rmg)  # standard D8 flow routing algorithm
sp = FastscapeEroder(rmg, K_sp='K_sp', m_sp=m, n_sp=n,
                     threshold_sp=0)  # river eroder
lin_diffuse = LinearDiffuser(rmg, linear_diffusivity='D')  #linear diffuser
fill = DepressionFinderAndRouter(rmg)  #lake filling algorithm

nts = int(num_frames)
ds = xr.Dataset(
    data_vars={
        'topographic__elevation': (
            ('time', 'y', 'x'),  # tuple of dimensions
            np.empty((nts, rmg.shape[0], rmg.shape[1])),  # n-d array of data
            {
                'units': 'meters'
            })
    },  # dictionary with data attributes
示例#21
0
         2] = ice_topo_f[0:lat.shape[0] - 1, :]  # top centre
extend_t[0:lat.shape[0] - 1, lon.shape[0] * 2:lon.shape[0] *
         3] = ice_topo_f[0:lat.shape[0] - 1, :]  # Top right
extend_t[lat.shape[0] - 1:lat.shape[0] * 2 - 2,
         0:lon.shape[0] * 3] = np.fliplr(
             np.flipud(extend_t[0:lat.shape[0] - 1,
                                0:lon.shape[0] * 3]))  # pad bottom

# Create raster grid for flow calculation and add data
fg = RasterModelGrid((extend_t.shape[0], extend_t.shape[1]), spacing=(1, 1))
_ = fg.add_field('node', 'topographic__elevation', extend_t)

fg.set_closed_boundaries_at_grid_edges(False, False, False, False)

# Calculate flow fields
fr = FlowRouter(fg)
fg = fr.route_flow()

# Preview the flow field with this plotting func.
# drainage_plot(fg, title='Grid 2 using FlowDirectorD8')

# Fill in Lakes/depressions
fg.at_node['flow__sink_flag'][
    fg.core_nodes].sum()  # how many depressions do we have?
hf = SinkFiller(fg, apply_slope=True)
hf.run_one_step()
fr.run_one_step()
# drainage_plot(fg, title='Grid 2 using FlowDirectorD8')
# Output is a single vector
flow_rec = fg.at_node['flow__receiver_node']
modeled_time = []
storm_events = []

a = 1

if a == 1:
    m = 0.3
    n = 0.7
    k_tau = 8.357150818380437e-15

tc0 = (k_tau * (0.)**a)
tc1 = (k_tau * (10.)**a)
tc5 = (k_tau * (25.)**a)
tc10 = (k_tau * (50.)**a)

fr = FlowRouter(rmg, method='D4')
fr1 = FlowRouter(rmg1, method='D4')
fr5 = FlowRouter(rmg5, method='D4')
fr10 = FlowRouter(rmg10, method='D4')
dle = StreamPowerEroder(rmg,
                        K_sp=(1e-10),
                        threshold_sp=float(tc0),
                        use_Q='water__discharge',
                        m_sp=m,
                        n_sp=n)  #(3.4e-11)
dle1 = StreamPowerEroder(rmg1,
                         K_sp=(1e-10),
                         threshold_sp=float(tc1),
                         use_Q='water__discharge',
                         m_sp=m,
                         n_sp=n)  #(3.4e-11)
g = 9.81 #m/s2
drag_cube = 0.8 #Carling
channel_width = 10 #m
threshold_drainage_area = 500 #unclear on what these units are
mg.add_zeros('node','water_depth')
mg.add_zeros('node','water_velocity')
mg.add_zeros('node','corrected_shear_stress')
mg.add_zeros('node', 'erodibility')
mg.add_zeros('node', 'incision_rate')
mg.add_zeros('node', 'num_blocks') #hopefully will contain array of sizes at a given node, one entry for each block
mg.add_zeros('node', 'f_covered')
mg['node']['erodibility'][:] = k
spatial_step = mg.empty(centering='node')

#instantiate components
fr = Flow(mg, input_file)
lf = LakeFill(mg, input_file)
sp = Fsc(mg, input_file)
hd = Diff(mg, input_file)

tracking_mat = np.zeros((100000, 4), dtype=np.float64) #colums: 0) which node, 1) side length 2) vol 3) sub/emergence
tracking_mat[:, :] = np.nan 
for_slicing = 0 #in case no blocks ever get put in

side_length = 4 #m, block side length
tau_c_br = 10 #Pa, for now
a1 = 6.5
a2 = 2.5
d = 0.1 #z0
tol = 0.01 #m water thickness error allowable
## Import what is needed
from landlab import RasterModelGrid
from landlab.components import LinearDiffuser, FlowRouter
from landlab.components import FastscapeEroder
from landlab.plot import imshow_grid
from matplotlib import pyplot as plt

## Make a grid that is 100 by 100 with dx=dy=100. m
rmg1 = RasterModelGrid((100, 100), 100.)
## Add elevation field to the grid.
z1 = rmg1.add_ones('node', 'topographic__elevation')

## Instantiate process components
ld1 = LinearDiffuser(rmg1, linear_diffusivity=0.1)
fr1 = FlowRouter(rmg1, method='D8')
fse1 = FastscapeEroder(rmg1, K_sp=1e-5, m_sp=0.5, n_sp=1.)

## Set some variables
rock_up_rate = 1e-3  #m/yr
dt = 1000  # yr
rock_up_len = dt * rock_up_rate  # m

## Time loop where evolution happens
for i in range(500):
    z1[rmg1.core_nodes] += rock_up_len  #uplift only the core nodes
    ld1.run_one_step(dt)  #linear diffusion happens.
    fr1.run_one_step()  #flow routing happens, time step not needed
    fse1.run_one_step(dt)  #fluvial incision happens
    ## optional print statement
    print('i', i)
示例#25
0
z[outlet]=0
#set boundary conditions of model grid (open only (fixed value) on south center pixel)
for edge in (mg.nodes_at_left_edge,mg.nodes_at_right_edge,mg.nodes_at_top_edge,mg.nodes_at_bottom_edge):
    mg.status_at_node[edge] = CLOSED_BOUNDARY
#set southcenter pixel to FIXED VALUE
mg.status_at_node[outlet]=1




#PROCESS SET-UP
#initialize linear diffuser component
lin_diffuse = LinearDiffuser(mg, linear_diffusivity=lin_dif)
#iniitalize erosion by run-off
fr = FlowRouter(mg)
sp = FastscapeEroder(mg,K_sp=K_sp, m_sp=m_sp, n_sp=n_sp)



for i in range(nt):
    fr.run_one_step() 
    sp.run_one_step(dt)
    lin_diffuse.run_one_step(dt)
    z[mg.core_nodes] += uplift_rate * dt  # add the uplift
    
#    color_list=np.linspace(1,0.3,nt)
    if i % 20 == 0:
        print(i*dt)
        
示例#26
0
    mg.at_node['topographic__elevation'] += np.random.rand(mg.at_node.size)/10000 
    print('No pre-existing topography. Creating own random noise topo.')

#Create boundary conditions of the model grid (either closed or fixed-head)
for edge in (mg.nodes_at_left_edge,mg.nodes_at_right_edge, mg.nodes_at_top_edge):
    mg.status_at_node[edge] = CLOSED_BOUNDARY
for edge in (mg.nodes_at_bottom_edge):
    mg.status_at_node[edge] = FIXED_VALUE_BOUNDARY

#Initialize Fastscape
fc = FastscapeEroder(mg,
                    K_sp = ksp ,
                    m_sp = msp,
                    n_sp = nsp,
                    rainfall_intensity = 1)
fr = FlowRouter(mg)
lm = DepressionFinderAndRouter(mg)

for i in range(nSteps):
    fr.run_one_step(dt=1)
    lm.map_depressions()
    fc.run_one_step(dt=1)
    mg.at_node['topographic__elevation'][mg.core_nodes] += 0.0002

z = mg.at_node['topographic__elevation']

plt.figure()
imshow_grid(mg,z)
plt.savefig('test.png')
plt.close()
示例#27
0
# In this case the difference components are:
#   * `FlowRouter` which determines the drainage area at each point. In this
# case we are using `D8` to determine downslope neighbors.
#   * `FastscapeEroder` which calculates the incision rate based on a power-law
# function of discharge and slope. This uses the Braun and Willet algorithm,
# reference <a href="http://www.sciencedirect.com/science/article/pii/S0169555X12004618">here</a>)
#   * `LinearDiffusers` which calculates erosion and deposition of material
# using a sediment transport rate which is proportional to the slope. Here we
# do not allow diffusion to deposit, but you can change that.
#   * Note that in the case of `FastscapeEroder`, the values are noted when the
# class is instantiated. In the case of the `LinearDiffuser`, the value is
# assigned to a variable and that variable is sent to the class. There are
# multiple ways to do things, depending on your coding style and what makes
# sense to you.

fr = FlowRouter(mg, method='D8')
sp = FastscapeEroder(mg,
                     K_sp=0.00005,
                     m_sp=0.5,
                     n_sp=1.0,
                     threshold_sp=0.,
                     rainfall_intensity=1.)

k_d = 0.5
lin_diffuse = LinearDiffuser(mg, linear_diffusivity=k_d)

# * The calculations are all done in the time loop below.

for i in range(nt):
    fr.run_one_step()  # route flow
    sp.run_one_step(dt)  # fluvial incision
示例#28
0
def test_edge_draining():
    """
    This tests when the lake attempts to drain from an edge, where an issue
    is suspected.
    """
    # Create a 7x7 test grid with a well defined hole in it, AT THE EDGE.
    mg = RasterModelGrid((7, 7), (1., 1.))

    z = mg.node_x.copy()
    guard_sides = np.concatenate((np.arange(7, 14), np.arange(35, 42)))
    edges = np.concatenate((np.arange(7), np.arange(42, 49)))
    hole_here = np.array(([15, 16, 22, 23, 29, 30]))
    z[guard_sides] = z[13]
    z[edges] = -2.  # force flow outwards from the tops of the guards
    z[hole_here] = -1.

    A_new = np.array(
        [
            [
                [
                    0.,
                    1.,
                    1.,
                    1.,
                    1.,
                    1.,
                    0.,
                    0.,
                    1.,
                    1.,
                    1.,
                    1.,
                    1.,
                    0.,
                    15.,
                    5.,
                    4.,
                    3.,
                    2.,
                    1.,
                    0.,
                    0.,
                    10.,
                    4.,
                    3.,
                    2.,
                    1.,
                    0.,
                    0.,
                    1.,
                    4.,
                    3.,
                    2.,
                    1.,
                    0.,
                    0.,
                    1.,
                    1.,
                    1.,
                    1.,
                    1.,
                    0.,
                    0.,
                    1.,
                    1.,
                    1.,
                    1.,
                    1.,
                    0.,
                ]
            ]
        ]
    ).flatten()

    depr_outlet_target = np.array(
        [
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            14,
            14,
            XX,
            XX,
            XX,
            XX,
            XX,
            14,
            14,
            XX,
            XX,
            XX,
            XX,
            XX,
            14,
            14,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
        ]
    ).flatten()

    mg.add_field("node", "topographic__elevation", z, units="-")

    fr = FlowRouter(mg)
    lf = DepressionFinderAndRouter(mg)

    fr.route_flow()
    lf.map_depressions()
    assert mg.at_node["drainage_area"] == approx(A_new)
    assert lf.depression_outlet_map == approx(depr_outlet_target)
class HybridAlluviumModel(_ErosionModel):
    """
    A HybridAlluviumModel computes erosion of sediment and bedrock
    using dual mass conservation on the bed and in the water column. It
    applies exponential entrainment rules to account for bed cover.
    """
    def __init__(self, input_file=None, params=None):
        """Initialize the HybridAlluviumModel."""

        # Call ErosionModel's init
        super(HybridAlluviumModel, self).__init__(input_file=input_file,
                                                  params=params)

        # Instantiate a FlowRouter and DepressionFinderAndRouter components
        self.flow_router = FlowRouter(self.grid, **self.params)
        self.lake_filler = DepressionFinderAndRouter(self.grid, **self.params)

        #make area_field and/or discharge_field depending on discharge_method
        if self.params['discharge_method'] is not None:
            if self.params['discharge_method'] == 'area_field':
                area_field = self.grid.at_node['drainage_area']
                discharge_field = None
            elif self.params['discharge_method'] == 'discharge_field':
                discharge_field = self.grid.at_node['surface_water__discharge']
                area_field = None
            else:
                raise (KeyError)
        else:
            area_field = None
            discharge_field = None

        # Instantiate a HybridAlluvium component
        self.eroder = Space(self.grid,
                            K_sed=self.params['K_sed'],
                            K_br=self.params['K_br'],
                            F_f=self.params['F_f'],
                            phi=self.params['phi'],
                            H_star=self.params['H_star'],
                            v_s=self.params['v_s'],
                            m_sp=self.params['m_sp'],
                            n_sp=self.params['n_sp'],
                            sp_crit_sed=self.params['sp_crit_sed'],
                            sp_crit_br=self.params['sp_crit_br'],
                            method=self.params['method'],
                            discharge_method=self.params['discharge_method'],
                            area_field=area_field,
                            discharge_field=discharge_field)

    def run_one_step(self, dt):
        """
        Advance model for one time-step of duration dt.
        """

        # Route flow
        self.flow_router.run_one_step()
        self.lake_filler.map_depressions()

        # Get IDs of flooded nodes, if any
        flooded = np.where(self.lake_filler.flood_status == 3)[0]

        # Do some erosion (but not on the flooded nodes)
        self.eroder.run_one_step(dt, flooded_nodes=flooded)
示例#30
0
def test_composite_pits():
    """
    A test to ensure the component correctly handles cases where there are
    multiple pits, inset into each other.
    """
    mg = RasterModelGrid(10, 10, 1.)
    z = mg.add_field("node", "topographic__elevation", mg.node_x.copy())
    # a sloping plane
    # np.random.seed(seed=0)
    # z += np.random.rand(100)/10000.
    # punch one big hole
    z.reshape((10, 10))[3:8, 3:8] = 0.
    # dig a couple of inset holes
    z[57] = -1.
    z[44] = -2.
    z[54] = -10.

    # make an outlet
    z[71] = 0.9

    fr = FlowRouter(mg)
    lf = DepressionFinderAndRouter(mg)
    fr.route_flow()
    lf.map_depressions()

    flow_sinks_target = np.zeros(100, dtype=bool)
    flow_sinks_target[mg.boundary_nodes] = True
    # no internal sinks now:
    assert_array_equal(mg.at_node["flow__sink_flag"], flow_sinks_target)

    # test conservation of mass:
    assert mg.at_node["drainage_area"].reshape((10, 10))[1:-1, 1].sum() == approx(
        8. ** 2
    )
    # ^all the core nodes

    # test the actual flow field:
    #    nA = np.array([  0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,
    #                     8.,   8.,   7.,   6.,   5.,   4.,   3.,   2.,   1.,   0.,
    #                     1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   0.,
    #                     1.,   1.,   1.,   4.,   2.,   2.,   8.,   4.,   1.,   0.,
    #                     1.,   1.,   1.,   8.,   3.,  15.,   3.,   2.,   1.,   0.,
    #                     1.,   1.,   1.,  13.,  25.,   6.,   3.,   2.,   1.,   0.,
    #                     1.,   1.,   1.,  45.,   3.,   3.,   5.,   2.,   1.,   0.,
    #                    50.,  50.,  49.,   3.,   2.,   2.,   2.,   4.,   1.,   0.,
    #                     1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   0.,
    #                     0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.])
    nA = np.array(
        [
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            8.,
            8.,
            7.,
            6.,
            5.,
            4.,
            3.,
            2.,
            1.,
            0.,
            1.,
            1.,
            1.,
            1.,
            1.,
            1.,
            1.,
            1.,
            1.,
            0.,
            1.,
            1.,
            1.,
            4.,
            2.,
            2.,
            6.,
            4.,
            1.,
            0.,
            1.,
            1.,
            1.,
            6.,
            3.,
            12.,
            3.,
            2.,
            1.,
            0.,
            1.,
            1.,
            1.,
            8.,
            20.,
            4.,
            3.,
            2.,
            1.,
            0.,
            1.,
            1.,
            1.,
            35.,
            5.,
            4.,
            3.,
            2.,
            1.,
            0.,
            50.,
            50.,
            49.,
            13.,
            10.,
            8.,
            6.,
            4.,
            1.,
            0.,
            1.,
            1.,
            1.,
            1.,
            1.,
            1.,
            1.,
            1.,
            1.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
        ]
    )
    assert_array_equal(mg.at_node["drainage_area"], nA)

    # the lake code map:
    lc = np.array(
        [
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            57,
            57,
            57,
            57,
            57,
            XX,
            XX,
            XX,
            XX,
            XX,
            57,
            57,
            57,
            57,
            57,
            XX,
            XX,
            XX,
            XX,
            XX,
            57,
            57,
            57,
            57,
            57,
            XX,
            XX,
            XX,
            XX,
            XX,
            57,
            57,
            57,
            57,
            57,
            XX,
            XX,
            XX,
            XX,
            XX,
            57,
            57,
            57,
            57,
            57,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
            XX,
        ]
    )

    # test the remaining properties:
    assert lf.lake_outlets.size == 1
    assert lf.lake_outlets[0] == 72
    outlets_in_map = np.unique(lf.depression_outlet_map)
    assert outlets_in_map.size == 2
    assert outlets_in_map[1] == 72
    assert lf.number_of_lakes == 1
    assert lf.lake_codes[0] == 57
    assert_array_equal(lf.lake_map, lc)
    assert lf.lake_areas[0] == approx(25.)
    assert lf.lake_volumes[0] == approx(63.)
from landlab.components import FlowRouter, FastscapeEroder, SteepnessFinder

import numpy as np
from landlab import RasterModelGrid, CLOSED_BOUNDARY
from landlab.plot.imshow import imshow_grid_at_node
import matplotlib.pyplot as plt

mg = RasterModelGrid((200, 200), 100.)

z = mg.add_zeros('node', 'topographic__elevation')
z += np.random.rand(mg.number_of_nodes)

mg.status_at_node[mg.nodes_at_left_edge] = CLOSED_BOUNDARY
mg.status_at_node[mg.nodes_at_right_edge] = CLOSED_BOUNDARY

fr = FlowRouter(mg)
sp = FastscapeEroder(mg, K_sp=1.e-5)
sf = SteepnessFinder(mg, min_drainage_area=1.e5)

dt = 20000.

for i in xrange(100):
    print(i)
    fr.route_flow()
    sp.run_one_timestep(dt)
    mg.at_node['topographic__elevation'][mg.core_nodes] += 1.

sf.calculate_steepnesses()
edges = mg.ones('node', dtype=bool)
edges.reshape(mg.shape)[2:-2, 2:-2] = False
steepness_mask = np.logical_or(sf.hillslope_mask, edges)
示例#32
0
Ksp = np.array(dfList)

# Set uplift rate
uplift_rate = 0.0001  # [m/yr]
m_sp = 0.5
n_sp = 1.

### Initialize components
# Set initial surface_water__discharge
rmg['node']['surface_water__discharge'] = np.zeros(rmg.number_of_nodes)
Q = rmg.at_node['surface_water__discharge']

### Initialize components

# Flow router using D8 Flow Director (default FD)
fr = FlowRouter(rmg)

# Stream Power Eroder (erosion by water)
sp = StreamPowerEroder(rmg,
                       K_sp=Ksp,
                       m_sp=m_sp,
                       n_sp=n_sp,
                       threshold_sp=0,
                       use_Q=Q)

# Set up LEM


def run_LEM(years):
    # Create list for saving rainfall
    rainOutput = []
示例#33
0
def test_degenerate_drainage():
    """
    This "hourglass" configuration should be one of the hardest to correctly
    re-route.
    """
    mg = RasterModelGrid(9, 5)
    z_init = mg.node_x.copy() * 0.0001 + 1.
    lake_pits = np.array([7, 11, 12, 13, 17, 27, 31, 32, 33, 37])
    z_init[lake_pits] = -1.
    z_init[22] = 0.  # the common spill pt for both lakes
    z_init[21] = 0.1  # an adverse bump in the spillway
    z_init[20] = -0.2  # the spillway
    z = mg.add_field("node", "topographic__elevation", z_init)

    fr = FlowRouter(mg)
    lf = DepressionFinderAndRouter(mg)
    fr.route_flow()
    lf.map_depressions()

    #    correct_A = np.array([ 0.,   0.,   0.,   0.,   0.,
    #                           0.,   1.,   3.,   1.,   0.,
    #                           0.,   5.,   1.,   2.,   0.,
    #                           0.,   1.,  10.,   1.,   0.,
    #                          21.,  21.,   1.,   1.,   0.,
    #                           0.,   1.,   9.,   1.,   0.,
    #                           0.,   3.,   1.,   2.,   0.,
    #                           0.,   1.,   1.,   1.,   0.,
    #                           0.,   0.,   0.,   0.,   0.])

    correct_A = np.array(
        [
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            1.,
            3.,
            1.,
            0.,
            0.,
            2.,
            4.,
            2.,
            0.,
            0.,
            1.,
            10.,
            1.,
            0.,
            21.,
            21.,
            1.,
            1.,
            0.,
            0.,
            1.,
            9.,
            1.,
            0.,
            0.,
            2.,
            2.,
            2.,
            0.,
            0.,
            1.,
            1.,
            1.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
        ]
    )

    thelake = np.concatenate((lake_pits, [22])).sort()

    assert mg.at_node["drainage_area"] == approx(correct_A)
    k[:] = k_unerodible #for hard rock
    mg['node']['K_values'] = k
elif hard_layer_on_or_off == 0:
    k[:] = k_erodible #soft rock
else:
    print 'WARNING: MUST SELECT 0 OR 1 IN LAYERED PARAM'

#set up its boundary conditions (left, top, right, bottom is inactive)
mg.set_closed_boundaries_at_grid_edges(False, True, False, True)

# Display initialization message
print('Running ...') 

#instantiate the components:
pr = PrecipitationDistribution(input_file)
fr = Flow(mg)
sp = Fsc(mg, input_file)
hd = Diff(mg, input_file)

####################RUN
track_uplift = 0 #track cumulative uplift to know top of hard layer
last_trunc = runtime
for (interval_duration, rainfall_rate) in pr.yield_storm_interstorm_duration_intensity():
    if rainfall_rate != 0.:
        # note diffusion also only happens when it's raining...
        _ = fr.route_flow()
        _ = sp.erode(mg, interval_duration, K_if_used='K_values')
        _ = hd.diffuse(interval_duration)
    track_uplift += uplift_rate * interval_duration #top of beginning surface
    mg.at_node['topographic__elevation'][mg.core_nodes] += uplift_rate * interval_duration
    this_trunc = pr.elapsed_time // t_plot
def get_ordered_cells_for_soil_moisture(grid, outlet_id=None):
    """
    Runs Landlab's FlowRouter and DepressionFinderAndRouter to
    route flow. Also orders the cells in the descending order of
    channel length (upstream cell order).
    
    Parameters:
    ==========    
    grid: grid object
        RasterModelGrid
    outlet_id: int (Optional)
        Outlet id to be set

    Returns:
    =======
    ordered_cells: np.array(dtype=int)
        cells ordered in descending order of channel length
    grid: grid object
        updated RasterModelGrid
    """

    if outlet_id == None:
        outlet_id = np.argmin(grid.at_node['topographic__elevation'])    
    outlet = grid.set_watershed_boundary_condition_outlet_id(outlet_id,
        grid.at_node['topographic__elevation'], nodata_value=-9999.,)
    grid.set_closed_boundaries_at_grid_edges(True, True, True, True)
    flw_r = FlowRouter(grid)
    flw_r.run_one_step()
    df = DepressionFinderAndRouter(grid)
    df.map_depressions()
    r = grid.at_node['flow__receiver_node'][grid.node_at_core_cell]
    R = np.zeros(grid.number_of_nodes, dtype=int)
    R[grid.node_at_core_cell] = r
    channel_length = np.zeros(grid.number_of_nodes, dtype=int)
    # Compute channel lengths for each node in the wtrshd (node_at_core_cell)
    for node in grid.node_at_core_cell:
        node_c = node.copy()
        while R[node_c] != node_c:
            channel_length[node] += 1
            node_c = R[node_c]
    grid.at_node['channel_length'] = channel_length
    # Sorting nodes in the ascending order of channel length
    # NOTE: length of ordered_nodes = grid.number_of_core_cells
    ordered_nodes = grid.node_at_core_cell[
        np.argsort(channel_length[grid.node_at_core_cell])]
    # Sorting nodes in the descending order of channel length
    ordered_nodes = ordered_nodes[::-1]
    dd = 1    # switch 2 for while loop
    count_loops = 0 # No. of loops while runs
    while dd:
        dd = 0
        count_loops += 1
        sorted_order = list(ordered_nodes)
        alr_counted_ = []
        for node_ in sorted_order:
            donors = []
            donors = list(grid.node_at_core_cell[np.where(r==node_)[0]])
            if len(donors) != 0:
                for k in range(0, len(donors)):
                    if donors[k] not in alr_counted_:
                        sorted_order.insert(donors[k], sorted_order.pop(sorted_order.index(node_)))
                        dd = 1    
            alr_counted_.append(node_)
        ordered_nodes = np.array(sorted_order)
    ordered_cells = grid.cell_at_node[ordered_nodes]
    return ordered_cells, grid
示例#36
0
def test_three_pits():
    """
    A test to ensure the component correctly handles cases where there are
    multiple pits.
    """
    mg = RasterModelGrid(10, 10, 1.)
    z = mg.add_field("node", "topographic__elevation", mg.node_x.copy())
    # a sloping plane
    # np.random.seed(seed=0)
    # z += np.random.rand(100)/10000.
    # punch some holes
    z[33] = 1.
    z[43] = 1.
    z[37] = 4.
    z[74:76] = 1.
    fr = FlowRouter(mg)
    lf = DepressionFinderAndRouter(mg)
    fr.route_flow()
    lf.map_depressions()

    flow_sinks_target = np.zeros(100, dtype=bool)
    flow_sinks_target[mg.boundary_nodes] = True
    # no internal sinks now:
    assert_array_equal(mg.at_node["flow__sink_flag"], flow_sinks_target)

    # test conservation of mass:
    assert mg.at_node["drainage_area"].reshape((10, 10))[1:-1, 1].sum() == approx(
        8. ** 2
    )
    # ^all the core nodes

    # test the actual flow field:
    nA = np.array(
        [
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            8.,
            8.,
            7.,
            6.,
            5.,
            4.,
            3.,
            2.,
            1.,
            0.,
            2.,
            2.,
            1.,
            1.,
            2.,
            1.,
            1.,
            1.,
            1.,
            0.,
            26.,
            26.,
            25.,
            15.,
            11.,
            10.,
            9.,
            8.,
            1.,
            0.,
            2.,
            2.,
            1.,
            9.,
            2.,
            1.,
            1.,
            1.,
            1.,
            0.,
            2.,
            2.,
            1.,
            1.,
            5.,
            4.,
            3.,
            2.,
            1.,
            0.,
            2.,
            2.,
            1.,
            1.,
            1.,
            1.,
            3.,
            2.,
            1.,
            0.,
            20.,
            20.,
            19.,
            18.,
            17.,
            12.,
            3.,
            2.,
            1.,
            0.,
            2.,
            2.,
            1.,
            1.,
            1.,
            1.,
            3.,
            2.,
            1.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
        ]
    )
    assert_array_equal(mg.at_node["drainage_area"], nA)

    # test a couple more properties:
    lc = np.empty(100, dtype=int)
    lc.fill(XX)
    lc[33] = 33
    lc[43] = 33
    lc[37] = 37
    lc[74:76] = 74
    assert_array_equal(lf.lake_map, lc)
    assert_array_equal(lf.lake_codes, [33, 37, 74])
    assert lf.number_of_lakes == 3
    assert lf.lake_areas == approx([2., 1., 2.])
    assert lf.lake_volumes == approx([2., 2., 4.])