def test_no_reroute():
    mg = RasterModelGrid((5, 5), xy_spacing=2.0)
    z = mg.add_zeros("topographic__elevation", at="node", dtype=float)
    z[1] = -1.0
    z[6] = -2.0
    z[19] = -2.0
    z[18] = -1.0
    z[17] = -3.0
    fd = FlowDirectorSteepest(mg)
    fa = FlowAccumulator(mg)
    lmb = LakeMapperBarnes(
        mg,
        method="Steepest",
        fill_flat=True,
        redirect_flow_steepest_descent=True,
        track_lakes=True,
    )
    openq = StablePriorityQueue()

    lake_dict = {1: deque([6]), 18: deque([17])}
    fd.run_one_step()  # fill the director fields
    fa.run_one_step()  # get a drainage_area
    orig_surf = lmb._track_original_surface()
    lmb._redirect_flowdirs(orig_surf, lake_dict, openq)

    assert mg.at_node["flow__receiver_node"][6] == 1
    assert mg.at_node["flow__receiver_node"][17] == 18
    assert mg.at_node["flow__receiver_node"][18] == 19
Exemple #2
0
def test_no_reroute():
    mg = RasterModelGrid((5, 5), 2.)
    z = mg.add_zeros('node', 'topographic__elevation', dtype=float)
    z[1] = -1.
    z[6] = -2.
    z[19] = -2.
    z[18] = -1.
    z[17] = -3.
    fd = FlowDirectorSteepest(mg)
    fa = FlowAccumulator(mg)
    lmb = LakeMapperBarnes(mg,
                           method='Steepest',
                           fill_flat=True,
                           redirect_flow_steepest_descent=True,
                           track_lakes=True)

    lake_dict = {
        1: deque([
            6,
        ]),
        18: deque([
            17,
        ])
    }
    fd.run_one_step()  # fill the director fields
    fa.run_one_step()  # get a drainage_area
    orig_surf = lmb._track_original_surface()
    lmb._redirect_flowdirs(orig_surf, lake_dict)

    assert mg.at_node['flow__receiver_node'][6] == 1
    assert mg.at_node['flow__receiver_node'][17] == 18
    assert mg.at_node['flow__receiver_node'][18] == 19
Exemple #3
0
def test_no_reroute():
    mg = RasterModelGrid((5, 5), xy_spacing=2.)
    z = mg.add_zeros("node", "topographic__elevation", dtype=float)
    z[1] = -1.
    z[6] = -2.
    z[19] = -2.
    z[18] = -1.
    z[17] = -3.
    fd = FlowDirectorSteepest(mg)
    fa = FlowAccumulator(mg)
    lmb = LakeMapperBarnes(
        mg,
        method="Steepest",
        fill_flat=True,
        redirect_flow_steepest_descent=True,
        track_lakes=True,
    )

    lake_dict = {1: deque([6]), 18: deque([17])}
    fd.run_one_step()  # fill the director fields
    fa.run_one_step()  # get a drainage_area
    orig_surf = lmb._track_original_surface()
    lmb._redirect_flowdirs(orig_surf, lake_dict)

    assert mg.at_node["flow__receiver_node"][6] == 1
    assert mg.at_node["flow__receiver_node"][17] == 18
    assert mg.at_node["flow__receiver_node"][18] == 19
Exemple #4
0
def test_drainage_area():
    """Test that correct error is raised when no flow__upstream_node_order."""
    mg = RasterModelGrid(30, 70)
    mg.add_ones("node", "topographic__elevation")
    mg.add_ones("node", "flow__upstream_node_order")
    fd = FlowDirectorSteepest(mg)
    fd.run_one_step()
    with pytest.raises(FieldError):
        calculate_distance_to_divide(mg)
    def __init__(self, grid, routing_method):

        self._grid = grid

        if routing_method == "D8":
            self.fd = FlowDirectorD8(self._grid)
        elif routing_method == "Steepest":
            self.fd = FlowDirectorSteepest(self._grid)
        else:
            raise ValueError("routing_method must be either D8 or Steepest.")

        self.fa = FlowAccumulator(
            self._grid,
            surface="topographic__elevation",
            flow_director=self.fd,
            runoff_rate="average_surface_water__specific_discharge",
        )
        self.lmb = LakeMapperBarnes(
            self._grid,
            method=routing_method,
            fill_flat=False,
            surface="topographic__elevation",
            fill_surface="topographic__elevation",
            redirect_flow_steepest_descent=False,
            reaccumulate_flow=False,
            track_lakes=False,
            ignore_overfill=True,
        )
        self.dfr = DepressionFinderAndRouter(self._grid)
