Esempio n. 1
0
def render_imshow_comparisons(mg, step, fig=None, axes=None, show=False):
    if fig is None or axes is None:
        fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(15, 10))
        axes[1, 2].set_visible(False)
    assert axes.shape == (2, 3)

    plt.sca(axes[0, 0])
    imshow_grid_at_node(mg, 'topographic__init_elevation')
    plt.title(f"Initial topography")

    plt.sca(axes[0, 1])
    imshow_grid_at_node(mg, 'topographic__elevation')
    plt.title(f"Topography at {step} steps")

    plt.sca(axes[0, 2])
    z_init = mg['node']['topographic__init_elevation']
    z_final = mg['node']['topographic__elevation']
    imshow_grid_at_node(mg, z_final - z_init)
    plt.title(f"Topographic difference")

    plt.sca(axes[1, 0])
    init_da = mg['node']['init_drainage_area']
    imshow_grid_at_node(mg, np.log10(init_da + 1))
    plt.title(f"Initial drainage network")

    plt.sca(axes[1, 1])
    da = mg['node']['drainage_area']
    imshow_grid_at_node(mg, np.log10(da + 1))
    plt.title(f"Drainage network at {step} steps")

    if show:
        plt.show()
 def show_possible_nodes(self):
     """Once the subsets by aspect and slope have been set, call this
     function to see both the whole elevation map, and the subset of nodes
     that will be searched."""
     possible_core_nodes = np.logical_and(self.steep_nodes,
                                          self.aspect_close_nodes)
     figure(1)
     gridshow.imshow_grid_at_node(self.grid, self.elevs)
     figure(2)
     gridshow.imshow_grid_at_node(self.grid, self.slopes)
     figure(3)
     gridshow.imshow_grid_at_node(self.grid, self.aspect)
     figure(4)
     gridshow.imshow_grid_at_node(self.grid, possible_core_nodes)
     show()
Esempio n. 3
0
 def show_possible_nodes(self):
     """
     Once the subsets by aspect and slope have been set, call this function
     to see both the whole elevation map, and the subset of nodes that
     will be searched.
     """
     possible_core_nodes = np.logical_and(
         self.steep_nodes, self.aspect_close_nodes)
     figure(1)
     gridshow.imshow_grid_at_node(self.grid, self.elevs)
     figure(2)
     gridshow.imshow_grid_at_node(self.grid, self.slopes)
     figure(3)
     gridshow.imshow_grid_at_node(self.grid, self.aspect)
     figure(4)
     gridshow.imshow_grid_at_node(self.grid, possible_core_nodes)
     show()
# Add a fault trace that angles roughly east-northeast.
fault_trace_y = 50.0 + 0.25 * mg.x_of_node

# Find the ID numbers of the nodes north of the fault trace with help from 
# NumPy's `where()` function.
upthrown_nodes = numpy.where(mg.y_of_node > fault_trace_y)

# Add elevation equal to 10m for all the nodes north of the fault, plus 1cm
# for every meter east (just to make it interesting).
z[upthrown_nodes] += 10.0 + 0.01 * mg.x_of_node[upthrown_nodes]

# Show the newly created initial topography using Landlab's *imshow_node_grid*
# plotting function (which we first need to import).
from landlab.plot.imshow import imshow_grid_at_node
plt.figure(2)
imshow_grid_at_node(mg, 'land_surface__elevation')
plt.show()

# To finish getting set up, we will define two parameters: the transport
# ("diffusivity") coefficient, D, and the time-step size, dt. (The latter is
# set using the Courant condition for a forward-time, centered-space
# finite-difference solution)
D = 0.01  # m2/yr transport coefficient
dt = 0.2 * mg.dx * mg.dx / D

# Boundary conditions: for this example, we'll assume that the east and west
# sides are closed to flow of sediment, but that the north and south sides are
# open. (The order of the function arguments is east, north, west, south)
mg.set_closed_boundaries_at_grid_edges(False, True, False, True)

