def test_director_adding_methods_are_equivalent_D8():
    """Check that different methods to specifying the director are the same."""

    mg0 = RasterModelGrid((10,10), spacing=(1, 1))
    z0 = mg0.add_field('topographic__elevation', mg0.node_x**2 + mg0.node_y**2, at = 'node')
    fa0 = FlowAccumulator(mg0, flow_director='D8')
    fa0.run_one_step()

    mg1 = RasterModelGrid((10,10), spacing=(1, 1))
    z1 = mg1.add_field('topographic__elevation', mg1.node_x**2 + mg1.node_y**2, at = 'node')
    fa1 = FlowAccumulator(mg1, flow_director='FlowDirectorD8')
    fa1.run_one_step()

    mg2 = RasterModelGrid((10,10), spacing=(1, 1))
    z2 = mg2.add_field('topographic__elevation', mg2.node_x**2 + mg2.node_y**2, at = 'node')
    fa2 = FlowAccumulator(mg2, flow_director=FlowDirectorD8)
    fa2.run_one_step()

    mg3 = RasterModelGrid((10,10), spacing=(1, 1))
    z3 = mg3.add_field('topographic__elevation', mg3.node_x**2 + mg3.node_y**2, at = 'node')
    fd = FlowDirectorD8(mg3)
    fa3 = FlowAccumulator(mg3, flow_director=fd)
    fa3.run_one_step()

    for key in mg0.at_node.keys():
        assert_array_equal(mg0.at_node[key],
                           mg1.at_node[key])

        assert_array_equal(mg1.at_node[key],
                           mg2.at_node[key])

        assert_array_equal(mg2.at_node[key],
                           mg3.at_node[key])
def test_netcdf_write():
    """Test generic write_netcdf."""
    if not WITH_NETCDF4:
        raise SkipTest('netCDF4 package not installed')

    field = RasterModelGrid(4, 3)
    field.add_field('node', 'topographic__elevation', np.arange(12.))

    with cdtemp() as _:
        write_netcdf('test.nc', field, format='NETCDF4')
        root = nc.Dataset('test.nc', 'r', format='NETCDF4')

        assert_equal(set(root.dimensions), set(['ni', 'nj', 'nt']))
        assert_equal(len(root.dimensions['ni']), 3)
        assert_equal(len(root.dimensions['nj']), 4)
        assert_true(len(root.dimensions['nt']), 1)
        assert_true(root.dimensions['nt'].isunlimited())

        assert_equal(set(root.variables),
                     set(['x', 'y', 'topographic__elevation']))

        assert_array_equal(root.variables['x'][:].flat,
                           np.array([0., 1., 2., 0., 1., 2., 0., 1., 2.,
                                     0., 1., 2., ]))
        assert_array_equal(root.variables['y'][:].flat,
                           np.array([0., 0., 0., 1., 1., 1., 2., 2., 2.,
                                     3., 3., 3., ]))
        assert_array_equal(root.variables['topographic__elevation'][:].flat,
                           field.at_node['topographic__elevation'])

        root.close()
Exemple #3
0
def test_save_esri_ascii(tmpdir):
    grid = RasterModelGrid((4, 5), xy_spacing=2.0)
    grid.add_field("node", "air__temperature", np.arange(20.0))

    with tmpdir.as_cwd():
        grid.save("test.asc", format="esri-ascii")
        assert os.path.isfile("test.asc")
Exemple #4
0
def test_netcdf_write_at_cells(tmpdir):
    """Test write_netcdf using with cell fields"""
    field = RasterModelGrid((4, 3))
    field.add_field("cell", "topographic__elevation", np.arange(field.number_of_cells))
    field.add_field("cell", "uplift_rate", np.arange(field.number_of_cells))

    with tmpdir.as_cwd():
        write_netcdf("test-cells.nc", field, format="NETCDF4")
        root = nc.Dataset("test-cells.nc", "r", format="NETCDF4")

        for name in ["topographic__elevation", "uplift_rate"]:
            assert name in root.variables
            assert_array_equal(root.variables[name][:].flatten(), field.at_cell[name])

        assert set(root.dimensions) == set(["nv", "ni", "nj", "nt"])
        assert len(root.dimensions["nv"]) == 4
        assert len(root.dimensions["ni"]) == 1
        assert len(root.dimensions["nj"]) == 2
        assert len(root.dimensions["nt"]) == 1
        assert root.dimensions["nt"].isunlimited()

        assert set(root.variables) == set(
            ["x_bnds", "y_bnds", "topographic__elevation", "uplift_rate"]
        )
        root.close()
def test_append_with_time(tmpdir):
    field = RasterModelGrid(4, 3)
    field.add_field("node", "topographic__elevation", np.ones(12, dtype=np.int64))

    with tmpdir.as_cwd():
        write_raster_netcdf("test.nc", field, append=False, format="NETCDF4", time=0)
        field.at_node["topographic__elevation"] *= 2
        write_raster_netcdf("test.nc", field, append=True, format="NETCDF4", time=1.)

        root = nc.Dataset("test.nc", "r", format="NETCDF4")

        for name in ["topographic__elevation"]:
            assert name in root.variables
            assert_array_equal(
                root.variables[name][:],
                [
                    [[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]],
                    [[2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2]],
                ],
            )
            assert root.variables[name][:].dtype == "int64"
            assert "nt" in root.dimensions
            assert len(root.dimensions["nt"]) == 2

        assert "t" in root.variables
        assert_array_equal(root.variables["t"][:], [0., 1.])

        root.close()
Exemple #6
0
def sink_grid4():
    """
    Create a 10x10 test grid with two well defined holes in it, into an
    inclined surface. This time, one of the holes is a stupid shape, which
    will require the component to arrange flow back "uphill".
    """
    sink_grid = RasterModelGrid((10, 10), xy_spacing=1.0)

    lake1 = np.array([34, 35, 36, 44, 45, 46, 54, 55, 56, 65, 74])
    lake2 = np.array([78, 87, 88])
    guard_nodes = np.array([23, 33, 53, 63, 73, 83])
    lake = np.concatenate((lake1, lake2))
    # outlet = 35  # shouldn't be needed
    # outlet_array = np.array([outlet])

    z = np.ones(100, dtype=float)
    # add slope
    z += sink_grid.node_x
    z[guard_nodes] += 0.001  # forces the flow out of a particular node
    z[lake] = 0.0

    # depr_outlet_target = np.empty(100, dtype=float)
    # depr_outlet_target.fill(XX)
    # depr_outlet_target = XX  # not well defined in this simplest case...?

    sink_grid.add_field("node", "topographic__elevation", z, units="-")
    sink_grid.lake1 = lake1
    sink_grid.lake2 = lake2

    return sink_grid
def test_netcdf_write():
    if not WITH_NETCDF4:
        raise SkipTest("netCDF4 package not installed")

    field = RasterModelGrid(4, 3)
    field.add_field("node", "topographic__elevation", np.arange(12.0))

    with cdtemp() as _:
        write_netcdf("test.nc", field, format="NETCDF4")
        root = nc.Dataset("test.nc", "r", format="NETCDF4")

        assert_equal(set(root.dimensions), set(["ni", "nj", "nt"]))
        assert_equal(len(root.dimensions["ni"]), 3)
        assert_equal(len(root.dimensions["nj"]), 4)
        assert_true(len(root.dimensions["nt"]), 1)
        assert_true(root.dimensions["nt"].isunlimited())

        assert_equal(set(root.variables), set(["x", "y", "topographic__elevation"]))

        assert_array_equal(
            root.variables["x"][:].flat, np.array([0.0, 1.0, 2.0, 0.0, 1.0, 2.0, 0.0, 1.0, 2.0, 0.0, 1.0, 2.0])
        )
        assert_array_equal(
            root.variables["y"][:].flat, np.array([0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0])
        )
        assert_array_equal(root.variables["topographic__elevation"][:].flat, field.at_node["topographic__elevation"])

        root.close()
Exemple #8
0
def test_netcdf_write(tmpdir):
    """Test generic write_netcdf."""
    field = RasterModelGrid(4, 3)
    field.add_field("node", "topographic__elevation", np.arange(12.))

    with tmpdir.as_cwd():
        write_netcdf("test.nc", field, format="NETCDF4")
        root = nc.Dataset("test.nc", "r", format="NETCDF4")

        assert set(root.dimensions) == set(["ni", "nj", "nt"])
        assert len(root.dimensions["ni"]) == 3
        assert len(root.dimensions["nj"]) == 4
        assert len(root.dimensions["nt"]) == 1
        assert root.dimensions["nt"].isunlimited()

        assert set(root.variables) == set(["x", "y", "topographic__elevation"])

        assert_array_equal(
            root.variables["x"][:].flatten(),
            np.array([0., 1., 2., 0., 1., 2., 0., 1., 2., 0., 1., 2.]),
        )
        assert_array_equal(
            root.variables["y"][:].flatten(),
            np.array([0., 0., 0., 1., 1., 1., 2., 2., 2., 3., 3., 3.]),
        )
        assert_array_equal(
            root.variables["topographic__elevation"][:].flatten(),
            field.at_node["topographic__elevation"],
        )

        root.close()
def test_names_keyword_with_bad_name(tmpdir):
    grid = RasterModelGrid((4, 5), spacing=(2., 2.))
    grid.add_field('node', 'air__temperature', np.arange(20.))

    with tmpdir.as_cwd():
        with pytest.raises(ValueError):
            write_esri_ascii('test.asc', grid, names='not_a_name')
def test_netcdf_write_at_cells():
    """Test write_netcdf using with cell fields"""
    if not WITH_NETCDF4:
        raise SkipTest("netCDF4 package not installed")

    field = RasterModelGrid((4, 3))
    field.add_field("cell", "topographic__elevation", np.arange(field.number_of_cells))
    field.add_field("cell", "uplift_rate", np.arange(field.number_of_cells))

    with cdtemp() as _:
        write_netcdf("test-cells.nc", field, format="NETCDF4")
        root = nc.Dataset("test-cells.nc", "r", format="NETCDF4")

        for name in ["topographic__elevation", "uplift_rate"]:
            assert_true(name in root.variables)
            assert_array_equal(root.variables[name][:].flat, field.at_cell[name])

        assert_equal(set(root.dimensions), set(["nv", "ni", "nj", "nt"]))
        assert_equal(len(root.dimensions["nv"]), 4)
        assert_equal(len(root.dimensions["ni"]), 1)
        assert_equal(len(root.dimensions["nj"]), 2)
        assert_true(len(root.dimensions["nt"]), 1)
        assert_true(root.dimensions["nt"].isunlimited())

        assert_equal(set(root.variables), set(["x_bnds", "y_bnds", "topographic__elevation", "uplift_rate"]))
        root.close()
def test_error_for_to_many_with_depression():
    """Check that an error is thrown when to_many methods started DF."""

    mg0 = RasterModelGrid((10, 10), xy_spacing=(1, 1))
    mg0.add_field(
        "topographic__elevation", mg0.node_x ** 2 + mg0.node_y ** 2, at="node"
    )

    mg1 = RasterModelGrid((10, 10), xy_spacing=(1, 1))
    mg1.add_field(
        "topographic__elevation", mg1.node_x ** 2 + mg1.node_y ** 2, at="node"
    )

    with pytest.raises(NotImplementedError):
        LossyFlowAccumulator(
            mg0, flow_director="MFD", depression_finder="DepressionFinderAndRouter"
        )
    with pytest.raises(NotImplementedError):
        LossyFlowAccumulator(
            mg0, flow_director="DINF", depression_finder="DepressionFinderAndRouter"
        )

    fa0 = LossyFlowAccumulator(mg0, flow_director="MFD")
    fa0.run_one_step()
    with pytest.raises(NotImplementedError):
        DepressionFinderAndRouter(mg0)

    fa1 = LossyFlowAccumulator(mg1, flow_director="DINF")
    fa1.run_one_step()
    with pytest.raises(NotImplementedError):
        DepressionFinderAndRouter(mg1)
