Ejemplo n.º 1
0
def calculate_gradient_across_cell_corners(grid, node_values, *args, **kwds):
    """calculate_gradient_across_cell_corners(grid, node_values, [cell_ids], out=None)
    Get gradients to diagonally opposite nodes.

    Calculate gradient of the value field provided by *node_values* to
    the values at diagonally opposite nodes. The returned gradients are
    ordered as upper-right, upper-left, lower-left and lower-right.

    Parameters
    ----------
    grid : RasterModelGrid
        Source grid.
    node_values : array_like
        Quantity to take the gradient of defined at each node.
    cell_ids : array_like, optional
        If provided, cell ids to measure gradients. Otherwise, find gradients
        for all cells.
    out : array_like, optional
        Alternative output array in which to place the result.  Must
        be of the same shape and buffer length as the expected output.

    Returns
    -------
    (N, 4) ndarray
        Gradients to each diagonal node.

    Examples
    --------
    Create a grid with two cells.

    >>> from landlab import RasterModelGrid
    >>> grid = RasterModelGrid(3, 4)
    >>> x = np.array([1., 0., 0., 1.,
    ...               0., 0., 1., 1.,
    ...               3., 3., 3., 3.])

    A decrease in quantity to a diagonal node is a negative gradient.

    >>> from math import sqrt
    >>> grid.calculate_gradient_across_cell_corners(x) * sqrt(2.)
    array([[ 3.,  3.,  1.,  0.],
           [ 2.,  2., -1.,  0.]])

    >>> grid = RasterModelGrid((3, 4), spacing=(3, 4))
    >>> grid.calculate_gradient_across_cell_corners(x)
    array([[ 0.6,  0.6,  0.2,  0. ],
           [ 0.4,  0.4, -0.2,  0. ]])
    """
    cell_ids = make_optional_arg_into_id_array(grid.number_of_cells, *args)
    node_ids = grid.node_at_cell[cell_ids]

    values_at_diagonals = node_values[grid.get_diagonal_list(node_ids)]
    values_at_nodes = node_values[node_ids].reshape(len(node_ids), 1)

    out = np.subtract(values_at_diagonals, values_at_nodes, **kwds)
    np.divide(out, np.sqrt(grid.dy ** 2. + grid.dx ** 2.), out=out)

    return out
Ejemplo n.º 2
0
def calculate_steepest_descent_across_cell_faces(grid, node_values, *args,
                                                 **kwds):
    """Get steepest gradient across the faces of a cell.

    This method calculates the gradients in *node_values* across all four
    faces of the cell or cells with ID *cell_ids*. Slopes upward from the
    cell are reported as positive. If *cell_ids* is not given, calculate
    gradients for all cells.

    Use the *return_node* keyword to return a tuple, with the first element
    being the gradients and the second the node id of the node in the direction
    of the minimum gradient, i.e., the steepest descent. Note the gradient
    value returned is probably thus negative.

    Parameters
    ----------
    grid : RasterModelGrid
        Input grid.
    node_values : array_like
        Values to take gradient of.
    cell_ids : array_like, optional
        IDs of grid cells to measure gradients.
    return_node: boolean, optional
        Return node IDs of the node that has the steepest descent.
    out : ndarray, optional
        Alternative output array in which to place the result.  Must
        be of the same shape and buffer length as the expected output.

    Returns
    -------
    ndarray :
        Calculated gradients to lowest node across cell faces.

    Convention: gradients positive UP

    Examples
    --------
    Create a rectilinear grid that is 3 nodes by 3 nodes and so has one cell
    centered around node 4.

    >>> from landlab import RasterModelGrid
    >>> grid = RasterModelGrid(3, 3)
    >>> values_at_nodes = np.arange(9.)

    Calculate gradients across each cell face and choose the gradient to the
    lowest node.

    >>> grid.calculate_steepest_descent_across_cell_faces(values_at_nodes)
    masked_array(data = [-3.],
                 mask = False,
           fill_value = 1e+20)
    <BLANKLINE>

    The steepest gradient is to node with id 1.

    >>> (_, ind) = grid.calculate_steepest_descent_across_cell_faces(
    ...     values_at_nodes, return_node=True)
    >>> ind
    array([1])

    >>> grid = RasterModelGrid(3, 3)
    >>> node_values = grid.zeros()
    >>> node_values[1] = -1
    >>> grid.calculate_steepest_descent_across_cell_faces(node_values, 0)
    masked_array(data = [-1.],
                 mask = False,
           fill_value = 1e+20)
    <BLANKLINE>

    Get both the maximum gradient and the node to which the gradient is
    measured.

    >>> grid.calculate_steepest_descent_across_cell_faces(node_values, 0,
    ...     return_node=True)
    (array([-1.]), array([1]))
    """
    return_node = kwds.pop('return_node', False)

    cell_ids = make_optional_arg_into_id_array(grid.number_of_cells, *args)

    grads = calculate_gradient_across_cell_faces(grid, node_values, cell_ids)

    if return_node:
        ind = np.argmin(grads, axis=1)
        node_ids = grid.get_active_neighbors_at_node()[grid.node_at_cell[cell_ids], ind]
        # node_ids = grid.neighbor_nodes[grid.node_at_cell[cell_ids], ind]
        if 'out' not in kwds:
            out = np.empty(len(cell_ids), dtype=grads.dtype)
        out[:] = grads[range(len(cell_ids)), ind]
        return (out, node_ids)
        # return (out, 3 - ind)
    else:
        return grads.min(axis=1, **kwds)
