Пример #1
0
def test_assertion_error():
    """Test that the correct assertion error will be raised."""
    mg = RasterModelGrid((10, 10))
    z = mg.add_zeros("topographic__elevation", at="node")
    z += 200 + mg.x_of_node + mg.y_of_node + np.random.randn(mg.size("node"))

    mg.set_closed_boundaries_at_grid_edges(
        bottom_is_closed=True,
        left_is_closed=True,
        right_is_closed=True,
        top_is_closed=True,
    )
    mg.set_watershed_boundary_condition_outlet_id(0, z, -9999)
    fa = FlowAccumulator(mg,
                         flow_director="D8",
                         depression_finder=DepressionFinderAndRouter)
    sp = FastscapeEroder(mg,
                         K_sp=0.0001,
                         m_sp=0.5,
                         n_sp=1,
                         erode_flooded_nodes=True)
    ld = LinearDiffuser(mg, linear_diffusivity=0.0001)

    dt = 100
    for i in range(200):
        fa.run_one_step()
        sp.run_one_step(dt=dt)
        ld.run_one_step(dt=dt)
        mg.at_node["topographic__elevation"][0] -= 0.001  # Uplift

    with pytest.raises(ValueError):
        ChannelProfiler(mg, outlet_nodes=[0], number_of_watersheds=2)
Пример #2
0
def test_assertion_error():
    """Test that the correct assertion error will be raised."""

    mg = RasterModelGrid(10, 10)
    z = mg.add_zeros('topographic__elevation', at='node')
    z += 200 + mg.x_of_node + mg.y_of_node + np.random.randn(mg.size('node'))

    mg.set_closed_boundaries_at_grid_edges(bottom_is_closed=True,
                                           left_is_closed=True,
                                           right_is_closed=True,
                                           top_is_closed=True)
    mg.set_watershed_boundary_condition_outlet_id(0, z, -9999)
    fa = FlowAccumulator(mg, depression_finder=DepressionFinderAndRouter)
    sp = FastscapeEroder(mg, K_sp=.0001, m_sp=.5, n_sp=1)
    ld = LinearDiffuser(mg, linear_diffusivity=0.0001)

    dt = 100
    for i in range(200):
        fa.run_one_step()
        flooded = np.where(fa.depression_finder.flood_status == 3)[0]
        sp.run_one_step(dt=dt, flooded_nodes=flooded)
        ld.run_one_step(dt=dt)
        mg.at_node['topographic__elevation'][0] -= 0.001  # Uplift

    assert_raises(AssertionError,
                  analyze_channel_network_and_plot,
                  mg,
                  threshold=100,
                  starting_nodes=[0],
                  number_of_channels=2)
Пример #3
0
def test_asking_for_too_many_watersheds():
    mg = RasterModelGrid((10, 10))
    z = mg.add_zeros("topographic__elevation", at="node")
    z += 200 + mg.x_of_node + mg.y_of_node
    mg.set_closed_boundaries_at_grid_edges(
        bottom_is_closed=True,
        left_is_closed=True,
        right_is_closed=True,
        top_is_closed=True,
    )
    mg.set_watershed_boundary_condition_outlet_id(0, z, -9999)
    fa = FlowAccumulator(mg, flow_director="D8")
    sp = FastscapeEroder(mg, K_sp=0.0001, m_sp=0.5, n_sp=1)

    dt = 100
    for i in range(200):
        fa.run_one_step()
        sp.run_one_step(dt=dt)
        mg.at_node["topographic__elevation"][0] -= 0.001

    with pytest.raises(ValueError):
        ChannelProfiler(mg, number_of_watersheds=3)

    with pytest.raises(ValueError):
        ChannelProfiler(mg,
                        number_of_watersheds=None,
                        minimum_outlet_threshold=200)
Пример #4
0
def test_assertion_error():
    """Test that the correct assertion error will be raised."""

    mg = RasterModelGrid(10, 10)
    z = mg.add_zeros('topographic__elevation', at='node')
    z += 200 + mg.x_of_node + mg.y_of_node + np.random.randn(mg.size('node'))

    mg.set_closed_boundaries_at_grid_edges(bottom_is_closed=True, left_is_closed=True, right_is_closed=True, top_is_closed=True)
    mg.set_watershed_boundary_condition_outlet_id(0, z, -9999)
    fa = FlowAccumulator(mg, flow_director='D8', depression_finder=DepressionFinderAndRouter)
    sp = FastscapeEroder(mg, K_sp=.0001, m_sp=.5, n_sp=1)
    ld = LinearDiffuser(mg, linear_diffusivity=0.0001)

    dt = 100
    for i in range(200):
        fa.run_one_step()
        flooded = np.where(fa.depression_finder.flood_status==3)[0]
        sp.run_one_step(dt=dt,  flooded_nodes=flooded)
        ld.run_one_step(dt=dt)
        mg.at_node['topographic__elevation'][0] -= 0.001 # Uplift


    assert_raises(AssertionError,
                  analyze_channel_network_and_plot,
                  mg,
                  threshold = 100,
                  starting_nodes = [0],
                  number_of_channels=2)
def test_mask_is_stable():
    mg = RasterModelGrid((10, 10))
    mg.add_zeros("node", "topographic__elevation")
    np.random.seed(3542)
    noise = np.random.rand(mg.size("node"))
    mg.at_node["topographic__elevation"] += noise
    fr = FlowAccumulator(mg, flow_director="D8")
    fsc = FastscapeEroder(mg, K_sp=0.01, m_sp=0.5, n_sp=1)
    for x in range(2):
        fr.run_one_step()
        fsc.run_one_step(dt=10.0)
        mg.at_node["topographic__elevation"][mg.core_nodes] += 0.01

    mask = np.zeros(len(mg.at_node["topographic__elevation"]), dtype=np.uint8)
    mask[np.where(mg.at_node["drainage_area"] > 0)] = 1

    mask0 = mask.copy()

    dd = DrainageDensity(mg, channel__mask=mask)
    mask1 = mask.copy()

    dd.calc_drainage_density()
    mask2 = mask.copy()

    assert_array_equal(mask0, mask1)
    assert_array_equal(mask0[mg.core_nodes], mask2[mg.core_nodes])