Exemple #6
0
def test_no_upstream_array():
    """Test that correct error is raised when no flow__upstream_node_order."""

    # instantiate a model grid, do not run flow accumulation on it

    mg = RasterModelGrid(30, 70)

    #Add a field called topographic__elevation to mg

    z = mg.add_ones('node','topographic__elevation')

    #Run the FlowDirectorSteepest component

    fd = FlowDirectorSteepest(mg)
    fd.run_one_step()

    # test that the flow distance utility will fail because of a ValueError

    assert_raises(FieldError, calculate_flow__distance, mg)
Exemple #7
0
def test_tl_hill_diff():
    """Test cases where S>Sc, S=Sc and S<Sc"""

    # Test cases where S>Sc, S=Sc and S<Sc
    # Set up a 3x16 grid with closed boundaries and initial elevations.
    mg = RasterModelGrid((3, 12))
    z = np.array(
        [
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            5.0,
            1.9,
            1.9,
            1.9,
            1.9,
            1.3,
            1.3,
            1.3,
            1.3,
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
        ]
    )
    mg.add_field("topographic__elevation", z, at="node")
    mg.set_closed_boundaries_at_grid_edges(True, True, True, True)

    # Parameter values for test
    k = 0.001
    Sc = 0.6

    # Instantiate flow director and tl hillslope diffuser
    fdir = FlowDirectorSteepest(mg)
    tl_diff = TransportLengthHillslopeDiffuser(mg, erodibility=k, slope_crit=Sc)

    # Run flow director
    fdir.run_one_step()

    # test slopes
    s_out = mg.at_node["topographic__steepest_slope"]
    s_test = np.array(
        [
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            3.1,
            0.0,
            0.0,
            0.0,
            0.6,
            0.0,
            0.0,
            0.0,
            0.3,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
        ]
    )
    assert_almost_equal(s_out, s_test, decimal=10)

    # Run tl hillslope diffusion component
    tl_diff.run_one_step(1.0)

    # Test results
    # flux_out
    fo_test = np.array(
        [
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.025,
            0.0,
            0.0,
            0.0,
            0.0006,
            0.0,
            0.0,
            0.0,
            0.0003,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
        ]
    )
    fo_out = mg.at_node["sediment__flux_out"]
    assert_almost_equal(fo_out, fo_test, decimal=10)

    # updated elevation
    elev_test = np.array(
        [
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            4.975,
            1.9,
            1.9,
            1.9,
            1.8994,
            1.3,
            1.3,
            1.3,
            1.2997,
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
        ]
    )
    elev_out = mg.at_node["topographic__elevation"]
    assert_almost_equal(elev_out, elev_test, decimal=10)

    # Run another time step because deposition and transfer were null
    # the first time
    fdir.run_one_step()
    tl_diff.run_one_step(1.0)

    # Test results
    # flux_out
    fo_test = np.array(
        [
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            2.47500000e-02,
            0.00000000e00,
            0.00000000e00,
            6.00000000e-07,
            5.99400000e-04,
            0.00000000e00,
            0.00000000e00,
            3.00000000e-07,
            2.99700000e-04,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
        ]
    )
    fo_out = mg.at_node["sediment__flux_out"]
    assert_almost_equal(fo_out, fo_test, decimal=10)

    # updated elevation
    elev_test = np.array(
        [
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            4.95025,
            1.925,
            1.9,
            1.8999994,
            1.8988006,
            1.3006,
            1.3,
            1.2999997,
            1.2994003,
            1.0003,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
        ]
    )
    elev_out = mg.at_node["topographic__elevation"]
    assert_almost_equal(elev_out, elev_test, decimal=10)
