def test_sp_discharges_new():
    input_str = os.path.join(_THIS_DIR, 'test_sp_params_discharge_new.txt')
    inputs = ModelParameterDictionary(input_str, auto_type=True)
    nrows = 5
    ncols = 5
    dx = inputs.read_float('dx')
    dt = inputs.read_float('dt')

    mg = RasterModelGrid(nrows, ncols, dx)
    mg.add_zeros('topographic__elevation', at='node')
    z = np.array([5., 5., 0., 5., 5.,
                  5., 2., 1., 2., 5.,
                  5., 3., 2., 3., 5.,
                  5., 4., 4., 4., 5.,
                  5., 5., 5., 5., 5.])
    mg['node']['topographic__elevation'] = z

    fr = FlowAccumulator(mg, flow_director='D8')
    sp = StreamPowerEroder(mg, **inputs)

    # perform the loop (once!)
    for i in range(1):
        fr.run_one_step()
        sp.run_one_step(dt)

    z_tg = np.array([5.        ,  5.        ,  0.        ,  5.        ,
                     5.        ,  5.        ,  1.47759225,  0.43050087,
                     1.47759225,  5.        ,  5.        ,  2.32883687,
                     1.21525044,  2.32883687,  5.        ,  5.        ,
                     3.27261262,  3.07175015,  3.27261262,  5.        ,
                     5.        ,  5.        ,  5.        ,  5.        ,
                     5.        ])

    assert_array_almost_equal(mg.at_node['topographic__elevation'], z_tg)
def test_sp_discharges_new():
    input_str = os.path.join(_THIS_DIR, 'test_sp_params_discharge_new.txt')
    inputs = ModelParameterDictionary(input_str, auto_type=True)
    nrows = 5
    ncols = 5
    dx = inputs.read_float('dx')
    dt = inputs.read_float('dt')

    mg = RasterModelGrid(nrows, ncols, dx)
    mg.add_zeros('topographic__elevation', at='node')
    z = np.array([
        5., 5., 0., 5., 5., 5., 2., 1., 2., 5., 5., 3., 2., 3., 5., 5., 4., 4.,
        4., 5., 5., 5., 5., 5., 5.
    ])
    mg['node']['topographic__elevation'] = z

    fr = FlowAccumulator(mg, flow_director='D8')
    sp = StreamPowerEroder(mg, **inputs)

    # perform the loop (once!)
    for i in range(1):
        fr.run_one_step()
        sp.run_one_step(dt)

    z_tg = np.array([
        5., 5., 0., 5., 5., 5., 1.47759225, 0.43050087, 1.47759225, 5., 5.,
        2.32883687, 1.21525044, 2.32883687, 5., 5., 3.27261262, 3.07175015,
        3.27261262, 5., 5., 5., 5., 5., 5.
    ])

    assert_array_almost_equal(mg.at_node['topographic__elevation'], z_tg)
def test_route_to_multiple_error_raised_run_StreamPowerEroder():
    mg = RasterModelGrid((10, 10))
    z = mg.add_zeros("node", "topographic__elevation")
    z += mg.x_of_node + mg.y_of_node
    sp = StreamPowerEroder(mg)

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

    with pytest.raises(NotImplementedError):
        sp.run_one_step(10)
Example #4
0
def test_route_to_multiple_error_raised_run_StreamPowerEroder():
    mg = RasterModelGrid((10, 10))
    z = mg.add_zeros('node', 'topographic__elevation')
    z += mg.x_of_node + mg.y_of_node
    sp = StreamPowerEroder(mg)

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

    with pytest.raises(NotImplementedError):
        sp.run_one_step(10)
Example #5
0
def test_sp_new():
    """
    Tests new style component instantiation and run.
    """
    input_str = os.path.join(_THIS_DIR, 'drive_sp_params.txt')
    inputs = ModelParameterDictionary(input_str, auto_type=True)
    nrows = inputs.read_int('nrows')
    ncols = inputs.read_int('ncols')
    dx = inputs.read_float('dx')
    dt = inputs.read_float('dt')
    time_to_run = inputs.read_float('run_time')
    uplift = inputs.read_float('uplift_rate')
    init_elev = inputs.read_float('init_elev')

    mg = RasterModelGrid((nrows, ncols), spacing=(dx, dx))
    mg.set_closed_boundaries_at_grid_edges(False, False, True, True)

    mg.add_zeros('topographic__elevation', at='node')
    z = mg.zeros(at='node') + init_elev
    numpy.random.seed(0)
    mg['node']['topographic__elevation'] = z + \
        numpy.random.rand(len(z)) / 1000.

    fr = FlowAccumulator(mg, flow_director='D8')
    sp = StreamPowerEroder(mg, **inputs)
    elapsed_time = 0.
    while elapsed_time < time_to_run:
        if elapsed_time + dt > time_to_run:
            dt = time_to_run - elapsed_time
        fr.run_one_step()
        sp.run_one_step(dt)
        mg.at_node['topographic__elevation'][mg.core_nodes] += uplift * dt
        elapsed_time += dt

    z_trg = numpy.array([
        5.48813504e-04, 7.15189366e-04, 6.02763376e-04, 5.44883183e-04,
        4.23654799e-04, 6.45894113e-04, 1.01830760e-02, 9.58036770e-03,
        6.55865452e-03, 3.83441519e-04, 7.91725038e-04, 1.00142749e-02,
        8.80798884e-03, 5.78387585e-03, 7.10360582e-05, 8.71292997e-05,
        9.81911417e-03, 9.52243406e-03, 7.55093226e-03, 8.70012148e-04,
        9.78618342e-04, 1.00629755e-02, 8.49253798e-03, 5.33216680e-03,
        1.18274426e-04, 6.39921021e-04, 9.88956320e-03, 9.47119567e-03,
        6.43790696e-03, 4.14661940e-04, 2.64555612e-04, 1.00450743e-02,
        8.37262908e-03, 5.21540904e-03, 1.87898004e-05, 6.17635497e-04,
        9.21286940e-03, 9.34022513e-03, 7.51114450e-03, 6.81820299e-04,
        3.59507901e-04, 6.19166921e-03, 7.10456176e-03, 6.62585507e-03,
        6.66766715e-04, 6.70637870e-04, 2.10382561e-04, 1.28926298e-04,
        3.15428351e-04, 3.63710771e-04
    ])

    assert_array_almost_equal(mg.at_node['topographic__elevation'], z_trg)
