|
4 | 4 | "cell_type": "markdown", |
5 | 5 | "metadata": {}, |
6 | 6 | "source": [ |
7 | | - "# Introduction to the RockBlock and LayeredRockBlock objects\n" |
| 7 | + "# Introduction to the RockBlock and LayeredRockBlock objects\n", |
| 8 | + "\n", |
| 9 | + "The RockBlock and LayeredRockBlock are two landlab objects meant to make it easier to work with spatially variable lithology that produces spatially variable parameter values (e.g. stream power erodability and diffusivity). \n", |
| 10 | + "\n", |
| 11 | + "In this tutorial we will first use the LayeredRockBlock to erode either dipping layeres or an anticline. Then we will use RockBlock to create inverted topography. \n", |
| 12 | + "\n", |
| 13 | + "To start, we will import the necessary modules. A note: this tutorial uses the [HoloViews package](http://holoviews.org) for visualization. This package is a great tool for dealing with multidimentional annotated data (e.g. an xarray dataset). If you get an error on import, consider updating dask (this is what the author needed to do in April 2018). " |
8 | 14 | ] |
9 | 15 | }, |
10 | 16 | { |
|
31 | 37 | { |
32 | 38 | "cell_type": "markdown", |
33 | 39 | "metadata": {}, |
34 | | - "source": [] |
| 40 | + "source": [ |
| 41 | + "## Part 1: Eroding layered rock\n", |
| 42 | + "\n", |
| 43 | + "First we will create an instance of a LayedRockBlock. Both LayeredRockBlock and RockBlock work closely with a landlab ModelGrid and stores information about rock type at each node. \n", |
| 44 | + "\n", |
| 45 | + "To create a LayeredRock you need the following information:\n", |
| 46 | + "\n", |
| 47 | + "1. A dictionary of rock property attributes. \n", |
| 48 | + "2. A model grid that has the field `'topographic__elevation'` already created.\n", |
| 49 | + "3. A list of elevations that your layers will go through at specified anchor point (default value for the anchor point is (0, 0). \n", |
| 50 | + "4. A functional form in two variables (x and y) that defines the shape of your surface. \n", |
| 51 | + "\n", |
| 52 | + "The use of this function form makes it possible for any function of x and y to be passed to Layered Rock Block.\n", |
| 53 | + "In this example the option for an anticline is currently uncommented, though options for steep and shallow dipping layers are also provided. " |
| 54 | + ] |
35 | 55 | }, |
36 | 56 | { |
37 | 57 | "cell_type": "code", |
|
54 | 74 | "ids = np.tile([0,1], 20) \n", |
55 | 75 | "\n", |
56 | 76 | "# Anticline\n", |
57 | | - "rb = LayeredRockBlock(mg, z0s, ids, x0=5000, y0=5000, function = lambda x, y : ((0.001*x)**2+(0.003*y)**2), attrs=attrs)\n", |
| 77 | + "rb = LayeredRockBlock(mg, z0s, ids, x0=2500, y0=2500, function = lambda x, y : ((0.005*x)**2+(0.005*y)**2), attrs=attrs)\n", |
58 | 78 | "\n", |
59 | 79 | "# Shallow dips\n", |
60 | 80 | "#rb = LayeredRockBlock(mg, z0s, ids, x0=5000, y0=5000, function = lambda x, y : ((0.001*x)+(0.003*y)), attrs=attrs)\n", |
|
66 | 86 | { |
67 | 87 | "cell_type": "markdown", |
68 | 88 | "metadata": {}, |
69 | | - "source": [] |
| 89 | + "source": [ |
| 90 | + "Now that we've created the LayeredRockBlock, model grid fields for each of the LayeredRockBlock attributes exist and have been set to the values of the rock exposed at the surface. \n", |
| 91 | + "\n", |
| 92 | + "Here we plot the value of `'K_sp'` as a function of the model grid. " |
| 93 | + ] |
70 | 94 | }, |
71 | 95 | { |
72 | 96 | "cell_type": "code", |
73 | 97 | "execution_count": null, |
74 | | - "metadata": { |
75 | | - "collapsed": true |
76 | | - }, |
| 98 | + "metadata": {}, |
77 | 99 | "outputs": [], |
78 | 100 | "source": [ |
79 | 101 | "imshow_grid(mg, 'K_sp')" |
|
82 | 104 | { |
83 | 105 | "cell_type": "markdown", |
84 | 106 | "metadata": {}, |
85 | | - "source": [] |
| 107 | + "source": [ |
| 108 | + "As you can see (in the default anticline option) we have concentric elipses of stronger and weaker rock. \n", |
| 109 | + "\n", |
| 110 | + "Next, lets instantiate a FlowAccumulator and a FastscapeEroder to create a simple landscape evolution model. \n", |
| 111 | + "\n", |
| 112 | + "We will point the FastscapeEroder to the model grid field `'K_sp'` so that it will respond to the spatially variable erodabilities created by the LayeredRockBlock. \n", |
| 113 | + "\n", |
| 114 | + "We will also instatiate an xarray dataset used to store the output of our model through time for visualization. " |
| 115 | + ] |
86 | 116 | }, |
87 | 117 | { |
88 | 118 | "cell_type": "code", |
|
108 | 138 | " 'rock_type__id': (('y', 'x', 't'), np.empty((mg.shape[0], mg.shape[1], nts)))},\n", |
109 | 139 | " coords={'x': mg.x_of_node.reshape(mg.shape)[0,:],\n", |
110 | 140 | " 'y': mg.y_of_node.reshape(mg.shape)[:, 1],\n", |
111 | | - " 't': dt*np.arange(nts)})" |
| 141 | + " 't': dt*np.arange(nts)/1e6})" |
112 | 142 | ] |
113 | 143 | }, |
114 | 144 | { |
115 | 145 | "cell_type": "markdown", |
116 | 146 | "metadata": {}, |
117 | | - "source": [] |
| 147 | + "source": [ |
| 148 | + "Here we run the model. In each time step we first run the FlowAccumulator to direct flow and accumulatate drainage area. Then the FastscapeEroder erodes the topography based on the stream power equation using the erodability value in the field`'K_sp'`. We create an uplift field that uplifts only the model grid's core nodes. After uplifting these core nodes, we update the LayeredRockBlock. Importantly, we must tell the LayeredRockBlock how it has been advected upward by uplift. \n", |
| 149 | + "\n", |
| 150 | + "Within each timestep we save information about the model for plotting. " |
| 151 | + ] |
118 | 152 | }, |
119 | 153 | { |
120 | 154 | "cell_type": "code", |
|
139 | 173 | { |
140 | 174 | "cell_type": "markdown", |
141 | 175 | "metadata": {}, |
142 | | - "source": [] |
| 176 | + "source": [ |
| 177 | + "Now that the model has run, lets start by plotting the resulting topography. " |
| 178 | + ] |
143 | 179 | }, |
144 | 180 | { |
145 | 181 | "cell_type": "code", |
146 | 182 | "execution_count": null, |
147 | | - "metadata": { |
148 | | - "collapsed": true |
149 | | - }, |
| 183 | + "metadata": {}, |
150 | 184 | "outputs": [], |
151 | 185 | "source": [ |
152 | | - "imshow_grid(mg, 'topographic__elevation')" |
| 186 | + "imshow_grid(mg, 'topographic__elevation', cmap='viridis')" |
153 | 187 | ] |
154 | 188 | }, |
155 | 189 | { |
156 | 190 | "cell_type": "markdown", |
157 | 191 | "metadata": {}, |
158 | | - "source": [] |
| 192 | + "source": [ |
| 193 | + "The layers of rock clearly influence the form of topography. \n", |
| 194 | + "\n", |
| 195 | + "Next we will use HoloViews to visualize the topography and rock type together. \n", |
| 196 | + "\n", |
| 197 | + "To start, we create a HoloViewDataset from our xarray datastructure. " |
| 198 | + ] |
159 | 199 | }, |
160 | 200 | { |
161 | 201 | "cell_type": "code", |
162 | 202 | "execution_count": null, |
163 | | - "metadata": { |
164 | | - "collapsed": true |
165 | | - }, |
| 203 | + "metadata": {}, |
166 | 204 | "outputs": [], |
167 | 205 | "source": [ |
168 | 206 | "hvds = hv.Dataset(ds)\n", |
|
172 | 210 | { |
173 | 211 | "cell_type": "markdown", |
174 | 212 | "metadata": {}, |
175 | | - "source": [] |
| 213 | + "source": [ |
| 214 | + "Next we specify that we want two images, one showing rock type and one showing topographic elevation. A slider bar " |
| 215 | + ] |
176 | 216 | }, |
177 | 217 | { |
178 | 218 | "cell_type": "code", |
|
236 | 276 | " 'rock_type__id': (('y', 'x', 't'), np.empty((mg2.shape[0], mg2.shape[1], nts)))},\n", |
237 | 277 | " coords={'x': mg2.x_of_node.reshape(mg2.shape)[0,:],\n", |
238 | 278 | " 'y': mg2.y_of_node.reshape(mg2.shape)[:, 1],\n", |
239 | | - " 't': dt*np.arange(nts)})\n", |
| 279 | + " 't': dt*np.arange(nts)/1e6})\n", |
240 | 280 | "half_nts = int(nts/2)\n", |
241 | 281 | "for i in range(half_nts):\n", |
242 | 282 | " fa2.run_one_step()\n", |
|
0 commit comments