Exemple #8
0
def test_add_pulse():

    y_of_node = (0, 0, 0, 0)
    x_of_node = (0, 100, 200, 300)
    nodes_at_link = ((0, 1), (1, 2), (2, 3))

    nmg_constant_slope = NetworkModelGrid((y_of_node, x_of_node), nodes_at_link)

    # add variables to nmg
    nmg_constant_slope.at_node["topographic__elevation"] = [3.0, 2.0, 1.0, 0.0]
    nmg_constant_slope.at_node["bedrock__elevation"] = [3.0, 2.0, 1.0, 0.0]
    nmg_constant_slope.at_link["channel_slope"] = [0.001, 0.001, 0.001]
    nmg_constant_slope.at_link["reach_length"] = [100.0, 100.0, 100.0]  # m
    nmg_constant_slope.at_link["channel_width"] = 15 * np.ones(
        nmg_constant_slope.size("link")
    )
    nmg_constant_slope.at_link["flow_depth"] = 2 * np.ones(
        nmg_constant_slope.size("link")
    )

    flow_director = FlowDirectorSteepest(nmg_constant_slope)
    flow_director.run_one_step()

    time = [0.0]

    items = {"grid_element": "link", "element_id": np.array([[0]])}

    initial_volume = np.array([[1]])
    abrasion_rate = np.array([0])

    variables = {
        "starting_link": (["item_id"], np.array([0])),
        "abrasion_rate": (["item_id"], abrasion_rate),
        "density": (["item_id"], np.array([2650])),
        "time_arrival_in_link": (["item_id", "time"], np.array([[0.71518937]])),
        "active_layer": (["item_id", "time"], np.array([[1]])),
        "location_in_link": (["item_id", "time"], np.array([[0]])),
        "D": (["item_id", "time"], np.array([[0.05]])),
        "volume": (["item_id", "time"], initial_volume),
    }

    parcels = DataRecord(
        nmg_constant_slope,
        items=items,
        time=time,
        data_vars=variables,
        dummy_elements={"link": [NetworkSedimentTransporter.OUT_OF_NETWORK]},
    )

    nst = NetworkSedimentTransporter(
        nmg_constant_slope,
        parcels,
        flow_director,
        bed_porosity=0.03,
        g=9.81,
        fluid_density=1000,
        transport_method="WilcockCrowe",
    )

    dt = 60  # (seconds) 1 min timestep

    nst.run_one_step(dt)

    # ONE TIMESTEP BEFORE PULSE
    # TIMESTEP 1 should have NANS.

    num_pulse_parcels = 2

    newpar_element_id = np.zeros(num_pulse_parcels, dtype=int)
    newpar_element_id = np.expand_dims(newpar_element_id, axis=1)

    new_starting_link = np.squeeze(newpar_element_id)

    np.random.seed(0)

    new_time_arrival_in_link = nst._time * np.ones(np.shape(newpar_element_id))

    new_volume = 0.5 * np.ones(
        np.shape(newpar_element_id)
    )  # (m3) the volume of each parcel

    new_lithology = ["pulse_material"] * np.size(
        newpar_element_id
    )  # a lithology descriptor for each parcel

    new_active_layer = np.ones(
        np.shape(newpar_element_id)
    )  # 1 = active/surface layer; 0 = subsurface layer

    new_density = 2650 * np.ones(np.size(newpar_element_id))  # (kg/m3)

    new_location_in_link = np.random.rand(np.size(newpar_element_id), 1)

    new_abrasion_rate = 0 * np.ones(np.size(newpar_element_id))

    new_D = 0.03 * np.ones(np.shape(newpar_element_id))

    newpar_grid_elements = np.array(
        np.empty((np.shape(newpar_element_id)), dtype=object)
    )  # BUG: should be able to pass ["link"], but datarecord fills it into an incorrect array shape-- the length of parcels (NOT new parcels)
    newpar_grid_elements.fill("link")

    new_parcels = {
        "grid_element": newpar_grid_elements,
        "element_id": newpar_element_id,
    }

    new_variables = {
        "starting_link": (["item_id"], new_starting_link),
        "abrasion_rate": (["item_id"], new_abrasion_rate),
        "density": (["item_id"], new_density),
        "lithology": (["item_id"], new_lithology),
        "time_arrival_in_link": (["item_id", "time"], new_time_arrival_in_link),
        "active_layer": (["item_id", "time"], new_active_layer),
        "location_in_link": (["item_id", "time"], new_location_in_link),
        "D": (["item_id", "time"], new_D),
        "volume": (["item_id", "time"], new_volume),
    }

    parcels.add_item(
        time=[nst._time], new_item=new_parcels, new_item_spec=new_variables
    )

    nst.run_one_step(dt)

    print(parcels.dataset.element_id.values)
    Parcel_element_id = parcels.dataset.element_id.values

    Parcel_element_id_Should_Be = np.array(
        [[0.0, 0.0, 0.0], [np.nan, 0.0, 0.0], [np.nan, 0.0, 0.0]]
    )

    assert_array_almost_equal(
        Parcel_element_id_Should_Be, Parcel_element_id, decimal=-1
    )