Example #6
0
def test_storms():

    dt = 500.0
    uplift = 0.0001

    mean_duration = 100.0
    mean_interstorm = 400.0
    mean_depth = 5.0

    storm_run_time = 3000000.0
    delta_t = 500.0
    mg = RasterModelGrid((10, 10), xy_spacing=1000.0)

    mg.add_zeros("topographic__elevation", at="node")
    z = mg.zeros(at="node")
    mg["node"]["topographic__elevation"] = z + np.random.rand(len(z)) / 1000.0
    mg.add_zeros("water__unit_flux_in", at="node")

    precip = PrecipitationDistribution(
        mean_storm_duration=mean_duration,
        mean_interstorm_duration=mean_interstorm,
        mean_storm_depth=mean_depth,
        total_t=storm_run_time,
        delta_t=delta_t,
    )
    fr = FlowAccumulator(mg, flow_director="D8")
    sp = StreamPowerEroder(
        mg,
        K_sp=0.0001,
        m_sp=0.5,
        n_sp=1.0,
        threshold_sp=1.0,
        discharge_field="surface_water__discharge",
    )

    for (
            interval_duration,
            rainfall_rate,
    ) in precip.yield_storm_interstorm_duration_intensity():
        if rainfall_rate != 0.0:
            mg.at_node["water__unit_flux_in"].fill(rainfall_rate)
            fr.run_one_step()
            sp.run_one_step(dt)
        mg.at_node["topographic__elevation"][mg.core_nodes] += (
            uplift * interval_duration)
Example #7
0
def test_storms():
    input_file_string = os.path.join(_THIS_DIR, "drive_sp_params_storms.txt")
    inputs = ModelParameterDictionary(input_file_string, auto_type=True)
    nrows = inputs.read_int("nrows")
    ncols = inputs.read_int("ncols")
    dx = inputs.read_float("dx")
    dt = inputs.read_float("dt")
    uplift = inputs.read_float("uplift_rate")

    mean_duration = inputs.read_float("mean_storm")
    mean_interstorm = inputs.read_float("mean_interstorm")
    mean_depth = inputs.read_float("mean_depth")

    storm_run_time = inputs.read_float("storm_run_time")
    delta_t = inputs.read_float("delta_t")
    mg = RasterModelGrid(nrows, ncols, xy_spacing=dx)

    mg.add_zeros("topographic__elevation", at="node")
    z = mg.zeros(at="node")
    mg["node"]["topographic__elevation"] = z + np.random.rand(len(z)) / 1000.
    mg.add_zeros("water__unit_flux_in", at="node")

    precip = PrecipitationDistribution(
        mean_storm_duration=mean_duration,
        mean_interstorm_duration=mean_interstorm,
        mean_storm_depth=mean_depth,
        total_t=storm_run_time,
        delta_t=delta_t,
    )
    fr = FlowAccumulator(mg, flow_director="D8")
    sp = StreamPowerEroder(mg, **inputs)

    for (
        interval_duration,
        rainfall_rate,
    ) in precip.yield_storm_interstorm_duration_intensity():
        if rainfall_rate != 0.:
            mg.at_node["water__unit_flux_in"].fill(rainfall_rate)
            fr.run_one_step()
            sp.run_one_step(dt)
        mg.at_node["topographic__elevation"][mg.core_nodes] += (
            uplift * interval_duration
        )
Example #8
0
def test_storms():
    input_file_string = os.path.join(_THIS_DIR, "drive_sp_params_storms.txt")
    inputs = ModelParameterDictionary(input_file_string, auto_type=True)
    nrows = inputs.read_int("nrows")
    ncols = inputs.read_int("ncols")
    dx = inputs.read_float("dx")
    dt = inputs.read_float("dt")
    uplift = inputs.read_float("uplift_rate")

    mean_duration = inputs.read_float("mean_storm")
    mean_interstorm = inputs.read_float("mean_interstorm")
    mean_depth = inputs.read_float("mean_depth")

    storm_run_time = inputs.read_float("storm_run_time")
    delta_t = inputs.read_float("delta_t")
    mg = RasterModelGrid((nrows, ncols), xy_spacing=dx)

    mg.add_zeros("topographic__elevation", at="node")
    z = mg.zeros(at="node")
    mg["node"]["topographic__elevation"] = z + np.random.rand(len(z)) / 1000.0
    mg.add_zeros("water__unit_flux_in", at="node")

    precip = PrecipitationDistribution(
        mean_storm_duration=mean_duration,
        mean_interstorm_duration=mean_interstorm,
        mean_storm_depth=mean_depth,
        total_t=storm_run_time,
        delta_t=delta_t,
    )
    fr = FlowAccumulator(mg, flow_director="D8")
    sp = StreamPowerEroder(mg, **inputs)

    for (
            interval_duration,
            rainfall_rate,
    ) in precip.yield_storm_interstorm_duration_intensity():
        if rainfall_rate != 0.0:
            mg.at_node["water__unit_flux_in"].fill(rainfall_rate)
            fr.run_one_step()
            sp.run_one_step(dt)
        mg.at_node["topographic__elevation"][mg.core_nodes] += (
            uplift * interval_duration)
def test_sp_widths():
    input_str = os.path.join(_THIS_DIR, 'test_sp_params_widths.txt')
    inputs = ModelParameterDictionary(input_str, auto_type=True)
    nrows = 5
    ncols = 5
    dx = inputs.read_float('dx')
    dt = inputs.read_float('dt')

    mg = RasterModelGrid(nrows, ncols, dx)
    widths = np.ones(mg.number_of_nodes, dtype=float)
    mg.add_zeros('topographic__elevation', at='node')
    z = np.array([5., 5., 0., 5., 5.,
                  5., 2., 1., 2., 5.,
                  5., 3., 2., 3., 5.,
                  5., 4., 4., 4., 5.,
                  5., 5., 5., 5., 5.])
    mg['node']['topographic__elevation'] = z

    fr = FlowAccumulator(mg, flow_director='D8')
    sp = StreamPowerEroder(mg, use_W=widths, **inputs)

    # perform the loop (once!)
    for i in range(1):
        fr.run_one_step()
        sqrt_A = mg.at_node['drainage_area']**0.5
        widths[mg.core_nodes] = sqrt_A[mg.core_nodes]/sqrt_A[
            mg.core_nodes].mean()
        # so widths has mean=1.
        # note the issue with drainage_area not defined at perimeter => nans
        # if not careful...
        sp.run_one_step(dt)

    z_tg = np.array([ 5.        ,  5.        ,  0.        ,  5.        ,
                      5.        ,  5.        ,  1.37222369,  0.36876358,
                      1.37222369,  5.        ,  5.        ,  2.17408606,
                      1.07986038,  2.17408606,  5.        ,  5.        ,
                      3.08340277,  2.85288049,  3.08340277,  5.        ,
                      5.        ,  5.        ,  5.        ,  5.        ,
                      5.        ])

    assert_array_almost_equal(mg.at_node['topographic__elevation'], z_tg)