Ejemplo n.º 3
0
def calculate_steepest_descent_across_cell_corners(grid, node_values, *args,
                                                   **kwds):
    """Get steepest gradient to the diagonals of a cell.

    Calculate the gradients in *node_values* measure to the diagonals of cells
    IDs, *cell_ids*. Slopes upward from the cell are reported as positive.
    If *cell_ids* is not given, calculate gradients for all cells.

    Use the *return_node* keyword to return a tuple, with the first element
    being the gradients and the second the node id of the node in the direction
    of the minimum gradient, i.e., the steepest descent. Note the gradient
    value returned is probably thus negative.

    Parameters
    ----------
    grid : RasterModelGrid
        Input grid.
    node_values : array_like
        Values to take gradient of.
    cell_ids : array_like, optional
        IDs of grid cells to measure gradients.
    return_node: boolean, optional
        If `True`, return node IDs of the node that has the steepest descent.
    out : ndarray, optional
        Alternative output array in which to place the result.  Must
        be of the same shape and buffer length as the expected output.

    Returns
    -------
    ndarray :
        Calculated gradients to lowest node across cell faces.

    Examples
    --------
    Create a rectilinear grid that is 3 nodes by 3 nodes and so has one cell
    centered around node 4.

    >>> from landlab import RasterModelGrid
    >>> grid = RasterModelGrid(3, 3)
    >>> values_at_nodes = np.arange(9.)

    Calculate gradients to cell diagonals and choose the gradient to the
    lowest node.

    >>> from math import sqrt
    >>> grid.calculate_steepest_descent_across_cell_corners(
    ...     values_at_nodes) * sqrt(2.)
    array([-4.])

    The steepest gradient is to node with id 0.

    >>> (_, ind) = grid.calculate_steepest_descent_across_cell_corners(
    ...                values_at_nodes, return_node=True)
    >>> ind
    array([0])

    >>> grid = RasterModelGrid(3, 3)
    >>> node_values = grid.zeros()
    >>> node_values[0] = -1
    >>> grid.calculate_steepest_descent_across_cell_corners(node_values, 0)
    array([-0.70710678])

    Get both the maximum gradient and the node to which the gradient is
    measured.

    >>> grid.calculate_steepest_descent_across_cell_corners(node_values, 0,
    ...     return_node=True)
    (array([-0.70710678]), array([0]))
    """
    return_node = kwds.pop('return_node', False)

    cell_ids = make_optional_arg_into_id_array(grid.number_of_cells, *args)

    grads = calculate_gradient_across_cell_corners(grid, node_values, cell_ids)

    if return_node:
        ind = np.argmin(grads, axis=1)
        node_ids = grid.diagonal_cells[grid.node_at_cell[cell_ids], ind]
        if 'out' not in kwds:
            out = np.empty(len(cell_ids), dtype=grads.dtype)
        out[:] = grads[range(len(cell_ids)), ind]
        return (out, node_ids)
    else:
        return grads.min(axis=1, **kwds)