Exemple #9
0
def test_defined_parcel_transport():

    y_of_node = (0, 0, 0, 0)
    x_of_node = (0, 100, 200, 300)
    nodes_at_link = ((0, 1), (1, 2), (2, 3))

    nmg_constant_slope = NetworkModelGrid((y_of_node, x_of_node),
                                          nodes_at_link)

    # add variables to nmg
    nmg_constant_slope.at_node["topographic__elevation"] = [3.0, 2.0, 1.0, 0.0]
    nmg_constant_slope.at_node["bedrock__elevation"] = [3.0, 2.0, 1.0, 0.0]
    nmg_constant_slope.at_link["channel_slope"] = [0.001, 0.001, 0.001]
    nmg_constant_slope.at_link["reach_length"] = [100.0, 100.0, 100.0]  # m
    nmg_constant_slope.at_link["channel_width"] = 15 * np.ones(
        nmg_constant_slope.size("link"))
    nmg_constant_slope.at_link["flow_depth"] = 2 * np.ones(
        nmg_constant_slope.size("link"))

    flow_director = FlowDirectorSteepest(nmg_constant_slope)
    flow_director.run_one_step()

    timesteps = 11

    time = [0.0]

    items = {"grid_element": "link", "element_id": np.array([[0]])}

    initial_volume = np.array([[1]])
    abrasion_rate = np.array([0])

    variables = {
        "starting_link": (["item_id"], np.array([0])),
        "abrasion_rate": (["item_id"], abrasion_rate),
        "density": (["item_id"], np.array([2650])),
        "time_arrival_in_link": (["item_id",
                                  "time"], np.array([[0.71518937]])),
        "active_layer": (["item_id", "time"], np.array([[1]])),
        "location_in_link": (["item_id", "time"], np.array([[0]])),
        "D": (["item_id", "time"], np.array([[0.05]])),
        "volume": (["item_id", "time"], initial_volume),
    }

    one_parcel = DataRecord(
        nmg_constant_slope,
        items=items,
        time=time,
        data_vars=variables,
        dummy_elements={"link": [NetworkSedimentTransporter.OUT_OF_NETWORK]},
    )

    nst = NetworkSedimentTransporter(
        nmg_constant_slope,
        one_parcel,
        flow_director,
        bed_porosity=0.03,
        g=9.81,
        fluid_density=1000,
        transport_method="WilcockCrowe",
    )

    dt = 60  # (seconds) 1 min timestep

    distance_traveled = np.arange(0.0, timesteps)
    # distance_traveled = np.arange(0.,timesteps)

    for t in range(0, (timesteps * dt), dt):
        nst.run_one_step(dt)
        distance_traveled[np.int(t / dt)] = nst._distance_traveled_cumulative
    # NEED TO CALCULATE THINGS HERE.
    # Transport distance should match?
    Distance_Traveled_Should_Be = [
        21.61998527,
        43.23997054,
        64.85995581,
        86.47994109,
        108.09992636,
        129.71991163,
        151.3398969,
        172.95988217,
        194.57986744,
        216.19985272,
        237.81983799,
    ]

    assert_array_almost_equal(Distance_Traveled_Should_Be,
                              distance_traveled,
                              decimal=-1)
Exemple #10
0
def test_tl_hill_diff():
    """Test cases where S>Sc, S=Sc and S<Sc"""

    # Test cases where S>Sc, S=Sc and S<Sc
    # Set up a 3x16 grid with closed boundaries and initial elevations.
    mg = RasterModelGrid((3, 12))
    z = np.array(
        [
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            5.0,
            1.9,
            1.9,
            1.9,
            1.9,
            1.3,
            1.3,
            1.3,
            1.3,
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
        ]
    )
    mg.add_field("node", "topographic__elevation", z)
    mg.set_closed_boundaries_at_grid_edges(True, True, True, True)

    # Parameter values for test
    k = 0.001
    Sc = 0.6

    # Instantiate flow director and tl hillslope diffuser
    fdir = FlowDirectorSteepest(mg)
    tl_diff = TransportLengthHillslopeDiffuser(mg, erodibility=k, slope_crit=Sc)

    # Run flow director
    fdir.run_one_step()

    # test slopes
    s_out = mg.at_node["topographic__steepest_slope"]
    s_test = np.array(
        [
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            3.1,
            0.0,
            0.0,
            0.0,
            0.6,
            0.0,
            0.0,
            0.0,
            0.3,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
        ]
    )
    assert_almost_equal(s_out, s_test, decimal=10)

    # Run tl hillslope diffusion component
    tl_diff.run_one_step(1.0)

    # Test results
    # flux_out
    fo_test = np.array(
        [
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.025,
            0.0,
            0.0,
            0.0,
            0.0006,
            0.0,
            0.0,
            0.0,
            0.0003,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
        ]
    )
    fo_out = mg.at_node["sediment__flux_out"]
    assert_almost_equal(fo_out, fo_test, decimal=10)

    # updated elevation
    elev_test = np.array(
        [
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            4.975,
            1.9,
            1.9,
            1.9,
            1.8994,
            1.3,
            1.3,
            1.3,
            1.2997,
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
        ]
    )
    elev_out = mg.at_node["topographic__elevation"]
    assert_almost_equal(elev_out, elev_test, decimal=10)

    # Run another time step because deposition and transfer were null
    # the first time
    fdir.run_one_step()
    tl_diff.run_one_step(1.0)

    # Test results
    # flux_out
    fo_test = np.array(
        [
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            2.47500000e-02,
            0.00000000e00,
            0.00000000e00,
            6.00000000e-07,
            5.99400000e-04,
            0.00000000e00,
            0.00000000e00,
            3.00000000e-07,
            2.99700000e-04,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
            0.00000000e00,
        ]
    )
    fo_out = mg.at_node["sediment__flux_out"]
    assert_almost_equal(fo_out, fo_test, decimal=10)

    # updated elevation
    elev_test = np.array(
        [
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            4.95025,
            1.925,
            1.9,
            1.8999994,
            1.8988006,
            1.3006,
            1.3,
            1.2999997,
            1.2994003,
            1.0003,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
            0.0,
        ]
    )
    elev_out = mg.at_node["topographic__elevation"]
    assert_almost_equal(elev_out, elev_test, decimal=10)