Example #10
0
def test_storms():
    input_file_string = os.path.join(_THIS_DIR, 'drive_sp_params_storms.txt')
    inputs = ModelParameterDictionary(input_file_string, auto_type=True)
    nrows = inputs.read_int('nrows')
    ncols = inputs.read_int('ncols')
    dx = inputs.read_float('dx')
    dt = inputs.read_float('dt')
    time_to_run = inputs.read_float('run_time')
    uplift = inputs.read_float('uplift_rate')

    mean_duration = inputs.read_float('mean_storm')
    mean_interstorm = inputs.read_float('mean_interstorm')
    mean_depth = inputs.read_float('mean_depth')

    storm_run_time = inputs.read_float('storm_run_time')
    delta_t = inputs.read_float('delta_t')
    mg = RasterModelGrid(nrows, ncols, dx)

    mg.add_zeros('topographic__elevation', at='node')
    z = mg.zeros(at='node')
    mg['node']['topographic__elevation'] = z + np.random.rand(len(z)) / 1000.
    mg.add_zeros('water__unit_flux_in', at='node')

    precip = PrecipitationDistribution(
        mean_storm_duration=mean_duration,
        mean_interstorm_duration=mean_interstorm,
        mean_storm_depth=mean_depth,
        total_t=storm_run_time,
        delta_t=delta_t)
    fr = FlowAccumulator(mg, flow_director='D8')
    sp = StreamPowerEroder(mg, **inputs)

    for (interval_duration, rainfall_rate) in \
            precip.yield_storm_interstorm_duration_intensity():
        if rainfall_rate != 0.:
            mg.at_node['water__unit_flux_in'].fill(rainfall_rate)
            fr.run_one_step()
            sp.run_one_step(dt)
        mg.at_node['topographic__elevation'][
            mg.core_nodes] += uplift * interval_duration
Example #11
0
def test_storms():
    input_file_string = os.path.join(_THIS_DIR, 'drive_sp_params_storms.txt')
    inputs = ModelParameterDictionary(input_file_string, auto_type=True)
    nrows = inputs.read_int('nrows')
    ncols = inputs.read_int('ncols')
    dx = inputs.read_float('dx')
    dt = inputs.read_float('dt')
    time_to_run = inputs.read_float('run_time')
    uplift = inputs.read_float('uplift_rate')

    mean_duration  = inputs.read_float('mean_storm')
    mean_interstorm  = inputs.read_float('mean_interstorm')
    mean_depth = inputs.read_float('mean_depth')

    storm_run_time  = inputs.read_float('storm_run_time')
    delta_t  = inputs.read_float('delta_t')
    mg = RasterModelGrid(nrows, ncols, dx)

    mg.add_zeros('topographic__elevation', at='node')
    z = mg.zeros(at='node')
    mg['node']['topographic__elevation'] = z + np.random.rand(len(z)) / 1000.
    mg.add_zeros('water__unit_flux_in', at='node')

    precip = PrecipitationDistribution(mean_storm_duration = mean_duration,
                                mean_interstorm_duration = mean_interstorm,
                                mean_storm_depth = mean_depth,
                                total_t = storm_run_time, delta_t = delta_t)
    fr = FlowAccumulator(mg, flow_director='D8')
    sp = StreamPowerEroder(mg, **inputs)

    for (interval_duration, rainfall_rate) in \
            precip.yield_storm_interstorm_duration_intensity():
        if rainfall_rate != 0.:
            mg.at_node['water__unit_flux_in'].fill(rainfall_rate)
            fr.run_one_step()
            sp.run_one_step(dt)
        mg.at_node['topographic__elevation'][
            mg.core_nodes] += uplift * interval_duration
Example #12
0
def test_sp_widths():
    input_str = os.path.join(_THIS_DIR, 'test_sp_params_widths.txt')
    inputs = ModelParameterDictionary(input_str, auto_type=True)
    nrows = 5
    ncols = 5
    dx = inputs.read_float('dx')
    dt = inputs.read_float('dt')

    mg = RasterModelGrid(nrows, ncols, dx)
    widths = np.ones(mg.number_of_nodes, dtype=float)
    mg.add_zeros('topographic__elevation', at='node')
    z = np.array([
        5., 5., 0., 5., 5., 5., 2., 1., 2., 5., 5., 3., 2., 3., 5., 5., 4., 4.,
        4., 5., 5., 5., 5., 5., 5.
    ])
    mg['node']['topographic__elevation'] = z

    fr = FlowAccumulator(mg, flow_director='D8')
    sp = StreamPowerEroder(mg, use_W=widths, **inputs)

    # perform the loop (once!)
    for i in range(1):
        fr.run_one_step()
        sqrt_A = mg.at_node['drainage_area']**0.5
        widths[mg.core_nodes] = sqrt_A[mg.core_nodes] / sqrt_A[
            mg.core_nodes].mean()
        # so widths has mean=1.
        # note the issue with drainage_area not defined at perimeter => nans
        # if not careful...
        sp.run_one_step(dt)

    z_tg = np.array([
        5., 5., 0., 5., 5., 5., 1.37222369, 0.36876358, 1.37222369, 5., 5.,
        2.17408606, 1.07986038, 2.17408606, 5., 5., 3.08340277, 2.85288049,
        3.08340277, 5., 5., 5., 5., 5., 5.
    ])

    assert_array_almost_equal(mg.at_node['topographic__elevation'], z_tg)