Ejemplo n.º 4
0
def calculate_gradient_along_node_links(grid, node_values, *args, **kwds):
    """Get gradients along links touching a node.

    Calculate gradient of the value field provided by *node_values* across
    each of the faces of the nodes of a grid. The returned gradients are
    ordered as right, top, left, and bottom. All returned values follow our
    standard sign convention, where a link pointing N or E and increasing in
    value is positive, a link pointing S or W and increasing in value is
    negative.

    Note that the returned gradients are masked to exclude neighbor nodes which
    are closed. Beneath the mask is the value numpy.iinfo(numpy.int32).max.

    Construction::

        calculate_gradient_along_node_links(grid, node_values, [cell_ids],
                                            out=None)

    Parameters
    ----------
    grid : RasterModelGrid
        Source grid.
    node_values : array_like or field name
        Quantity to take the gradient of defined at each node.
    node_ids : array_like, optional
        If provided, node ids to measure gradients. Otherwise, find gradients
        for all nodes.
    out : array_like, optional
        Alternative output array in which to place the result.  Must
        be of the same shape and buffer length as the expected output.

    Returns
    -------
    (N, 4) Masked ndarray
        Gradients for each link of the node. Ordering is E,N,W,S.

    Examples
    --------
    Create a grid with nine nodes.

    >>> from landlab import RasterModelGrid
    >>> grid = RasterModelGrid(3, 3)
    >>> x = np.array([0., 0., 0.,
    ...               0., 1., 2.,
    ...               2., 2., 2.])

    A decrease in quantity across a face is a negative gradient.

    >>> grid.calculate_gradient_along_node_links(x) # doctest: +NORMALIZE_WHITESPACE
    masked_array(data =
     [[-- -- -- --]
     [-- 1.0 -- --]
     [-- -- -- --]
     [1.0 -- -- --]
     [1.0 1.0 1.0 1.0]
     [-- -- 1.0 --]
     [-- -- -- --]
     [-- -- -- 1.0]
     [-- -- -- --]],
                 mask =
     [[ True  True  True  True]
     [ True False  True  True]
     [ True  True  True  True]
     [False  True  True  True]
     [False False False False]
     [ True  True False  True]
     [ True  True  True  True]
     [ True  True  True False]
     [ True  True  True  True]],
           fill_value = 1e+20)

    >>> grid = RasterModelGrid((3, 3), spacing=(2, 4))
    >>> grid.calculate_gradient_along_node_links(x) # doctest: +NORMALIZE_WHITESPACE
    masked_array(data =
     [[-- -- -- --]
     [-- 0.5 -- --]
     [-- -- -- --]
     [0.25 -- -- --]
     [0.25 0.5 0.25 0.5]
     [-- -- 0.25 --]
     [-- -- -- --]
     [-- -- -- 0.5]
     [-- -- -- --]],
                 mask =
     [[ True  True  True  True]
     [ True False  True  True]
     [ True  True  True  True]
     [False  True  True  True]
     [False False False False]
     [ True  True False  True]
     [ True  True  True  True]
     [ True  True  True False]
     [ True  True  True  True]],
           fill_value = 1e+20)
    """
    padded_node_values = np.empty(node_values.size + 1, dtype=float)
    padded_node_values[-1] = BAD_INDEX_VALUE
    padded_node_values[:-1] = node_values
    node_ids = make_optional_arg_into_id_array(grid.number_of_nodes, *args)

    neighbors = grid.get_active_neighbors_at_node(node_ids, bad_index=-1)
    values_at_neighbors = padded_node_values[neighbors]
    masked_neighbor_values = np.ma.array(
        values_at_neighbors, mask=values_at_neighbors == BAD_INDEX_VALUE)
    values_at_nodes = node_values[node_ids].reshape(len(node_ids), 1)

    out = np.ma.empty_like(masked_neighbor_values, dtype=float)
    np.subtract(masked_neighbor_values[:, :2],
                values_at_nodes, out=out[:, :2], **kwds)
    np.subtract(values_at_nodes, masked_neighbor_values[:, 2:],
                out=out[:, 2:], **kwds)

    out[:, (0, 2)] /= grid.dx
    out[:, (1, 3)] /= grid.dy

    return out