Exemple #11
0
def example_flow_director(example_nmg):

    fd = FlowDirectorSteepest(example_nmg)
    fd.run_one_step()
    return fd
Exemple #12
0
def methow():
    example_data_dir = ExampleData("io/shapefile", case="methow").base
    shp_file = example_data_dir / "MethowSubBasin.shp"
    points_shapefile = example_data_dir / "MethowSubBasin_Nodes_4.shp"

    grid2 = read_shapefile(
        shp_file,
        points_shapefile=points_shapefile,
        node_fields=["usarea_km2", "Elev_m"],
        link_fields=["usarea_km2", "Length_m"],
        link_field_conversion={
            "usarea_km2": "drainage_area",
            "Slope": "channel_slope",
            "Length_m": "reach_length",
        },
        node_field_conversion={
            "usarea_km2": "drainage_area",
            "Elev_m": "topographic__elevation",
        },
        threshold=0.01,
    )
    grid2.at_node["bedrock__elevation"] = grid2.at_node[
        "topographic__elevation"].copy()
    grid2.at_link["channel_width"] = 1 * np.ones(grid2.number_of_links)
    grid2.at_link["flow_depth"] = 0.5 * np.ones(grid2.number_of_links)

    # element_id is the link on which the parcel begins.
    element_id = np.repeat(np.arange(grid2.number_of_links), 50)
    element_id = np.expand_dims(element_id, axis=1)

    volume = 1 * np.ones(np.shape(element_id))  # (m3)
    active_layer = np.ones(np.shape(element_id))  # 1= active, 0 = inactive
    density = 2650 * np.ones(np.size(element_id))  # (kg/m3)
    abrasion_rate = 0 * np.ones(np.size(element_id))  # (mass loss /m)

    # Lognormal GSD
    medianD = 0.15  # m
    mu = np.log(medianD)
    sigma = np.log(2)  # assume that D84 = sigma*D50
    np.random.seed(0)
    D = np.random.lognormal(
        mu, sigma,
        np.shape(element_id))  # (m) the diameter of grains in each parcel

    time_arrival_in_link = np.random.rand(np.size(element_id), 1)
    location_in_link = np.random.rand(np.size(element_id), 1)

    lithology = ["quartzite"] * np.size(element_id)

    variables = {
        "abrasion_rate": (["item_id"], abrasion_rate),
        "density": (["item_id"], density),
        "lithology": (["item_id"], lithology),
        "time_arrival_in_link": (["item_id", "time"], time_arrival_in_link),
        "active_layer": (["item_id", "time"], active_layer),
        "location_in_link": (["item_id", "time"], location_in_link),
        "D": (["item_id", "time"], D),
        "volume": (["item_id", "time"], volume),
    }

    items = {"grid_element": "link", "element_id": element_id}

    parcels2 = DataRecord(
        grid2,
        items=items,
        time=[0.0],
        data_vars=variables,
        dummy_elements={"link": [NetworkSedimentTransporter.OUT_OF_NETWORK]},
    )

    fd2 = FlowDirectorSteepest(grid2, "topographic__elevation")
    fd2.run_one_step()

    nst2 = NetworkSedimentTransporter(
        grid2,
        parcels2,
        fd2,
        bed_porosity=0.3,
        g=9.81,
        fluid_density=1000,
        transport_method="WilcockCrowe",
    )
    timesteps = 2  # total number of timesteps
    dt = 60 * 60 * 24 * 1  # length of timestep (seconds)
    for t in range(0, (timesteps * dt), dt):
        nst2.run_one_step(dt)

    return nst2