Exemple #12
0
def test_save_esri_ascii(tmpdir):
    grid = RasterModelGrid(4, 5, 2.)
    grid.add_field('node', 'air__temperature', np.arange(20.))

    with tmpdir.as_cwd():
        grid.save('test.asc', format='esri-ascii')
        assert os.path.isfile('test.asc')
def test_netcdf_write():
    field = RasterModelGrid(4, 3)
    #field.new_field_location('node', 12.)
    values = np.arange(12.)
    field.add_field('node', 'planet_surface__elevation', values)

    write_netcdf('test.nc', field)

    import netCDF4 as nc

    root = nc.Dataset('test.nc', 'r', format='NETCDF4')
    assert_equal(set(root.dimensions), set(['ni', 'nj', 'nt']))
    assert_equal(len(root.dimensions['ni']), 3)
    assert_equal(len(root.dimensions['nj']), 4)
    assert_true(len(root.dimensions['nt']), 1)
    assert_true(root.dimensions['nt'].isunlimited())

    assert_equal(set(root.variables),
                 set(['x', 'y', 'planet_surface__elevation']))

    assert_list_equal(list(root.variables['x'][:].flat),
                      [0., 1., 2.,
                       0., 1., 2.,
                       0., 1., 2.,
                       0., 1., 2., ])
    assert_list_equal(list(root.variables['y'][:].flat),
                      [0., 0., 0.,
                       1., 1., 1.,
                       2., 2., 2.,
                       3., 3., 3., ])
    assert_list_equal(
        list(root.variables['planet_surface__elevation'][:].flat),
        range(12))
    root.close()
def test_run_with_2_fn_args():
    mg = RasterModelGrid((3, 5), xy_spacing=(2, 1))
    mg.set_closed_boundaries_at_grid_edges(True, True, False, True)
    mg.add_field("topographic__elevation", mg.node_x + mg.node_y, at="node")

    def mylossfunction(qw, nodeID):
        return 0.5 * qw

    fa = LossyFlowAccumulator(
        mg,
        "topographic__elevation",
        flow_director=FlowDirectorSteepest,
        routing="D4",
        loss_function=mylossfunction,
    )
    fa.run_one_step()

    assert np.allclose(
        mg.at_node["drainage_area"].reshape(mg.shape),
        np.array([[0., 0., 0., 0., 0.], [6., 6., 4., 2., 0.], [0., 0., 0., 0., 0.]]),
    )
    assert np.allclose(
        mg.at_node["surface_water__discharge"].reshape(mg.shape),
        np.array(
            [
                [0.00, 0.00, 0.00, 0.00, 0.00],
                [1.75, 3.50, 3.00, 2.00, 0.00],
                [0.00, 0.00, 0.00, 0.00, 0.00],
            ]
        ),
    )
Exemple #15
0
def setup_dans_grid2():
    """
    Create a 10x10 test grid with a well defined hole in it, from a flat
    surface.
    """
    global hf, mg
    global z, depr_outlet_target
    global lake, outlet, lake_code, outlet_array

    lake = np.array([44, 45, 46, 54, 55, 56, 64, 65, 66])
    outlet = 35  # shouldn't be needed
    lake_code = 44
    outlet_array = np.array([outlet])

    mg = RasterModelGrid(10, 10, 1.)

    z = np.ones(100, dtype=float)
    z[lake] = 0.

    depr_outlet_target = np.empty(100, dtype=float)
    depr_outlet_target.fill(XX)
    depr_outlet_target = XX  # not well defined in this simplest case...?

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

    hf = SinkFiller(mg)
Exemple #16
0
def setup_dans_grid3():
    """
    Create a 10x10 test grid with two well defined holes in it, into an
    inclined surface.
    """
    global hf, fr, mg
    global z, depr_outlet_target
    global lake, lake1, lake2, outlet, outlet_array, rcvr

    lake1 = np.array([34, 35, 36, 44, 45, 46, 54, 55, 56])
    lake2 = np.array([77, 78, 87, 88])
    guard_nodes = np.array([23, 33, 53, 63])
    lake = np.concatenate((lake1, lake2))
    outlet = 35  # shouldn't be needed
    outlet_array = np.array([outlet])

    mg = RasterModelGrid(10, 10, 1.)

    z = np.ones(100, dtype=float)
    # add slope
    z += mg.node_x
    z[guard_nodes] += 0.001
    z[lake] = 0.

    depr_outlet_target = np.empty(100, dtype=float)
    depr_outlet_target.fill(XX)
    depr_outlet_target = XX  # not well defined in this simplest case...?

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

    fr = FlowRouter(mg)
Exemple #17
0
def setup_dans_grid4():
    """
    Create a 10x10 test grid with two well defined holes in it, into an
    inclined surface. This time, one of the holes is a stupid shape, which
    will require the component to arrange flow back "uphill".
    """
    global hf, fr, mg
    global z, depr_outlet_target
    global lake, lake1, lake2, outlet, outlet_array

    lake1 = np.array([34, 35, 36, 44, 45, 46, 54, 55, 56, 65, 74])
    lake2 = np.array([78, 87, 88])
    guard_nodes = np.array([23, 33, 53, 63, 73, 83])
    lake = np.concatenate((lake1, lake2))
    outlet = 35  # shouldn't be needed
    outlet_array = np.array([outlet])

    mg = RasterModelGrid(10, 10, 1.)

    z = np.ones(100, dtype=float)
    # add slope
    z += mg.node_x
    z[guard_nodes] += 0.001  # forces the flow out of a particular node
    z[lake] = 0.

    depr_outlet_target = np.empty(100, dtype=float)
    depr_outlet_target.fill(XX)
    depr_outlet_target = XX  # not well defined in this simplest case...?

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

    fr = FlowRouter(mg)
def test_names_keyword_with_bad_name(tmpdir):
    grid = RasterModelGrid((4, 5), xy_spacing=(2.0, 2.0))
    grid.add_field("node", "air__temperature", np.arange(20.0))

    with tmpdir.as_cwd():
        with pytest.raises(ValueError):
            write_esri_ascii("test.asc", grid, names="not_a_name")
def test_names_keyword_with_bad_name():
    grid = RasterModelGrid((4, 5), spacing=(2., 2.))
    grid.add_field('node', 'air__temperature', np.arange(20.))

    with cdtemp() as _:
        assert_raises(ValueError, write_esri_ascii, 'test.asc', grid,
                      names='not_a_name')
Exemple #20
0
def read_netcdf(nc_file, reshape=False, just_grid=False):
    """
    Reads the NetCDF file *nc_file*, and writes it to the fields of a new
    RasterModelGrid, which it then returns.
    Check the names of the fields in the returned grid with
    grid.at_nodes.keys().
    """
    try:
        root = nc.netcdf_file(nc_file, 'r', version=2)
    except TypeError:
        root = nc4.Dataset(nc_file, 'r', format='NETCDF4')

    shape = _read_netcdf_grid_shape(root)
    spacing = _read_netcdf_grid_spacing(root)

    assert(len(shape) == 2)
    assert(len(spacing) == 2)
    if spacing[0] != spacing[1]:
        raise NotRasterGridError()

    grid = RasterModelGrid(num_rows=shape[0], num_cols=shape[1], dx=spacing[0])

    if not just_grid:
        fields = _read_netcdf_structured_data(root)
        for (name, values) in fields.items():
            grid.add_field('node', name, values)

    root.close()

    return grid
def test_with_time_netcdf3(tmpdir):
    field = RasterModelGrid((4, 3))
    field.add_field("node", "topographic__elevation", 2.0 * np.arange(12.0))
    field.add_field("node", "uplift_rate", 2.0 * np.arange(12.0))

    with tmpdir.as_cwd():
        write_raster_netcdf("test.nc", field, format="NETCDF3_64BIT", time=10.0)

        root = nc.Dataset("test.nc", "r", format="NETCDF3_64BIT")

        for name in ["uplift_rate", "topographic__elevation"]:
            assert name in root.variables
            assert_array_equal(
                root.variables[name][:],
                [
                    [
                        [0.0, 2.0, 4.0],
                        [6.0, 8.0, 10.0],
                        [12.0, 14.0, 16.0],
                        [18.0, 20.0, 22.0],
                    ]
                ],
            )
            assert "nt" in root.dimensions
            assert len(root.dimensions["nt"]) == 1

        assert "t" in root.variables
        assert_array_equal(root.variables["t"][:], [10.0])

        root.close()
def setup_D4_grid():
    """
    Test functionality of routing when D4 is specified.
    
    The elevation field in this test looks like:
    
    1   2   3   4   5   6   7
    
    1   2   3   0   5   0   7
    
    1   2   3   4   0   0   7
    
    1   2   3   0   5   6   7
    
    1   2   0   0   0   6   7
    
    1   2   3   0   5   6   7
    
    1   2   3   4   5   6   7
    """
    global frD8, frD4, lfD8, lfD4, mg1, mg2
    global z, lake_nodes

    mg1 = RasterModelGrid(7, 7, 1.)
    mg2 = RasterModelGrid(7, 7, 1.)
    z = mg1.node_x.copy() + 1.
    lake_nodes = np.array([10, 16, 17, 18, 24, 32, 33, 38, 40])
    z[lake_nodes] = 0.
    mg1.add_field('node', 'topographic__elevation', z, units='-')
    mg2.add_field('node', 'topographic__elevation', z, units='-')

    frD8 = FlowRouter(mg1, method='D8')
    frD4 = FlowRouter(mg2, method='D4')
    lfD8 = DepressionFinderAndRouter(mg1, routing='D8')
    lfD4 = DepressionFinderAndRouter(mg2, routing='D4')
Exemple #23
0
def test_add_field_at_corners():
    """Test add a field to corners."""
    grid = RasterModelGrid((4, 5))
    x = np.arange(grid.number_of_corners)
    grid.add_field('z', x, at='corner')

    assert_array_equal(grid.at_corner['z'], x)
Exemple #24
0
def test_MFD_S_slope_w_diag():
    mg = RasterModelGrid((10, 10))
    mg.add_field("topographic__elevation", mg.node_y, at="node")
    fa = FlowAccumulator(mg, flow_director="FlowDirectorMFD", diagonals=True)
    fa.run_one_step()

    # this one should part to south west, part to south, and part to southeast
    sw_diags = mg.diagonal_adjacent_nodes_at_node[:, 2]
    se_diags = mg.diagonal_adjacent_nodes_at_node[:, 3]
    s_links = mg.adjacent_nodes_at_node[:, 3]
    node_ids = np.arange(mg.number_of_nodes)
    true_recievers = -1 * np.ones(fa.flow_director.receivers.shape)
    true_recievers[mg.core_nodes, 3] = s_links[mg.core_nodes]
    true_recievers[mg.core_nodes, 6] = sw_diags[mg.core_nodes]
    true_recievers[mg.core_nodes, 7] = se_diags[mg.core_nodes]
    true_recievers[mg.boundary_nodes, 0] = node_ids[mg.boundary_nodes]

    true_proportions = np.zeros(fa.flow_director.proportions.shape)
    true_proportions[mg.boundary_nodes, 0] = 1

    total_sum_of_slopes = 1. + 2. * (1. / 2. ** 0.5)

    true_proportions[mg.core_nodes, 3] = 1.0 / total_sum_of_slopes
    true_proportions[mg.core_nodes, 6] = (1. / 2. ** 0.5) / total_sum_of_slopes
    true_proportions[mg.core_nodes, 7] = (1. / 2. ** 0.5) / total_sum_of_slopes

    assert_array_equal(true_recievers, fa.flow_director.receivers)
    assert_array_almost_equal(true_proportions, fa.flow_director.proportions)