Ejemplo n.º 5
0
def calculate_gradient_across_cell_faces(grid, node_values, *args, **kwds):
    """Get gradients across the faces of a cell.

    Calculate gradient of the value field provided by *node_values* across
    each of the faces of the cells of a grid. The returned gradients are
    ordered as right, top, left, and bottom.

    Note that the returned gradients are masked to exclude neighbor nodes which
    are closed. Beneath the mask is the value numpy.iinfo(numpy.int32).max.

    Construction::

        calculate_gradient_across_cell_faces(grid, node_values, [cell_ids],
                                             out=None)

    Parameters
    ----------
    grid : RasterModelGrid
        Source grid.
    node_values : array_like or field name
        Quantity to take the gradient of defined at each node.
    cell_ids : array_like, optional
        If provided, cell ids to measure gradients. Otherwise, find gradients
        for all cells.
    out : array_like, optional
        Alternative output array in which to place the result.  Must
        be of the same shape and buffer length as the expected output.

    Returns
    -------
    (N, 4) Masked ndarray
        Gradients for each face of the cell.

    Examples
    --------
    Create a grid with two cells.

    >>> from landlab import RasterModelGrid
    >>> grid = RasterModelGrid(3, 4)
    >>> x = np.array([0., 0., 0., 0.,
    ...               0., 0., 1., 1.,
    ...               3., 3., 3., 3.])

    A decrease in quantity across a face is a negative gradient.

    >>> grid.calculate_gradient_across_cell_faces(x) # doctest: +NORMALIZE_WHITESPACE
    masked_array(data =
     [[ 1.  3.  0.  0.]
     [ 0.  2. -1. -1.]],
                 mask =
     False,
           fill_value = 1e+20)

    >>> grid = RasterModelGrid((3, 4), spacing=(2, 1))
    >>> grid.calculate_gradient_across_cell_faces(x) # doctest: +NORMALIZE_WHITESPACE
    masked_array(data =
     [[ 1.   1.5  0.   0. ]
     [ 0.   1.  -1.  -0.5]],
                  mask =
     False,
           fill_value = 1e+20)
    """
    padded_node_values = np.empty(node_values.size + 1, dtype=float)
    padded_node_values[-1] = BAD_INDEX_VALUE
    padded_node_values[:-1] = node_values
    cell_ids = make_optional_arg_into_id_array(grid.number_of_cells, *args)
    node_ids = grid.node_at_cell[cell_ids]

    neighbors = grid.get_active_neighbors_at_node(node_ids)
    if BAD_INDEX_VALUE != -1:
        neighbors = np.where(neighbors == BAD_INDEX_VALUE, -1, neighbors)
    values_at_neighbors = padded_node_values[neighbors]
    masked_neighbor_values = np.ma.array(
        values_at_neighbors, mask=values_at_neighbors == BAD_INDEX_VALUE)
    values_at_nodes = node_values[node_ids].reshape(len(node_ids), 1)

    out = np.subtract(masked_neighbor_values, values_at_nodes, **kwds)

    out[:, (0, 2)] /= grid.dx
    out[:, (1, 3)] /= grid.dy

    return out