Exemple #13
0
def test_first_in_last_out():
    y_of_node = (0, 0, 0, 0, 0, 0)
    x_of_node = (0, 100, 200, 300, 400, 500)
    nodes_at_link = ((0, 1), (1, 2), (2, 3), (3, 4), (4, 5))

    nmg_constant_slope = NetworkModelGrid((y_of_node, x_of_node), nodes_at_link)

    # add variables to nmg
    nmg_constant_slope.at_node["topographic__elevation"] = [
        5.0,
        4.0,
        3.0,
        2.0,
        1.0,
        0.0,
    ]
    nmg_constant_slope.at_node["bedrock__elevation"] = [5.0, 4.0, 3.0, 2.0, 1.0, 0.0]
    nmg_constant_slope.at_link["channel_slope"] = [0.001, 0.001, 0.001, 0.001, 0.001]
    nmg_constant_slope.at_link["flow_depth"] = [1.75, 1.75, 1.75, 1.75, 1.75]
    nmg_constant_slope.at_link["reach_length"] = [
        100.0,
        100.0,
        100.0,
        100.0,
        100.0,
    ]  # m
    nmg_constant_slope.at_link["channel_width"] = 15 * np.ones(
        nmg_constant_slope.size("link")
    )

    flow_director = FlowDirectorSteepest(nmg_constant_slope)
    flow_director.run_one_step()

    timesteps = 20

    time = [0.0]

    element_id = np.zeros(100, dtype=int)
    element_id = np.expand_dims(element_id, axis=1)

    items = {"grid_element": "link", "element_id": element_id}

    abrasion_rate = np.zeros(np.size(element_id))
    initial_volume = np.ones(np.shape(element_id))
    time_arrival_in_link = np.arange(0, 0.1, 0.001)
    time_arrival_in_link = np.expand_dims(time_arrival_in_link, axis=1)

    variables = {
        "starting_link": (["item_id"], np.squeeze(element_id)),
        "abrasion_rate": (["item_id"], abrasion_rate),
        "density": (["item_id"], 2650 * np.ones(np.size(element_id))),
        "time_arrival_in_link": (["item_id", "time"], time_arrival_in_link),
        "active_layer": (["item_id", "time"], initial_volume),
        "location_in_link": (["item_id", "time"], element_id),
        "D": (["item_id", "time"], initial_volume * 0.05),
        "volume": (["item_id", "time"], initial_volume),
    }

    hundred_boring_parcels = DataRecord(
        nmg_constant_slope,
        items=items,
        time=time,
        data_vars=variables,
        dummy_elements={"link": [NetworkSedimentTransporter.OUT_OF_NETWORK]},
    )

    nst = NetworkSedimentTransporter(
        nmg_constant_slope,
        hundred_boring_parcels,
        flow_director,
        bed_porosity=0.03,
        g=9.81,
        fluid_density=1000,
        transport_method="WilcockCrowe",
    )

    dt = 60 * 60  # (seconds) 1 hour timestep

    for t in range(0, (timesteps * dt), dt):
        nst.run_one_step(dt)

    first_in_parcel = np.argmin(time_arrival_in_link)
    last_in_parcel = np.argmax(time_arrival_in_link)
    link_of_first_in_parcel = hundred_boring_parcels.dataset.element_id.values[
        first_in_parcel, :
    ]
    link_of_last_in_parcel = hundred_boring_parcels.dataset.element_id.values[
        last_in_parcel, :
    ]

    First_in_lags_behind = np.greater_equal(
        link_of_last_in_parcel, link_of_first_in_parcel
    )
    SO_TRUE = np.ones(np.shape(First_in_lags_behind), dtype=bool)

    assert_array_equal(SO_TRUE, First_in_lags_behind)
