Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Geoclaw notebooks #81

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
372 changes: 372 additions & 0 deletions notebooks/geoclaw/Okada.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,372 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# The Okada model for computing seafloor deformation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This [Jupyter notebook](http://www.jupyter.org) can be found in [collection of Clawpack apps](http://www.clawpack.org/apps.html) as the file [`$CLAW/apps/notebooks/geoclaw/Okada.ipynb`](https://github.com/clawpack/apps/tree/master/notebooks/geoclaw/Okada.ipynb). \n",
"To run this notebook, [install Clawpack](http://www.clawpack.org/installing.html), and clone the [apps repository](https://github.com/clawpack/apps)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook is part of the GeoClaw documentation, see \n",
" - <http://www.clawpack.org> For general Clawpack documentation,\n",
" - <http://www.clawpack.org/okada.html> for more documentation on the use of the Okada model in GeoClaw. \n",
" - <http://www.clawpack.org/apps.html> for information on obtaining the *apps* repository. The source for this notebook is maintained in `$CLAW/apps/notebooks/geoclaw/Okada.ipynb`.\n",
" - <http://www.clawpack.org/dtopotools_module.html>: In GeoClaw the Okada model is implemented in `dtopotools.SubFault.okada`, \n",
" \n",
"## Contents\n",
"\n",
"- <a href=\"#examples\">Examples</a>\n",
"- <a href=\"#szthrust\">Typical subduction zone thrust event</a>\n",
"- <a href=\"#strike\">Varying the strike</a>\n",
"- <a href=\"#dip\">Varying the dip</a>\n",
"- <a href=\"#rake\">Varying the rake</a>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Introduction\n",
"\n",
"The \"Okada model\" takes as input the slip on a rectangular patch of a fault deep in the earth and produces the resulting deformation of the earth's surface. For tsunami modeling, we are particularly interested in the vertical motion of the seafloor above the fault. \n",
"\n",
"The Okada model makes many assumptions that only approximate reality, in particular:\n",
" - The earth is modeled as a perfectly elastic half space. The slip is uniform on a rectangular patch and a Greens' function solution to the half space problem is integrated to obtain the vertical deformation at the surface of the half plane. The seafloor topography is ignored in computing the Okada deformation (which is then generally added to the real topography to get the modified topography during the earthquake).\n",
" - The half space is assumed to be isotropic with uniform elastic moduli. The Poisson ratio is generally taken to be 0.25 and the shear modulus (or rigidity) is constant, often taken to be $4\\times 10^{11}$ dyne/cm$^2 = 40$ GPa.\n",
" \n",
"Complex earthquake fault surfaces are generally approximated by a subdividing into a set of rectangular subfaults, each of which might have different orientation and slip properties. The Okada model is applied to each and then the resulting surface deformations are summed. The Okada model is linear, so that if a single planar fault is split into subfaults the resulting surface deformation should be independent of the number of pieces its split into.\n",
"\n",
"The GeoClaw *dtopotools.Fault* class provides tools for specifying a fault as a collection of *dtopotools.SubFault* objects, and an object of this class has a method *create_dtopography* that applies the Okada model and returns a *dtopotools.DTopography* object expressing the surface deformation. In this notebook we illustrate the Okada model by working with a fault that consists of a single subfault.\n",
"\n",
"A subfault is specified via the following standard parameters:\n",
" - *length* and *width* of the fault plane (specified in meters below),\n",
" - *latitude* and *longitude* of some point on the fault plane, typically\n",
" either the centroid or the center of the top (shallowest edge),\n",
" - *depth* of the specified point below the sea floor (in meters below),\n",
" - *strike*, the orientation of the top edge, measured in degrees\n",
" clockwise from North, between 0 and 360. The fault plane dips downward\n",
" to the right when moving along the top edge in the strike direction.\n",
" - *dip*, angle at which the plane dips downward from the top edge, a\n",
" positive angle between 0 and 90 degrees.\n",
" - *rake*, the angle in the fault plane in which the slip occurs,\n",
" measured in degrees counterclockwise from the strike direction.\n",
" Between -180 and 180.\n",
" - *slip > 0*, the distance (measured in meters below) the hanging-wall block moves\n",
" relative to the footwall block, in the direction specified by the rake.\n",
" The \"hanging-wall block\" is the one above the dipping fault plane (or to the\n",
" right if you move along the fault in the strike direction).\n",
" \n",
"\n",
"For other descriptions and illustrations, see e.g.\n",
" - <http://www.opensha.org/glossary-strikeDipRake> \n",
" - <http://quakeinfo.ucsd.edu/~gabi/sio15/lectures/Lecture05.html>\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Import modules and define some utility functions used below..."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%pylab inline"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from __future__ import print_function\n",
"from clawpack.geoclaw import dtopotools\n",
"from clawpack.visclaw.JSAnimation import IPython_display\n",
"import clawpack.visclaw.JSAnimation.JSAnimation_frametools as J"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def set_fault(strike, dip, rake, depth):\n",
" \"\"\"\n",
" Set the subfault parameters.\n",
" Most are fixed for the examples below, \n",
" and only the strike, dip, and rake will be varied.\n",
" \"\"\"\n",
" subfault = dtopotools.SubFault()\n",
" subfault.strike = strike\n",
" subfault.dip = dip\n",
" subfault.rake = rake\n",
" subfault.length = 100.e3\n",
" subfault.width = 50.e3\n",
" subfault.depth = depth\n",
" subfault.slip = 1.\n",
" subfault.longitude = 0.\n",
" subfault.latitude = 0.\n",
" subfault.coordinate_specification = \"top center\"\n",
"\n",
" fault = dtopotools.Fault()\n",
" fault.subfaults = [subfault]\n",
" return fault, subfault\n",
"\n",
"# Create a sample fault and print out some information about it...\n",
"fault, subfault = set_fault(0,0,0,5e3)\n",
"print(\"This sample fault has %s meter of slip over a %s by %s km patch\" \\\n",
" % (subfault.slip,subfault.length/1e3,subfault.width/1e3))\n",
"print(\"With shear modulus %4.1e Pa the seismic moment is %4.1e\" % (subfault.mu, subfault.Mo()))\n",
"print(\" corresponding to an earthquake with moment magnitude %s\" % fault.Mw())\n",
"print(\"The depth at the top edge of the fault plane is %s km\" % (subfault.depth/1e3))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def plot_okada(strike, dip, rake, depth, verbose=False):\n",
" \"\"\"\n",
" Make 3 plots to illustrate the Okada solution.\n",
" \"\"\"\n",
"\n",
" fault,subfault = set_fault(strike, dip, rake, depth)\n",
" ax1 = subplot(2,2,1)\n",
" ax2 = subplot(2,2,2)\n",
" ax3 = subplot(2,2,3)\n",
" ax4 = subplot(2,2,4)\n",
"\n",
" # Subfault projection on surface on ax1:\n",
" ax = fault.plot_subfaults(axes=ax1, plot_rake=True, xylim=[-.5,1.5, -1,1])\n",
" text(0.6,0.8,\"Strike = %5.1f\" % strike, fontsize=12)\n",
" text(0.6,0.6,\"Dip = %5.1f\" % dip, fontsize=12)\n",
" text(0.6,0.4,\"Rake = %5.1f\" % rake, fontsize=12)\n",
" text(0.6,0.2,\"Depth = %5.1f km\" % (depth/1e3), fontsize=12)\n",
" ax1.set_ylabel('latitude (degrees)')\n",
"\n",
" # Depth profile on ax3:\n",
" z_top = -subfault.centers[0][2] / 1e3 # convert to km\n",
" z_bottom = -subfault.centers[2][2] / 1e3 # convert to km\n",
" ax3.plot([0,cos(subfault.dip*pi/180.)*subfault.width/1.e3], [z_top, z_bottom])\n",
" ax3.set_xlim(-50,150)\n",
" ax3.set_ylim(-55,0)\n",
" ax3.set_xlabel('distance orthogonal to strike')\n",
" ax3.set_ylabel('depth (km)')\n",
" ax3.set_title('Depth profile')\n",
" \n",
" \n",
" # Grid to use for evaluating and plotting dz\n",
" x = numpy.linspace(-0.5, 1., 101)\n",
" y = numpy.linspace(-1., 1., 101)\n",
" times = [1.]\n",
"\n",
" # color map of deformation dz on ax2:\n",
" fault.create_dtopography(x,y,times,verbose=verbose)\n",
" dtopo = fault.dtopo\n",
" dtopo.plot_dZ_colors(t=1., axes=ax2)\n",
" \n",
" # transect of dz on ax4:\n",
" dZ = dtopo.dZ[-1,50,:]\n",
" ax4.plot(x,dZ)\n",
" ax4.set_ylim(-0.5,0.5)\n",
" ax4.set_title('Transect of dz along y=0')\n",
" ax4.set_xlabel('Longitude (degrees)')\n",
" ax4.set_ylabel('Seafloor deformation (m)')\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div id=\"examples\"></div>\n",
"## Examples\n",
"\n",
"<div id=\"szthrust\"></div>\n",
"### Typical subduction zone thrust event\n",
"\n",
"For a subduction zone earthquake, the rake is generally close to 90 degrees. In the first example below we take it to be 80 degrees -- note that the green line on the fault plane extending from the centroid in the rake direction is 80 degrees counterclockwise from north (the strike direction, since *strike = 0*). \n",
"\n",
"Note that the fault plane plot shows the projection of the fault plane on the flat surface. It dips down to the right as seen in the depth profile. The *dip* is 10 degrees and the fault extends from a depth of 5 km at the up-dip edge to about 14 km at the downdip edge. Note that above the width of the subfault is set to 50 km and that the \"Fault planes\" plot axes are in degrees. This fault is located at the equator where 1 degree is approximate 111 km in both directions.\n",
"\n",
"The rock above the fault plane (the hanging block) is moving to the left relative to the lower block (as shown by the green line) and hence the rock above the fault will be compressed to the left and bulge upwards. The rock to the right is under tension and the surface dips downwards as a result. This can be seen in the \"seafloor deformation\" plot, where the colors indicate meters of vertical motion. \n",
"\n",
"The *slip* on this subfault was set to 1 meter above. Since the Okada model is linear, changing the slip to some other value would simply multiply the deformation by the same factor everywhere."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fig=figure(figsize=(10,10))\n",
"plot_okada(strike=0, dip=10, rake=80, depth=5e3, verbose=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div id=\"strike\"></div>\n",
"## Varying the strike\n",
"\n",
"Changing the strike simply rotates the fault and the resulting deformation. The animation below illustrates this...\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plotdir = 'okada_strike_plots'\n",
"J.make_plotdir(plotdir, clobber=True)\n",
"fig=figure(figsize=(10,10))\n",
"for k,strike in enumerate(linspace(0,340,18)):\n",
" clf()\n",
" plot_okada(strike, 10., 80., 5e3)\n",
" J.save_frame(k, plotdir=plotdir, verbose=False)\n",
" \n",
"clf()\n",
"anim = J.make_anim(plotdir)\n",
"anim"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div id=\"dip\"></div>\n",
"## Varying the dip\n",
"\n",
"When *dip=0* the fault plane is horizontal. If the *rake* is near 90 degrees we expect compression and uplift to the left and subsidence to the right, as illustrated above. \n",
"\n",
"When the *dip=90* the fault plane is vertical with the hanging-wall block to the right moving upward and the footwall block to the left moving downward. We then expect to see uplift on the right and subsidence on the left, opposite to what is seen when *dip=0*. \n",
"\n",
"Note how this transition takes place as the dip is changed..."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plotdir = 'okada_dip_plots'\n",
"J.make_plotdir(plotdir, clobber=True)\n",
"fig=figure(figsize=(10,10))\n",
"for k,dip in enumerate(linspace(0,90,10)):\n",
" clf()\n",
" plot_okada(0., dip, 90., 5e3)\n",
" J.save_frame(k, plotdir=plotdir, verbose=False)\n",
" \n",
"clf()\n",
"anim = J.make_anim(plotdir)\n",
"anim"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div id=\"rake\"></div>\n",
"## Varying the rake\n",
"\n",
"If we fix the *dip* at 10 degrees and vary the direction of slip on the fault plane (the *rake*), we get the following patterns:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plotdir = 'okada_rake_plots'\n",
"J.make_plotdir(plotdir, clobber=True)\n",
"fig=figure(figsize=(9,9))\n",
"for k,rake in enumerate(linspace(-90,90,19)):\n",
" clf()\n",
" plot_okada(0., 10., rake, 5e3)\n",
" J.save_frame(k, plotdir=plotdir, verbose=False)\n",
" \n",
"clf()\n",
"anim = J.make_anim(plotdir)\n",
"anim"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div id=\"depth\"></div>\n",
"## Varying the depth\n",
"\n",
"If the fault surface is near the surface the surface deformation will be more concentrated near the fault plane than if the fault is deeper, as the next animation illustrates.\n",
"\n",
"Note that the grid used in this example for evaluting the seafloor deformation *dz* does not extend out far enough to capture all of the deformation, particularly for deeper faults!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plotdir = 'okada_depth_plots'\n",
"J.make_plotdir(plotdir, clobber=True)\n",
"fig=figure(figsize=(9,9))\n",
"for k,depth in enumerate(arange(0,40,2)*1e3):\n",
" clf()\n",
" plot_okada(0., 10., 80, depth)\n",
" J.save_frame(k, plotdir=plotdir, verbose=False)\n",
" \n",
"clf()\n",
"anim = J.make_anim(plotdir)\n",
"anim"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"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.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
Loading