Ejemplo n.º 6
0
def _calc_steepest_descent_across_cell_faces(grid, node_values, *args, **kwds):
    """Get steepest gradient across the faces of a cell.

    This method calculates the gradients in *node_values* across all four
    faces of the cell or cells with ID *cell_ids*. Slopes upward from the
    cell are reported as positive. If *cell_ids* is not given, calculate
    gradients for all cells.

    Use the *return_node* keyword to return a tuple, with the first element
    being the gradients and the second the node id of the node in the direction
    of the minimum gradient, i.e., the steepest descent. Note the gradient
    value returned is probably thus negative.

    Parameters
    ----------
    grid : RasterModelGrid
        Input grid.
    node_values : array_like
        Values to take gradient of.
    cell_ids : array_like, optional
        IDs of grid cells to measure gradients.
    return_node: boolean, optional
        Return node IDs of the node that has the steepest descent.
    out : ndarray, optional
        Alternative output array in which to place the result.  Must
        be of the same shape and buffer length as the expected output.

    Returns
    -------
    ndarray :
        Calculated gradients to lowest node across cell faces.

    Convention: gradients positive UP

    Examples
    --------
    Create a rectilinear grid that is 3 nodes by 3 nodes and so has one cell
    centered around node 4.

    >>> from landlab import RasterModelGrid
    >>> grid = RasterModelGrid(3, 3)
    >>> values_at_nodes = np.arange(9.)

    Calculate gradients across each cell face and choose the gradient to the
    lowest node.

    >>> grid._calc_steepest_descent_across_cell_faces(values_at_nodes)
    masked_array(data = [-3.],
                 mask = False,
           fill_value = 1e+20)
    <BLANKLINE>

    The steepest gradient is to node with id 1.

    >>> (_, ind) = grid._calc_steepest_descent_across_cell_faces(
    ...     values_at_nodes, return_node=True)
    >>> ind
    array([1])

    >>> grid = RasterModelGrid(3, 3)
    >>> node_values = grid.zeros()
    >>> node_values[1] = -1
    >>> grid._calc_steepest_descent_across_cell_faces(node_values, 0)
    masked_array(data = [-1.],
                 mask = False,
           fill_value = 1e+20)
    <BLANKLINE>

    Get both the maximum gradient and the node to which the gradient is
    measured.

    >>> grid._calc_steepest_descent_across_cell_faces(node_values, 0,
    ...     return_node=True)
    (array([-1.]), array([1]))
    """
    return_node = kwds.pop('return_node', False)

    cell_ids = make_optional_arg_into_id_array(grid.number_of_cells, *args)

    grads = calc_grad_across_cell_faces(grid, node_values, cell_ids)

    if return_node:
        ind = np.argmin(grads, axis=1)
        node_ids = grid.active_neighbors_at_node[grid.node_at_cell[cell_ids],
                                                 ind]
        # node_ids = grid.neighbor_nodes[grid.node_at_cell[cell_ids], ind]
        if 'out' not in kwds:
            out = np.empty(len(cell_ids), dtype=grads.dtype)
        out[:] = grads[range(len(cell_ids)), ind]
        return (out, node_ids)
        # return (out, 3 - ind)
    else:
        return grads.min(axis=1, **kwds)