class BasicRtVs(ErosionModel):
    """
    A BasicVsRt computes erosion using linear diffusion, basic stream
    power with 2 lithologies, and Q ~ A exp( -b S / A).
    """
    def __init__(self,
                 input_file=None,
                 params=None,
                 BaselevelHandlerClass=None):
        """Initialize the BasicVsRt."""

        # Call ErosionModel's init
        super(BasicVsRt,
              self).__init__(input_file=input_file,
                             params=params,
                             BaselevelHandlerClass=BaselevelHandlerClass)
        contact_zone__width = (self._length_factor) * self.params[
            'contact_zone__width']  # has units length
        self.K_rock_sp = self.get_parameter_from_exponent('K_rock_sp')
        self.K_till_sp = self.get_parameter_from_exponent('K_till_sp')
        linear_diffusivity = (
            self._length_factor**
            2.) * self.get_parameter_from_exponent('linear_diffusivity')

        recharge_rate = (self._length_factor) * self.params[
            'recharge_rate']  # has units length per time
        soil_thickness = (self._length_factor) * self.params[
            'initial_soil_thickness']  # has units length
        K_hydraulic_conductivity = (self._length_factor) * self.params[
            'K_hydraulic_conductivity']  # has units length per time

        # Set up rock-till
        self.setup_rock_and_till(self.params['rock_till_file__name'],
                                 self.K_rock_sp, self.K_till_sp,
                                 contact_zone__width)

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

        # Add a field for effective drainage area
        if 'effective_drainage_area' in self.grid.at_node:
            self.eff_area = self.grid.at_node['effective_drainage_area']
        else:
            self.eff_area = self.grid.add_zeros('node',
                                                'effective_drainage_area')

        # Get the effective-area parameter
        self.sat_param = (K_hydraulic_conductivity * soil_thickness *
                          self.grid.dx) / (recharge_rate)

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

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

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

        Effective drainage area is defined as:

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

        where $S$ is downslope-positive steepest gradient, $A$ is drainage
        area, $R_r$ is the runoff ratio, and $\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
        self.eff_area[cores] = (
            area[cores] *
            (np.exp(-self.sat_param * slope[cores] / area[cores])))

    def setup_rock_and_till(self, file_name, rock_erody, till_erody,
                            contact_width):
        """Set up lithology handling for two layers with different erodibility.

        Parameters
        ----------
        file_name : string
            Name of arc-ascii format file containing elevation of contact
            position at each grid node (or NODATA)

        Read elevation of rock-till contact from an esri-ascii format file
        containing the basal elevation value at each node, create a field for
        erodibility.

        Some considerations here:
            1. We could represent the contact between two layers either as a
               depth below present land surface, or as an altitude. Using a
               depth would allow for vertical motion, because for a fixed
               surface, the depth remains constant while the altitude changes.
               But the depth must be updated every time the surface is eroded
               or aggrades. Using an altitude avoids having to update the
               contact position every time the surface erodes or aggrades, but
               any tectonic motion would need to be applied to the contact
               position as well. Here we'll use the altitude approach because
               this model was originally written for an application with lots
               of erosion expected but no tectonics.
        """
        from landlab.io import read_esri_ascii

        # Read input data on rock-till contact elevation
        read_esri_ascii(file_name,
                        grid=self.grid,
                        name='rock_till_contact__elevation',
                        halo=1)

        # Get a reference to the rock-till field
        self.rock_till_contact = self.grid.at_node[
            'rock_till_contact__elevation']

        # Create field for erodibility
        if 'substrate__erodibility' in self.grid.at_node:
            self.erody = self.grid.at_node['substrate__erodibility']
        else:
            self.erody = self.grid.add_zeros('node', 'substrate__erodibility')

        # Create array for erodibility weighting function
        self.erody_wt = np.zeros(self.grid.number_of_nodes)

        # Read the erodibility value of rock and till
        self.rock_erody = rock_erody
        self.till_erody = till_erody

        # Read and remember the contact zone characteristic width
        self.contact_width = contact_width

    def update_erodibility_field(self):
        """Update erodibility at each node based on elevation relative to
        contact elevation.

        To promote smoothness in the solution, the erodibility at a given point
        (x,y) is set as follows:

            1. Take the difference between elevation, z(x,y), and contact
               elevation, b(x,y): D(x,y) = z(x,y) - b(x,y). This number could
               be positive (if land surface is above the contact), negative
               (if we're well within the rock), or zero (meaning the rock-till
               contact is right at the surface).
            2. Define a smoothing function as:
                $F(D) = 1 / (1 + exp(-D/D*))$
               This sigmoidal function has the property that F(0) = 0.5,
               F(D >> D*) = 1, and F(-D << -D*) = 0.
                   Here, D* describes the characteristic width of the "contact
               zone", where the effective erodibility is a mixture of the two.
               If the surface is well above this contact zone, then F = 1. If
               it's well below the contact zone, then F = 0.
            3. Set the erodibility using F:
                $K = F K_till + (1-F) K_rock$
               So, as F => 1, K => K_till, and as F => 0, K => K_rock. In
               between, we have a weighted average.

        Translating these symbols into variable names:

            z = self.elev
            b = self.rock_till_contact
            D* = self.contact_width
            F = self.erody_wt
            K_till = self.till_erody
            K_rock = self.rock_erody
        """

        # Update the erodibility weighting function (this is "F")
        core = self.grid.core_nodes
        if self.contact_width > 0.0:
            self.erody_wt[core] = (
                1.0 /
                (1.0 + np.exp(-(self.z[core] - self.rock_till_contact[core]) /
                              self.contact_width)))
        else:
            self.erody_wt[core] = 0.0
            self.erody_wt[np.where(self.z > self.rock_till_contact)[0]] = 1.0

        # (if we're varying K through time, update that first)
        if self.opt_var_precip:
            erode_factor = self.pc.get_erodibility_adjustment_factor(
                self.model_time)
            self.till_erody = self.K_till_sp * erode_factor
            self.rock_erody = self.K_rock_sp * erode_factor

        # Calculate the effective erodibilities using weighted averaging
        self.erody[:] = (self.erody_wt * self.till_erody +
                         (1.0 - self.erody_wt) * self.rock_erody)

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

        # Update effective runoff ratio
        self.calc_effective_drainage_area()

        # Zero out effective area in flooded nodes
        self.eff_area[self.flow_router.depression_finder.flood_status ==
                      3] = 0.0

        # Update the erodibility field
        self.update_erodibility_field()

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

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

        # calculate model time
        self.model_time += dt

        # Lower outlet
        self.update_outlet(dt)

        # Check walltime
        self.check_walltime()