Пример #6
0
    def __init__(self, input_file=None, params=None,
                 BaselevelHandlerClass=None):
        """Initialize the BasicCh."""

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

        # Get Parameters and convert units if necessary:
        self.K_sp = self.get_parameter_from_exponent('K_sp')
        linear_diffusivity = (self._length_factor**2.)*self.get_parameter_from_exponent('linear_diffusivity') # has units length^2/time

        # Instantiate a FlowAccumulator with DepressionFinderAndRouter using D8 method
        self.flow_router = FlowAccumulator(self.grid,
                                           flow_director='D8',
                                           depression_finder = DepressionFinderAndRouter)

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

        # Instantiate a LinearDiffuser component
        self.diffuser = TaylorNonLinearDiffuser(self.grid,
                                               linear_diffusivity=linear_diffusivity,
                                               slope_crit=self.params['slope_crit'],
                                               nterms=11)
Пример #7
0
def test_re_calculating_nodes_and_distance():
    mg = RasterModelGrid((20, 20), xy_spacing=100)
    z = mg.add_zeros("topographic__elevation", at="node")
    z += np.random.rand(z.size)
    mg.set_closed_boundaries_at_grid_edges(
        bottom_is_closed=False,
        left_is_closed=True,
        right_is_closed=True,
        top_is_closed=True,
    )

    fa = FlowAccumulator(mg, flow_director="D8")
    sp = FastscapeEroder(mg, K_sp=0.0001, m_sp=0.5, n_sp=1)

    dt = 1000
    uplift_per_step = 0.001 * dt

    for i in range(10):
        z[mg.core_nodes] += uplift_per_step
        fa.run_one_step()
        sp.run_one_step(dt=dt)

    profiler = ChannelProfiler(mg)
    profiler.run_one_step()
    assert len(profiler.distance_along_profile) == 1  # result: 1
    profiler.run_one_step()
    # here nathan originally found result: 2, a bug!
    assert len(profiler.distance_along_profile) == 1

    # make the most complicated profile structure
    profiler = ChannelProfiler(mg,
                               main_channel_only=False,
                               number_of_watersheds=2)
    profiler.run_one_step()
    p1 = list(profiler.nodes)
    d1 = list(profiler.distance_along_profile)

    profiler.run_one_step()
    p2 = list(profiler.nodes)
    d2 = list(profiler.distance_along_profile)

    # assert that these are copies, not pointers to same thing
    assert p1 is not p2
    assert d1 is not d2

    # test that structures are the same.
    for idx_watershed in range(len(p1)):
        p1_w = p1[idx_watershed]
        p2_w = p2[idx_watershed]

        d1_w = d1[idx_watershed]
        d2_w = d2[idx_watershed]

        for idx_segment in range(len(p1_w)):
            np.testing.assert_array_equal(p1_w[idx_segment], p2_w[idx_segment])
            np.testing.assert_array_equal(d1_w[idx_segment], d2_w[idx_segment])
Пример #8
0
    def __init__(self, input_file=None, params=None,
                 BaselevelHandlerClass=None):
        """Initialize the BasicChSa model."""

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

        self.K_sp = self.get_parameter_from_exponent('K_sp')
        linear_diffusivity = (self._length_factor**2.)*self.get_parameter_from_exponent('linear_diffusivity') # has units length^2/time
        try:
            initial_soil_thickness = (self._length_factor)*self.params['initial_soil_thickness'] # has units length
        except KeyError:
            initial_soil_thickness = 1.0  # default value
        soil_transport_decay_depth = (self._length_factor)*self.params['soil_transport_decay_depth']  # has units length
        max_soil_production_rate = (self._length_factor)*self.params['max_soil_production_rate'] # has units length per time
        soil_production_decay_depth = (self._length_factor)*self.params['soil_production_decay_depth']   # has units length

        # Create soil thickness (a.k.a. depth) field
        if 'soil__depth' in self.grid.at_node:
            soil_thickness = self.grid.at_node['soil__depth']
        else:
            soil_thickness = self.grid.add_zeros('node', 'soil__depth')

        # Create bedrock elevation field
        if 'bedrock__elevation' in self.grid.at_node:
            bedrock_elev = self.grid.at_node['bedrock__elevation']
        else:
            bedrock_elev = self.grid.add_zeros('node', 'bedrock__elevation')

        soil_thickness[:] = initial_soil_thickness
        bedrock_elev[:] = self.z - initial_soil_thickness

        # Instantiate a FlowAccumulator with DepressionFinderAndRouter using D8 method
        self.flow_router = FlowAccumulator(self.grid,
                                           flow_director='D8',
                                           depression_finder = DepressionFinderAndRouter)

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

        # Instantiate a weathering component
        self.weatherer = ExponentialWeatherer(self.grid,
                                              max_soil_production_rate=max_soil_production_rate,
                                              soil_production_decay_depth=soil_production_decay_depth)

        # Instantiate a soil-transport component
        self.diffuser = DepthDependentTaylorDiffuser(self.grid,
                                                    linear_diffusivity=linear_diffusivity,
                                                    slope_crit=self.params['slope_crit'],
                                                    soil_transport_decay_depth=soil_transport_decay_depth,
                                                    nterms=11)