Ejemplo n.º 7
0
def _calc_steepest_descent_across_cell_corners(grid, node_values, *args,
                                               **kwds):
    """Get steepest gradient to the diagonals of a cell.

    Calculate the gradients in *node_values* measure to the diagonals of cells
    IDs, *cell_ids*. Slopes upward from the cell are reported as positive.
    If *cell_ids* is not given, calculate gradients for all cells.

    Use the *return_node* keyword to return a tuple, with the first element
    being the gradients and the second the node id of the node in the direction
    of the minimum gradient, i.e., the steepest descent. Note the gradient
    value returned is probably thus negative.

    Parameters
    ----------
    grid : RasterModelGrid
        Input grid.
    node_values : array_like
        Values to take gradient of.
    cell_ids : array_like, optional
        IDs of grid cells to measure gradients.
    return_node: boolean, optional
        If `True`, return node IDs of the node that has the steepest descent.
    out : ndarray, optional
        Alternative output array in which to place the result.  Must
        be of the same shape and buffer length as the expected output.

    Returns
    -------
    ndarray :
        Calculated gradients to lowest node across cell faces.

    Examples
    --------
    Create a rectilinear grid that is 3 nodes by 3 nodes and so has one cell
    centered around node 4.

    >>> from landlab import RasterModelGrid
    >>> grid = RasterModelGrid(3, 3)
    >>> values_at_nodes = np.arange(9.)

    Calculate gradients to cell diagonals and choose the gradient to the
    lowest node.

    >>> from math import sqrt
    >>> grid._calc_steepest_descent_across_cell_corners(
    ...     values_at_nodes) * sqrt(2.)
    array([-4.])

    The steepest gradient is to node with id 0.

    >>> (_, ind) = grid._calc_steepest_descent_across_cell_corners(
    ...                values_at_nodes, return_node=True)
    >>> ind
    array([0])

    >>> grid = RasterModelGrid(3, 3)
    >>> node_values = grid.zeros()
    >>> node_values[0] = -1
    >>> grid._calc_steepest_descent_across_cell_corners(node_values, 0)
    array([-0.70710678])

    Get both the maximum gradient and the node to which the gradient is
    measured.

    >>> grid._calc_steepest_descent_across_cell_corners(node_values, 0,
    ...     return_node=True)
    (array([-0.70710678]), array([0]))
    """
    return_node = kwds.pop('return_node', False)

    cell_ids = make_optional_arg_into_id_array(grid.number_of_cells, *args)

    grads = calc_grad_across_cell_corners(grid, node_values, cell_ids)

    if return_node:
        ind = np.argmin(grads, axis=1)
        node_ids = grid.diagonal_cells[grid.node_at_cell[cell_ids], ind]
        if 'out' not in kwds:
            out = np.empty(len(cell_ids), dtype=grads.dtype)
        out[:] = grads[range(len(cell_ids)), ind]
        return (out, node_ids)
    else:
        return grads.min(axis=1, **kwds)