Example #14
0
def test_sp_discharges_new():
    dt = 1.0

    mg = RasterModelGrid((5, 5))
    mg.add_zeros("topographic__elevation", at="node")
    z = np.array([
        5.0,
        5.0,
        0.0,
        5.0,
        5.0,
        5.0,
        2.0,
        1.0,
        2.0,
        5.0,
        5.0,
        3.0,
        2.0,
        3.0,
        5.0,
        5.0,
        4.0,
        4.0,
        4.0,
        5.0,
        5.0,
        5.0,
        5.0,
        5.0,
        5.0,
    ])
    mg["node"]["topographic__elevation"] = z

    fr = FlowAccumulator(mg, flow_director="D8")
    sp = StreamPowerEroder(mg, K_sp=0.5, m_sp=0.5, n_sp=1.0, threshold_sp=0.0)

    # perform the loop (once!)
    for i in range(1):
        fr.run_one_step()
        sp.run_one_step(dt)

    z_tg = np.array([
        5.0,
        5.0,
        0.0,
        5.0,
        5.0,
        5.0,
        1.47759225,
        0.43050087,
        1.47759225,
        5.0,
        5.0,
        2.32883687,
        1.21525044,
        2.32883687,
        5.0,
        5.0,
        3.27261262,
        3.07175015,
        3.27261262,
        5.0,
        5.0,
        5.0,
        5.0,
        5.0,
        5.0,
    ])

    assert_array_almost_equal(mg.at_node["topographic__elevation"], z_tg)
def test_sp_discharges_new():
    input_str = os.path.join(_THIS_DIR, "test_sp_params_discharge_new.txt")
    inputs = ModelParameterDictionary(input_str, auto_type=True)
    nrows = 5
    ncols = 5
    dx = inputs.read_float("dx")
    dt = inputs.read_float("dt")

    mg = RasterModelGrid(nrows, ncols, xy_spacing=dx)
    mg.add_zeros("topographic__elevation", at="node")
    z = np.array([
        5.0,
        5.0,
        0.0,
        5.0,
        5.0,
        5.0,
        2.0,
        1.0,
        2.0,
        5.0,
        5.0,
        3.0,
        2.0,
        3.0,
        5.0,
        5.0,
        4.0,
        4.0,
        4.0,
        5.0,
        5.0,
        5.0,
        5.0,
        5.0,
        5.0,
    ])
    mg["node"]["topographic__elevation"] = z

    fr = FlowAccumulator(mg, flow_director="D8")
    sp = StreamPowerEroder(mg, **inputs)

    # perform the loop (once!)
    for i in range(1):
        fr.run_one_step()
        sp.run_one_step(dt)

    z_tg = np.array([
        5.0,
        5.0,
        0.0,
        5.0,
        5.0,
        5.0,
        1.47759225,
        0.43050087,
        1.47759225,
        5.0,
        5.0,
        2.32883687,
        1.21525044,
        2.32883687,
        5.0,
        5.0,
        3.27261262,
        3.07175015,
        3.27261262,
        5.0,
        5.0,
        5.0,
        5.0,
        5.0,
        5.0,
    ])

    assert_array_almost_equal(mg.at_node["topographic__elevation"], z_tg)
def test_sp_discharges_old():
    input_str = os.path.join(_THIS_DIR, "test_sp_params_discharge.txt")
    inputs = ModelParameterDictionary(input_str)
    nrows = 5
    ncols = 5
    dx = inputs.read_float("dx")
    dt = inputs.read_float("dt")

    mg = RasterModelGrid(nrows, ncols, dx)
    mg.add_zeros("topographic__elevation", at="node")
    z = np.array([
        5.,
        5.,
        0.,
        5.,
        5.,
        5.,
        2.,
        1.,
        2.,
        5.,
        5.,
        3.,
        2.,
        3.,
        5.,
        5.,
        4.,
        4.,
        4.,
        5.,
        5.,
        5.,
        5.,
        5.,
        5.,
    ])
    mg["node"]["topographic__elevation"] = z

    fr = FlowAccumulator(mg, flow_director="D8")
    my_Q = mg.at_node["surface_water__discharge"]
    sp = StreamPowerEroder(mg, input_str, use_Q=my_Q)

    # perform the loop (once!)
    for i in range(1):
        fr.run_one_step()
        my_Q[:] = mg.at_node["surface_water__discharge"] * 1.
        sp.run_one_step(dt)

    z_tg = np.array([
        5.,
        5.,
        0.,
        5.,
        5.,
        5.,
        1.47759225,
        0.43050087,
        1.47759225,
        5.,
        5.,
        2.32883687,
        1.21525044,
        2.32883687,
        5.,
        5.,
        3.27261262,
        3.07175015,
        3.27261262,
        5.,
        5.,
        5.,
        5.,
        5.,
        5.,
    ])

    assert_array_almost_equal(mg.at_node["topographic__elevation"], z_tg)
