{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Using the Landlab 1D flexure component\n", "\n", "
\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 }