Ejemplo n.º 8
0
def calc_grad_along_node_links(grid, node_values, *args, **kwds):
    """Get gradients along links touching a node.

    Calculate gradient of the value field provided by *node_values* across
    each of the faces of the nodes of a grid. The returned gradients are
    ordered as right, top, left, and bottom. All returned values follow our
    standard sign convention, where a link pointing N or E and increasing in
    value is positive, a link pointing S or W and increasing in value is
    negative.

    Note that the returned gradients are masked to exclude neighbor nodes which
    are closed. Beneath the mask is the value -1.

    Construction::

        calc_grad_along_node_links(grid, node_values, [cell_ids],
                                            out=None)

    Parameters
    ----------
    grid : RasterModelGrid
        Source grid.
    node_values : array_like or field name
        Quantity to take the gradient of defined at each node.
    node_ids : array_like, optional
        If provided, node ids to measure gradients. Otherwise, find gradients
        for all nodes.
    out : array_like, optional
        Alternative output array in which to place the result.  Must
        be of the same shape and buffer length as the expected output.

    Returns
    -------
    (N, 4) Masked ndarray
        Gradients for each link of the node. Ordering is E,N,W,S.

    Examples
    --------
    Create a grid with nine nodes.

    >>> from landlab import RasterModelGrid
    >>> grid = RasterModelGrid(3, 3)
    >>> x = np.array([0., 0., 0.,
    ...               0., 1., 2.,
    ...               2., 2., 2.])

    A decrease in quantity across a face is a negative gradient.

    >>> grid.calc_grad_along_node_links(x) # doctest: +NORMALIZE_WHITESPACE
    masked_array(data =
     [[-- -- -- --]
     [-- 1.0 -- --]
     [-- -- -- --]
     [1.0 -- -- --]
     [1.0 1.0 1.0 1.0]
     [-- -- 1.0 --]
     [-- -- -- --]
     [-- -- -- 1.0]
     [-- -- -- --]],
                 mask =
     [[ True  True  True  True]
     [ True False  True  True]
     [ True  True  True  True]
     [False  True  True  True]
     [False False False False]
     [ True  True False  True]
     [ True  True  True  True]
     [ True  True  True False]
     [ True  True  True  True]],
           fill_value = 1e+20)

    >>> grid = RasterModelGrid((3, 3), spacing=(2, 4))
    >>> grid.calc_grad_along_node_links(x) # doctest: +NORMALIZE_WHITESPACE
    masked_array(data =
     [[-- -- -- --]
     [-- 0.5 -- --]
     [-- -- -- --]
     [0.25 -- -- --]
     [0.25 0.5 0.25 0.5]
     [-- -- 0.25 --]
     [-- -- -- --]
     [-- -- -- 0.5]
     [-- -- -- --]],
                 mask =
     [[ True  True  True  True]
     [ True False  True  True]
     [ True  True  True  True]
     [False  True  True  True]
     [False False False False]
     [ True  True False  True]
     [ True  True  True  True]
     [ True  True  True False]
     [ True  True  True  True]],
           fill_value = 1e+20)
    """
    padded_node_values = np.empty(node_values.size + 1, dtype=float)
    padded_node_values[-1] = BAD_INDEX_VALUE
    padded_node_values[:-1] = node_values
    node_ids = make_optional_arg_into_id_array(grid.number_of_nodes, *args)

    neighbors = grid.active_neighbors_at_node(node_ids, bad_index=-1)
    values_at_neighbors = padded_node_values[neighbors]
    masked_neighbor_values = np.ma.array(
        values_at_neighbors, mask=values_at_neighbors == BAD_INDEX_VALUE)
    values_at_nodes = node_values[node_ids].reshape(len(node_ids), 1)

    out = np.ma.empty_like(masked_neighbor_values, dtype=float)
    np.subtract(masked_neighbor_values[:, :2],
                values_at_nodes,
                out=out[:, :2],
                **kwds)
    np.subtract(values_at_nodes,
                masked_neighbor_values[:, 2:],
                out=out[:, 2:],
                **kwds)

    out[:, (0, 2)] /= grid.dx
    out[:, (1, 3)] /= grid.dy

    return out
Ejemplo n.º 9
0
def calc_grad_across_cell_corners(grid, node_values, *args, **kwds):
    """Get gradients to diagonally opposite nodes.

    Calculate gradient of the value field provided by *node_values* to
    the values at diagonally opposite nodes. The returned gradients are
    ordered as upper-right, upper-left, lower-left and lower-right.

    Construction::

        calc_grad_across_cell_corners(grid, node_values, [cell_ids],
                                               out=None)

    Parameters
    ----------
    grid : RasterModelGrid
        Source grid.
    node_values : array_like or field name
        Quantity to take the gradient of defined at each node.
    cell_ids : array_like, optional
        If provided, cell ids to measure gradients. Otherwise, find gradients
        for all cells.
    out : array_like, optional
        Alternative output array in which to place the result.  Must
        be of the same shape and buffer length as the expected output.

    Returns
    -------
    (N, 4) ndarray
        Gradients to each diagonal node.

    Examples
    --------
    Create a grid with two cells.

    >>> from landlab import RasterModelGrid
    >>> grid = RasterModelGrid(3, 4)
    >>> x = np.array([1., 0., 0., 1.,
    ...               0., 0., 1., 1.,
    ...               3., 3., 3., 3.])

    A decrease in quantity to a diagonal node is a negative gradient.

    >>> from math import sqrt
    >>> grid.calc_grad_across_cell_corners(x) * sqrt(2.)
    array([[ 3.,  3.,  1.,  0.],
           [ 2.,  2., -1.,  0.]])

    >>> grid = RasterModelGrid((3, 4), spacing=(3, 4))
    >>> grid.calc_grad_across_cell_corners(x)
    array([[ 0.6,  0.6,  0.2,  0. ],
           [ 0.4,  0.4, -0.2,  0. ]])
    """
    cell_ids = make_optional_arg_into_id_array(grid.number_of_cells, *args)
    node_ids = grid.node_at_cell[cell_ids]

    values_at_diagonals = node_values[grid._get_diagonal_list(node_ids)]
    values_at_nodes = node_values[node_ids].reshape(len(node_ids), 1)

    out = np.subtract(values_at_diagonals, values_at_nodes, **kwds)
    np.divide(out, np.sqrt(grid.dy**2. + grid.dx**2.), out=out)

    return out