def test_route_to_multiple_error_raised_run_FastscapeEroder():
    mg = RasterModelGrid((10, 10))
    z = mg.add_zeros("node", "topographic__elevation")
    z += mg.x_of_node + mg.y_of_node
    sp = FastscapeEroder(mg, K_sp=0.1)

    fa = FlowAccumulator(mg, flow_director="MFD")
    fa.run_one_step()

    with pytest.raises(NotImplementedError):
        sp.run_one_step(10)
Пример #10
0
    def __init__(self,
                 input_file=None,
                 params=None,
                 BaselevelHandlerClass=None):
        """Initialize the Basic model."""
        # Call ErosionModel's init
        super(Basic,
              self).__init__(input_file=input_file,
                             params=params,
                             BaselevelHandlerClass=BaselevelHandlerClass)

        # Get Parameters:
        K_sp = self.get_parameter_from_exponent('K_sp', raise_error=False)
        K_ss = self.get_parameter_from_exponent('K_ss', raise_error=False)
        linear_diffusivity = (
            self._length_factor**2.) * self.get_parameter_from_exponent(
                'linear_diffusivity')  # has units length^2/time

        # check that a stream power and a shear stress parameter have not both been given
        if K_sp != None and K_ss != None:
            raise ValueError('A parameter for both K_sp and K_ss has been'
                             'provided. Only one of these may be provided')
        elif K_sp != None or K_ss != None:
            if K_sp != None:
                self.K = K_sp
            else:
                self.K = (self._length_factor**(
                    1. / 3.)) * K_ss  # K_ss has units Lengtg^(1/3) per Time
        else:
            raise ValueError('A value for K_sp or K_ss  must be provided.')

        # run the sink filler, only on initiation.
        sink_filler = SinkFiller(self.grid, apply_slope=True, fill_slope=1e-3)
        sink_filler.run_one_step()

        # Instantiate a FlowAccumulator with DepressionFinderAndRouter using D8 method
        self.flow_router = FlowAccumulator(
            self.grid,
            flow_director='D8',
            depression_finder=DepressionFinderAndRouter)

        # Instantiate a FastscapeEroder component
        self.eroder = FastscapeEroder(self.grid,
                                      K_sp=self.K,
                                      m_sp=self.params['m_sp'],
                                      n_sp=self.params['n_sp'])

        # Instantiate a LinearDiffuser component
        self.diffuser = LinearDiffuser(self.grid,
                                       linear_diffusivity=linear_diffusivity)
