\n",
"For more Landlab tutorials, click here: https://landlab.readthedocs.io/en/latest/user_guide/tutorials.html\n",
"\n",
"\n",
"In this example we will:\n",
"* create a Landlab component that solves the (1D) flexure equation\n",
"* apply a point load\n",
"* run the component\n",
"* plot some output\n",
"* apply a distributed load\n",
"\n",
"(Note that this tutorial uses the one-dimensional flexure component, `Flexure1D`. A separate tutorial notebook, \"lots_of_loads\", explores the two-dimensional elastic flexure component `Flexure`.)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A bit of magic so that we can plot within this notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# %matplotlib inline\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create the grid\n",
"\n",
"We are going to build a uniform rectilinear grid with a node spacing of 100 km in the *y*-direction and 10 km in the *x*-direction on which we will solve the flexure equation.\n",
"\n",
"First we need to import *RasterModelGrid*."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from landlab import RasterModelGrid"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Create a rectilinear grid with a spacing of 100 km between rows and 10 km between columns. The numbers of rows and columms are provided as a `tuple` of `(n_rows, n_cols)`, in the same manner as similar numpy functions. The spacing is also a `tuple`, `(dy, dx)`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"grid = RasterModelGrid((3, 800), xy_spacing=(100e3, 10e3))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"grid.dy, grid.dx"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create the component"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we create the flexure component and tell it to use our newly created grid. First, though, we'll examine the Flexure component a bit."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from landlab.components import Flexure1D"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `Flexure1D` component, as with most landlab components, will require our grid to have some data that it will use. We can get the names of these data fields with the `input_var_names` attribute of the component *class*."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Flexure1D.input_var_names"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We see that flexure uses just one data field: the change in lithospheric loading. Landlab component classes can provide additional information about each of these fields. For instance, to see the units for a field, use the `var_units` method."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Flexure1D.var_units('lithosphere__increment_of_overlying_pressure')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To print a more detailed description of a field, use `var_help`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Flexure1D.var_help('lithosphere__increment_of_overlying_pressure')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"What about the data that `Flexure1D` provides? Use the `output_var_names` attribute."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Flexure1D.output_var_names"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Flexure1D.var_help('lithosphere_surface__increment_of_elevation')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now that we understand the component a little more, create it using our grid."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"grid.add_zeros(\"lithosphere__increment_of_overlying_pressure\", at=\"node\")\n",
"\n",
"flex = Flexure1D(grid, method='flexure')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Add a point load"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First we'll add just a single point load to the grid. We need to call the `update` method of the component to calculate the resulting deflection (if we don't run `update` the deflections would still be all zeros).\n",
"\n",
"Use the `load_at_node` attribute of `Flexure1D` to set the loads. Notice that `load_at_node` has the same shape as the grid. Likewise, `x_at_node` and `dz_at_node` also reshaped."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"flex.load_at_node[1, 200] = 1e6\n",
"flex.update()\n",
"plt.plot(flex.x_at_node[1, :400] / 1000., flex.dz_at_node[1, :400])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Before we make any changes, reset the deflections to zero."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"flex.dz_at_node[:] = 0."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we will double the effective elastic thickness but keep the same point load. Notice that, as expected, the deflections are more spread out."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"flex.eet *= 2.\n",
"flex.update()\n",
"plt.plot(flex.x_at_node[1, :400] / 1000., flex.dz_at_node[1, :400])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Add some loading\n",
"We will now add a distributed load. As we saw above, for this component, the name of the attribute that holds the applied loads is `load_at_node`. For this example we create a loading that increases linearly of the center portion of the grid until some maximum. This could by thought of as the water load following a sea-level rise over a (linear) continental shelf."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"flex.load_at_node[1, :100] = 0.\n",
"flex.load_at_node[1, 100:300] = np.arange(200) * 1e6 / 200.\n",
"flex.load_at_node[1, 300:] = 1e6"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.plot(flex.load_at_node[1, :400])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Update the component to solve for deflection\n",
"Clear the current deflections, and run `update` to get the new deflections."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"flex.dz_at_node[:] = 0.\n",
"flex.update()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"plt.plot(flex.x_at_node[1, :400] / 1000., flex.dz_at_node[1, :400])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Exercise: try maintaining the same loading distribution but double the effective elastic thickness."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Click here for more Landlab tutorials"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 1
}