Exemple #14
0
def test_recycling():
    y_of_node = (0, 0, 0, 0)
    x_of_node = (0, 100, 200, 300)
    nodes_at_link = ((0, 1), (1, 2), (2, 3))

    nmg_constant_slope = NetworkModelGrid((y_of_node, x_of_node), nodes_at_link)

    # add variables to nmg
    nmg_constant_slope.at_node["topographic__elevation"] = [3.0, 2.0, 1.0, 0.0]
    nmg_constant_slope.at_node["bedrock__elevation"] = [3.0, 2.0, 1.0, 0.0]
    nmg_constant_slope.at_link["channel_slope"] = [0.001, 0.001, 0.001]
    nmg_constant_slope.at_link["reach_length"] = [100.0, 100.0, 100.0]  # m
    nmg_constant_slope.at_link["channel_width"] = 15 * np.ones(
        nmg_constant_slope.size("link")
    )
    nmg_constant_slope.at_link["flow_depth"] = 3 * np.ones(
        nmg_constant_slope.size("link")
    )

    flow_director = FlowDirectorSteepest(nmg_constant_slope)
    flow_director.run_one_step()

    time = [0.0]

    items = {"grid_element": "link", "element_id": np.array([[0]])}

    initial_volume = np.array([[1]])
    abrasion_rate = np.array([0])

    variables = {
        "starting_link": (["item_id"], np.array([0])),
        "abrasion_rate": (["item_id"], abrasion_rate),
        "density": (["item_id"], np.array([2650])),
        "time_arrival_in_link": (["item_id", "time"], np.array([[0.71518937]])),
        "active_layer": (["item_id", "time"], np.array([[1]])),
        "location_in_link": (["item_id", "time"], np.array([[0]])),
        "D": (["item_id", "time"], np.array([[0.05]])),
        "volume": (["item_id", "time"], initial_volume),
    }

    parcels = DataRecord(
        nmg_constant_slope,
        items=items,
        time=time,
        data_vars=variables,
        dummy_elements={"link": [NetworkSedimentTransporter.OUT_OF_NETWORK]},
    )

    nst = NetworkSedimentTransporter(
        nmg_constant_slope,
        parcels,
        flow_director,
        bed_porosity=0.03,
        g=9.81,
        fluid_density=1000,
        transport_method="WilcockCrowe",
    )

    dt = 60  # (seconds) 1 min timestep

    timesteps = 8

    for t in range(0, (timesteps * dt), dt):
        # RECYCLE sediment: what left the network gets added back in at top.
        parcels.dataset.location_in_link.values[
            parcels.dataset.element_id.values
            == NetworkSedimentTransporter.OUT_OF_NETWORK
        ] = 0
        parcels.dataset.element_id.values[
            parcels.dataset.element_id.values
            == NetworkSedimentTransporter.OUT_OF_NETWORK
        ] = 0
        nst.run_one_step(dt)

        print("done with another timestep")
        print(parcels.dataset.element_id.values)

    Parcel_element_id = parcels.dataset.element_id.values

    Parcel_element_id_Should_Be = np.array(
        [[0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 0.0, 0.0]]
    )

    assert_array_almost_equal(
        Parcel_element_id_Should_Be, Parcel_element_id, decimal=-1
    )
#ylabel('Local slope')
#title('Slope-Area plot for whole landscape')

#%%fit:
a = mg.at_node['drainage_area']
g = mg.at_node['topographic__steepest_slope']

#figure the rest out yourself!
#use log binning or the following approach: https://github.com/keflavich/plfit
figure('final slope-area plot')
loglog(a,g, '.')
xlabel('Drainage area (k**2)')
ylabel('Local slope (m/m)')

#%% Steepness finder and Chi plots
fd = FlowDirectorSteepest(mg, 'topographic__elevation')
fd.run_one_step()
fa = FlowAccumulator(mg, 'topographic__elevation', flow_director='FlowDirectorSteepest')
fa.run_one_step()
sf = SteepnessFinder(mg, reference_concavity=0.45, 
                     min_drainage_area=1e3)
sf.calculate_steepnesses()
cf = ChiFinder(mg, reference_concavity=0.45, min_drainage_area=1.e3, reference_area=1., use_true_dx=False)
cf.calculate_chi()

imshow_grid(mg, 'channel__chi_index', plot_name='Channel steepness (theta = 0.45)', var_units='norm. steepness (m^0.9)', cmap='hot', limits=(0,300))

imshow_grid(mg, 'channel__chi_index', 
            plot_name='Chi finder', var_units='norm. steepness (m^0.9)', cmap='hot', limits=(0,300))