Пример #11
0
    def __init__(self, input_file=None, params=None):
        """Initialize the BasicStreamPowerErosionModel."""

        # Call ErosionModel's init
        super(BasicStreamPowerErosionModel,
              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 = FastscapeEroder(self.grid,
                                      K_sp=self.params['K_sp'],
                                      m_sp=self.params['m_sp'],
                                      n_sp=self.params['n_sp'])
Пример #12
0
def test_stream_power_save_output(tmpdir):

    mg = RasterModelGrid((3, 3), xy_spacing=10.0)
    mg.set_status_at_node_on_edges(
        right=mg.BC_NODE_IS_CLOSED,
        top=mg.BC_NODE_IS_CLOSED,
        left=mg.BC_NODE_IS_CLOSED,
        bottom=mg.BC_NODE_IS_FIXED_VALUE,
    )
    mg.add_ones("node", "topographic__elevation")
    mg.add_zeros("node", "aquifer_base__elevation")
    mg.add_ones("node", "water_table__elevation")

    gdp = GroundwaterDupuitPercolator(mg, recharge_rate=1e-4)
    hm = HydrologySteadyStreamPower(mg, groundwater_model=gdp)
    sp = FastscapeEroder(
        mg,
        K_sp=1e-10,
        m_sp=1,
        n_sp=1,
        discharge_field="surface_water_area_norm__discharge",
    )
    ld = LinearDiffuser(mg, linear_diffusivity=1e-10)
    rm = RegolithConstantThickness(mg, uplift_rate=0.0)

    output = {}
    output["output_interval"] = 1000
    output["output_fields"] = [
        "at_node:topographic__elevation",
        "at_node:aquifer_base__elevation",
        "at_node:water_table__elevation",
    ]
    output["base_output_path"] = tmpdir.strpath + "/"
    output["run_id"] = 0  # make this task_id if multiple runs

    mdl = StreamPowerModel(
        mg,
        hydrology_model=hm,
        diffusion_model=ld,
        erosion_model=sp,
        regolith_model=rm,
        total_morphological_time=1e8,
        output_dict=output,
    )

    mdl.run_model()

    file = tmpdir.join("0_grid_0.nc")
    mg1 = from_netcdf(file.strpath)
    keys = [
        "topographic__elevation",
        "aquifer_base__elevation",
        "water_table__elevation",
    ]
    assert isinstance(mg1, RasterModelGrid)
    assert set(mg1.at_node.keys()) == set(keys)
    assert_equal(mg1.status_at_node, mg.status_at_node)
Пример #13
0
def test_route_to_multiple_error_raised_init_FastscapeEroder():
    mg = RasterModelGrid((10, 10))
    z = mg.add_zeros("node", "topographic__elevation")
    z += mg.x_of_node + mg.y_of_node
    fa = FlowAccumulator(mg, flow_director="MFD")
    fa.run_one_step()

    with pytest.raises(NotImplementedError):
        FastscapeEroder(mg)
Пример #14
0
def profile_example_grid():
    mg = RasterModelGrid((40, 60))
    z = mg.add_zeros("topographic__elevation", at="node")
    z += 200 + mg.x_of_node + mg.y_of_node
    mg.set_closed_boundaries_at_grid_edges(
        bottom_is_closed=True,
        left_is_closed=True,
        right_is_closed=True,
        top_is_closed=True,
    )
    mg.set_watershed_boundary_condition_outlet_id(0, z, -9999)
    fa = FlowAccumulator(mg, flow_director="D8")
    sp = FastscapeEroder(mg, K_sp=0.0001, m_sp=0.5, n_sp=1)

    dt = 100
    for i in range(200):
        fa.run_one_step()
        sp.run_one_step(dt=dt)
        mg.at_node["topographic__elevation"][0] -= 0.001
    return mg
Пример #15
0
def test_getting_all_the_way_to_the_divide(main, nshed):
    np.random.seed(42)
    mg = RasterModelGrid((10, 12))
    z = mg.add_zeros("topographic__elevation", at="node")
    z += np.random.rand(z.size)

    fa = FlowAccumulator(mg, flow_director="D8")
    sp = FastscapeEroder(mg, K_sp=0.0001, m_sp=0.5, n_sp=1)

    dt = 1000
    uplift_per_step = 0.001 * dt

    for i in range(100):
        z[mg.core_nodes] += uplift_per_step
        fa.run_one_step()
        sp.run_one_step(dt=dt)

    profiler = ChannelProfiler(
        mg,
        number_of_watersheds=nshed,
        minimum_outlet_threshold=0,
        main_channel_only=main,
        minimum_channel_threshold=0,
    )
    profiler.run_one_step()

    # assert that with minimum_channel_threshold set to zero, we get all the way to the top of the divide.
    for outlet_id in profiler._data_struct:
        seg_tuples = profiler._data_struct[outlet_id].keys()

        wshd_ids = [
            profiler._data_struct[outlet_id][seg]["ids"] for seg in seg_tuples
        ]

        nodes = np.concatenate(wshd_ids).ravel()
        da = mg.at_node["drainage_area"][nodes]

        # if "profile" is just bits of the edge, then da is 0.
        assert (mg.area_of_cell.min() in da) or (0.0 in da)
Пример #16
0
    def __init__(self,
                 input_file=None,
                 params=None,
                 BaselevelHandlerClass=None):
        """Initialize the BasicCv model."""
        # Call ErosionModel's init
        super(BasicCv,
              self).__init__(input_file=input_file,
                             params=params,
                             BaselevelHandlerClass=BaselevelHandlerClass)

        K_sp = self.get_parameter_from_exponent('K_sp')
        linear_diffusivity = (
            self._length_factor**
            2.) * self.get_parameter_from_exponent('linear_diffusivity')

        self.climate_factor = self.params['climate_factor']
        self.climate_constant_date = self.params['climate_constant_date']

        time = [0, self.climate_constant_date, self.params['run_duration']]
        K = [K_sp * self.climate_factor, K_sp, K_sp]
        self.K_through_time = interp1d(time, K)

        # Instantiate a FlowAccumulator with DepressionFinderAndRouter using D8 method
        self.flow_router = FlowAccumulator(
            self.grid,
            flow_director='D8',
            depression_finder=DepressionFinderAndRouter)

        # Instantiate a FastscapeEroder component
        self.eroder = FastscapeEroder(self.grid,
                                      K_sp=K[0],
                                      m_sp=self.params['m_sp'],
                                      n_sp=self.params['n_sp'])

        # Instantiate a LinearDiffuser component
        self.diffuser = LinearDiffuser(self.grid,
                                       linear_diffusivity=linear_diffusivity)
Пример #17
0
class BasicStreamPowerErosionModel(_ErosionModel):
    """
    A BasicStreamPowerErosionModel computes erosion using the simplest form of
    the unit stream power model.
    """
    def __init__(self, input_file=None, params=None):
        """Initialize the BasicStreamPowerErosionModel."""

        # Call ErosionModel's init
        super(BasicStreamPowerErosionModel,
              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 = FastscapeEroder(self.grid,
                                      K_sp=self.params['K_sp'],
                                      m_sp=self.params['m_sp'],
                                      n_sp=self.params['n_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)
Пример #18
0
def test_stream_power_run_model_subdivide():

    mg = RasterModelGrid((3, 3), xy_spacing=10.0)
    mg.set_status_at_node_on_edges(
        right=mg.BC_NODE_IS_CLOSED,
        top=mg.BC_NODE_IS_CLOSED,
        left=mg.BC_NODE_IS_CLOSED,
        bottom=mg.BC_NODE_IS_FIXED_VALUE,
    )
    z = mg.add_ones("node", "topographic__elevation")
    z[1] = 1e-15
    zb = mg.add_zeros("node", "aquifer_base__elevation")
    mg.add_ones("node", "water_table__elevation")

    gdp = GroundwaterDupuitPercolator(mg, recharge_rate=1e-4)
    hm = HydrologySteadyStreamPower(mg, groundwater_model=gdp)
    sp = FastscapeEroder(
        mg,
        K_sp=1e-10,
        m_sp=1,
        n_sp=1,
        discharge_field="surface_water_area_norm__discharge",
    )
    ld = LinearDiffuser(mg, linear_diffusivity=1e-10)
    rm = RegolithConstantThickness(mg, uplift_rate=0.0)

    mdl = StreamPowerModel(
        mg,
        hydrology_model=hm,
        diffusion_model=ld,
        erosion_model=sp,
        regolith_model=rm,
        total_morphological_time=1e8,
        maximum_morphological_dt=2e7,
    )

    mdl.run_step(1e5, dt_m_max=2e4)

    assert z[4] < 1.0
    assert_equal(z[4] - zb[4], 1.0)
    assert_equal(mdl.num_substeps, 5)
Пример #19
0
    def __init__(self, clock, grid, hydraulic_conductivity=0.1, **kwargs):
        """
        Parameters
        ----------
        clock : terrainbento Clock instance
        grid : landlab model grid instance
            The grid must have all required fields.
        m_sp : float, optional
            Drainage area exponent (:math:`m`). Default is 0.5.
        n_sp : float, optional
            Slope exponent (:math:`n`). Default is 1.0.
        water_erodibility_upper : float, optional
            Water erodibility of the upper layer (:math:`K_{1}`). Default is
            0.001.
        water_erodibility_lower : float, optional
            Water erodibility of the upper layer (:math:`K_{2}`). Default is
            0.0001.
        contact_zone__width : float, optional
            Thickness of the contact zone (:math:`W_c`). Default is 1.
        regolith_transport_parameter : float, optional
            Regolith transport efficiency (:math:`D`). Default is 0.1.
        hydraulic_conductivity : float, optional
            Hydraulic conductivity (:math:`K_{sat}`). Default is 0.1.
        **kwargs :
            Keyword arguments to pass to :py:class:`TwoLithologyErosionModel`.
            Importantly these arguments specify the precipitator and the runoff
            generator that control the generation of surface water discharge
            (:math:`Q`).

        Returns
        -------
        BasicRtVs : model object

        Examples
        --------
        This is a minimal example to demonstrate how to construct an instance
        of model **BasicRtVs**. For more detailed examples, including
        steady-state test examples, see the terrainbento tutorials.

        To begin, import the model class.

        >>> from landlab import RasterModelGrid
        >>> from landlab.values import random, constant
        >>> from terrainbento import Clock, BasicRtVs
        >>> clock = Clock(start=0, stop=100, step=1)
        >>> grid = RasterModelGrid((5,5))
        >>> _ = random(grid, "topographic__elevation")
        >>> _ = random(grid, "soil__depth")
        >>> _ = constant(grid, "lithology_contact__elevation", value=-10.)

        Construct the model.

        >>> model = BasicRtVs(clock, grid)

        Running the model with ``model.run()`` would create output, so here we
        will just run it one step.

        >>> model.run_one_step(1.)
        >>> model.model_time
        1.0

        """
        # Call ErosionModel"s init
        super(BasicRtVs, self).__init__(clock, grid, **kwargs)

        # ensure Precipitator and RunoffGenerator are vanilla
        self._ensure_precip_runoff_are_vanilla()

        # verify correct fields are present.
        self._verify_fields(self._required_fields)

        # Set up rock-till boundary and associated grid fields.
        self._setup_rock_and_till()

        # Get the effective-area parameter
        self._Kdx = hydraulic_conductivity * self.grid.dx

        # Instantiate a FastscapeEroder component
        self.eroder = FastscapeEroder(
            self.grid,
            K_sp=self.erody,
            m_sp=self.m,
            n_sp=self.n,
            discharge_name="surface_water__discharge",
        )

        # Instantiate a LinearDiffuser component
        self.diffuser = LinearDiffuser(
            self.grid, linear_diffusivity=self.regolith_transport_parameter
        )
Пример #20
0
class BasicRtVs(TwoLithologyErosionModel):
    r"""**BasicRtVs** model program.

    This model program combines the :py:class:`BasicRt` and :py:class:`BasicVs`
    programs by allowing for two lithologies, an "upper" layer and a "lower"
    layer, and using discharge proportional to effective drainage area based on
    variable source area hydrology. Given a spatially varying contact zone
    elevation, :math:`\eta_C(x,y))`, model **BasicRtVs** evolves a topographic
    surface described by :math:`\eta` with the following governing equations:

    .. math::

        \frac{\partial \eta}{\partial t} = - K(\eta,\eta_C) A_{eff}^{m}S^{n}
                                           + D\nabla^2 \eta

        K(\eta, \eta_C ) = w K_1 + (1 - w) K_2

        w = \frac{1}{1+\exp \left( -\frac{(\eta -\eta_C )}{W_c}\right)}

        A_{eff} = A \exp \left( -\frac{-\alpha S}{A}\right)

        \alpha = \frac{K_{sat} dx }{R_m}


    where :math:`Q` is the local stream discharge, :math:`S` is the local
    slope, :math:`m` and :math:`n` are the discharge and slope exponent
    parameters, :math:`W_c` is the contact-zone width, :math:`K_1` and
    :math:`K_2` are the erodabilities of the upper and lower lithologies, and
    :math:`D` is the regolith transport parameter. :math:`\alpha` is the
    saturation area scale used for transforming area into effective area and it
    is given as a function of the saturated hydraulic conductivity
    :math:`K_{sat}`, the soil thickness :math:`H`, the grid spacing :math:`dx`,
    and the recharge rate, :math:`R_m`. :math:`w` is a weight used to calculate
    the effective erodibility :math:`K(\eta, \eta_C)` based on the depth to
    the contact zone and the width of the contact zone.

    The weight :math:`w` promotes smoothness in the solution of erodibility at
    a given point. When the surface elevation is at the contact elevation, the
    erodibility is the average of :math:`K_1` and :math:`K_2`; above and below
    the contact, the erodibility approaches the value of :math:`K_1` and
    :math:`K_2` at a rate related to the contact zone width. Thus, to make a
    very sharp transition, use a small value for the contact zone width.

    Refer to
    `Barnhart et al. (2019) <https://doi.org/10.5194/gmd-12-1267-2019>`_
    Table 5 for full list of parameter symbols, names, and dimensions.

    The following at-node fields must be specified in the grid:
        - ``topographic__elevation``
        - ``lithology_contact__elevation``
        - ``soil__depth``
    """

    _required_fields = [
        "topographic__elevation",
        "lithology_contact__elevation",
        "soil__depth",
    ]

    def __init__(self, clock, grid, hydraulic_conductivity=0.1, **kwargs):
        """
        Parameters
        ----------
        clock : terrainbento Clock instance
        grid : landlab model grid instance
            The grid must have all required fields.
        m_sp : float, optional
            Drainage area exponent (:math:`m`). Default is 0.5.
        n_sp : float, optional
            Slope exponent (:math:`n`). Default is 1.0.
        water_erodibility_upper : float, optional
            Water erodibility of the upper layer (:math:`K_{1}`). Default is
            0.001.
        water_erodibility_lower : float, optional
            Water erodibility of the upper layer (:math:`K_{2}`). Default is
            0.0001.
        contact_zone__width : float, optional
            Thickness of the contact zone (:math:`W_c`). Default is 1.
        regolith_transport_parameter : float, optional
            Regolith transport efficiency (:math:`D`). Default is 0.1.
        hydraulic_conductivity : float, optional
            Hydraulic conductivity (:math:`K_{sat}`). Default is 0.1.
        **kwargs :
            Keyword arguments to pass to :py:class:`TwoLithologyErosionModel`.
            Importantly these arguments specify the precipitator and the runoff
            generator that control the generation of surface water discharge
            (:math:`Q`).

        Returns
        -------
        BasicRtVs : model object

        Examples
        --------
        This is a minimal example to demonstrate how to construct an instance
        of model **BasicRtVs**. For more detailed examples, including
        steady-state test examples, see the terrainbento tutorials.

        To begin, import the model class.

        >>> from landlab import RasterModelGrid
        >>> from landlab.values import random, constant
        >>> from terrainbento import Clock, BasicRtVs
        >>> clock = Clock(start=0, stop=100, step=1)
        >>> grid = RasterModelGrid((5,5))
        >>> _ = random(grid, "topographic__elevation")
        >>> _ = random(grid, "soil__depth")
        >>> _ = constant(grid, "lithology_contact__elevation", value=-10.)

        Construct the model.

        >>> model = BasicRtVs(clock, grid)

        Running the model with ``model.run()`` would create output, so here we
        will just run it one step.

        >>> model.run_one_step(1.)
        >>> model.model_time
        1.0

        """
        # Call ErosionModel"s init
        super(BasicRtVs, self).__init__(clock, grid, **kwargs)

        # ensure Precipitator and RunoffGenerator are vanilla
        self._ensure_precip_runoff_are_vanilla()

        # verify correct fields are present.
        self._verify_fields(self._required_fields)

        # Set up rock-till boundary and associated grid fields.
        self._setup_rock_and_till()

        # Get the effective-area parameter
        self._Kdx = hydraulic_conductivity * self.grid.dx

        # Instantiate a FastscapeEroder component
        self.eroder = FastscapeEroder(
            self.grid,
            K_sp=self.erody,
            m_sp=self.m,
            n_sp=self.n,
            discharge_name="surface_water__discharge",
        )

        # Instantiate a LinearDiffuser component
        self.diffuser = LinearDiffuser(
            self.grid, linear_diffusivity=self.regolith_transport_parameter
        )

    def _calc_effective_drainage_area(self):
        r"""Calculate and store effective drainage area.

        Effective drainage area is defined as:

        .. math::

            A_{eff} = A \exp ( \alpha S / A) = A R_r

        where :math:`S` is downslope-positive steepest gradient, :math:`A` is
        drainage area, :math:`R_r` is the runoff ratio, and :math:`\alpha` is
        the saturation parameter.
        """
        area = self.grid.at_node["drainage_area"]
        slope = self.grid.at_node["topographic__steepest_slope"]
        cores = self.grid.core_nodes

        sat_param = (
            self._Kdx
            * self.grid.at_node["soil__depth"]
            / self.grid.at_node["rainfall__flux"]
        )

        eff_area = area[cores] * (
            np.exp(-sat_param[cores] * slope[cores] / area[cores])
        )

        self.grid.at_node["surface_water__discharge"][cores] = eff_area

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

        The **run_one_step** method does the following:

        1. Directs flow, accumulates drainage area, and calculates effective
           drainage area.

        2. Assesses the location, if any, of flooded nodes where erosion should
           not occur.

        3. Assesses if a :py:mod:`PrecipChanger` is an active boundary handler
           and if so, uses it to modify the erodibility by water.

        4. Updates the spatially variable erodibility value based on the
           relative distance between the topographic surface and the lithology
           contact.

        5. Calculates detachment-limited erosion by water.

        6. Calculates topographic change by linear diffusion.

        7. Finalizes the step using the :py:mod:`ErosionModel` base class
           function **finalize__run_one_step**. This function updates all
           boundary handlers handlers by ``step`` and increments model time by
           ``step``.

        Parameters
        ----------
        step : float
            Increment of time for which the model is run.
        """
        # create and move water
        self.create_and_move_water(step)

        # Update effective runoff ratio
        self._calc_effective_drainage_area()

        # Get IDs of flooded nodes, if any
        if self.flow_accumulator.depression_finder is None:
            flooded = []
        else:
            flooded = np.where(
                self.flow_accumulator.depression_finder.flood_status == 3
            )[0]

        # Zero out effective area in flooded nodes
        self.grid.at_node["surface_water__discharge"][flooded] = 0.0

        # Update the erodibility field
        self._update_erodibility_field()

        # Do some erosion (but not on the flooded nodes)
        self.eroder.run_one_step(step)

        # Do some soil creep
        self.diffuser.run_one_step(step)

        # Finalize the run_one_step_method
        self.finalize__run_one_step(step)
Пример #21
0
class BasicCh(_ErosionModel):
    """
    A BasicCh computes erosion using cubic diffusion, basic stream
    power, and Q~A.
    """

    def __init__(self, input_file=None, params=None,
                 BaselevelHandlerClass=None):
        """Initialize the BasicCh."""

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

        # Get Parameters and convert units if necessary:
        self.K_sp = self.get_parameter_from_exponent('K_sp')
        linear_diffusivity = (self._length_factor**2.)*self.get_parameter_from_exponent('linear_diffusivity') # has units length^2/time

        # Instantiate a FlowAccumulator with DepressionFinderAndRouter using D8 method
        self.flow_router = FlowAccumulator(self.grid,
                                           flow_director='D8',
                                           depression_finder = DepressionFinderAndRouter)

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

        # Instantiate a LinearDiffuser component
        self.diffuser = TaylorNonLinearDiffuser(self.grid,
                                               linear_diffusivity=linear_diffusivity,
                                               slope_crit=self.params['slope_crit'],
                                               nterms=11)

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

        # Route flow
        self.flow_router.run_one_step()

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

        # Do some erosion (but not on the flooded nodes)
        # (if we're varying K through time, update that first)
        if self.opt_var_precip:
            self.eroder.K = (self.K_sp
                             * self.pc.get_erodibility_adjustment_factor(self.model_time))
        self.eroder.run_one_step(dt, flooded_nodes=flooded)

        # Do some soil creep
        self.diffuser.run_one_step(dt, 
                                   dynamic_dt=True,
                                   if_unstable='raise', 
                                   courant_factor=0.1)

        # calculate model time
        self.model_time += dt

        # Lower outlet
        self.update_outlet(dt)

        # Check walltime
        self.check_walltime()
Пример #22
0
    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
    if this_trunc != last_trunc: # time to plot a new profile!
Пример #23
0
# make some K values in a field to test
mg.at_node["K_values"] = 0.00001 + np.random.rand(nrows * ncols) / 100000.

# mg.at_node['water__unit_flux_in'] = dx*dx*np.ones_like(z)
mg.at_node["water__unit_flux_in"] = (
    dx * dx * np.ones_like(z) * 100. / (60. * 60. * 24. * 365.25)
)  # remember, flux is /sec, so this is a small number!
# mg.set_closed_boundaries_at_grid_edges(False, False, True, True)
# mg.set_closed_boundaries_at_grid_edges(True, False, True, True)

print("Running ...")

# instantiate the components:
fr = FlowAccumulator(mg, flow_director="D8")
# load the Fastscape module too, to allow direct comparison
fsp = FastscapeEroder(mg, "./pot_fr_params.txt")

# perform the loop:
elapsed_time = 0.  # total time in simulation
while elapsed_time < time_to_run:
    print(elapsed_time)
    if elapsed_time + dt > time_to_run:
        print("Short step!")
        dt = time_to_run - elapsed_time
    mg = fr.run_one_step()
    # print 'Area: ', numpy.max(mg.at_node['drainage_area'])
    # mg = fsp.erode(mg)
    mg = fsp.erode(mg, K_if_used="K_values")
    # mg,_,_ = sp.erode(mg, dt, node_drainage_areas='drainage_area', slopes_at_nodes='topographic__steepest_slope')
    # add uplift
    mg.at_node["topographic__elevation"][mg.core_nodes] += uplift * dt
Пример #24
0
# make some K values in a field to test
# mg.at_node['K_values'] = 0.1+numpy.random.rand(nrows*ncols)/10.
mg.at_node["K_values"] = numpy.empty(nrows * ncols, dtype=float)
# mg.at_node['K_values'].fill(0.1+numpy.random.rand()/10.)
mg.at_node["K_values"].fill(0.001)

print("Running ...")

# instantiate the components:
fr = FlowAccumulator(mg, flow_director="D8")
sp = StreamPowerEroder(mg, input_file_string)
# fsp = FastscapeEroder(mg, input_file_string)
precip = PrecipitationDistribution(input_file=input_file_string)

# load the Fastscape module too, to allow direct comparison
fsp = FastscapeEroder(mg, input_file_string)

try:
    # raise NameError
    mg = copy.deepcopy(mg_mature)
except NameError:
    print("building a new grid...")
    out_interval = 50000.
    last_trunc = time_to_run  # we use this to trigger taking an output plot
    # run to a steady state:
    # We're going to cheat by running Fastscape SP for the first part of the solution
    for (
            interval_duration,
            rainfall_rate,
    ) in precip.yield_storm_interstorm_duration_intensity():
        if rainfall_rate != 0.:
Пример #25
0
    mg.at_node['topographic__elevation'] += topoSeed
    print('Using pre-existing topography from file topoSeed.npy')
else:
    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)
Пример #26
0
#create the fields in the grid
mg.add_zeros('topographic__elevation', at='node')
z = mg.zeros(at='node') + init_elev
mg['node']['topographic__elevation'] = z + numpy.random.rand(len(z))/1000.

#make some K values in a field to test
mg.at_node['K_values'] = 0.1+numpy.random.rand(nrows*ncols)/10.

print( 'Running ...' )

#instantiate the components:
fr = FlowAccumulator(mg, flow_director='D8')
sp = StreamPowerEroder(mg, './drive_sp_params.txt')
#load the Fastscape module too, to allow direct comparison
fsp = FastscapeEroder(mg, './drive_sp_params.txt')

#perform the loop:
elapsed_time = 0. #total time in simulation
while elapsed_time < time_to_run:
    print(elapsed_time)
    if elapsed_time+dt>time_to_run:
        print("Short step!")
        dt = time_to_run - elapsed_time
    mg = fr.run_one_step()
    #print 'Area: ', numpy.max(mg.at_node['drainage_area'])
    #mg = fsp.erode(mg)
    mg = fsp.erode(mg, K_if_used='K_values')
    #mg,_,_ = sp.erode(mg, dt, node_drainage_areas='drainage_area', slopes_at_nodes='topographic__steepest_slope')
    #add uplift
    mg.at_node['topographic__elevation'][mg.core_nodes] += uplift*dt
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)
steepnesses = np.ma.array(mg.at_node['channel__steepness_index'],
    # Set a new random outlet position
    mg.set_inactive_boundaries(True, True, True, True)
    #mg.set_closed_boundaries_at_grid_edges(True,True,True,True)
    random_boundary_node = random.choice(boundary_node_list)
    mg.status_at_node[random_boundary_node] = FIXED_VALUE_BOUNDARY

    # MN: Set the elevation of that random outlet boundary node to zero
    #mg['node'][ 'topographic__elevation'][random_boundary_node] = 0

    print('Random boundary node',  random_boundary_node)


    #instantiate the components:
    fr = FlowAccumulator(mg, flow_director='D8')
    sp = FastscapeEroder(mg, input_file)

    time_on = time()

    #perform the inner time loops:
    for i in range(nt):
        mg['node']['topographic__elevation'][mg.core_nodes] += uplift_per_step
        mg = fr.run_one_step()
        mg = sp.erode(mg)

        #plot long profiles along channels
        pylab.figure(6)
        profile_IDs = prf.channel_nodes(mg, mg.at_node['topographic__steepest_slope'],
                mg.at_node['drainage_area'], mg.at_node['flow__upstream_node_order'],
                mg.at_node['flow__receiver_node'])
        dists_upstr = prf.get_distances_upstream(mg, len(mg.at_node['topographic__steepest_slope']),
Пример #29
0
# create the fields in the grid
mg.add_zeros("topographic__elevation", at="node")
z = mg.zeros(at="node") + init_elev
mg["node"]["topographic__elevation"] = z + numpy.random.rand(len(z)) / 1000.

# make some K values in a field to test
mg.at_node["K_values"] = 0.1 + numpy.random.rand(nrows * ncols) / 10.

print("Running ...")

# instantiate the components:
fr = FlowAccumulator(mg, flow_director="D8")
sp = StreamPowerEroder(mg, "./drive_sp_params.txt")
# load the Fastscape module too, to allow direct comparison
fsp = FastscapeEroder(mg, "./drive_sp_params.txt")

# perform the loop:
elapsed_time = 0.  # total time in simulation
while elapsed_time < time_to_run:
    print(elapsed_time)
    if elapsed_time + dt > time_to_run:
        print("Short step!")
        dt = time_to_run - elapsed_time
    mg = fr.run_one_step()
    # print 'Area: ', numpy.max(mg.at_node['drainage_area'])
    # mg = fsp.erode(mg)
    mg = fsp.erode(mg, K_if_used="K_values")
    # mg,_,_ = sp.erode(mg, dt, node_drainage_areas='drainage_area', slopes_at_nodes='topographic__steepest_slope')
    # add uplift
    mg.at_node["topographic__elevation"][mg.core_nodes] += uplift * dt
Пример #30
0
grid = RasterModelGrid((125, 125), xy_spacing=v0)
grid.set_status_at_node_on_edges(
    right=grid.BC_NODE_IS_CLOSED,
    top=grid.BC_NODE_IS_CLOSED,
    left=grid.BC_NODE_IS_FIXED_VALUE,
    bottom=grid.BC_NODE_IS_CLOSED,
)
z = grid.add_zeros('node', 'topographic__elevation')
z[:] = 0.1 * hg * np.random.rand(len(z))

fa = FlowAccumulator(grid,
                     surface='topographic__elevation',
                     flow_director='D8',
                     depression_finder='LakeMapperBarnes')
ld = LinearDiffuser(grid, D)
sp = FastscapeEroder(grid, K_sp=Ksp, m_sp=0.5, n_sp=1.0)

for i in range(N):

    z[grid.core_nodes] += U * dt

    ld.run_one_step(dt)
    fa.run_one_step()
    sp.run_one_step(dt)

    # print('completed loop %d'%i)

    if i % output_interval == 0:
        print('finished iteration %d' % i)
        filename = base_path + '%d_grid_%d.nc' % (ID, i)
        to_netcdf(grid, filename, include="at_node:topographic__elevation")
Пример #31
0
mean_elev   = [] #mean elevation within model area
max_elev    = [] #maximum elevation within model area
min_elev    = [] #minimum elevation within model area
vegi_P_mean = [] #mostly for bugfixing because Manu is stupid fuckup without brain and life and f**k you
mean_SD     = [] #mean soil depth

##---------------------------------Component initialization---------------------#
#sp = StreamPowerEroder(mg,
#                       K_sp = Kv,
#                       m_sp = msp,
#                       n_sp = nsp,
#                       threshold_sp=thresholdSP)

fc = FastscapeEroder(mg,
                    K_sp = Kv,
                    m_sp = msp,
                    n_sp = nsp,
                    threshold_sp = 0,
                    rainfall_intensity = 1)

fr = FlowRouter(mg)

lm = DepressionFinderAndRouter(mg)

expw = ExponentialWeatherer(mg,
                            max_soil_production_rate = maxSoilProductionRate,
                            soil_production_decay_depth = soilProductionDepth)

dld  = DepthDependentDiffuser(mg,
                              linear_diffusivity = linDiff,
                              soil_transport_decay_depth = soilTransportDepth)
Пример #32
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
    coords={
        'x': (
Пример #33
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)
        

mg.set_watershed_boundary_condition(z,remove_disconnected=True)
Пример #34
0
                               mean_storm_depth=ds,
                               total_t=Th)
pd.seed_generator(seedval=1235)
ld = LinearDiffuser(grid, linear_diffusivity=D)

#initialize other models
hm = HydrologyEventStreamPower(
    grid,
    precip_generator=pd,
    groundwater_model=gdp,
)

#use surface_water_area_norm__discharge (Q/sqrt(A)) for Theodoratos definitions
sp = FastscapeEroder(grid,
                     K_sp=Ksp,
                     m_sp=1,
                     n_sp=1,
                     discharge_field="surface_water_area_norm__discharge")
rm = RegolithConstantThickness(grid, equilibrium_depth=b, uplift_rate=U)

mdl = StreamPowerModel(
    grid,
    hydrology_model=hm,
    diffusion_model=ld,
    erosion_model=sp,
    regolith_model=rm,
    morphologic_scaling_factor=ksf,
    maximum_morphological_dt=dtg_max,
    total_morphological_time=Tg,
    verbose=False,
    output_dict=output,
## 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)