class BasicVsSa(_ErosionModel):
    """
    A BasicVsSa computes erosion using depth-dependent linear diffusion, basic
    stream power, and Q ~ A exp( -c H S / A); H = soil thickness.

    This "c" parameter has dimensions of length, and is defined as
    c = K dx / R, where K is saturated hydraulic conductivity, dx is grid
    spacing, and R is recharge.
    """

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

        # Call ErosionModel's init
        super(BasicVsSa, 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
        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

        recharge_rate = (self._length_factor)*self.params['recharge_rate'] # has units length per time
        K_hydraulic_conductivity = (self._length_factor)*self.params['K_hydraulic_conductivity'] # has units length per time

        # 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)

        # Add a field for effective drainage area
        if 'effective_drainage_area' in self.grid.at_node:
            self.eff_area = self.grid.at_node['effective_drainage_area']
        else:
            self.eff_area = self.grid.add_zeros('node',
                                                'effective_drainage_area')

        # Get the effective-length parameter
        self.sat_len = (K_hydraulic_conductivity*self.grid.dx)/(recharge_rate)

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

        # Instantiate a DepthDependentDiffuser component
        self.diffuser = DepthDependentDiffuser(self.grid,
                                               linear_diffusivity=linear_diffusivity,
                                               soil_transport_decay_depth=soil_transport_decay_depth)

        self.weatherer = ExponentialWeatherer(self.grid,
                                              max_soil_production_rate=max_soil_production_rate,
                                              soil_production_decay_depth=soil_production_decay_depth)



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

        Effective drainage area is defined as:

        $A_{eff} = A \exp ( c H S / A) = A R_r$

        where $H$ is soil thickness, $S$ is downslope-positive steepest
        gradient, $A$ is drainage area, $R_r$ is the runoff ratio, and $c$ is
        the saturation length parameter.
        """

        area = self.grid.at_node['drainage_area']
        slope = self.grid.at_node['topographic__steepest_slope']
        soil = self.grid.at_node['soil__depth']
        cores = self.grid.core_nodes
        self.eff_area[cores] = (area[cores] * (np.exp(-self.sat_len
                                                      * soil[cores]
                                                      * slope[cores]
                                                      / area[cores])))

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

        # Route flow
        self.flow_router.run_one_step()

        # Update effective runoff ratio
        self.calc_effective_drainage_area()

        # Zero out effective area in flooded nodes
        self.eff_area[self.flow_router.depression_finder.flood_status==3] = 0.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)

        # We must also now erode the bedrock where relevant. If water erosion
        # into bedrock has occurred, the bedrock elevation will be higher than
        # the actual elevation, so we simply re-set bedrock elevation to the
        # lower of itself or the current elevation.
        b = self.grid.at_node['bedrock__elevation']
        b[:] = np.minimum(b, self.grid.at_node['topographic__elevation'])

        # Calculate regolith-production rate
        self.weatherer.calc_soil_prod_rate()

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

        # calculate model time
        self.model_time += dt

        # Lower outlet
        self.update_outlet(dt)

        # Check walltime
        self.check_walltime()
def test_sp_discharges_old():
    input_str = os.path.join(_THIS_DIR, "test_sp_params_discharge.txt")
    inputs = ModelParameterDictionary(input_str)
    nrows = 5
    ncols = 5
    dx = inputs.read_float("dx")
    dt = inputs.read_float("dt")

    mg = RasterModelGrid(nrows, ncols, xy_spacing=dx)
    mg.add_zeros("topographic__elevation", at="node")
    z = np.array(
        [
            5.,
            5.,
            0.,
            5.,
            5.,
            5.,
            2.,
            1.,
            2.,
            5.,
            5.,
            3.,
            2.,
            3.,
            5.,
            5.,
            4.,
            4.,
            4.,
            5.,
            5.,
            5.,
            5.,
            5.,
            5.,
        ]
    )
    mg["node"]["topographic__elevation"] = z

    fr = FlowAccumulator(mg, flow_director="D8")
    my_Q = mg.at_node["surface_water__discharge"]
    sp = StreamPowerEroder(mg, input_str, use_Q=my_Q)

    # perform the loop (once!)
    for i in range(1):
        fr.run_one_step()
        my_Q[:] = mg.at_node["surface_water__discharge"] * 1.
        sp.run_one_step(dt)

    z_tg = np.array(
        [
            5.,
            5.,
            0.,
            5.,
            5.,
            5.,
            1.47759225,
            0.43050087,
            1.47759225,
            5.,
            5.,
            2.32883687,
            1.21525044,
            2.32883687,
            5.,
            5.,
            3.27261262,
            3.07175015,
            3.27261262,
            5.,
            5.,
            5.,
            5.,
            5.,
            5.,
        ]
    )

    assert_array_almost_equal(mg.at_node["topographic__elevation"], z_tg)
                        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()
    lake.map_depressions()
    spr.run_one_step(dt, flooded_nodes=lake.lake_at_node)
    keep_running = np.mean(np.abs(zr - zr_last)) >= end_thresh
    ti += dt
    print ti/1000., 'kyr elapsed; ', np.mean(zr-zr_last) / dt * 1E6, \
          'um/yr surface uplift'
print "Convergence reached! Landscape is at steady state."

A = mg.at_node['drainage_area']#[not_edge]
A = A.reshape(ncells_side, ncells_side)
S = mg.at_node['topographic__steepest_slope']
S = S.reshape(ncells_side, ncells_side)

np.savetxt('Synthetic_data/z.txt', zr, fmt='%.2f')
np.savetxt('Synthetic_data/A.txt', A, fmt='%d')
np.savetxt('Synthetic_data/S.txt', S, fmt='%.5f')
Example #20
0
def test_sp_new():
    """
    Tests new style component instantiation and run.
    """
    input_str = os.path.join(_THIS_DIR, "drive_sp_params.txt")
    inputs = ModelParameterDictionary(input_str, auto_type=True)
    nrows = inputs.read_int("nrows")
    ncols = inputs.read_int("ncols")
    dx = inputs.read_float("dx")
    dt = inputs.read_float("dt")
    time_to_run = inputs.read_float("run_time")
    uplift = inputs.read_float("uplift_rate")
    init_elev = inputs.read_float("init_elev")

    mg = RasterModelGrid((nrows, ncols), xy_spacing=(dx, dx))
    mg.set_closed_boundaries_at_grid_edges(False, False, True, True)

    mg.add_zeros("topographic__elevation", at="node")
    z = mg.zeros(at="node") + init_elev
    numpy.random.seed(0)
    mg["node"]["topographic__elevation"] = z + numpy.random.rand(len(z)) / 1000.0

    fr = FlowAccumulator(mg, flow_director="D8")
    sp = StreamPowerEroder(mg, **inputs)
    elapsed_time = 0.0
    while elapsed_time < time_to_run:
        if elapsed_time + dt > time_to_run:
            dt = time_to_run - elapsed_time
        fr.run_one_step()
        sp.run_one_step(dt)
        mg.at_node["topographic__elevation"][mg.core_nodes] += uplift * dt
        elapsed_time += dt

    z_trg = numpy.array(
        [
            5.48813504e-04,
            7.15189366e-04,
            6.02763376e-04,
            5.44883183e-04,
            4.23654799e-04,
            6.45894113e-04,
            1.01830760e-02,
            9.58036770e-03,
            6.55865452e-03,
            3.83441519e-04,
            7.91725038e-04,
            1.00142749e-02,
            8.80798884e-03,
            5.78387585e-03,
            7.10360582e-05,
            8.71292997e-05,
            9.81911417e-03,
            9.52243406e-03,
            7.55093226e-03,
            8.70012148e-04,
            9.78618342e-04,
            1.00629755e-02,
            8.49253798e-03,
            5.33216680e-03,
            1.18274426e-04,
            6.39921021e-04,
            9.88956320e-03,
            9.47119567e-03,
            6.43790696e-03,
            4.14661940e-04,
            2.64555612e-04,
            1.00450743e-02,
            8.37262908e-03,
            5.21540904e-03,
            1.87898004e-05,
            6.17635497e-04,
            9.21286940e-03,
            9.34022513e-03,
            7.51114450e-03,
            6.81820299e-04,
            3.59507901e-04,
            6.19166921e-03,
            7.10456176e-03,
            6.62585507e-03,
            6.66766715e-04,
            6.70637870e-04,
            2.10382561e-04,
            1.28926298e-04,
            3.15428351e-04,
            3.63710771e-04,
        ]
    )

    assert_array_almost_equal(mg.at_node["topographic__elevation"], z_trg)
Example #21
0
class BasicVs(ErosionModel):
    """
    A BasicVs computes erosion using linear diffusion, basic stream
    power, and Q ~ A exp( -b S / A).

    "VSA" stands for "variable source area".
    """

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

        # Call ErosionModel's init
        super(BasicVs, 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

        recharge_rate = (self._length_factor)*self.params['recharge_rate'] # has units length per time
        soil_thickness = (self._length_factor)*self.params['initial_soil_thickness'] # has units length
        K_hydraulic_conductivity = (self._length_factor)*self.params['K_hydraulic_conductivity'] # has units length per 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.')


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

        # Add a field for effective drainage area
        if 'effective_drainage_area' in self.grid.at_node:
            self.eff_area = self.grid.at_node['effective_drainage_area']
        else:
            self.eff_area = self.grid.add_zeros('node',
                                                'effective_drainage_area')

        # Get the effective-area parameter

        self.sat_param = (K_hydraulic_conductivity*soil_thickness*self.grid.dx)/(recharge_rate)

        # Instantiate a FastscapeEroder component
        self.eroder = StreamPowerEroder(self.grid,
                                        use_Q=self.eff_area,
                                        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)


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

        Effective drainage area is defined as:

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

        where $S$ is downslope-positive steepest gradient, $A$ is drainage
        area, $R_r$ is the runoff ratio, and $\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
        self.eff_area[cores] = (area[cores] * (np.exp(-self.sat_param
                                                      * slope[cores]
                                                      / area[cores])))


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

        # Route flow
        self.flow_router.run_one_step()

        # Update effective runoff ratio
        self.calc_effective_drainage_area()

        # Zero out effective area in flooded nodes
        self.eff_area[self.flow_router.depression_finder.flood_status==3] = 0.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
                             * self.pc.get_erodibility_adjustment_factor(self.model_time))
        self.eroder.run_one_step(dt)

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

        # calculate model time
        self.model_time += dt

        # Lower outlet
        self.update_outlet(dt)

        # Check walltime
        self.check_walltime()
Example #22
0
def test_sp_old():

    uplift = 0.001
    dt = 1.0
    time_to_run = 10.0
    mg = RasterModelGrid((10, 5))
    mg.set_closed_boundaries_at_grid_edges(False, False, True, True)

    mg.add_zeros("topographic__elevation", at="node")
    z = mg.zeros(at="node")
    numpy.random.seed(0)
    mg["node"]["topographic__elevation"] = z + numpy.random.rand(len(z)) / 1000.0

    fr = FlowAccumulator(mg, flow_director="D8")
    sp = StreamPowerEroder(mg, K_sp=0.1, m_sp=0.5, n_sp=1.0, threshold_sp=0.0)
    elapsed_time = 0.0
    while elapsed_time < time_to_run:
        if elapsed_time + dt > time_to_run:
            dt = time_to_run - elapsed_time
        fr.run_one_step()
        sp.run_one_step(dt)
        mg.at_node["topographic__elevation"][mg.core_nodes] += uplift * dt
        elapsed_time += dt

    z_trg = numpy.array(
        [
            5.48813504e-04,
            7.15189366e-04,
            6.02763376e-04,
            5.44883183e-04,
            4.23654799e-04,
            6.45894113e-04,
            1.01830760e-02,
            9.58036770e-03,
            6.55865452e-03,
            3.83441519e-04,
            7.91725038e-04,
            1.00142749e-02,
            8.80798884e-03,
            5.78387585e-03,
            7.10360582e-05,
            8.71292997e-05,
            9.81911417e-03,
            9.52243406e-03,
            7.55093226e-03,
            8.70012148e-04,
            9.78618342e-04,
            1.00629755e-02,
            8.49253798e-03,
            5.33216680e-03,
            1.18274426e-04,
            6.39921021e-04,
            9.88956320e-03,
            9.47119567e-03,
            6.43790696e-03,
            4.14661940e-04,
            2.64555612e-04,
            1.00450743e-02,
            8.37262908e-03,
            5.21540904e-03,
            1.87898004e-05,
            6.17635497e-04,
            9.21286940e-03,
            9.34022513e-03,
            7.51114450e-03,
            6.81820299e-04,
            3.59507901e-04,
            6.19166921e-03,
            7.10456176e-03,
            6.62585507e-03,
            6.66766715e-04,
            6.70637870e-04,
            2.10382561e-04,
            1.28926298e-04,
            3.15428351e-04,
            3.63710771e-04,
        ]
    )

    assert_array_almost_equal(mg.at_node["topographic__elevation"], z_trg)
Example #23
0
def test_sp_voronoi():
    nnodes = 100

    np.random.seed(0)
    x = np.random.rand(nnodes)
    np.random.seed(1)
    y = np.random.rand(nnodes)
    mg = VoronoiDelaunayGrid(x, y)

    np.random.seed(2)
    z = mg.add_field(
        "topographic__elevation",
        np.random.rand(nnodes) / 10000.0,
        at="node",
        copy=False,
    )

    fr = FlowAccumulator(mg)
    spe = StreamPowerEroder(mg,
                            K_sp=0.15,
                            m_sp=0.5,
                            n_sp=1.0,
                            threshold_sp=0.0)

    for i in range(10):
        z[mg.core_nodes] += 0.01
        fr.run_one_step()
        spe.run_one_step(1.0)

    z_tg = np.array([
        4.35994902e-05,
        2.59262318e-06,
        5.49662478e-05,
        6.56738615e-03,
        4.20367802e-05,
        1.21371424e-02,
        2.16596169e-02,
        4.73320898e-02,
        6.00389761e-02,
        5.22007356e-02,
        5.37507115e-02,
        5.95794752e-02,
        5.29862904e-02,
        6.76465914e-02,
        7.31720024e-02,
        6.18730861e-02,
        8.53975293e-05,
        5.32189275e-02,
        7.34302556e-02,
        8.07385044e-02,
        5.05246090e-05,
        4.08940657e-02,
        7.39971005e-02,
        3.31915602e-02,
        6.72650419e-02,
        5.96745309e-05,
        4.72752445e-02,
        3.60359567e-02,
        7.59432065e-02,
        7.24461985e-02,
        7.80305760e-02,
        4.93866869e-02,
        8.69642467e-02,
        7.21627626e-02,
        8.96368291e-02,
        4.65142080e-02,
        6.07720217e-02,
        8.83372939e-02,
        2.35887558e-02,
        7.97616193e-02,
        8.35615355e-02,
        4.61809032e-02,
        6.34634214e-02,
        9.25711770e-02,
        4.11717225e-03,
        7.24493623e-02,
        7.97908053e-02,
        9.10375623e-02,
        9.13155023e-02,
        7.10567915e-02,
        7.35271752e-02,
        6.13091341e-02,
        9.45498463e-02,
        8.48532386e-02,
        8.82702021e-02,
        7.14969941e-02,
        2.22640943e-02,
        8.53311932e-02,
        7.49161159e-02,
        3.48837223e-02,
        9.30132692e-02,
        6.01817121e-05,
        3.87455443e-02,
        8.44673586e-02,
        9.35213577e-02,
        6.76075824e-02,
        1.58614508e-02,
        8.51346837e-02,
        8.83645680e-02,
        8.69944117e-02,
        5.04000439e-05,
        5.02319084e-02,
        8.63882765e-02,
        5.00991880e-02,
        7.65156630e-02,
        5.07591983e-02,
        6.54909962e-02,
        6.91505342e-02,
        7.33358371e-02,
        5.30109890e-02,
        2.99074601e-02,
        2.55509418e-06,
        8.21523907e-02,
        8.09368483e-02,
        4.35073025e-02,
        3.04096109e-02,
        3.26298627e-02,
        4.92259177e-02,
        5.48690358e-02,
        6.44732130e-02,
        6.28133567e-02,
        4.17977098e-06,
        5.37149677e-02,
        4.32828136e-02,
        1.30559903e-02,
        2.62405261e-02,
        2.86079272e-02,
        6.61481327e-05,
        1.70477133e-05,
        8.81652236e-05,
    ])

    assert_array_almost_equal(mg.at_node["topographic__elevation"], z_tg)
Example #24
0
def test_sp_widths():
    nrows = 5
    ncols = 5
    dt = 1

    mg = RasterModelGrid((nrows, ncols))
    widths = np.ones(mg.number_of_nodes, dtype=float)
    mg.add_zeros("topographic__elevation", at="node")
    z = np.array([
        5.0,
        5.0,
        0.0,
        5.0,
        5.0,
        5.0,
        2.0,
        1.0,
        2.0,
        5.0,
        5.0,
        3.0,
        2.0,
        3.0,
        5.0,
        5.0,
        4.0,
        4.0,
        4.0,
        5.0,
        5.0,
        5.0,
        5.0,
        5.0,
        5.0,
    ])
    mg["node"]["topographic__elevation"] = z

    fr = FlowAccumulator(mg, flow_director="D8")
    sp = StreamPowerEroder(mg,
                           channel_width_field=widths,
                           K_sp=0.5,
                           m_sp=1.0,
                           n_sp=1.0,
                           threshold_sp=0.0)

    # perform the loop (once!)
    for i in range(1):
        fr.run_one_step()
        sqrt_A = mg.at_node["drainage_area"]**0.5
        widths[mg.core_nodes] = sqrt_A[mg.core_nodes] / sqrt_A[
            mg.core_nodes].mean()
        # so widths has mean=1.
        # note the issue with drainage_area not defined at perimeter => nans
        # if not careful...
        sp.run_one_step(dt)

    z_tg = np.array([
        5.0,
        5.0,
        0.0,
        5.0,
        5.0,
        5.0,
        1.37222369,
        0.36876358,
        1.37222369,
        5.0,
        5.0,
        2.17408606,
        1.07986038,
        2.17408606,
        5.0,
        5.0,
        3.08340277,
        2.85288049,
        3.08340277,
        5.0,
        5.0,
        5.0,
        5.0,
        5.0,
        5.0,
    ])

    assert_array_almost_equal(mg.at_node["topographic__elevation"], z_tg)
def test_sp_discharges_new():
    input_str = os.path.join(_THIS_DIR, "test_sp_params_discharge_new.txt")
    inputs = ModelParameterDictionary(input_str, auto_type=True)
    nrows = 5
    ncols = 5
    dx = inputs.read_float("dx")
    dt = inputs.read_float("dt")

    mg = RasterModelGrid((nrows, ncols), xy_spacing=dx)
    mg.add_zeros("topographic__elevation", at="node")
    z = np.array(
        [
            5.0,
            5.0,
            0.0,
            5.0,
            5.0,
            5.0,
            2.0,
            1.0,
            2.0,
            5.0,
            5.0,
            3.0,
            2.0,
            3.0,
            5.0,
            5.0,
            4.0,
            4.0,
            4.0,
            5.0,
            5.0,
            5.0,
            5.0,
            5.0,
            5.0,
        ]
    )
    mg["node"]["topographic__elevation"] = z

    fr = FlowAccumulator(mg, flow_director="D8")
    sp = StreamPowerEroder(mg, **inputs)

    # perform the loop (once!)
    for i in range(1):
        fr.run_one_step()
        sp.run_one_step(dt)

    z_tg = np.array(
        [
            5.0,
            5.0,
            0.0,
            5.0,
            5.0,
            5.0,
            1.47759225,
            0.43050087,
            1.47759225,
            5.0,
            5.0,
            2.32883687,
            1.21525044,
            2.32883687,
            5.0,
            5.0,
            3.27261262,
            3.07175015,
            3.27261262,
            5.0,
            5.0,
            5.0,
            5.0,
            5.0,
            5.0,
        ]
    )

    assert_array_almost_equal(mg.at_node["topographic__elevation"], z_tg)