Exemple #25
0
def setup_dans_grid1():
    """
    Create a 7x7 test grid with a well defined hole in it.
    """
    global hf, mg
    global z, r_new, r_old, A_new, A_old, s_new, depr_outlet_target
    global lake, outlet, lake_code, outlet_array

    mg = RasterModelGrid(7, 7, 1.)

    z = np.array([0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,
                  0.0,  2.0,  2.0,  2.0,  2.0,  2.0,  0.0,
                  0.0,  2.0,  1.6,  1.5,  1.6,  2.0,  0.0,
                  0.0,  2.0,  1.7,  1.6,  1.7,  2.0,  0.0,
                  0.0,  2.0,  1.8,  2.0,  2.0,  2.0,  0.0,
                  0.0,  1.0,  0.6,  1.0,  1.0,  1.0,  0.0,
                  0.0,  0.0, -0.5,  0.0,  0.0,  0.0,  0.0]).flatten()

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

    lake = np.array([16, 17, 18, 23, 24, 25])
    outlet = 30
    lake_code = 17
    outlet_array = np.array([outlet])

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

    hf = SinkFiller(mg)
def test_grid_with_one_field():
    grid = RasterModelGrid((4, 5), spacing=(2., 2.))
    grid.add_field('node', 'air__temperature', np.arange(20.))
    with cdtemp() as _:
        files = write_esri_ascii('test.asc', grid)
        assert_list_equal(files, ['test.asc'])
        for fname in files:
            assert_true(os.path.isfile(fname))
def test_grid_with_one_field(tmpdir):
    grid = RasterModelGrid((4, 5), xy_spacing=(2.0, 2.0))
    grid.add_field("node", "air__temperature", np.arange(20.0))
    with tmpdir.as_cwd():
        files = write_esri_ascii("test.asc", grid)
        assert files == ["test.asc"]
        for fname in files:
            assert os.path.isfile(fname)
def test_grid_with_one_field(tmpdir):
    grid = RasterModelGrid((4, 5), spacing=(2., 2.))
    grid.add_field('node', 'air__temperature', np.arange(20.))
    with tmpdir.as_cwd():
        files = write_esri_ascii('test.asc', grid)
        assert files == ['test.asc']
        for fname in files:
            assert os.path.isfile(fname)
def test_instantiated_depression_finder_with_kwargs():
    mg = RasterModelGrid((5, 5), xy_spacing=(1, 1))
    mg.add_field("topographic__elevation", mg.node_x + mg.node_y, at="node")
    df = DepressionFinderAndRouter(mg)
    with pytest.raises(ValueError):
        LossyFlowAccumulator(
            mg, flow_director="D8", depression_finder=df, routing="eggs"
        )
def test_flow__distance_regular_grid_d8():
    """Test to demonstrate that flow__distance utility works as expected with
    regular grids"""

    # instantiate a model grid

    mg = RasterModelGrid((5, 4), spacing=(1, 1))

    # instantiate an elevation array

    z = np.array([[0, 0, 0, 0], [0, 21, 10, 0], [0, 31, 20, 0], [0, 32, 30, 0],
                  [0, 0, 0, 0]], dtype='float64')

    # add the elevation field to the grid

    mg.add_field('node', 'topographic__elevation', z)

    # instantiate the expected flow__distance array
    # considering flow directions calculated with D8 algorithm

    flow__distance_expected = np.array([[0, 0, 0, 0], [0, 1, 0, 0],
                                       [0, math.sqrt(2), 1, 0],
                                       [0, 1+math.sqrt(2), 2, 0], [0, 0, 0, 0]],
                                       dtype='float64')
    flow__distance_expected = np.reshape(flow__distance_expected,
                                        mg.number_of_node_rows *
                                        mg.number_of_node_columns)

    #setting boundary conditions

    mg.set_closed_boundaries_at_grid_edges(bottom_is_closed=True,
                                           left_is_closed=True,
                                           right_is_closed=True,
                                           top_is_closed=True)

    # calculating flow directions with FlowAccumulator component

    fr = FlowAccumulator(mg, flow_director='D8')
    fr.run_one_step()

    # calculating flow distance map

    flow__distance = calculate_flow__distance(mg, add_to_grid=True,
                                             noclobber=False)
    flow__distance = np.reshape(flow__distance, mg.number_of_node_rows *
                               mg.number_of_node_columns)

    # modifying the flow distance map because boundary and outlet nodes should
    # not have flow__distance value different from 0

    flow__distance[mg.boundary_nodes] = 0
    outlet_id = 6
    flow__distance[outlet_id] = 0


    # test that the flow distance utility works as expected

    assert_array_equal(flow__distance_expected, flow__distance)
def test_check_fields():
    """Check to make sure the right fields have been created.

    Check that the sizes of at least one are also correct (they are at node
    so if one is the right size, then they all should be)
    """

    mg0 = RasterModelGrid((10, 10), spacing=(1, 1))
    mg0.add_field("topographic__elevation",
                  mg0.node_x**2 + mg0.node_y**2,
                  at="node")
    _FlowDirector(mg0, "topographic__elevation")
    assert sorted(list(mg0.at_node.keys())) == [
        "flow__sink_flag",
        "topographic__elevation",
    ]
    assert np.size(
        mg0.at_node["topographic__elevation"]) == mg0.number_of_nodes

    mg1 = RasterModelGrid((10, 10), spacing=(1, 1))
    mg1.add_field("topographic__elevation",
                  mg1.node_x**2 + mg1.node_y**2,
                  at="node")
    _FlowDirectorToMany(mg1, "topographic__elevation")
    assert sorted(list(mg1.at_node.keys())) == [
        "flow__sink_flag",
        "topographic__elevation",
    ]
    assert np.size(
        mg1.at_node["topographic__elevation"]) == mg1.number_of_nodes

    mg2 = RasterModelGrid((10, 10), spacing=(1, 1))
    mg2.add_field("topographic__elevation",
                  mg2.node_x**2 + mg2.node_y**2,
                  at="node")
    _FlowDirectorToOne(mg2, "topographic__elevation")
    assert sorted(list(mg2.at_node.keys())) == [
        "flow__link_to_receiver_node",
        "flow__receiver_node",
        "flow__sink_flag",
        "topographic__elevation",
        "topographic__steepest_slope",
    ]
    assert np.size(
        mg2.at_node["topographic__elevation"]) == mg2.number_of_nodes

    mg3 = RasterModelGrid((10, 10), spacing=(1, 1))
    mg3.add_field("topographic__elevation",
                  mg3.node_x**2 + mg3.node_y**2,
                  at="node")
    FlowDirectorMFD(mg3, "topographic__elevation")
    assert sorted(list(mg3.at_node.keys())) == [
        "flow__link_to_receiver_node",
        "flow__receiver_node",
        "flow__receiver_proportions",
        "flow__sink_flag",
        "topographic__elevation",
        "topographic__steepest_slope",
    ]
    assert np.size(
        mg3.at_node["topographic__elevation"]) == mg3.number_of_nodes

    mg4 = RasterModelGrid((10, 10), spacing=(1, 1))
    mg4.add_field("topographic__elevation",
                  mg4.node_x**2 + mg4.node_y**2,
                  at="node")
    FlowDirectorDINF(mg4, "topographic__elevation")
    assert sorted(list(mg4.at_node.keys())) == [
        "flow__link_to_receiver_node",
        "flow__receiver_node",
        "flow__receiver_proportions",
        "flow__sink_flag",
        "topographic__elevation",
        "topographic__steepest_slope",
    ]
    assert np.size(
        mg4.at_node["topographic__elevation"]) == mg4.number_of_nodes

    mg5 = RasterModelGrid((10, 10), spacing=(1, 1))
    mg5.add_field("topographic__elevation",
                  mg5.node_x**2 + mg5.node_y**2,
                  at="node")
    FlowDirectorSteepest(mg5, "topographic__elevation")
    assert sorted(list(mg5.at_node.keys())) == [
        "flow__link_to_receiver_node",
        "flow__receiver_node",
        "flow__sink_flag",
        "topographic__elevation",
        "topographic__steepest_slope",
    ]
    assert np.size(
        mg5.at_node["topographic__elevation"]) == mg5.number_of_nodes

    mg6 = RasterModelGrid((10, 10), spacing=(1, 1))
    mg6.add_field("topographic__elevation",
                  mg6.node_x**2 + mg6.node_y**2,
                  at="node")
    FlowDirectorD8(mg6, "topographic__elevation")
    assert sorted(list(mg6.at_node.keys())) == [
        "flow__link_to_receiver_node",
        "flow__receiver_node",
        "flow__sink_flag",
        "topographic__elevation",
        "topographic__steepest_slope",
    ]
    assert np.size(
        mg6.at_node["topographic__elevation"]) == mg6.number_of_nodes
Exemple #32
0
def dans_grid1():
    """
    Create a 5x5 test grid.
    This is a sheet flow test.
    """
    mg = RasterModelGrid((5, 5), spacing=(10., 10.))

    this_dir = os.path.abspath(os.path.dirname(__file__))
    infile = os.path.join(this_dir, "test_fr_input.txt")

    z = mg.node_x.copy()

    Q_in = np.full(25, 2.)

    A_target = (np.array([
        [0., 0., 0., 0., 0.],
        [3., 3., 2., 1., 0.],
        [3., 3., 2., 1., 0.],
        [3., 3., 2., 1., 0.],
        [0., 0., 0., 0., 0.],
    ]).flatten() * 100.)

    frcvr_target = np.array([
        [0, 1, 2, 3, 4],
        [5, 5, 6, 7, 9],
        [10, 10, 11, 12, 14],
        [15, 15, 16, 17, 19],
        [20, 21, 22, 23, 24],
    ]).flatten()

    upids_target = np.array([
        [0, 1, 2, 3, 4],
        [5, 6, 7, 8, 9],
        [10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19],
        [20, 21, 22, 23, 24],
    ]).flatten()

    links2rcvr_target = np.full(25, XX)
    links2rcvr_target[mg.core_nodes] = np.array(
        [9, 10, 11, 18, 19, 20, 27, 28, 29])

    Q_target = A_target * 2.  # only once Q_in is used

    steepest_target = np.array([
        [0., 0., 0., 0., 0.],
        [0., 1., 1., 1., 0.],
        [0., 1., 1., 1., 0.],
        [0., 1., 1., 1., 0.],
        [0., 0., 0., 0., 0.],
    ]).flatten()

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

    class DansGrid(object):
        pass

    dans_grid = DansGrid()
    dans_grid.mg = mg
    dans_grid.z = z
    dans_grid.infile = infile
    dans_grid.A_target = A_target
    dans_grid.frcvr_target = frcvr_target
    dans_grid.upids_target = upids_target
    dans_grid.Q_target = Q_target
    dans_grid.steepest_target = steepest_target
    dans_grid.links2rcvr_target = links2rcvr_target

    return dans_grid
