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
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
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
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)
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)
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)
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 )
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)
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)
def example_flow_director(example_nmg): fd = FlowDirectorSteepest(example_nmg) fd.run_one_step() return fd
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
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)
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')
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')
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