scatter(mg.x_of_node[da_outlet_idx], mg.y_of_node[da_outlet_idx], c='red', marker='x', label='outlet')
Exemple #16
0
    Z = mg.at_node[surface].reshape(mg.shape)
    color = cm.gray((Z - Z.min()) / (Z.max() - Z.min()))
    surf = ax.plot_surface(mg.node_x.reshape(mg.shape),
                           mg.node_y.reshape(mg.shape),
                           Z,
                           rstride=1,
                           cstride=1,
                           facecolors=color,
                           linewidth=0.,
                           antialiased=False)
    ax.view_init(elev=35, azim=-120)
    ax.set_xlabel('X axis')
    ax.set_ylabel('Y axis')
    ax.set_zlabel('Elevation')
    plt.title(title)
    plt.show()


mg1 = RasterModelGrid((10, 10), spacing=(1, 1))
_ = mg1.add_field('topographic__elevation', mg1.node_y, at='node')
surf_plot(mg1, title='Grid 1: A basic ramp')
fd = FlowDirectorSteepest(mg1, 'topographic__elevation')

fd.run_one_step()

receivers = fd.direct_flow()

print(receivers)

drainage_plot(mg1, title='Basic Ramp using FlowDirectorSteepest')
Exemple #17
0
def synthetic():
    y_of_node = (0, 100, 200, 200, 300, 400, 400, 125)
    x_of_node = (0, 0, 100, -50, -100, 50, -150, -100)

    nodes_at_link = ((1, 0), (2, 1), (1, 7), (3, 1), (3, 4), (4, 5), (4, 6))

    grid1 = NetworkModelGrid((y_of_node, x_of_node), nodes_at_link)
    grid1.at_node["topographic__elevation"] = [
        0.0,
        0.08,
        0.25,
        0.15,
        0.25,
        0.4,
        0.8,
        0.8,
    ]
    grid1.at_node["bedrock__elevation"] = [
        0.0, 0.08, 0.25, 0.15, 0.25, 0.4, 0.8, 0.8
    ]
    grid1.at_link["flow_depth"] = 2.5 * np.ones(grid1.number_of_links)
    grid1.at_link["channel_slope"] = np.ones(
        grid1.number_of_links)  # AP ?? Does it get overwritten?? check
    grid1.at_link["reach_length"] = 200 * np.ones(grid1.number_of_links)  # m
    grid1.at_link["channel_width"] = 1 * np.ones(grid1.number_of_links)

    # element_id is the link on which the parcel begins.
    element_id = np.repeat(np.arange(grid1.number_of_links), 30)
    element_id = np.expand_dims(element_id, axis=1)

    volume = 0.05 * np.ones(np.shape(element_id))  # (m3)
    active_layer = np.ones(np.shape(element_id))  # 1= active, 0 = inactive
    density = 2650 * np.ones(np.size(element_id))  # (kg/m3)
    abrasion_rate = 0 * np.ones(np.size(element_id))  # (mass loss /m)

    # Lognormal GSD
    medianD = 0.085  # m
    mu = np.log(medianD)
    sigma = np.log(2)  # assume that D84 = sigma*D50
    np.random.seed(0)
    D = np.random.lognormal(
        mu, sigma,
        np.shape(element_id))  # (m) the diameter of grains in each parcel

    time_arrival_in_link = np.random.rand(np.size(element_id), 1)
    location_in_link = np.random.rand(np.size(element_id), 1)

    lithology = ["quartzite"] * np.size(element_id)

    variables = {
        "abrasion_rate": (["item_id"], abrasion_rate),
        "density": (["item_id"], density),
        "lithology": (["item_id"], lithology),
        "time_arrival_in_link": (["item_id", "time"], time_arrival_in_link),
        "active_layer": (["item_id", "time"], active_layer),
        "location_in_link": (["item_id", "time"], location_in_link),
        "D": (["item_id", "time"], D),
        "volume": (["item_id", "time"], volume),
    }

    items = {"grid_element": "link", "element_id": element_id}

    parcels1 = DataRecord(
        grid1,
        items=items,
        time=[0.0],
        data_vars=variables,
        dummy_elements={"link": [NetworkSedimentTransporter.OUT_OF_NETWORK]},
    )

    fd1 = FlowDirectorSteepest(grid1, "topographic__elevation")
    fd1.run_one_step()

    nst1 = NetworkSedimentTransporter(
        grid1,
        parcels1,
        fd1,
        bed_porosity=0.3,
        g=9.81,
        fluid_density=1000,
        transport_method="WilcockCrowe",
    )
    timesteps = 2  # total number of timesteps
    dt = 60 * 60 * 24 * 1  # length of timestep (seconds)
    for t in range(0, (timesteps * dt), dt):
        nst1.run_one_step(dt)

    return nst1