# One more thing before we run the time loop: we'll create an array to contain
 def define_aspect_node_subset_local(self,
                                     dist_tolerance=4.0,
                                     angle_tolerance=15.0,
                                     dip_dir="E"):
     """ """
     grid = self.grid
     try:
         print("using subset")
         # remember, steep_nodes is already core_nodes.size long
         subset = np.where(self.steep_nodes)[0]
     except NameError:
         print("using all nodes")
         subset = np.arange(grid.core_nodes.size)
     closest_ft_node = np.empty(subset.size, dtype=int)
     angle_to_ft = np.empty_like(closest_ft_node, dtype=float)
     new_angle_to_ft = np.empty_like(closest_ft_node, dtype=float)
     distance_to_ft = np.empty_like(closest_ft_node, dtype=float)
     distance_to_ft.fill(sys.float_info.max)
     new_distance_to_ft = np.empty_like(closest_ft_node, dtype=float)
     for i in self.ft_trace_node_ids:
         grid.calc_distances_of_nodes_to_point(
             (grid.node_x[i], grid.node_y[i]),
             node_subset=grid.core_nodes[subset],
             get_az="angles",
             out_distance=new_distance_to_ft,
             out_azimuth=new_angle_to_ft,
         )
         closer_nodes = new_distance_to_ft < distance_to_ft
         distance_to_ft[closer_nodes] = new_distance_to_ft[closer_nodes]
         angle_to_ft[closer_nodes] = new_angle_to_ft[closer_nodes]
         closest_ft_node[closer_nodes] = i
     self.closest_ft_node = -np.ones(grid.core_nodes.size)
     self.distance_to_ft = -np.ones(grid.core_nodes.size)
     self.angle_to_ft = -np.ones(grid.core_nodes.size)
     self.closest_ft_node[subset] = closest_ft_node
     self.distance_to_ft[subset] = distance_to_ft
     # angle_to_ft is actually the angle_from_ft! So we need to adjust.
     # a second problem is that pts downslope (opposite az) can also be on the line.
     # solution - take a dip_dir input...
     angle_to_ft = (angle_to_ft + np.pi) % (2.0 * np.pi)
     self.angle_to_ft[subset] = angle_to_ft
     # gridshow.imshow_grid_at_node(self.grid, self.distance_to_ft)
     # show()
     # gridshow.imshow_grid_at_node(self.grid, self.angle_to_ft)
     # show()
     # the relevant condition is now that the local aspect and angle to fault
     # are the same...
     # We need to bias the five degrees against distant points, as it's easier
     # to have similar angles in the far field. Rule should be in px - the
     # two angles should be within *angle_tol* px of each other at the ft
     # trace.
     divergence_at_ft = distance_to_ft * np.tan(
         (angle_to_ft - self.aspect[subset]) % np.pi)
     # might be *too* forgiving for close-in nodes
     condition = np.less(np.fabs(divergence_at_ft),
                         grid.dx * dist_tolerance)
     # ...so add another tester; must be w/i 15 degrees of each other:
     diff_angles = np.min(
         [
             np.fabs(angle_to_ft - self.aspect[subset]),
             np.fabs(
                 np.fabs(angle_to_ft - self.aspect[subset]) - 2.0 * np.pi),
         ],
         axis=0,
     )
     self.diff_angles = np.empty(grid.core_nodes.size, dtype=float)
     self.diff_angles.fill(sys.float_info.max)
     self.diff_angles[subset] = diff_angles
     # gridshow.imshow_grid_at_node(self.grid, self.angle_to_ft)
     # show()
     figure(6)
     gridshow.imshow_grid_at_node(
         self.grid,
         np.where(self.diff_angles < 100000.0, self.diff_angles, -1.0))
     condition2 = np.less(diff_angles, angle_tolerance * np.pi / 180.0)
     condition = np.logical_and(condition, condition2)
     core_nodes_size_condition = np.zeros(grid.core_nodes.size, dtype=bool)
     core_nodes_size_condition[subset] = condition
     # gridshow.imshow_grid_at_node(self.grid, core_nodes_size_condition)
     # show()
     # core_nodes_size_condition = np.zeros(grid.core_nodes.size, dtype=bool)
     # core_nodes_size_condition[subset] = condition2
     # gridshow.imshow_grid_at_node(self.grid, core_nodes_size_condition)
     # show()
     self.aspect_close_nodes = core_nodes_size_condition
     print(
         "Calculated and stored nodes with aspects compatible with fault trace..."
     )
     return self.aspect_close_nodes
Esempio n. 6
0
# Modify the boundary conditions of an interior rectangle in the grid

from landlab import RasterModelGrid, CLOSED_BOUNDARY
import numpy as np
from landlab.plot.imshow import imshow_grid_at_node
from matplotlib.pyplot import show

mg = RasterModelGrid((10, 10), 1.)

min_x = 2.5
max_x = 5.
min_y = 3.5
max_y = 7.5

x_condition = np.logical_and(mg.node_x < max_x, mg.node_x > min_x)
y_condition = np.logical_and(mg.node_y < max_y, mg.node_y > min_y)
my_nodes = np.logical_and(x_condition, y_condition)

mg.status_at_node[my_nodes] = CLOSED_BOUNDARY

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

imshow_grid_at_node(mg, z)
show()
Esempio n. 7
0
(da, q) = fa.accumulate_flow()