def setup_dans_grid():
    """
    Create a 7x7 test grid with a well defined hole in it.
    """
    from landlab import RasterModelGrid
    from landlab.components.flow_routing import (FlowRouter,
                                                 DepressionFinderAndRouter)

    global fr, lf, mg
    global z, r_new, r_old, A_new, A_old, s_new, depr_outlet_target
    global links_old, links_new

    mg = RasterModelGrid(7, 7, 1.)

    z = np.array([
        0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 2.0, 2.0, 0.0,
        0.0, 2.0, 1.6, 1.5, 1.6, 2.0, 0.0, 0.0, 2.0, 1.7, 1.6, 1.7, 2.0, 0.0,
        0.0, 2.0, 1.8, 2.0, 2.0, 2.0, 0.0, 0.0, 1.0, 0.6, 1.0, 1.0, 1.0, 0.0,
        0.0, 0.0, -0.5, 0.0, 0.0, 0.0, 0.0
    ]).flatten()

    r_old = np.array([
        0, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 13, 14, 14, 17, 17, 17, 20, 20,
        21, 21, 17, 17, 17, 27, 27, 28, 28, 37, 38, 39, 34, 34, 35, 44, 44, 44,
        46, 41, 41, 42, 43, 44, 45, 46, 47, 48
    ]).flatten()

    #    r_new = np.array([0,  1,  2,  3,  4,  5,  6,
    #                      7,  1,  2,  3,  4,  5, 13,
    #                     14, 14, 23, 23, 24, 20, 20,
    #                     21, 21, 30, 30, 24, 27, 27,
    #                     28, 28, 37, 38, 39, 34, 34,
    #                     35, 44, 44, 44, 46, 41, 41,
    #                     42, 43, 44, 45, 46, 47, 48]).flatten()

    r_new = np.array([
        0, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 13, 14, 14, 23, 24, 24, 20, 20,
        21, 21, 30, 30, 24, 27, 27, 28, 28, 37, 38, 39, 34, 34, 35, 44, 44, 44,
        46, 41, 41, 42, 43, 44, 45, 46, 47, 48
    ]).flatten()

    A_old = np.array([[
        0., 1., 1., 1., 1., 1., 0., 0., 1., 1., 1., 1., 1., 0., 1., 1., 1., 6.,
        1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 0.,
        1., 2., 2., 2., 1., 1., 0., 0., 5., 0., 2., 0., 0.
    ]]).flatten()

    #    A_new = np.array([[0.,  1.,  1.,  1.,  1.,  1.,  0.,
    #                       0.,  1.,  1.,  1.,  1.,  1.,  0.,
    #                       1.,  1.,  1.,  1.,  1.,  1.,  1.,
    #                       1.,  1.,  3.,  3.,  1.,  1.,  1.,
    #                       1.,  1.,  7.,  1.,  1.,  1.,  1.,
    #                       0.,  1.,  8.,  2.,  2.,  1.,  1.,
    #                       0.,  0., 11.,  0.,  2.,  0.,  0.]]).flatten()

    A_new = np.array([[
        0., 1., 1., 1., 1., 1., 0., 0., 1., 1., 1., 1., 1., 0., 1., 1., 1., 1.,
        1., 1., 1., 1., 1., 2., 4., 1., 1., 1., 1., 1., 7., 1., 1., 1., 1., 0.,
        1., 8., 2., 2., 1., 1., 0., 0., 11., 0., 2., 0., 0.
    ]]).flatten()

    #    s_new = np.array([0,  1,  8,  2,  9,  3, 10,
    #                      4, 11,  5, 12,  6,  7, 13,
    #                     14, 15, 20, 19, 21, 22, 27,
    #                     26, 28, 29, 34, 33, 35, 41,
    #                     40, 42, 43, 44, 36, 37, 30,
    #                     23, 16, 17, 24, 18, 25, 38,
    #                     31, 45, 46, 39, 32, 47, 48]).flatten()

    s_new = np.array([
        0, 1, 8, 2, 9, 3, 10, 4, 11, 5, 12, 6, 7, 13, 14, 15, 20, 19, 21, 22,
        27, 26, 28, 29, 34, 33, 35, 41, 40, 42, 43, 44, 36, 37, 30, 23, 16, 24,
        17, 18, 25, 38, 31, 45, 46, 39, 32, 47, 48
    ]).flatten()

    links_old = np.array([
        -1, -1, -1, -1, -1, -1, -1, -1, 7, 8, 9, 10, 11, -1, -1, 26, 28, -1,
        29, 31, -1, -1, 39, 113, 35, 114, 44, -1, -1, 52, 60, 61, 62, 57, -1,
        -1, 146, 73, 149, 75, 70, -1, -1, -1, -1, -1, -1, -1, -1
    ]).flatten()

    #    links_new = np.array([-1,  -1,  -1,  -1,  -1,  -1,  -1,
    #                          -1,   7,   8,   9,  10,  11,  -1,
    #                          -1,  26,  34, 113, 115,  31,  -1,
    #                          -1,  39,  47, 125,  42,  44,  -1,
    #                          -1,  52,  60,  61,  62,  57,  -1,
    #                          -1, 146,  73, 149,  75,  70,  -1,
    #                          -1,  -1,  -1,  -1,  -1,  -1,  -1]).flatten()

    links_new = np.array([
        -1, -1, -1, -1, -1, -1, -1, -1, 7, 8, 9, 10, 11, -1, -1, 26, 34, 35,
        115, 31, -1, -1, 39, 47, 125, 42, 44, -1, -1, 52, 60, 61, 62, 57, -1,
        -1, 146, 73, 149, 75, 70, -1, -1, -1, -1, -1, -1, -1, -1
    ]).flatten()

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

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

    fr = FlowRouter(mg)
    lf = DepressionFinderAndRouter(mg)
def test_flow_accumulator_properties():
    mg = RasterModelGrid((5, 5), xy_spacing=(1, 1))
    mg.add_field("topographic__elevation", mg.node_x + mg.node_y, at="node")
    fa = LossyFlowAccumulator(mg)
    fa.run_one_step()

    node_drainage_area = np.array(
        [
            0.,
            3.,
            3.,
            3.,
            0.,
            0.,
            3.,
            3.,
            3.,
            0.,
            0.,
            2.,
            2.,
            2.,
            0.,
            0.,
            1.,
            1.,
            1.,
            0.,
            0.,
            0.,
            0.,
            0.,
            0.,
        ]
    )

    node_order_upstream = np.array(
        [
            0,
            1,
            6,
            11,
            16,
            2,
            7,
            12,
            17,
            3,
            8,
            13,
            18,
            4,
            5,
            9,
            10,
            14,
            15,
            19,
            20,
            21,
            22,
            23,
            24,
        ]
    )

    assert_array_equal(fa.node_order_upstream, node_order_upstream)
    assert_array_equal(fa.node_water_discharge, node_drainage_area)
    assert_array_equal(fa.node_drainage_area, node_drainage_area)
def test_field_name_array_float_case4():
    """Topography as array, runoff rate as float"""
    mg = RasterModelGrid((5, 4), xy_spacing=(1, 1))
    topographic__elevation = np.array(
        [
            0.,
            0.,
            0.,
            0.,
            0.,
            21.,
            10.,
            0.,
            0.,
            31.,
            20.,
            0.,
            0.,
            32.,
            30.,
            0.,
            0.,
            0.,
            0.,
            0.,
        ]
    )
    mg.add_field("node", "topographic__elevation", topographic__elevation)
    mg.set_closed_boundaries_at_grid_edges(True, True, True, False)

    fa = LossyFlowAccumulator(mg, topographic__elevation, runoff_rate=10.)
    assert_array_equal(
        mg.at_node["water__unit_flux_in"], 10. * np.ones(mg.size("node"))
    )

    fa.run_one_step()
    reciever = np.array(
        [0, 1, 2, 3, 4, 1, 2, 7, 8, 10, 6, 11, 12, 14, 10, 15, 16, 17, 18, 19]
    )

    da = np.array(
        [0., 1., 5., 0., 0., 1., 5., 0., 0., 1., 4., 0., 0., 1., 2., 0., 0., 0., 0., 0.]
    )

    q = np.array(
        [
            0.,
            10.,
            50.,
            0.,
            0.,
            10.,
            50.,
            0.,
            0.,
            10.,
            40.,
            0.,
            0.,
            10.,
            20.,
            0.,
            0.,
            0.,
            0.,
            0.,
        ]
    )

    assert_array_equal(mg.at_node["flow__receiver_node"], reciever)
    assert_array_equal(mg.at_node["drainage_area"], da)
    assert_array_equal(mg.at_node["surface_water__discharge"], q)