Ejemplo n.º 10
0
def calc_grad_across_cell_faces(grid, node_values, *args, **kwds):
    """Get gradients across the faces of a cell.

    Calculate gradient of the value field provided by *node_values* across
    each of the faces of the cells of a grid. The returned gradients are
    ordered as right, top, left, and bottom.

    Note that the returned gradients are masked to exclude neighbor nodes which
    are closed. Beneath the mask is the value -1.

    Construction::

        calc_grad_across_cell_faces(grid, node_values, [cell_ids],
                                             out=None)

    Parameters
    ----------
    grid : RasterModelGrid
        Source grid.
    node_values : array_like or field name
        Quantity to take the gradient of defined at each node.
    cell_ids : array_like, optional
        If provided, cell ids to measure gradients. Otherwise, find gradients
        for all cells.
    out : array_like, optional
        Alternative output array in which to place the result.  Must
        be of the same shape and buffer length as the expected output.

    Returns
    -------
    (N, 4) Masked ndarray
        Gradients for each face of the cell.

    Examples
    --------
    Create a grid with two cells.

    >>> from landlab import RasterModelGrid
    >>> grid = RasterModelGrid(3, 4)
    >>> x = np.array([0., 0., 0., 0.,
    ...               0., 0., 1., 1.,
    ...               3., 3., 3., 3.])

    A decrease in quantity across a face is a negative gradient.

    >>> grid.calc_grad_across_cell_faces(x) # doctest: +NORMALIZE_WHITESPACE
    masked_array(data =
     [[ 1.  3.  0.  0.]
     [ 0.  2. -1. -1.]],
                 mask =
     False,
           fill_value = 1e+20)

    >>> grid = RasterModelGrid((3, 4), spacing=(2, 1))
    >>> grid.calc_grad_across_cell_faces(x) # doctest: +NORMALIZE_WHITESPACE
    masked_array(data =
     [[ 1.   1.5  0.   0. ]
     [ 0.   1.  -1.  -0.5]],
                  mask =
     False,
           fill_value = 1e+20)
    """
    padded_node_values = np.empty(node_values.size + 1, dtype=float)
    padded_node_values[-1] = BAD_INDEX_VALUE
    padded_node_values[:-1] = node_values
    cell_ids = make_optional_arg_into_id_array(grid.number_of_cells, *args)
    node_ids = grid.node_at_cell[cell_ids]

    neighbors = grid.active_neighbors_at_node(node_ids)
    if BAD_INDEX_VALUE != -1:
        neighbors = np.where(neighbors == BAD_INDEX_VALUE, -1, neighbors)
    values_at_neighbors = padded_node_values[neighbors]
    masked_neighbor_values = np.ma.array(values_at_neighbors,
                                         mask=neighbors == BAD_INDEX_VALUE)
    values_at_nodes = node_values[node_ids].reshape(len(node_ids), 1)

    out = np.subtract(masked_neighbor_values, values_at_nodes, **kwds)

    out[:, (0, 2)] /= grid.dx
    out[:, (1, 3)] /= grid.dy

    return out