outlet_node_to_sample = np.argmax(rmg.at_node['drainage_area'])
print('Outlet Node = ' + str(outlet_node_to_sample) + '; Drainage Area= ' +
      str(da[outlet_node_to_sample] / 1000000) + ' km^2; Elev = ' +
      str(round(z[outlet_node_to_sample], 1)) + ' m')

# For each of the links, there is a tail and head and node.
# Look at tail nodes of all links, and look at node area, find link that connects

#the link number that carries the largest q
outlet_link_to_sample = rmg.links_at_node[outlet_node_to_sample][3]

rmg.links_at_node[outlet_node_to_sample]

imshow_grid_at_node(rmg, 'drainage_area')

fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(6, 6))
ax.xaxis.set_visible(False)
ax.set_facecolor("blue")
imshow_grid(rmg,
            z,
            plot_name='Spring Creek',
            var_name='topographic__elevation',
            var_units='m',
            grid_units=('m', 'm'),
            cmap='terrain',
            color_for_closed='white')
ax.plot(rmg.node_x[outlet_node_to_sample],
        rmg.node_y[outlet_node_to_sample],
        'ro',
dt = 20000.

for i in xrange(100):
    print(i)
    fr.route_flow()
    sp.run_one_timestep(dt)
    mg.at_node['topographic__elevation'][mg.core_nodes] += 1.

sf.calculate_steepnesses()
edges = mg.ones('node', dtype=bool)
edges.reshape(mg.shape)[2:-2, 2:-2] = False
steepness_mask = np.logical_or(sf.hillslope_mask, edges)
steepnesses = np.ma.array(mg.at_node['channel__steepness_index'],
                          mask=steepness_mask)
imshow_grid_at_node(mg, 'topographic__elevation')
imshow_grid_at_node(mg, steepnesses, color_for_closed=None,
                    cmap='winter')
plt.show()

dt=10000.
for i in xrange(100):
    print(i)
    fr.route_flow()
    sp.run_one_timestep(dt)
    mg.at_node['topographic__elevation'][mg.core_nodes] += 10.
    if i%5 == 0:
        sf.calculate_steepnesses()
        edges = mg.ones('node', dtype=bool)
        edges.reshape(mg.shape)[2:-2, 2:-2] = False
        steepness_mask = np.logical_or(sf.hillslope_mask, edges)
# want final depth of sinkhole to be 1m deep
dz = 0.5 #[m] the sinkdown nodes are spatially overlapping so 0.5m dz is really 1m of elevation decrease
z[sinkdown_nodes1] -= dz
z[sinkdown_nodes2] -= dz

# fix nodes that overlap that are falsly sinking to the N and S of sinkhole
fixed_nodes1 = np.where(mg.y_of_node > sinkhole_trace_y_upper) 
fixed_nodes2 = np.where(mg.y_of_node < sinkhole_trace_y_lower)

# reset the falsely sinking nodes to zero
z[fixed_nodes1] += dz
z[fixed_nodes2] += dz

# now you can see a solid location of the sinkhole on the grid
imshow_grid_at_node(mg, 'Plan view topography', grid_units = ['m','m'], var_name='Elevation (m)')

#### make the sinkhole more releastic (conical) and show its soluble degradation #######
# parameters
D = 0.005 # radial diffusion constant... run with different values to find most representitive value 
dt = 10 # years

qs = mg.add_zeros('link', 'sediment_flux')

t_plot = 0
dt_plot = 10 # graphically show evolution

for i in range(30): #30 iterations
    g = mg.calc_grad_at_link(z)
    qs[mg.active_links] = D * g[mg.active_links]
    dqsdx = mg.calc_flux_div_at_node(qs)
Esempio n. 10
0
 def define_aspect_node_subset_local(self, dist_tolerance=4., angle_tolerance=15., dip_dir='E'):
     """
     """
     grid = self.grid
     try:
         print('using subset')
         # remember, steep_nodes is already core_nodes.size long
         subset = np.where(self.steep_nodes)[0]
     except NameError:
         print('using all nodes')
         subset = np.arange(grid.core_nodes.size)
     closest_ft_node = np.empty(subset.size, dtype=int)
     angle_to_ft = np.empty_like(closest_ft_node, dtype=float)
     new_angle_to_ft = np.empty_like(closest_ft_node, dtype=float)
     distance_to_ft = np.empty_like(closest_ft_node, dtype=float)
     distance_to_ft.fill(sys.float_info.max)
     new_distance_to_ft = np.empty_like(closest_ft_node, dtype=float)
     for i in self.ft_trace_node_ids:
         grid.calc_distances_of_nodes_to_point((grid.node_x[i], grid.node_y[i]),
                                              node_subset=grid.core_nodes[
                                                  subset], get_az='angles',
                                              out_distance=new_distance_to_ft, out_azimuth=new_angle_to_ft)
         closer_nodes = new_distance_to_ft < distance_to_ft
         distance_to_ft[closer_nodes] = new_distance_to_ft[closer_nodes]
         angle_to_ft[closer_nodes] = new_angle_to_ft[closer_nodes]
         closest_ft_node[closer_nodes] = i
     self.closest_ft_node = -np.ones(grid.core_nodes.size)
     self.distance_to_ft = -np.ones(grid.core_nodes.size)
     self.angle_to_ft = -np.ones(grid.core_nodes.size)
     self.closest_ft_node[subset] = closest_ft_node
     self.distance_to_ft[subset] = distance_to_ft
     # angle_to_ft is actually the angle_from_ft! So we need to adjust.
     # a second problem is that pts downslope (opposite az) can also be on the line.
     # solution - take a dip_dir input...
     angle_to_ft = (angle_to_ft + np.pi) % (2. * np.pi)
     self.angle_to_ft[subset] = angle_to_ft
     #gridshow.imshow_grid_at_node(self.grid, self.distance_to_ft)
     # show()
     #gridshow.imshow_grid_at_node(self.grid, self.angle_to_ft)
     # show()
     # the relevant condition is now that the local aspect and angle to fault
     # are the same...
     # We need to bias the five degrees against distant points, as it's easier
     # to have similar angles in the far field. Rule should be in px - the
     # two angles should be within *angle_tol* px of each other at the ft
     # trace.
     divergence_at_ft = distance_to_ft * \
         np.tan((angle_to_ft - self.aspect[subset]) % np.pi)
     # might be *too* forgiving for close-in nodes
     condition = np.less(np.fabs(divergence_at_ft),
                         grid.dx * dist_tolerance)
     #...so add another tester; must be w/i 15 degrees of each other:
     diff_angles = np.min([np.fabs(angle_to_ft - self.aspect[subset]), np.fabs(
         np.fabs(angle_to_ft - self.aspect[subset]) - 2. * np.pi)], axis=0)
     self.diff_angles = np.empty(grid.core_nodes.size, dtype=float)
     self.diff_angles.fill(sys.float_info.max)
     self.diff_angles[subset] = diff_angles
     #gridshow.imshow_grid_at_node(self.grid, self.angle_to_ft)
     # show()
     figure(6)
     gridshow.imshow_grid_at_node(self.grid, np.where(
         self.diff_angles < 100000., self.diff_angles, -1.))
     condition2 = np.less(diff_angles, angle_tolerance * np.pi / 180.)
     condition = np.logical_and(condition, condition2)
     core_nodes_size_condition = np.zeros(grid.core_nodes.size, dtype=bool)
     core_nodes_size_condition[subset] = condition
     #gridshow.imshow_grid_at_node(self.grid, core_nodes_size_condition)
     # show()
     #core_nodes_size_condition = np.zeros(grid.core_nodes.size, dtype=bool)
     #core_nodes_size_condition[subset] = condition2
     #gridshow.imshow_grid_at_node(self.grid, core_nodes_size_condition)
     # show()
     self.aspect_close_nodes = core_nodes_size_condition
     print('Calculated and stored nodes with aspects compatible with fault trace...')
     return self.aspect_close_nodes
Esempio n. 11
0
#one node/grid cell
len(mg.core_nodes)  # there are 874 core nodes, 126 boundary nodes

# make plan view fault trace by equation of a line y = mx + b
fault_trace_y = 0.25 * mg.x_of_node + 50

# north of the fault trace is the upthrow
upthrown_nodes = np.where(mg.y_of_node > fault_trace_y)
# numpy where function says nodes above fault trace are upthrown

z[upthrown_nodes] += 10 + 0.01 * mg.x_of_node[upthrown_nodes]
# adds 10m of elevation to each upthrown node
# also adds 1cm for each node to the east to make scissor fault feel

from landlab.plot.imshow import imshow_grid_at_node
imshow_grid_at_node(mg, 'topographic__elevation')
# plots a plan view map of elevation

D = 0.01  # m2/yr transport coefficient
dt = 0.2 * mg.dx * mg.dx / D  # D = c dx^2 / dt
dt
# D is diffusivity coefficient
# dt is time step size dt
# dt is 2000 years
# ASK ANDY TO EXPLAIN THIS

# say the north side and south side are open ot sediment flow
# the east and west sides are closed
mg.set_closed_boundaries_at_grid_edges(True, False, True, False)

qs = mg.add_zeros('link', 'sediment_flux')