Exemple #36
0
def dans_grid3():
    """
    Create a 7x7 test grid with a well defined hole in it.
    """
    mg = RasterModelGrid(7, 7, 1.)

    z = np.array([
        [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        [0.0, 2.0, 2.0, 2.0, 2.0, 2.0, 0.0],
        [0.0, 2.0, 1.6, 1.5, 1.6, 2.0, 0.0],
        [0.0, 2.0, 1.7, 1.6, 1.7, 2.0, 0.0],
        [0.0, 2.0, 1.8, 2.0, 2.0, 2.0, 0.0],
        [0.0, 1.0, 0.6, 1.0, 1.0, 1.0, 0.0],
        [0.0, 0.0, -0.5, 0.0, 0.0, 0.0, 0.0],
    ]).flatten()

    r_old = np.array([
        [0, 1, 2, 3, 4, 5, 6],
        [7, 1, 2, 3, 4, 5, 13],
        [14, 14, 17, 17, 17, 20, 20],
        [21, 21, 17, 17, 17, 27, 27],
        [28, 28, 37, 38, 39, 34, 34],
        [35, 44, 44, 44, 46, 41, 41],
        [42, 43, 44, 45, 46, 47, 48],
    ]).flatten()

    r_new = np.array([
        [0, 1, 2, 3, 4, 5, 6],
        [7, 1, 2, 3, 4, 5, 13],
        [14, 14, 23, 24, 24, 20, 20],
        [21, 21, 30, 30, 24, 27, 27],
        [28, 28, 37, 38, 39, 34, 34],
        [35, 44, 44, 44, 46, 41, 41],
        [42, 43, 44, 45, 46, 47, 48],
    ]).flatten()

    A_old = np.array([
        [0., 1., 1., 1., 1., 1., 0.],
        [0., 1., 1., 1., 1., 1., 0.],
        [1., 1., 1., 6., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1., 1., 1.],
        [0., 1., 2., 2., 2., 1., 1.],
        [0., 0., 5., 0., 2., 0., 0.],
    ]).flatten()

    A_new = np.array([
        [0., 1., 1., 1., 1., 1., 0.],
        [0., 1., 1., 1., 1., 1., 0.],
        [1., 1., 1., 1., 1., 1., 1.],
        [1., 1., 2., 4., 1., 1., 1.],
        [1., 1., 7., 1., 1., 1., 1.],
        [0., 1., 8., 2., 2., 1., 1.],
        [0., 0., 11., 0., 2., 0., 0.],
    ]).flatten()

    s_new = np.array([
        [0, 1, 8, 2, 9, 3, 10],
        [4, 11, 5, 12, 6, 7, 13],
        [14, 15, 20, 19, 21, 22, 27],
        [26, 28, 29, 34, 33, 35, 41],
        [40, 42, 43, 44, 36, 37, 30],
        [23, 16, 24, 17, 18, 25, 38],
        [31, 45, 46, 39, 32, 47, 48],
    ]).flatten()

    links_old = np.array([
        [-1, -1, -1, -1, -1, -1, -1],
        [-1, 7, 8, 9, 10, 11, -1],
        [-1, 26, 28, -1, 29, 31, -1],
        [-1, 39, 113, 35, 114, 44, -1],
        [-1, 52, 60, 61, 62, 57, -1],
        [-1, 146, 73, 149, 75, 70, -1],
        [-1, -1, -1, -1, -1, -1, -1],
    ]).flatten()

    links_new = np.array([
        [-1, -1, -1, -1, -1, -1, -1],
        [-1, 7, 8, 9, 10, 11, -1],
        [-1, 26, 34, 35, 115, 31, -1],
        [-1, 39, 47, 125, 42, 44, -1],
        [-1, 52, 60, 61, 62, 57, -1],
        [-1, 146, 73, 149, 75, 70, -1],
        [-1, -1, -1, -1, -1, -1, -1],
    ]).flatten()

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

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

    fr = FlowAccumulator(mg, flow_director='D8')
    lf = DepressionFinderAndRouter(mg)

    class DansGrid(object):
        pass

    dans_grid = DansGrid()
    dans_grid.mg = mg
    dans_grid.fr = fr
    dans_grid.lf = lf
    dans_grid.z = z
    dans_grid.r_new = r_new
    dans_grid.r_old = r_old
    dans_grid.A_new = A_new
    dans_grid.A_old = A_old
    dans_grid.s_new = s_new
    dans_grid.depr_outlet_target = depr_outlet_target
    dans_grid.links_old = links_old
    dans_grid.links_new = links_new

    return dans_grid
Exemple #37
0
def read_netcdf(nc_file, just_grid=False):
    """Create a :class:`~.RasterModelGrid` from a netcdf file.

    Create a new :class:`~.RasterModelGrid` from the netcdf file, *nc_file*.
    If the netcdf file also contains data, add that data to the grid's fields.
    To create a new grid without any associated data from the netcdf file,
    set the *just_grid* keyword to ``True``.

    Parameters
    ----------
    nc_file : str
        Name of a netcdf file.
    just_grid : boolean, optional
        Create a new grid but don't add value data.

    Returns
    -------
    :class:`~.RasterModelGrid`
        A newly-created :class:`~.RasterModelGrid`.

    Examples
    --------
    Import :func:`read_netcdf` and the path to an example netcdf file included
    with landlab.

    >>> from landlab.io.netcdf import read_netcdf
    >>> from landlab.io.netcdf import NETCDF4_EXAMPLE_FILE

    Create a new grid from the netcdf file. The example grid is a uniform
    rectilinear grid with 4 rows and 3 columns of nodes with unit spacing.
    The data file also contains data defined at the nodes for the grid for
    a variable called, *surface__elevation*.

    >>> grid = read_netcdf(NETCDF4_EXAMPLE_FILE)
    >>> grid.shape == (4, 3)
    True
    >>> grid.dy, grid.dx
    (1.0, 1.0)
    >>> [str(k) for k in grid.at_node.keys()]
    ['surface__elevation']
    >>> grid.at_node['surface__elevation']
    array([  0.,   1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.,
            11.])

    :func:`read_netcdf` will try to determine the format of the netcdf file.
    For example, the same call will also work for *netcdf3*-formatted files.

    >>> from landlab.io.netcdf import NETCDF3_64BIT_EXAMPLE_FILE
    >>> grid = read_netcdf(NETCDF3_64BIT_EXAMPLE_FILE)
    >>> grid.shape == (4, 3)
    True
    >>> grid.dy, grid.dx
    (1.0, 1.0)
    """
    from landlab import RasterModelGrid

    try:
        root = nc.netcdf_file(nc_file, 'r', version=2)
    except TypeError:
        root = nc4.Dataset(nc_file, 'r', format='NETCDF4')

    node_coords = _read_netcdf_structured_grid(root)

    assert len(node_coords) == 2

    spacing = _get_raster_spacing(node_coords)

    shape = node_coords[0].shape

    grid = RasterModelGrid(shape, spacing=spacing)

    if not just_grid:
        fields = _read_netcdf_structured_data(root)
        for (name, values) in fields.items():
            grid.add_field('node', name, values)

    root.close()

    return grid
Exemple #38
0
dt = inputs.read_float('dt') 
run_time = inputs.read_float('run_time') 
uplift = inputs.read_float('uplift_rate') 
initial_slope = inputs.read_float('initial_slope') 
nt = int(run_time//dt) #this is how many loops we'll need


#Build the grid
mg = RasterModelGrid(x, y, dx) #sp

# Load topography output rotated from WRF-Hydro and add to topography field
# Since the discharge files were created on the WRF-Hydro topography, we use that topography as our input. The original Landlab topography and the WRF-Hydro topography are almost identical, with only slight differences created by the rotation.
topo=Dataset('topography_wrf_hydro.nc')
topography=topo.variables['TOPOGRAPHY'][:]
topographic__elevation=np.asarray(topography, dtype=float).ravel()
mg.add_field('node', 'topographic__elevation', topographic__elevation) #create the field


#set boundary conditions -- these should match those used in the topography creation driver
for edge in (mg.nodes_at_left_edge, mg.nodes_at_right_edge):
    mg.status_at_node[edge] = CLOSED_BOUNDARY
for edge in (mg.nodes_at_top_edge, mg.nodes_at_bottom_edge):
    mg.status_at_node[edge] = FIXED_VALUE_BOUNDARY

#instantiate the components
fr = FlowRouter(mg)
sp = StreamPowerEroder(mg, input_file)
lin_diffuse = LinearDiffuser(mg, input_file)

print( 'Running ...' )
time_on = time.time()
Exemple #39
0
def test_degenerate_drainage():
    """
    This "hourglass" configuration should be one of the hardest to correctly
    re-route.
    """
    mg = RasterModelGrid((9, 5))
    z_init = mg.node_x.copy() * 0.0001 + 1.0
    lake_pits = np.array([7, 11, 12, 13, 17, 27, 31, 32, 33, 37])
    z_init[lake_pits] = -1.0
    z_init[22] = 0.0  # the common spill pt for both lakes
    z_init[21] = 0.1  # an adverse bump in the spillway
    z_init[20] = -0.2  # the spillway
    mg.add_field("topographic__elevation", z_init, at="node")

    fr = FlowAccumulator(mg, flow_director="D8")
    lf = DepressionFinderAndRouter(mg)
    fr.run_one_step()
    lf.map_depressions()

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

    correct_A = np.array([
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        1.0,
        3.0,
        1.0,
        0.0,
        0.0,
        2.0,
        4.0,
        2.0,
        0.0,
        0.0,
        1.0,
        10.0,
        1.0,
        0.0,
        21.0,
        21.0,
        1.0,
        1.0,
        0.0,
        0.0,
        1.0,
        9.0,
        1.0,
        0.0,
        0.0,
        2.0,
        2.0,
        2.0,
        0.0,
        0.0,
        1.0,
        1.0,
        1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
    ])

    assert mg.at_node["drainage_area"] == approx(correct_A)
Exemple #40
0
def test_three_pits():
    """
    A test to ensure the component correctly handles cases where there are
    multiple pits.
    """
    mg = RasterModelGrid(10, 10, 1.)
    z = mg.add_field("node", "topographic__elevation", mg.node_x.copy())
    # a sloping plane
    # np.random.seed(seed=0)
    # z += np.random.rand(100)/10000.
    # punch some holes
    z[33] = 1.
    z[43] = 1.
    z[37] = 4.
    z[74:76] = 1.
    fr = FlowRouter(mg)
    lf = DepressionFinderAndRouter(mg)
    fr.route_flow()
    lf.map_depressions()

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

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

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

    # test a couple more properties:
    lc = np.empty(100, dtype=int)
    lc.fill(XX)
    lc[33] = 33
    lc[43] = 33
    lc[37] = 37
    lc[74:76] = 74
    assert_array_equal(lf.lake_map, lc)
    assert_array_equal(lf.lake_codes, [33, 37, 74])
    assert lf.number_of_lakes == 3
    assert lf.lake_areas == approx([2., 1., 2.])
    assert lf.lake_volumes == approx([2., 2., 4.])
Exemple #41
0
def test_degenerate_drainage():
    """
    This "hourglass" configuration should be one of the hardest to correctly
    re-route.
    """
    mg = RasterModelGrid(9, 5)
    z_init = mg.node_x.copy() * 0.0001 + 1.
    lake_pits = np.array([7, 11, 12, 13, 17, 27, 31, 32, 33, 37])
    z_init[lake_pits] = -1.
    z_init[22] = 0.  # the common spill pt for both lakes
    z_init[21] = 0.1  # an adverse bump in the spillway
    z_init[20] = -0.2  # the spillway
    z = mg.add_field("node", "topographic__elevation", z_init)

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

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

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

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

    assert mg.at_node["drainage_area"] == approx(correct_A)
Exemple #42
0
def test_composite_pits():
    """
    A test to ensure the component correctly handles cases where there are
    multiple pits, inset into each other.
    """
    mg = RasterModelGrid((10, 10))
    z = mg.add_field("topographic__elevation", mg.node_x.copy(), at="node")
    # a sloping plane
    # np.random.seed(seed=0)
    # z += np.random.rand(100)/10000.
    # punch one big hole
    z.reshape((10, 10))[3:8, 3:8] = 0.0
    # dig a couple of inset holes
    z[57] = -1.0
    z[44] = -2.0
    z[54] = -10.0

    # make an outlet
    z[71] = 0.9

    fr = FlowAccumulator(mg, flow_director="D8")
    lf = DepressionFinderAndRouter(mg)
    fr.run_one_step()
    lf.map_depressions()

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

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

    # test the actual flow field:
    #    nA = np.array([  0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,
    #                     8.,   8.,   7.,   6.,   5.,   4.,   3.,   2.,   1.,   0.,
    #                     1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   0.,
    #                     1.,   1.,   1.,   4.,   2.,   2.,   8.,   4.,   1.,   0.,
    #                     1.,   1.,   1.,   8.,   3.,  15.,   3.,   2.,   1.,   0.,
    #                     1.,   1.,   1.,  13.,  25.,   6.,   3.,   2.,   1.,   0.,
    #                     1.,   1.,   1.,  45.,   3.,   3.,   5.,   2.,   1.,   0.,
    #                    50.,  50.,  49.,   3.,   2.,   2.,   2.,   4.,   1.,   0.,
    #                     1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   0.,
    #                     0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.])
    nA = np.array([
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        8.0,
        8.0,
        7.0,
        6.0,
        5.0,
        4.0,
        3.0,
        2.0,
        1.0,
        0.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        0.0,
        1.0,
        1.0,
        1.0,
        4.0,
        2.0,
        2.0,
        6.0,
        4.0,
        1.0,
        0.0,
        1.0,
        1.0,
        1.0,
        6.0,
        3.0,
        12.0,
        3.0,
        2.0,
        1.0,
        0.0,
        1.0,
        1.0,
        1.0,
        8.0,
        20.0,
        4.0,
        3.0,
        2.0,
        1.0,
        0.0,
        1.0,
        1.0,
        1.0,
        35.0,
        5.0,
        4.0,
        3.0,
        2.0,
        1.0,
        0.0,
        50.0,
        50.0,
        49.0,
        13.0,
        10.0,
        8.0,
        6.0,
        4.0,
        1.0,
        0.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
    ])
    assert_array_equal(mg.at_node["drainage_area"], nA)

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

    # test the remaining properties:
    assert lf.lake_outlets.size == 1
    assert lf.lake_outlets[0] == 72
    outlets_in_map = np.unique(lf.depression_outlet_map)
    assert outlets_in_map.size == 2
    assert outlets_in_map[1] == 72
    assert lf.number_of_lakes == 1
    assert lf.lake_codes[0] == 57
    assert_array_equal(lf.lake_map, lc)
    assert lf.lake_areas[0] == approx(25.0)
    assert lf.lake_volumes[0] == approx(63.0)
def test_in_network():
    # a valley network produced by stream power:
    z = np.array([
        3.12900830e-04, 3.66462671e-04, 9.44438515e-04, 1.45006772e-04,
        1.91406099e-04, 4.42053204e-04, 2.99818052e-04, 5.45267467e-04,
        4.12129514e-04, 7.43816953e-04, 1.59251681e-04, 7.39577249e+01,
        6.68718419e+01, 2.95535987e+01, 7.69715256e+01, 4.61083179e+01,
        5.70611522e+01, 6.99664564e+01, 8.29355817e+01, 5.85563532e-04,
        2.60300016e-04, 8.99636726e+01, 1.11946320e+02, 5.16553709e+01,
        1.38432251e+02, 1.02903579e+02, 1.27601424e+02, 8.59469601e+01,
        4.77495429e+01, 8.00781223e-04, 4.13095981e-04, 7.41309307e+01,
        1.31747968e+02, 1.11724617e+02, 1.71687943e+02, 1.93482716e+02,
        1.61044205e+02, 1.34775824e+02, 7.63077925e+01, 8.85837646e-04,
        6.94907676e-04, 5.53654246e+01, 9.95405009e+01, 1.81345288e+02,
        1.88975196e+02, 1.78104180e+02, 1.75231160e+02, 1.14932425e+02,
        5.12018382e+01, 1.26501797e-04, 8.34527300e-04, 8.80562940e+01,
        1.24009142e+02, 1.55635807e+02, 1.56683637e+02, 1.62398410e+02,
        1.04070282e+02, 6.99665030e+01, 6.41256897e+01, 5.50951003e-04,
        2.02545919e-04, 3.05799760e+01, 5.02285119e+01, 8.31442034e+01,
        1.75898080e+02, 1.80095770e+02, 1.23416767e+02, 6.97604901e+01,
        3.04864568e+01, 4.42047775e-04, 5.75778629e-04, 8.13990441e+01,
        1.17362500e+02, 1.35317452e+02, 1.78842796e+02, 9.65391990e+01,
        1.16520146e+02, 1.59289373e+02, 8.29784784e+01, 4.21911459e-04,
        7.83145812e-04, 8.44510235e+01, 6.85512072e+01, 3.99258990e+01,
        9.07740020e+01, 4.47116751e+01, 1.05333999e+02, 1.04965376e+02,
        6.42615041e+01, 8.48184002e-04, 9.92952214e-04, 5.44805365e-04,
        6.83657298e-04, 4.27967811e-04, 4.40101095e-04, 5.47248461e-04,
        5.77178429e-06, 4.39642103e-04, 4.80194778e-04, 9.24014550e-04
    ])

    flux = np.array([
        0.71259633, 1.8368437, 7.98879652, 9.29556375, 10.55574455, 7.24717392,
        7.35872882, 4.50198662, 1.97243346, 0.54930274, 1.71629518, 4.0949232,
        4.50641349, 19.45300944, 5.73451891, 10.2200909, 8.84475793,
        5.62433494, 3.63816461, 3.2288009, 3.64720491, 4.08050742, 3.55208345,
        12.80703452, 4.51455295, 7.22640241, 4.82518478, 6.0364361, 8.21399889,
        4.89790743, 6.37085345, 7.20139071, 3.66063349, 6.65749537, 4.5201495,
        3.16880878, 4.56500213, 4.47976874, 5.91287906, 7.65823897, 6.75481467,
        10.33585975, 7.95868492, 3.44967745, 3.30272455, 3.79822256,
        3.72583825, 5.35268783, 11.33346169, 7.61218948, 13.23332132,
        5.52663873, 4.71401637, 5.25380598, 6.32221242, 5.21692832, 9.95021529,
        12.12012981, 9.62887235, 12.51966215, 12.20119879, 28.07778172,
        21.69415422, 13.44016311, 3.42523128, 3.16880878, 5.79132165,
        11.8326263, 20.62850507, 10.58826741, 10.25347039, 3.76593706,
        3.58815683, 4.10381596, 3.23987285, 7.32040184, 4.62625103, 3.16880878,
        4.05801502, 8.29763076, 1.42053684, 3.54385495, 4.9815377, 7.32862308,
        5.884002, 12.71539344, 4.14640372, 4.17838374, 4.74896355, 1.84587995,
        0.57901706, 1.94727505, 4.37381493, 5.18582678, 7.70532408, 6.86738548,
        6.04728603, 2.94714791, 2.00238741, 0.88296836
    ])

    potnt = np.array([
        7.12596329e+23, 1.83684370e+24, 7.98879652e+24, 9.29556375e+24,
        1.05557446e+25, 7.24717392e+24, 7.35872882e+24, 4.50198662e+24,
        1.97243346e+24, 5.49302741e+23, 1.71629518e+24, 3.11607783e+00,
        4.55006629e+00, 4.21948454e+01, 4.51089464e+00, 1.77476721e+01,
        1.18679201e+01, 5.93094410e+00, 2.26828834e+00, 3.22880090e+24,
        3.64720491e+24, 3.44492074e+00, 2.99141371e+00, 8.61459830e+01,
        3.22150654e+00, 1.30493764e+01, 4.51470413e+00, 1.01713137e+01,
        1.40167801e+01, 4.89790743e+24, 6.37085345e+24, 8.30460195e+00,
        2.72370114e+00, 1.97019871e+01, 4.81322624e+00, 2.37203116e+00,
        4.76156755e+00, 3.84190281e+00, 5.53509619e+00, 7.65823897e+24,
        6.75481467e+24, 1.63796499e+01, 1.83238435e+01, 2.62626616e+00,
        3.21546392e+00, 5.36483147e+00, 3.18817285e+00, 5.90189403e+00,
        1.86765515e+01, 7.61218948e+24, 1.32333213e+25, 4.00510836e+00,
        3.72650975e+00, 5.71530086e+00, 2.42783091e+01, 1.07981219e+01,
        2.92283301e+01, 3.24892464e+01, 9.86359779e+00, 1.25196622e+25,
        1.22011988e+25, 5.98718495e+01, 1.54766737e+02, 7.40803538e+01,
        3.21059221e+00, 2.38746227e+00, 7.36767180e+00, 4.52838697e+01,
        4.40547155e+01, 1.05882674e+25, 1.02534704e+25, 3.05098779e+00,
        2.45849055e+00, 3.12955438e+00, 1.87486164e+00, 2.51124463e+01,
        6.21239889e+00, 1.64106832e+00, 3.28554137e+00, 8.29763076e+24,
        1.42053684e+24, 2.36944471e+00, 5.71708702e+00, 1.36764251e+01,
        4.71435055e+00, 2.24231064e+01, 3.41364652e+00, 3.49569086e+00,
        4.14217801e+00, 1.84587995e+24, 5.79017064e+23, 1.94727505e+24,
        4.37381493e+24, 5.18582678e+24, 7.70532408e+24, 6.86738548e+24,
        6.04728603e+24, 2.94714791e+24, 2.00238741e+24, 8.82968356e+23
    ])

    mg = RasterModelGrid((NROWS, NCOLS), (DX, DX))

    mg.add_field('node', 'topographic__elevation', z)

    Qin = np.ones_like(z) * 100. / (60. * 60. * 24. * 365.25)
    # ^remember, flux is /s, so this is a small number!
    mg.add_field('node', 'water__unit_flux_in', Qin)

    pfr = PotentialityFlowRouter(mg, flow_equation='Manning')
    pfr.route_flow()

    assert_allclose(mg.at_node['surface_water__discharge'], flux)
    assert_allclose(mg.at_node['flow__potential'][mg.core_nodes],
                    potnt[mg.core_nodes])
Exemple #44
0
def read_netcdf(nc_file,
                grid=None,
                name=None,
                just_grid=False,
                halo=0,
                nodata_value=-9999.0):
    """Create a :class:`~.RasterModelGrid` from a netcdf file.

    Create a new :class:`~.RasterModelGrid` from the netcdf file, *nc_file*.
    If the netcdf file also contains data, add that data to the grid's fields.
    To create a new grid without any associated data from the netcdf file,
    set the *just_grid* keyword to ``True``.

    A halo can be added with the keyword *halo*.

    If you want the fields to be added to an existing grid, it can be passed
    to the keyword argument *grid*.

    Parameters
    ----------
    nc_file : str
        Name of a netcdf file.
    grid : *grid* , optional
        Adds data to an existing *grid* instead of creating a new one.
    name : str, optional
        Add only fields with NetCDF variable name to the grid. Default is to
        add all NetCDF varibles to the grid.
    just_grid : boolean, optional
        Create a new grid but don't add value data.
    halo : integer, optional
        Adds outer border of depth halo to the *grid*.
    nodata_value : float, optional
        Value that indicates an invalid value. Default is -9999.

    Returns
    -------
    :class:`~.RasterModelGrid`
        A newly-created :class:`~.RasterModelGrid`.

    Examples
    --------
    Import :func:`read_netcdf` and the path to an example netcdf file included
    with landlab.

    >>> from landlab.io.netcdf import read_netcdf

    Create a new grid from the netcdf file. The example grid is a uniform
    rectilinear grid with 4 rows and 3 columns of nodes with unit spacing.
    The data file also contains data defined at the nodes for the grid for
    a variable called, *surface__elevation*.

    >>> grid = read_netcdf("test-netcdf4.nc") # doctest: +SKIP
    >>> grid.shape == (4, 3) # doctest: +SKIP
    True
    >>> grid.dy, grid.dx # doctest: +SKIP
    (1.0, 1.0)
    >>> list(grid.at_node.keys()) # doctest: +SKIP
    ['surface__elevation']
    >>> grid.at_node['surface__elevation'] # doctest: +SKIP
    array([  0.,   1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.,
            11.])

    :func:`read_netcdf` will try to determine the format of the netcdf file.
    For example, the same call will also work for *netcdf3*-formatted files.

    >>> grid = read_netcdf("test-netcdf3-64bit.nc") # doctest: +SKIP
    >>> grid.shape == (4, 3) # doctest: +SKIP
    True
    >>> grid.dy, grid.dx # doctest: +SKIP
    (1.0, 1.0)

    A more complicated example might add data with a halo to an existing grid.
    Note that the lower left corner must be specified correctly for the data
    and the grid to align correctly.

    >>> from landlab import RasterModelGrid
    >>> grid = RasterModelGrid((6, 5), xy_of_lower_left=(-1., -1.)) # doctest: +SKIP
    >>> grid = read_netcdf(
    ...     "test-netcdf4.nc",
    ...     grid=grid,
    ...     halo=1,
    ...     nodata_value=-1,
    ... ) # doctest: +SKIP
    >>> grid.at_node['surface__elevation'].reshape(grid.shape) # doctest: +SKIP
    array([[ -1.,  -1.,  -1.,  -1.,  -1.],
           [ -1.,   0.,   1.,   2.,  -1.],
           [ -1.,   3.,   4.,   5.,  -1.],
           [ -1.,   6.,   7.,   8.,  -1.],
           [ -1.,   9.,  10.,  11.,  -1.],
           [ -1.,  -1.,  -1.,  -1.,  -1.]])
    """
    from landlab import RasterModelGrid

    try:
        root = nc.netcdf_file(nc_file, "r", version=2)
    except TypeError:
        root = nc4.Dataset(nc_file, "r", format="NETCDF4")

    try:
        node_coords = _read_netcdf_structured_grid(root)
    except ValueError:
        if (len(root.variables["x"].dimensions) == 1) and (len(
                root.variables["y"].dimensions) == 1):

            node_coords = _read_netcdf_raster_structured_grid(root)
        else:
            assert ValueError("x and y dimensions must both either be 2D "
                              "(nj, ni) or 1D (ni,) and (nj).")

    assert len(node_coords) == 2

    dx = _get_raster_spacing(node_coords)
    xy_spacing = (dx, dx)
    shape = node_coords[0].shape
    xy_of_lower_left = (
        node_coords[0].min() - halo * dx,
        node_coords[1].min() - halo * dx,
    )

    if grid is not None:
        if (grid.number_of_node_rows != shape[0] + 2 * halo) or (
                grid.number_of_node_columns != shape[1] + 2 * halo):
            raise MismatchGridDataSizeError(
                shape[0] + 2 * halo * shape[1] + 2 * halo,
                grid.number_of_node_rows * grid.number_of_node_columns,
            )
        if (grid.dx, grid.dy) != xy_spacing:
            raise MismatchGridXYSpacing((grid.dx, grid.dy), xy_spacing)

        if grid.xy_of_lower_left != xy_of_lower_left:
            raise MismatchGridXYLowerLeft(grid.xy_of_lower_left,
                                          xy_of_lower_left)

    if grid is None:
        grid = RasterModelGrid(shape,
                               xy_spacing=xy_spacing,
                               xy_of_lower_left=xy_of_lower_left)

    if not just_grid:
        fields, grid_mapping_dict = _read_netcdf_structured_data(root)
        for (field_name, values) in fields.items():

            # add halo if necessary
            if halo > 0:
                values = add_halo(values.reshape(shape),
                                  halo=halo,
                                  halo_value=nodata_value).reshape((-1, ))

            # add only the requested fields.
            if (name is None) or (field_name == name):
                add_field = True
            else:
                add_field = False

            if add_field:
                grid.add_field(field_name, values, at="node", clobber=True)

        if (name is not None) and (name not in grid.at_node):
            raise ValueError(
                "Specified field {name} was not in provided NetCDF.".format(
                    name=name))

    # save grid mapping
    if grid_mapping_dict is not None:
        grid.grid_mapping = grid_mapping_dict

    root.close()

    return grid
def test_depression_finder_bad_instance():
    mg = RasterModelGrid((5, 5), xy_spacing=(1, 1))
    mg.add_field("topographic__elevation", mg.node_x + mg.node_y, at="node")
    ld = LinearDiffuser(mg, linear_diffusivity=1.)
    with pytest.raises(ValueError):
        LossyFlowAccumulator(mg, flow_director="D8", depression_finder=ld)
Exemple #46
0
y_distance_from_center = mg.node_y - mg.node_y.mean()
x_distance_from_edge = np.amin(np.vstack(
    (mg.node_x.max() - mg.node_x, mg.node_x - mg.node_x.min())),
                               axis=0)
y_distance_from_edge = np.amin(np.vstack(
    (mg.node_y.max() - mg.node_y, mg.node_y - mg.node_y.min())),
                               axis=0)
# make the "hole"
hole_elev = np.sqrt(x_distance_from_center**2 + y_distance_from_center**2)
# make the rim:
rim_elev = np.sqrt(x_distance_from_edge**2 + y_distance_from_edge**2)
# assemble
z = np.amin(np.vstack((hole_elev, rim_elev)), axis=0)
z += np.random.rand(nx * ny) / 1000.

mg.add_field("node", "topographic__elevation", z, copy=False)

fr = FlowAccumulator(mg, flow_director="D8")
lf = DepressionFinderAndRouter(mg)

fr.run_one_step()

figure("old drainage area")
imshow_node_grid(mg, "drainage_area")

lf.map_depressions(pits=mg.at_node["flow__sink_flag"])

figure("depression depth")
imshow_node_grid(mg, "depression__depth")

figure("new drainage area")
def test_depression_finder_bad_uninstantiated_component():
    mg = RasterModelGrid((5, 5), xy_spacing=(1, 1))
    mg.add_field("topographic__elevation", mg.node_x + mg.node_y, at="node")
    with pytest.raises(ValueError):
        LossyFlowAccumulator(mg, flow_director="D8", depression_finder=LinearDiffuser)
Exemple #48
0
def test_bad_director_name():
    mg = RasterModelGrid((5, 5), spacing=(1, 1))
    mg.add_field("topographic__elevation", mg.node_x + mg.node_y, at="node")
    with pytest.raises(ValueError):
        LossyFlowAccumulator(mg, flow_director="spam")
Exemple #49
0
def dans_grid2():
    """
    Create a 5x5 test grid.
    This tests more complex routing, with diffs between D4 & D8.
    """
    mg = RasterModelGrid((5, 5), spacing=(10., 10.))

    this_dir = os.path.abspath(os.path.dirname(__file__))
    infile = os.path.join(this_dir, "test_fr_input.txt")

    z = np.array([
        [7., 7., 7., 7., 7.],
        [7., 5., 3.2, 6., 7.],
        [7., 2., 3., 5., 7.],
        [7., 1., 1.9, 4., 7.],
        [7., 0., 7., 7., 7.],
    ]).flatten()

    A_target_D8 = np.array([
        [0., 0., 0., 0., 0.],
        [0., 100., 200., 100., 0.],
        [0., 400., 100., 100., 0.],
        [0., 600., 300., 100., 0.],
        [0., 900., 0., 0., 0.],
    ]).flatten()

    A_target_D4 = np.array([
        [0., 0., 0., 0., 0.],
        [0., 100., 200., 100., 0.],
        [0., 200., 400., 100., 0.],
        [0., 900., 600., 100., 0.],
        [0., 900., 0., 0., 0.],
    ]).flatten()

    frcvr_target_D8 = np.array([
        [0, 1, 2, 3, 4],
        [5, 11, 11, 7, 9],
        [10, 16, 16, 17, 14],
        [15, 21, 21, 17, 19],
        [20, 21, 22, 23, 24],
    ]).flatten()

    frcvr_target_D4 = np.array([
        [0, 1, 2, 3, 4],
        [5, 11, 12, 7, 9],
        [10, 16, 17, 12, 14],
        [15, 21, 16, 17, 19],
        [20, 21, 22, 23, 24],
    ]).flatten()

    upids_target_D8 = np.array([
        [0, 1, 2, 3, 4],
        [5, 9, 10, 14, 15],
        [19, 20, 21, 16, 11],
        [6, 7, 8, 12, 17],
        [13, 18, 22, 23, 24],
    ]).flatten()

    upids_target_D4 = np.array([
        [0, 1, 2, 3, 4],
        [5, 9, 10, 14, 15],
        [19, 20, 21, 16, 11],
        [6, 17, 12, 7, 8],
        [13, 18, 22, 23, 24],
    ]).flatten()

    links2rcvr_target_D8 = np.full(25, XX)
    links2rcvr_target_D8[mg.core_nodes] = np.array(
        [14, 51, 11, 23, 59, 61, 32, 67, 29])

    links2rcvr_target_D4 = np.full(25, XX)
    links2rcvr_target_D4[mg.core_nodes] = np.array(
        [14, 15, 11, 23, 24, 20, 32, 28, 29])

    steepest_target_D8 = np.array([
        [0., 0., 0., 0., 0.],
        [0., 0.3, 0.08485281, 0.28, 0.],
        [0., 0.1, 0.14142136, 0.21920310, 0.],
        [0., 0.1, 0.13435029, 0.21, 0.],
        [0., 0., 0., 0., 0.],
    ]).flatten()

    steepest_target_D4 = np.array([
        [0., 0., 0., 0., 0.],
        [0., 0.3, 0.02, 0.28, 0.],
        [0., 0.1, 0.11, 0.2, 0.],
        [0., 0.1, 0.09, 0.21, 0.],
        [0., 0., 0., 0., 0.],
    ]).flatten()

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

    class DansGrid(object):
        pass

    dans_grid = DansGrid()
    dans_grid.mg = mg
    dans_grid.z = z
    dans_grid.infile = infile
    dans_grid.A_target_D8 = A_target_D8
    dans_grid.A_target_D4 = A_target_D4
    dans_grid.frcvr_target_D8 = frcvr_target_D8
    dans_grid.frcvr_target_D4 = frcvr_target_D4
    dans_grid.upids_target_D8 = upids_target_D8
    dans_grid.upids_target_D4 = upids_target_D4
    dans_grid.steepest_target_D8 = steepest_target_D8
    dans_grid.steepest_target_D4 = steepest_target_D4
    dans_grid.links2rcvr_target_D8 = links2rcvr_target_D8
    dans_grid.links2rcvr_target_D4 = links2rcvr_target_D4

    return dans_grid
Exemple #50
0
def internal_closed():
    """
    Create a 6x5 test grid, but with two internal nodes closed.
    This is a sheet flow test.
    """
    mg = RasterModelGrid((6, 5), spacing=(10., 10.))

    mg.set_closed_boundaries_at_grid_edges(True, True, False, True)
    mg.status_at_node[7] = CLOSED_BOUNDARY
    mg.status_at_node[16] = CLOSED_BOUNDARY

    z = mg.node_x.copy()

    Q_in = np.full(25, 2.)

    A_target = (np.array([
        [0., 0., 0., 0., 0.],
        [1., 1., 0., 1., 0.],
        [6., 6., 3., 1., 0.],
        [0., 0., 2., 1., 0.],
        [3., 3., 2., 1., 0.],
        [0., 0., 0., 0., 0.],
    ]).flatten() * 100.)

    frcvr_target = np.array([
        [0, 1, 2, 3, 4],
        [5, 5, 7, 12, 9],
        [10, 10, 11, 12, 14],
        [15, 16, 11, 17, 19],
        [20, 20, 21, 22, 24],
        [25, 26, 27, 28, 29],
    ]).flatten()

    links2rcvr_target = np.full(mg.number_of_nodes, XX)
    links2rcvr_target[mg.core_nodes] = np.array(
        [9, 62, 18, 19, 20, 67, 29, 36, 37, 38])

    steepest_target = np.array([
        [0., 0., 0., 0., 0.],
        [0., 1., 0., 0., 0.],
        [0., 1., 1., 1., 0.],
        [0., 0., 0., 1., 0.],
        [0., 1., 1., 1., 0.],
        [0., 0., 0., 0., 0.],
    ]).flatten()

    steepest_target[np.array([8, 17])] = 1. / np.sqrt(2.)

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

    class DansGrid(object):
        pass

    dans_grid = DansGrid()
    dans_grid.mg = mg
    dans_grid.z = z
    dans_grid.Q_in = Q_in
    dans_grid.A_target = A_target
    dans_grid.frcvr_target = frcvr_target
    dans_grid.steepest_target = steepest_target
    dans_grid.links2rcvr_target = links2rcvr_target

    return dans_grid
def test_field_name_array_float_case6():
    """Topography as array, runoff rate as array"""
    mg = RasterModelGrid((5, 4), xy_spacing=(1, 1))
    topographic__elevation = np.array(
        [
            0.,
            0.,
            0.,
            0.,
            0.,
            21.,
            10.,
            0.,
            0.,
            31.,
            20.,
            0.,
            0.,
            32.,
            30.,
            0.,
            0.,
            0.,
            0.,
            0.,
        ]
    )

    runoff_rate = [
        1.,
        1.,
        1.,
        1.,
        2.,
        2.,
        2.,
        2.,
        3.,
        3.,
        3.,
        3.,
        4.,
        4.,
        4.,
        4.,
        5.,
        5.,
        5.,
        5.,
    ]

    mg.add_field("node", "topographic__elevation", topographic__elevation)

    mg.set_closed_boundaries_at_grid_edges(True, True, True, False)

    fa = LossyFlowAccumulator(mg, topographic__elevation, runoff_rate=runoff_rate)

    fa.run_one_step()
    reciever = np.array(
        [0, 1, 2, 3, 4, 1, 2, 7, 8, 10, 6, 11, 12, 14, 10, 15, 16, 17, 18, 19]
    )

    da = np.array(
        [0., 1., 5., 0., 0., 1., 5., 0., 0., 1., 4., 0., 0., 1., 2., 0., 0., 0., 0., 0.]
    )

    q = np.array(
        [
            0.,
            2.,
            16.,
            0.,  # KRB double checked these numbers by hand 5/15/18 - OK
            0.,
            2.,
            16.,
            0.,
            0.,
            3.,
            14.,
            0.,
            0.,
            4.,
            8.,
            0.,
            0.,
            0.,
            0.,
            0.,
        ]
    )

    assert_array_equal(mg.at_node["flow__receiver_node"], reciever)
    assert_array_equal(mg.at_node["drainage_area"], da)
    assert_array_equal(mg.at_node["surface_water__discharge"], q)
def test_MS_params():

    # This commented code block ingests MS's grid setup to come close to a
    # version of this topo (DEJH believes there may be a bug in the STORM
    # code's allocation of elevations, which precludes a precise replication)
    # a = shp.Reader(os.path.join(datapath, 'boundary', 'boundary.shp'))
    # # This is shapefile of the watershed boundary
    # b = shp.Reader(os.path.join(
    #     datapath, 'point_elevations', 'point_elevations',
    #     'point_elevations.shp'))
    # # This is shapefile of the elevations at each 'gauging' point on the
    # # grid within the watershed boundary
    # coords = a.shapeRecords()[0].shape.__geo_interface__['coordinates'][0]
    # Yy = [Y for (X, Y) in coords]
    # Xx = [X for (X, Y) in coords]
    # polypts_xy = [[X, Y] for (X, Y) in coords]
    # (X1, Y1) = np.meshgrid(
    #     np.linspace(min(Xx), max(Xx),
    #                 int(round((max(Xx)-min(Xx))/1000.))),
    #     np.linspace(min(Yy), max(Yy),
    #                 int(round((max(Yy)-min(Yy))/1000.))))
    # # creates a mesh with 1000m spacings
    # isin = Path(polypts_xy).contains_points(
    #     [(zx, zy) for (zx, zy) in zip(X1.flat, Y1.flat)]).reshape(X1.shape)
    # # isin=inpolygon(X1(:),Y1(:),Xx,Yy)
    # Yin = Y1[isin]
    # Xin = X1[isin]
    #
    # Easting = np.loadtxt(os.path.join(_THIS_DIR, 'model_input', 'Easting.csv'))
    # # This is the Longitudinal data for each gauge.
    # Northing = np.loadtxt(os.path.join(_THIS_DIR, 'model_input', 'Northing.csv'))
    # # This is the Latitudinal data for each gauge. It will be sampled
    # # below.
    # vdg = VoronoiDelaunayGrid(Easting, Northing)
    # gauges = np.loadtxt(os.path.join(_THIS_DIR, 'model_input', 'gauges.csv'))
    # # This is the list of gauge numbers. It will be sampled below.
    # gauge_elev = np.loadtxt(os.path.join(_THIS_DIR, 'model_input', 'gauge_elev.csv'))
    # # This is the list of gauge numbers. It will be sampled below.
    # # put the elevs on the grid. Mind the ordering
    # vdg_z = vdg.add_field('node', 'topographic__elevation',
    #                       gauge_elev[np.argsort(Northing)])
    # numgauges = len(gauges)
    #
    # mg = RasterModelGrid((12, 26), (1042.3713, 1102.0973))
    # mg.status_at_node[:] = 4
    # mg.status_at_node[isin.flatten()] = 0
    # z = mg.add_zeros('node', 'topographic__elevation')
    #
    # closest_core_node_in_vdg = []
    # for E, N in zip(Xin, Yin):
    #     closest_core_node_in_vdg.append(
    #        np.argmin(vdg.calc_distances_of_nodes_to_point((E, N))))
    # z[mg.status_at_node == 0] = vdg_z[np.array(closest_core_node_in_vdg)]

    mg = RasterModelGrid((12, 26), (1042.3713, 1102.0973))
    mg.status_at_node = np.loadtxt(os.path.join(_THIS_DIR, "BCs_Singer.txt"))
    mg.add_field(
        "node",
        "topographic__elevation",
        np.loadtxt(os.path.join(_THIS_DIR, "elevs_Singer.txt")),
    )

    np.random.seed(10)
    rain = SpatialPrecipitationDistribution(mg,
                                            number_of_years=2,
                                            orographic_scenario="Singer")

    max_intensity = []
    storm_dur = []
    istorm_dur = []
    rec = []
    depth = []
    count = 0
    for (storm, istorm) in rain.yield_storms(
            # style='monsoonal', limit='total_rainfall'):
            style="whole_year",
            limit="total_rainfall",
    ):
        # print('storm dur:', storm, rain.storm_duration_last_storm)
        # print('istorm dur:', istorm)
        # print('intensity:', rain.storm_intensity_last_storm)
        # print('recession:', rain.storm_recession_value_last_storm)
        # print('depth:', rain.storm_depth_last_storm)
        # # print('accum depth:', rain.total_rainfall_this_season)
        # print('target depth:', rain.target_median_total_rainfall_this_season)
        # print('***')
        max_intensity.append(rain.storm_intensity_last_storm)
        storm_dur.append(storm)
        istorm_dur.append(istorm)
        rec.append(rain.storm_recession_value_last_storm)
        depth.append(rain.storm_depth_last_storm)
        count += 1
    # print('Total number of storms:', count)
    # print('Target_depth:', rain.target_median_total_rainfall_this_season)
    assert np.isclose(np.mean(max_intensity), 35.84806631859928)  # mm/hr
    assert np.isclose(np.mean(storm), 0.40865380457460571)  # hrs
    assert np.isclose(np.mean(istorm), 85.258871894485694)  # hrs
Exemple #53
0
def setup_dans_grid2():
    """
    Create a 5x5 test grid.
    This tests more complex routing, with diffs between D4 & D8.
    """
    global fr, mg, infile
    global z, A_target_D8, A_target_D4, frcvr_target_D8, frcvr_target_D4, \
        upids_target_D8, upids_target_D4, steepest_target_D8, \
        steepest_target_D4, links2rcvr_target_D8, links2rcvr_target_D4

    mg = RasterModelGrid((5, 5), spacing=(10., 10.))

    infile = os.path.join(_THIS_DIR, 'test_fr_input.txt')

    z = np.array([7.,  7.,  7.,  7.,  7.,
                  7.,  5., 3.2,  6.,  7.,
                  7.,  2.,  3.,  5.,  7.,
                  7.,  1., 1.9,  4.,  7.,
                  7.,  0.,  7.,  7.,  7.])

    A_target_D8 = np.array([0.,     0.,     0.,     0.,     0.,
                            0.,   100.,   200.,   100.,     0.,
                            0.,   400.,   100.,   100.,     0.,
                            0.,   600.,   300.,   100.,     0.,
                            0.,   900.,     0.,     0.,     0.])

    A_target_D4 = np.array([0.,     0.,     0.,     0.,     0.,
                            0.,   100.,   200.,   100.,     0.,
                            0.,   200.,   400.,   100.,     0.,
                            0.,   900.,   600.,   100.,     0.,
                            0.,   900.,     0.,     0.,     0.])

    frcvr_target_D8 = np.array([0, 1, 2, 3, 4, 5, 11, 11, 7, 9, 10, 16, 16, 17,
                                14, 15, 21, 21, 17, 19, 20, 21, 22, 23, 24])

    frcvr_target_D4 = np.array([ 0,  1,  2,  3,  4, 
                                 5, 11, 12,  7,  9,
                                10, 16, 17, 12, 14,
                                15, 21, 16, 17, 19,
                                20, 21, 22, 23, 24])

    upids_target_D8 = np.array([0, 1, 2, 3, 4, 5, 9, 10, 14, 15, 19, 20, 21,
                                16, 11, 6, 7, 8, 12, 17, 13, 18, 22, 23, 24])

    upids_target_D4 = np.array([0, 1, 2, 3, 4, 5, 9, 10, 14, 15, 19, 20, 21,
                                16, 11, 6, 17, 12, 7, 8, 13, 18, 22, 23, 24])

    links2rcvr_target_D8 = np.full(25, XX)
    links2rcvr_target_D8[mg.core_nodes] = np.array([14, 51, 11,
                                                    23, 59, 61,
                                                    32, 67, 29])

    links2rcvr_target_D4 = np.full(25, XX)
    links2rcvr_target_D4[mg.core_nodes] = np.array([14, 15, 11,
                                                    23, 24, 20,
                                                    32, 28, 29])

    steepest_target_D8 = np.array([0., 0., 0., 0., 0.,
                                   0., 0.3, 0.08485281, 0.28, 0.,
                                   0., 0.1, 0.14142136, 0.21920310, 0.,
                                   0., 0.1, 0.13435029, 0.21,  0.,
                                   0., 0., 0., 0.,  0.])

    steepest_target_D4 = np.array([0., 0., 0., 0., 0.,
                                   0., 0.3, 0.02, 0.28, 0.,
                                   0., 0.1, 0.11, 0.2, 0.,
                                   0., 0.1, 0.09, 0.21, 0.,
                                   0., 0., 0., 0., 0.])

    mg.add_field('node', 'topographic__elevation', z, units='-')
def test_water_discharge_in_supplied():
    mg = RasterModelGrid((5, 5), xy_spacing=(1, 1))
    mg.add_field("topographic__elevation", mg.node_x + mg.node_y, at="node")
    mg.add_field("water__discharge_in", mg.node_x + mg.node_y, at="node")
    with pytest.deprecated_call():
        LossyFlowAccumulator(mg)
def test_composite_pits():
    """
    A test to ensure the component correctly handles cases where there are
    multiple pits, inset into each other.
    """
    mg = RasterModelGrid(10, 10, 1.)
    z = mg.add_field('node', 'topographic__elevation', mg.node_x.copy())
    # a sloping plane
    #np.random.seed(seed=0)
    #z += np.random.rand(100)/10000.
    # punch one big hole
    z.reshape((10, 10))[3:8, 3:8] = 0.
    # dig a couple of inset holes
    z[57] = -1.
    z[44] = -2.
    z[54] = -10.

    # make an outlet
    z[71] = 0.9

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

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

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

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

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

    #test the remaining properties:
    assert_equal(lf.lake_outlets.size, 1)
    assert_equal(lf.lake_outlets[0], 72)
    outlets_in_map = np.unique(lf.depression_outlet_map)
    assert_equal(outlets_in_map.size, 2)
    assert_equal(outlets_in_map[1], 72)
    assert_equal(lf.number_of_lakes, 1)
    assert_equal(lf.lake_codes[0], 57)
    assert_array_equal(lf.lake_map, lc)
    assert_almost_equal(lf.lake_areas[0], 25.)
    assert_almost_equal(lf.lake_volumes[0], 63.)
def test_instantiated_director_with_kwargs():
    mg = RasterModelGrid((5, 5), xy_spacing=(1, 1))
    mg.add_field("topographic__elevation", mg.node_x + mg.node_y, at="node")
    fd = FlowDirectorSteepest(mg)
    with pytest.raises(ValueError):
        LossyFlowAccumulator(mg, flow_director=fd, partition_method="eggs")
def test_depression_finder_as_bad_string():
    mg = RasterModelGrid((5, 5), xy_spacing=(1, 1))
    mg.add_field("topographic__elevation", mg.node_x + mg.node_y, at="node")
    with pytest.raises(ValueError):
        LossyFlowAccumulator(mg, flow_director="D8", depression_finder="spam")
def test_depression_finder_as_instance():
    mg = RasterModelGrid((5, 5), xy_spacing=(1, 1))
    mg.add_field("topographic__elevation", mg.node_x + mg.node_y, at="node")
    df = DepressionFinderAndRouter(mg)
    LossyFlowAccumulator(mg, flow_director="D8", depression_finder=df)
Exemple #59
0
def test_edge_draining():
    """
    This tests when the lake attempts to drain from an edge, where an issue
    is suspected.
    """
    # Create a 7x7 test grid with a well defined hole in it, AT THE EDGE.
    mg = RasterModelGrid((7, 7), (1., 1.))

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

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

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

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

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

    fr.route_flow()
    lf.map_depressions()
    assert mg.at_node["drainage_area"] == approx(A_new)
    assert lf.depression_outlet_map == approx(depr_outlet_target)
Exemple #60
0
print("Running fastscaper")
print(datetime.datetime.now().time())
spr.run_one_step(dt)  # erosion: stream power
zrnew = zr[mg.nodes]  # post-incision elevations
incise = zrold - zrnew  # incision per cell
qs = incise * cell_area  # Volume sediment produced per cell
qsflat = qs.ravel()  # flatten qs for flow routing calculation

# extract cumulative flux (q) as function of flow length.
a, q = find_drainage_area_and_discharge(
    mg.at_node['flow__upstream_node_order'],
    mg.at_node['flow__receiver_node'],
    runoff=qsflat)  # a is number of nodes

area = mg.at_node['drainage_area']
mg.add_field('node', 'flux', q, noclobber=False)
area_threshold = 25  #float(sys.argv[1]) #km2
is_drainage = area > (area_threshold * 1000000)  #km2 to m2

q_rate = q / dt
incise_rate = (incise / dt) * 0.001  #mm/yr
# Update fields
print("Updating fields")
print(datetime.datetime.now().time())
mg.add_field('node', 'elevation', zrold, noclobber=False)
# Outputs present day elevation
mg.add_field('node', 'incision', incise_rate, noclobber=False)
# Channels
mg.add_field('node', 'channels', is_drainage, noclobber=False)
# Incision rate
mg.add_field('node', 'sedflux', q_rate, noclobber=False)