From fac90fee37a691af5b1dcb9df1775cb0bab4407b Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 07:53:10 -0600 Subject: [PATCH 01/52] Add script that will run a notebook(s). --- run_notebook.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100755 run_notebook.py diff --git a/run_notebook.py b/run_notebook.py new file mode 100755 index 0000000..dd7d8bf --- /dev/null +++ b/run_notebook.py @@ -0,0 +1,62 @@ +#! /usr/bin/env python +from __future__ import print_function + +import os +import sys +import argparse +import tempfile +import subprocess + +from scripting.unix import system, check_output +from scripting.contexts import cd +from scripting.prompting import success, error + + +def convert_notebook(notebook): + script = check_output(['jupyter', 'nbconvert', '--to', 'python', + '--stdout', notebook]) + return script + + +def run_notebook(notebook): + with cd(os.path.dirname(notebook)): + script = convert_notebook(os.path.basename(notebook)) + _, script_file = tempfile.mkstemp(prefix='.', suffix='.py', dir='.') + with open(script_file, 'w') as fp: + fp.write(script) + try: + subprocess.check_call(['ipython', script_file]) + except Exception: + raise + finally: + os.remove(script_file) + + +def main(): + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('notebook', type=str, nargs='+', + help='Notebook to test.') + + args = parser.parse_args() + + failures, passed = [], [] + for notebook in args.notebook: + try: + run_notebook(notebook) + except subprocess.CalledProcessError: + error(notebook) + failures.append(notebook) + else: + success(notebook) + passed.append(notebook) + + if failures: + print('Failed notebooks:') + print(os.linesep.join(failures)) + + return len(failures) + + +if __name__ == '__main__': + sys.exit(main()) From 2da4022a041bc12c35ef1f167e63dbef490d997d Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 07:53:39 -0600 Subject: [PATCH 02/52] Add a template notebook for landlab tutorials. --- tutorial_template.ipynb | 125 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 tutorial_template.ipynb diff --git a/tutorial_template.ipynb b/tutorial_template.ipynb new file mode 100644 index 0000000..f7dd2b4 --- /dev/null +++ b/tutorial_template.ipynb @@ -0,0 +1,125 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "# Using the Landlab flexure component\n", + "\n", + "
\n", + " For instructions on how to run an interactive iPython notebook, click here: https://github.com/landlab/tutorials/blob/master/README.md
\n", + "For more Landlab tutorials, click here: https://github.com/landlab/landlab/wiki/Tutorials\n", + "
\n", + "\n", + "In this tutorial we will:\n", + "* do this\n", + "* do that\n", + "* do the other thing" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "A bit of magic so that we can plot within this notebook." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "deletable": true, + "editable": true + }, + "outputs": [], + "source": [ + "%matplotlib auto\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "## This\n", + "\n", + "Here we will do this." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "## That\n", + "\n", + "Now we will do that." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "## The other thing\n", + "\n", + "Finally we will do the other thing." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "### Click here for more Landlab tutorials" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} From 26f5992be760057bc975f23563dc26184d02f40a Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 07:55:41 -0600 Subject: [PATCH 03/52] Use new script to run all notebooks. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 659d039..a99eeac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,6 @@ install: - export PATH="$HOME/miniconda/bin:$PATH" - conda install -q -c https://conda.anaconda.org/landlab/label/dev landlab script: -- python .ci/run_tutorials.py +- ./run_notebook.py **/*.ipynb virtualenv: system_site_packages: false From 75427b5baad41ba7516f68f5d02c2e35ceaa0b3e Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 08:03:38 -0600 Subject: [PATCH 04/52] Clean up Travis CI config file. --- .travis.yml | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a99eeac..27e4b1c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,15 +3,37 @@ env: - TRAVIS_PYTHON_VERSION="2.7" - TRAVIS_PYTHON_VERSION="3.4" - TRAVIS_PYTHON_VERSION="3.5" + global: + - CONDA_PREFIX=$HOME/miniconda + - MINICONDA_URL_BASE="https://repo.continuum.io/miniconda/Miniconda3-latest" os: - linux - osx sudo: false +before_install: +- | + if [[ $TRAVIS_OS_NAME == "osx" ]]; then + brew remove --force $(brew list) + brew cleanup -s + rm -rf $(brew --cache) + fi install: - echo "Build on $TRAVIS_OS_NAME for Python $TRAVIS_PYTHON_VERSION" -- bash .ci/travis/install_python.sh -- export PATH="$HOME/miniconda/bin:$PATH" -- conda install -q -c https://conda.anaconda.org/landlab/label/dev landlab +- | + if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + OS="MacOSX-x86_64" + else + OS="Linux-x86_64" + fi +- curl $MINICONDA_URL_BASE-$OS.sh > $HOME/minconda.sh +- bash $HOME/minconda.sh -b -p $CONDA_PREFIX +- export PATH="$CONDA_PREFIX/bin:$PATH" +- hash -r +- conda config --set always_yes yes --set changeps1 no +- conda install python=$TRAVIS_PYTHON_VERSION +- conda install py-scripting -c csdms-stack +- conda install landlab jupyter -c landlab +- conda info -a && conda list script: - ./run_notebook.py **/*.ipynb virtualenv: From 8c9b0549261678938ba6c35d4631b19243d11f80 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 10:52:11 -0600 Subject: [PATCH 05/52] Change matplotlib inline magic to auto. --- run_notebook.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/run_notebook.py b/run_notebook.py index dd7d8bf..31ab7ee 100755 --- a/run_notebook.py +++ b/run_notebook.py @@ -6,6 +6,7 @@ import argparse import tempfile import subprocess +import re from scripting.unix import system, check_output from scripting.contexts import cd @@ -15,7 +16,10 @@ def convert_notebook(notebook): script = check_output(['jupyter', 'nbconvert', '--to', 'python', '--stdout', notebook]) - return script + + p = re.compile("^get_ipython\(\)\.magic\(u'matplotlib (?P\w+)'\)", + re.MULTILINE) + return p.sub("get_ipython().magic(u'matplotlib auto')", script) def run_notebook(notebook): From 1b646415eba5cd29143c733be6e424512716a5cc Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 14:24:04 -0600 Subject: [PATCH 06/52] Remove ipython magic pinfo commands from script. --- run_notebook.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/run_notebook.py b/run_notebook.py index 31ab7ee..69ebbe5 100755 --- a/run_notebook.py +++ b/run_notebook.py @@ -19,7 +19,12 @@ def convert_notebook(notebook): p = re.compile("^get_ipython\(\)\.magic\(u'matplotlib (?P\w+)'\)", re.MULTILINE) - return p.sub("get_ipython().magic(u'matplotlib auto')", script) + script = p.sub("get_ipython().magic(u'matplotlib auto')", script) + p = re.compile("(?P^get_ipython\(\)\.magic\(u'pinfo[\w\s]+'\))", + re.MULTILINE) + script = p.sub("# \\1", script) + + return script def run_notebook(notebook): From 14550642c385e71065230133c580f3988e513722 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 14:48:33 -0600 Subject: [PATCH 07/52] Add matplotlib magic. --- .../Comparison of FlowDirectors.ipynb | 84 +++++++------------ .../Introduction to FlowDirectors.ipynb | 49 +++++------ .../Introduction to the FlowAccumulator.ipynb | 71 +++++++--------- 3 files changed, 78 insertions(+), 126 deletions(-) diff --git a/flow_direction_and_accumulation/Comparison of FlowDirectors.ipynb b/flow_direction_and_accumulation/Comparison of FlowDirectors.ipynb index bceae7b..72f8950 100644 --- a/flow_direction_and_accumulation/Comparison of FlowDirectors.ipynb +++ b/flow_direction_and_accumulation/Comparison of FlowDirectors.ipynb @@ -29,11 +29,21 @@ "First, we import the necessary python modules and make a small plotting routine. " ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "%matplotlib auto" + ] + }, { "cell_type": "code", "execution_count": 1, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [], @@ -95,7 +105,6 @@ "cell_type": "code", "execution_count": 2, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -121,9 +130,7 @@ { "cell_type": "code", "execution_count": 3, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -147,9 +154,7 @@ { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -200,7 +205,6 @@ "cell_type": "code", "execution_count": 5, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -234,7 +238,6 @@ "cell_type": "code", "execution_count": 6, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -266,7 +269,6 @@ "cell_type": "code", "execution_count": 7, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -297,9 +299,7 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -330,9 +330,7 @@ { "cell_type": "code", "execution_count": 9, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -366,7 +364,6 @@ "cell_type": "code", "execution_count": 10, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -400,7 +397,6 @@ "cell_type": "code", "execution_count": 11, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -432,7 +428,6 @@ "cell_type": "code", "execution_count": 12, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -463,9 +458,7 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -494,9 +487,7 @@ { "cell_type": "code", "execution_count": 14, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -532,7 +523,6 @@ "cell_type": "code", "execution_count": 15, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -564,7 +554,6 @@ "cell_type": "code", "execution_count": 16, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -596,7 +585,6 @@ "cell_type": "code", "execution_count": 17, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -627,9 +615,7 @@ { "cell_type": "code", "execution_count": 18, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -658,9 +644,7 @@ { "cell_type": "code", "execution_count": 19, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -697,9 +681,7 @@ { "cell_type": "code", "execution_count": 20, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -735,9 +717,7 @@ { "cell_type": "code", "execution_count": 21, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -766,9 +746,7 @@ { "cell_type": "code", "execution_count": 22, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -797,9 +775,7 @@ { "cell_type": "code", "execution_count": 23, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -828,9 +804,7 @@ { "cell_type": "code", "execution_count": 24, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -869,21 +843,21 @@ ], "metadata": { "kernelspec": { - "display_name": "Python [conda root]", + "display_name": "Python 2", "language": "python", - "name": "conda-root-py" + "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 3 + "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.5.2" + "pygments_lexer": "ipython2", + "version": "2.7.13" } }, "nbformat": 4, diff --git a/flow_direction_and_accumulation/Introduction to FlowDirectors.ipynb b/flow_direction_and_accumulation/Introduction to FlowDirectors.ipynb index 09616c3..4607cb2 100644 --- a/flow_direction_and_accumulation/Introduction to FlowDirectors.ipynb +++ b/flow_direction_and_accumulation/Introduction to FlowDirectors.ipynb @@ -27,11 +27,21 @@ "First, we import the necessary python modules and make a small plotting routine. " ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "%matplotlib auto" + ] + }, { "cell_type": "code", "execution_count": 1, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [], @@ -92,7 +102,6 @@ "cell_type": "code", "execution_count": 2, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -129,7 +138,6 @@ "cell_type": "code", "execution_count": 3, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [], @@ -152,7 +160,6 @@ "cell_type": "code", "execution_count": 4, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [ @@ -198,7 +205,6 @@ "cell_type": "code", "execution_count": 5, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -232,7 +238,6 @@ "cell_type": "code", "execution_count": 6, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -263,9 +268,7 @@ { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -294,9 +297,7 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -334,9 +335,7 @@ { "cell_type": "code", "execution_count": 9, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -361,9 +360,7 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -393,7 +390,6 @@ "cell_type": "code", "execution_count": 11, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -436,7 +432,6 @@ "cell_type": "code", "execution_count": 12, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -471,9 +466,7 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -517,21 +510,21 @@ ], "metadata": { "kernelspec": { - "display_name": "Python [conda root]", + "display_name": "Python 2", "language": "python", - "name": "conda-root-py" + "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 3 + "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.5.2" + "pygments_lexer": "ipython2", + "version": "2.7.13" } }, "nbformat": 4, diff --git a/flow_direction_and_accumulation/Introduction to the FlowAccumulator.ipynb b/flow_direction_and_accumulation/Introduction to the FlowAccumulator.ipynb index 6a00a98..0f67df1 100644 --- a/flow_direction_and_accumulation/Introduction to the FlowAccumulator.ipynb +++ b/flow_direction_and_accumulation/Introduction to the FlowAccumulator.ipynb @@ -17,11 +17,21 @@ "First, we import the necessary python modules and make a small plotting routine. " ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "%matplotlib auto" + ] + }, { "cell_type": "code", "execution_count": 1, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [], @@ -83,9 +93,7 @@ { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -128,9 +136,7 @@ { "cell_type": "code", "execution_count": 3, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "fa = FlowAccumulator(mg)\n", @@ -187,9 +193,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -217,7 +221,6 @@ "cell_type": "code", "execution_count": 6, "metadata": { - "collapsed": false, "scrolled": false }, "outputs": [ @@ -246,9 +249,7 @@ { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -281,9 +282,7 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -309,9 +308,7 @@ { "cell_type": "code", "execution_count": 9, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -347,9 +344,7 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -491,9 +486,7 @@ { "cell_type": "code", "execution_count": 14, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -520,9 +513,7 @@ { "cell_type": "code", "execution_count": 15, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -549,9 +540,7 @@ { "cell_type": "code", "execution_count": 16, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -580,9 +569,7 @@ { "cell_type": "code", "execution_count": 17, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -615,9 +602,7 @@ { "cell_type": "code", "execution_count": 18, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -667,21 +652,21 @@ ], "metadata": { "kernelspec": { - "display_name": "Python [conda root]", + "display_name": "Python 2", "language": "python", - "name": "conda-root-py" + "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 3 + "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.5.2" + "pygments_lexer": "ipython2", + "version": "2.7.13" } }, "nbformat": 4, From 0b967d16fe962d4efc59e0935d9d41107697384b Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 14:51:37 -0600 Subject: [PATCH 08/52] Remove from __future__ imports. --- mappers/mappers.ipynb | 65 +++++++----------------- mappers/mappers_unexpanded.ipynb | 65 +++++++----------------- overland_flow/overland_flow_driver.ipynb | 30 +++-------- 3 files changed, 42 insertions(+), 118 deletions(-) diff --git a/mappers/mappers.ipynb b/mappers/mappers.ipynb index 6af1238..3a10cab 100644 --- a/mappers/mappers.ipynb +++ b/mappers/mappers.ipynb @@ -37,9 +37,7 @@ { "cell_type": "code", "execution_count": 1, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "from landlab import RasterModelGrid\n", @@ -59,12 +57,9 @@ { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ - "from __future__ import print_function\n", "def show_node_values(mg, u):\n", " for r in range(mg.number_of_node_rows - 1, -1, -1):\n", " for c in range(mg.number_of_node_columns):\n", @@ -75,9 +70,7 @@ { "cell_type": "code", "execution_count": 3, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -103,9 +96,7 @@ { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -148,9 +139,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -198,9 +187,7 @@ { "cell_type": "code", "execution_count": 6, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -242,9 +229,7 @@ { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -292,9 +277,7 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -322,9 +305,7 @@ { "cell_type": "code", "execution_count": 9, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -351,9 +332,7 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -397,9 +376,7 @@ { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -445,9 +422,7 @@ { "cell_type": "code", "execution_count": 12, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -482,9 +457,7 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -527,9 +500,7 @@ { "cell_type": "code", "execution_count": 14, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -577,9 +548,7 @@ { "cell_type": "code", "execution_count": 15, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -638,9 +607,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.13" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } diff --git a/mappers/mappers_unexpanded.ipynb b/mappers/mappers_unexpanded.ipynb index 9324572..0dc8fc4 100644 --- a/mappers/mappers_unexpanded.ipynb +++ b/mappers/mappers_unexpanded.ipynb @@ -36,9 +36,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "from landlab import RasterModelGrid\n", @@ -58,12 +56,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ - "from __future__ import print_function\n", "def show_node_values(mg, u):\n", " for r in range(mg.number_of_node_rows - 1, -1, -1):\n", " for c in range(mg.number_of_node_columns):\n", @@ -74,9 +69,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "show_node_values(mg, h)" @@ -92,9 +85,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "for i in range(mg.number_of_links):\n", @@ -113,9 +104,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "h_edge = mg.map_mean_of_link_nodes_to_link('surface_water__depth')\n", @@ -139,9 +128,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "h_edge = mg.map_min_of_link_nodes_to_link('surface_water__depth')\n", @@ -159,9 +146,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "h_edge = mg.map_max_of_link_nodes_to_link('surface_water__depth')\n", @@ -185,9 +170,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "z = mg.add_zeros('node', 'topographic__elevation')\n", @@ -205,9 +188,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "w = z + h\n", @@ -224,9 +205,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "h_edge = mg.map_value_at_max_node_to_link(w, h)\n", @@ -246,9 +225,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "h_edge = mg.map_value_at_min_node_to_link(w, h)\n", @@ -270,9 +247,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "h_edge = mg.map_link_head_node_to_link('surface_water__depth')\n", @@ -283,9 +258,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "h_edge = mg.map_link_tail_node_to_link('surface_water__depth')\n", @@ -304,9 +277,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "gamma = 25000.0 # unit weight of fluid, N/m2\n", @@ -330,9 +301,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "h_edge = mg.map_value_at_max_node_to_link(w, h)\n", @@ -367,9 +336,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.13" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } diff --git a/overland_flow/overland_flow_driver.ipynb b/overland_flow/overland_flow_driver.ipynb index a5d2c06..68a82a7 100644 --- a/overland_flow/overland_flow_driver.ipynb +++ b/overland_flow/overland_flow_driver.ipynb @@ -42,8 +42,6 @@ }, "outputs": [], "source": [ - "from __future__ import print_function\n", - "\n", "from landlab.components.overland_flow import OverlandFlow\n", "from landlab.plot.imshow import imshow_grid\n", "from landlab.plot.colors import water_colormap\n", @@ -127,9 +125,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -175,9 +171,7 @@ { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -215,9 +209,7 @@ { "cell_type": "code", "execution_count": 9, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -262,9 +254,7 @@ { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -295,9 +285,7 @@ { "cell_type": "code", "execution_count": 12, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -324,9 +312,7 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -408,9 +394,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.10" + "version": "2.7.13" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } From 6884c21d1b2d132ec9192cb05a64152896d05a0b Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 14:53:33 -0600 Subject: [PATCH 09/52] Fix name of scripting package. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 27e4b1c..1889c72 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ install: - hash -r - conda config --set always_yes yes --set changeps1 no - conda install python=$TRAVIS_PYTHON_VERSION -- conda install py-scripting -c csdms-stack +- conda install scripting -c csdms-stack - conda install landlab jupyter -c landlab - conda info -a && conda list script: From 1c49e69e84cfea98027ecf0bcd6008eca766b6fc Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 15:27:45 -0600 Subject: [PATCH 10/52] Remove use of help function, use ? instead. --- .../reading_dem_into_landlab.ipynb | 167 +++---------- .../reading_dem_into_landlab_unexpanded.ipynb | 221 ++++++++++++------ 2 files changed, 186 insertions(+), 202 deletions(-) diff --git a/reading_dem_into_landlab/reading_dem_into_landlab.ipynb b/reading_dem_into_landlab/reading_dem_into_landlab.ipynb index 006d966..d0959ea 100644 --- a/reading_dem_into_landlab/reading_dem_into_landlab.ipynb +++ b/reading_dem_into_landlab/reading_dem_into_landlab.ipynb @@ -33,9 +33,7 @@ { "cell_type": "code", "execution_count": 1, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "from landlab.io import read_esri_ascii" @@ -51,91 +49,10 @@ { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Help on function read_esri_ascii in module landlab.io.esri_ascii:\n", - "\n", - "read_esri_ascii(asc_file, grid=None, reshape=False, name=None, halo=0)\n", - " Read :py:class:`~landlab.RasterModelGrid` from an ESRI ASCII file.\n", - " \n", - " Read data from *asc_file*, an ESRI_ ASCII file, into a\n", - " :py:class:`~landlab.RasterModelGrid`. *asc_file* is either the name of\n", - " the data file or is a file-like object.\n", - " \n", - " The grid and data read from the file are returned as a tuple\n", - " (*grid*, *data*) where *grid* is an instance of\n", - " :py:class:`~landlab.RasterModelGrid` and *data* is a numpy\n", - " array of doubles with that has been reshaped to have the number of rows\n", - " and columns given in the header.\n", - " \n", - " .. _ESRI: http://resources.esri.com/help/9.3/arcgisengine/java/GP_ToolRef/spatial_analyst_tools/esri_ascii_raster_format.htm\n", - " \n", - " Parameters\n", - " ----------\n", - " asc_file : str of file-like\n", - " Data file to read.\n", - " reshape : boolean, optional\n", - " Reshape the returned array, otherwise return a flattened array.\n", - " name : str, optional\n", - " Add data to the grid as a named field.\n", - " grid : *grid* , optional\n", - " Adds data to an existing *grid* instead of creating a new one.\n", - " halo : integer, optional\n", - " Adds outer border of depth halo to the *grid*. \n", - " \n", - " Returns\n", - " -------\n", - " (grid, data) : tuple\n", - " A newly-created RasterModel grid and the associated node data.\n", - " \n", - " Raises\n", - " ------\n", - " DataSizeError\n", - " Data are not the same size as indicated by the header file.\n", - " MismatchGridDataSizeError\n", - " If a grid is passed, the size of the grid does not agree with the\n", - " size of the data.\n", - " \n", - " Examples\n", - " --------\n", - " Assume that fop is the name of a file that contains text below\n", - " (make sure you have your path correct):\n", - " ncols 3\n", - " nrows 4\n", - " xllcorner 1.\n", - " yllcorner 2.\n", - " cellsize 10.\n", - " NODATA_value -9999\n", - " 0. 1. 2.\n", - " 3. 4. 5.\n", - " 6. 7. 8.\n", - " 9. 10. 11.\n", - " --------\n", - " >>> from landlab.io import read_esri_ascii\n", - " >>> (grid, data) = read_esri_ascii('fop') # doctest: +SKIP\n", - " >>> #grid is an object of type RasterModelGrid with 4 rows and 3 cols\n", - " >>> #data contains an array of length 4*3 that is equal to\n", - " >>> # [9., 10., 11., 6., 7., 8., 3., 4., 5., 0., 1., 2.]\n", - " >>> (grid, data) = read_esri_ascii('fop', halo=1) # doctest: +SKIP\n", - " >>> #now the data has a nodata_value ring of -9999 around it. So array is\n", - " >>> # [-9999, -9999, -9999, -9999, -9999, -9999,\n", - " >>> # -9999, 9., 10., 11., -9999, \n", - " >>> # -9999, 6., 7., 8., -9999, \n", - " >>> # -9999, 3., 4., 5., -9999,\n", - " >>> # -9999, 0., 1., 2. -9999,\n", - " >>> # -9999, -9999, -9999, -9999, -9999, -9999]\n", - "\n" - ] - } - ], + "metadata": {}, + "outputs": [], "source": [ - "help(read_esri_ascii)" + "read_esri_ascii?" ] }, { @@ -166,9 +83,7 @@ { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "from landlab.plot.imshow import imshow_grid" @@ -177,15 +92,13 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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\nSUVORK5CYII=\n", + "image/png": "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\nQmCC\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -209,15 +122,13 @@ { "cell_type": "code", "execution_count": 6, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\nUHAAAAAASUVORK5CYII=\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -242,9 +153,7 @@ { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -264,9 +173,7 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -297,15 +204,13 @@ { "cell_type": "code", "execution_count": 9, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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\nf/9a3LPu0HwBAAAAAElFTkSuQmCC\n", + "image/png": "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\nAAAAAElFTkSuQmCC\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -336,15 +241,13 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -370,15 +273,13 @@ { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -402,15 +303,13 @@ { "cell_type": "code", "execution_count": 12, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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\nRU5ErkJggg==\n", + "image/png": "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\nAABJRU5ErkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -432,9 +331,7 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -480,15 +377,13 @@ { "cell_type": "code", "execution_count": 14, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { - "image/png": "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\ngg==\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAATwAAAEKCAYAAACPJum2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFJNJREFUeJzt3X+wHWV9x/H3hwjFH7QQEzMZEgztpD8YR9CmQEc6Ig42\nUCt0pqVg1ZRBM0yhox2nCnWq4/QfOnYY6xTJZDQlVivSCiVlohij1HYUTVL5FSCSIj8SA2nwF5UR\nSO6nf+wGjpd77zkxz57de/fzmtk5Z/fs3fPlXvjw7D77PCvbRET0wRFtFxARMS4JvIjojQReRPRG\nAi8ieiOBFxG9kcCLiN5I4EVE50haJ2mvpHum+VySPiZpp6S7JL12lOMm8CKii64DVs7w+TnA8npZ\nDVw7ykETeBHROba/Bnx/hl3OAz7lyu3AsZIWDzvui0oV2CRpgWFZ22VEzGEPYe/T4Rxh5cqV3rdv\n30j7btu2bTvw04FNa22vPYSvOx54dGB9V71tz0w/NCsCrwq7rW0XETGHrTjsI+zbt4+tW0f771TS\nT20f/pceolkSeBExO4xtbP5uYOnA+pJ624xyDS8iirEnRloK2AC8o+6tPR34ke0ZT2chLbyIKMaU\nauFJ+ixwJrBA0i7gQ8CRALbXABuBc4GdwFPAxaMcN4EXEcWUmm7O9kVDPjdw2aEeN4EXEQV1e37N\nBF5EFJTAi4ie6PoM6gm8iCjEQJEe2MYk8CKiCDstvIjolQReRPRGAi8iesE5pY2IPkmnRUT0RFp4\nEdET5cbSNiWBFxEF5ZQ2Inoip7QdcgKHNYN1ROc80rlTyK7V87N6FXgR0SSXmtyzMQm8iCgoLbyI\n6I0EXkT0QO8nD5D0EPAkcADYb3uFpPnA56ievfgQcIHtHzRZR0SMQ/fvwxvHU8veYPuUgWdQXgFs\ntr0c2FyvR8QcYB8YaWlLG49pPA9YX79fD5zfQg0R0QiPuLSj6cAz8GVJ2yStrrctGnh+5GPAooZr\niIixqGZLGWVpS9OdFmfY3i3pFcAmSfcPfmjbkqb8p68Dsg7JExouMyLK6PE1PNu769e9wE3AqcDj\nkhYD1K97p/nZtbZXVNf+FjZZZkQU09NTWkkvlXTMwffAm4B7gA3Aqnq3VcDNTdUQEePV51PaRcBN\nkg5+zz/b/qKkLcANki4BHgYuaLCGiBgbU92B1l2NBZ7tB4GTp9j+BPDGpr43ItrT6xuPI6JvEngR\n0RsJvIjogbY7JEaRwIuIghJ4EdETbY6THUUCLyIK6f5sKQm8iCgogRcRPdH1Z1q0MT1URMxZ5cbS\nSlopaYeknZJeMG+mpF+S9O+S7pS0XdLFw46ZFl5EFFLuqWWS5gHXAGcDu4AtkjbYvndgt8uAe23/\nvqSFwA5Jn7H9zHTHTQsvIgqaGHEZ6lRgp+0H6wC7nmry4EEGjlE1YP9lwPeB/TMdNC28iCjiEB/i\ns0DS1oH1tbbXDqwfDzw6sL4LOG3SMf6Baval7wHHAH/sIU3MBF5EFHJIt6XsG3jOzc/rd4E7gLOA\nX6GaZPg/bf94uh/IKW1EFFSs02I3sHRgfUm9bdDFwI2u7AS+C/z6TAdN4EVEMfbESMsItgDLJZ0o\n6SjgQqrT10GPUE81J2kR8GvAgzMdNKe0EVGIGbFDYviR7P2SLgduBeYB62xvl3Rp/fka4G+A6yTd\nDQh4v+19Mx03gRcRxZS88dj2RmDjpG1rBt5/j+rRESNL4EVEQRlaFhG9kcCLiF4oN9KiKQm8iCgo\nLbyI6AVnAtCI6JO08CKiBw5xLG0rEngRUU7HAy9DyyKiN9LCi4hiPNHtFl4CLyIK6f6DuBs/pZU0\nT9K3Jd1Sr8+XtEnSA/XrcU3XEBFjMOrMUC1m4jiu4b0buG9g/Qpgs+3lwOZ6PSLmgqqrdvjSkkYD\nT9IS4PeATwxsPg9YX79fD5zfZA0RMT4dz7vGr+F9FHgf1XzzBy2yvad+/xiwaKoflLQaWF2tndBc\nhRFRTl+v4Ul6M7DX9rbp9nF1hXPK35DttbZXVPPeL2yqzIgoyPZIS1uabOG9DniLpHOBo4FflPRp\n4HFJi23vkbQY2NtgDRExLi13SIyisRae7SttL7G9jGo++q/YfhvVvPSr6t1WATc3VUNEjFnHL+K1\ncR/eVcANki4BHgYuaKGGiCjMdP4S3ngCz/ZtwG31+yeonzQUEXNJy12wI8hIi4gopuN5l8CLiEIM\nZCxtRPSFO95Nm8CLiHK6nXcJvIgoqOMX8RJ4EVFMx/MugRcRhTgTgEZEb+Q+vIjok27nXQIvIsqo\nhpZ1O/ESeBFRxiyYLSWBFxHFpIUXEf2RXtqI6IuON/DG8tSyiOiDgxPiFZoAVNJKSTsk7ZQ05dMN\nJZ0p6Q5J2yX9x7BjpoUXEeUUauFJmgdcA5wN7AK2SNpg+96BfY4FPg6stP2IpFcMO25aeBFRyGgP\n8BmxY+NUYKftB20/A1xP9YjXQW8FbrT9CIDtoc/HSeBFRDGe8EgLsEDS1oFl9aRDHQ88OrC+q942\n6FeB4yTdJmmbpHcMqy+ntBFRxqHdh7evegTrYXkR8JtUj4x4MfANSbfb/s5MPxARUUa5btrdwNKB\n9SX1tkG7gCds/wT4iaSvAScD0wZeTmkjoojCnbRbgOWSTpR0FNWjXjdM2udm4AxJL5L0EuA04L6Z\nDpoWXkSUU6iFZ3u/pMuBW4F5wDrb2yVdWn++xvZ9kr4I3AVMAJ+wfc9Mx03gRUQxJW88tr0R2Dhp\n25pJ6x8BPjLqMRN4EVGGnaFlEdEfmTwgIvojgRcRfdHxvGvuthRJR0v6lqQ764G9H663z5e0SdID\n9etxTdUQEWNU+L6UJjR5H97TwFm2TwZOAVZKOh24AthsezmwuV6PiLnAIy4taSzwXPm/evXIejHV\nAOD19fb1wPlN1RAR43UIY2lb0ehIC0nzJN0B7AU22f4msMj2nnqXx4BF0/zs6oMDi+F/mywzIgpw\n2dlSGtFo4Nk+YPsUqnFwp0p61aTPp23g2l5re0U1wHhhk2VGRAmjns7OxVPaQbZ/CHwVWAk8Lmkx\nQP06dA6riJgl+tppIWlhPSMpkl5MNXPp/VQDgFfVu62iGgAcEXNA109pm7wPbzGwvp6q+QjgBtu3\nSPoGcIOkS4CHgQsarCEixqjNDolRNBZ4tu8CXjPF9ieoJuyLiLnEVHOWdFhGWkREOR0fajHtNTxJ\nGyUtG18pETHbdbzPYsZOi38EviTpA5KOHFdBETFbjZh2Xey0sP0vkr4A/DWwVdI/MXCGbvvqMdQX\nEbNFy623UQy7hvcM8BPgF4Bj6PwlyYho1US3I2LawJO0Eria6r6519p+amxVRcSsY8DdzrsZW3gf\nAP7I9vZxFRMRs9jB6aE6bKZreL8zzkIiYvbreN7lPryIKKjjiZfAi4hCut9Nm8CLiDIMPpDAi4ie\n6HgDL4EXEQV1PPESeBFRhvMg7ojok1l843FExMiqkRZp4UVEH9iQwIuIvsg1vIjoj27nXQIvIgpK\nCy8iesHptIiIHul64DX2IO6I6JmDj2kcZRmBpJWSdkjaKemKGfb7LUn7Jf3hsGMm8CKiEGOPtgwj\naR5wDXAOcBJwkaSTptnvb4EvjVJhAi8iypnwaMtwpwI7bT9o+xngeuC8Kfb7c+DzwN5RDprAi4hy\nPOICCyRtHVhWTzrS8cCjA+u76m3PkXQ88AfAtaOWl06LiCjChzZ5wD7bKw7zKz8KvN/2hKSRfqCx\nwJO0FPgUsIgq09fa/ntJ84HPAcuAh4ALbP+gqToiYnwKTgC6G1g6sL6k3jZoBXB9HXYLgHMl7bf9\nb9MdtMlT2v3Ae22fBJwOXFZfdLwC2Gx7ObC5Xo+I2c6UvIa3BVgu6URJRwEXUj0y9vmvs0+0vcz2\nMuBfgT+bKeygwRae7T3Anvr9k5LuozoHPw84s95tPXAb8P6m6oiIcRmtB3akI9n7JV0O3ArMA9bZ\n3i7p0vrzNT/PccdyDU/SMuA1wDeBRXUYAjxGdco71c+sBuoLmSc0XWJElFBwPjzbG4GNk7ZNGXS2\n/3SUYzbeSyvpZVTdxu+x/ePBz1z972DK/yXYXmt7RXVhc2HTZUZEAaXuw2tKoy08SUdShd1nbN9Y\nb35c0mLbeyQtZsT7ZyKi4wx0/KlljbXwVHWdfBK4z/bVAx9tAFbV71cBNzdVQ0SMV59beK8D3g7c\nLemOettfAVcBN0i6BHgYuKDBGiJiTEyPJwC1/V/AdHcDvrGp742I9nT8GT4ZaRERhbR8ujqKBF5E\nFJPAi4heqAZaJPAioifSwouI3kjgRURvdDvuEngRUUjbNxWPIoEXEcWk0yIieiMtvIjojQReRPRC\nr8fSRkT/ZCxtRPRDemkjoi8MTEx0u42XwIuIYrrdvkvgRURBOaWNiN5I4EVEL9jOSIuI6I9ux10C\nLyIKSi9tRPRGruFFRC9kiveI6I+MtIiIPul23CXwIqIQAwfSaRERfZFT2ojoja4H3hFNHVjSOkl7\nJd0zsG2+pE2SHqhfj2vq+yNivA4+xGeUpS2NBR5wHbBy0rYrgM22lwOb6/WImCMmRlza0ljg2f4a\n8P1Jm88D1tfv1wPnN/X9ETF+JVt4klZK2iFpp6QXNI4k/YmkuyTdLenrkk4edsxxX8NbZHtP/f4x\nYNGYvz8iGlKyl1bSPOAa4GxgF7BF0gbb9w7s9l3g9bZ/IOkcYC1w2kzHba3TwrYlTRv1klYDq6u1\nE8ZUVUQcjoLX504Fdtp+EEDS9VRniM8Fnu2vD+x/O7Bk2EGbvIY3lcclLQaoX/dOt6PttbZX2F4B\nC8dWYET8nA6t02KBpK0Dy+pJRzseeHRgfVe9bTqXAF8YVuK4W3gbgFXAVfXrzWP+/ohoyCGOpd1X\nNWYOn6Q3UAXeGcP2bSzwJH0WOJMqyXcBH6IKuhskXQI8DFzQ1PdHxPgVPKXdDSwdWF9Sb/sZkl4N\nfAI4x/YTww7aWODZvmiaj97Y1HdGRLsKBt4WYLmkE6mC7kLgrYM7SDoBuBF4u+3vjHLQjLSIiCJs\nF+ultb1f0uXArcA8YJ3t7ZIurT9fA3wQeDnwcUkA+4edJifwIqKYkvPh2d4IbJy0bc3A+3cC7zyU\nYybwIqKYro+lTeBFRBGZ8Thm9HChfzleWV2/mHPy+5l90sKLiH4o2GnRlAReRBSRU9qI6JWc0kZE\nP9hp4UVEP5i08CKiR9LCi4heyGMaI6I/cg0vIvokgRcRvWDAOaWNiL5ICy8i+iHX8CKiLwzsP3Cg\n7TJmlMCLiGJy43FE9IJzShsRfTKRXtqI6INMD9Uxj9CtP0a5iXi79c9VSn4/s4ydTouI6AcDB9LC\ni4i+yDW8iOiF9NJGRK+khRcRvTAb5sM7oo0vlbRS0g5JOyVd0UYNEVGWbZ49cGCkpS1jb+FJmgdc\nA5wN7AK2SNpg+95x1xIRZeWU9oVOBXbafhBA0vXAeUACL2IWcx7EPaXjgUcH1ncBp03eSdJqYHW1\ndsI46oqIwzAbruF1ttPC9lpgLYC0ott93REBaeFNaTewdGB9Sb0tImYxk2t4U9kCLJd0IlXQXQi8\ntYU6IqIg2zz9zDNtlzGjsQee7f2SLgduBeYB62xvH3cdEVGWbfanhfdCtjcCG9v47ohozoGOz5bS\nyo3HETH3eGKCZ59+eqRlFMMGKKjysfrzuyS9dtgxO9tLGxGzi22eLXQNb8QBCucAy+vlNOBaprjF\nbVACLyKKmJiY4Kknnyx1uFEGKJwHfMrVk4Nul3SspMW290x30FkSeNv2gR4estMCYN84qhlR6hmu\nazX1uZ5XHu4BnoFbH6lqHsXRkrYOrK+t7709aJQBClPtczwwuwPP9sJh+0jaanvFOOoZReoZrms1\npZ7DY3tl2zUMk06LiOiiUQYoHPIghgReRHTRcwMUJB1FNUBhw6R9NgDvqHtrTwd+NNP1O5glp7Qj\nWjt8l7FKPcN1rabU0xHTDVCQdGn9+Rqqe3nPBXYCTwEXDzuu3PE56CMiSskpbUT0RgIvInpj1gde\nF56PIWmdpL2S7hnYNl/SJkkP1K/HjbGepZK+KuleSdslvbvNmiQdLelbku6s6/lwm/UM1DVP0rcl\n3dKReh6SdLekOw7eo9Z2TXPNrA68geEn5wAnARdJOqmFUq4DJt+DdAWw2fZyYHO9Pi77gffaPgk4\nHbis/r20VdPTwFm2TwZOAVbWvWpt/o4A3g3cN7Dedj0Ab7B9ysD9d12oae6wPWsX4LeBWwfWrwSu\nbKmWZcA9A+s7gMX1+8XAjhZ/TzdTjUlsvSbgJcB/U90131o9VPdsbQbOAm7pwt8MeAhYMGlb63+z\nubTM6hYe0w8t6YJFfv6eoMeARW0UIWkZ8Brgm23WVJ8+3gHsBTbZbrUe4KPA+4DBCdza/psZ+LKk\nbfUzXbpQ05wyl+7D6yzbljT2+38kvQz4PPAe2z+W1FpNtg8Ap0g6FrhJ0qsmfT62eiS9Gdhre5uk\nM6fap6W/2Rm2d0t6BbBJ0v0dqGlOme0tvC4/H+NxSYsB6te94/xySUdShd1nbN/YhZoAbP8Q+CrV\nNc+26nkd8BZJDwHXA2dJ+nSL9QBge3f9uhe4iWrGkNb/ZnPJbA+8UYaftGUDsKp+v4rqOtpYqGrK\nfRK4z/bVbdckaWHdskPSi6muJ97fVj22r7S9xPYyqn9nvmL7bW3VAyDppZKOOfgeeBNwT5s1zUlt\nX0Q83IVqaMl3gP8BPtBSDZ+lmpLmWarriJcAL6e6KP4A8GVg/hjrOYPqetBdwB31cm5bNQGvBr5d\n13MP8MF6e2u/o4HazuT5Tos2/2a/DNxZL9sP/rvchd/RXFoytCwiemO2n9JGRIwsgRcRvZHAi4je\nSOBFRG8k8CKiNxJ4UUw9S8t3Jc2v14+r15e1W1lEJYEXxdh+lOphyFfVm66ievzeQ60VFTEg9+FF\nUfWQtm3AOuBdwCm2n223qohKJg+Iomw/K+kvgS8Cb0rYRZfklDaacA7VULtXDdsxYpwSeFGUpFOo\nJgc4HfiLgzN9RHRBAi+KqWdpuZZq/r1HgI8Af9duVRHPS+BFSe8CHrG9qV7/OPAbkl7fYk0Rz0kv\nbUT0Rlp4EdEbCbyI6I0EXkT0RgIvInojgRcRvZHAi4jeSOBFRG/8P+uRaRrGZZ7WAAAAAElFTkSu\nQmCC\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -536,9 +431,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.13" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } diff --git a/reading_dem_into_landlab/reading_dem_into_landlab_unexpanded.ipynb b/reading_dem_into_landlab/reading_dem_into_landlab_unexpanded.ipynb index d178960..ff04564 100644 --- a/reading_dem_into_landlab/reading_dem_into_landlab_unexpanded.ipynb +++ b/reading_dem_into_landlab/reading_dem_into_landlab_unexpanded.ipynb @@ -32,10 +32,8 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, + "execution_count": 1, + "metadata": {}, "outputs": [], "source": [ "from landlab.io import read_esri_ascii" @@ -50,13 +48,11 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, + "execution_count": 2, + "metadata": {}, "outputs": [], "source": [ - "help(read_esri_ascii)" + "read_esri_ascii?" ] }, { @@ -68,7 +64,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "collapsed": true }, @@ -86,10 +82,8 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, + "execution_count": 4, + "metadata": {}, "outputs": [], "source": [ "from landlab.plot.imshow import imshow_grid" @@ -97,11 +91,20 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "%matplotlib inline\n", "imshow_grid(mg, 'topographic__elevation')" @@ -118,11 +121,20 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nUHAAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import numpy as np\n", "min_z = np.min(z[np.where(z>0)])\n", @@ -140,22 +152,40 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "89" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mg.number_of_node_rows" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "43" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mg.number_of_node_columns" ] @@ -173,11 +203,20 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "mg.set_watershed_boundary_condition(z, 0)\n", "imshow_grid(mg, mg.status_at_node, color_for_closed='blue')" @@ -201,11 +240,20 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "(mg1, z1) = read_esri_ascii('synthetic_landscape.asc', name='topographic__elevation')\n", "imshow_grid(mg1, z1)" @@ -224,11 +272,20 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "mg1.set_closed_boundaries_at_grid_edges(True, True, True, False)\n", "imshow_grid(mg1, mg1.status_at_node, color_for_closed='blue')" @@ -245,11 +302,20 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "(mg2, z2) = read_esri_ascii('synthetic_landscape.asc', name='topographic__elevation', halo=1)\n", "imshow_grid(mg2, z2)" @@ -264,11 +330,25 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'cellsize': 5.0,\n", + " 'ncols': 10,\n", + " 'nodata_value': -9.0,\n", + " 'nrows': 10,\n", + " 'xllcorner': 0.0,\n", + " 'yllcorner': 0.0}" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from landlab.io import read_asc_header\n", "fop = open('synthetic_landscape.asc', 'r')\n", @@ -296,11 +376,20 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "mg2.set_nodata_nodes_to_closed(z2, -9.)\n", "from landlab import FIXED_VALUE_BOUNDARY\n", @@ -342,9 +431,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.13" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } From bda1a77c9a32cdb5f35415503b51ab54e26e3600 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 21:52:39 -0600 Subject: [PATCH 11/52] Make re pattern string bytes objects. --- run_notebook.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/run_notebook.py b/run_notebook.py index 69ebbe5..d6f1a6d 100755 --- a/run_notebook.py +++ b/run_notebook.py @@ -8,6 +8,8 @@ import subprocess import re +import six + from scripting.unix import system, check_output from scripting.contexts import cd from scripting.prompting import success, error @@ -17,12 +19,12 @@ def convert_notebook(notebook): script = check_output(['jupyter', 'nbconvert', '--to', 'python', '--stdout', notebook]) - p = re.compile("^get_ipython\(\)\.magic\(u'matplotlib (?P\w+)'\)", + p = re.compile(b"^get_ipython\(\)\.magic\(u'matplotlib (?P\w+)'\)", re.MULTILINE) - script = p.sub("get_ipython().magic(u'matplotlib auto')", script) - p = re.compile("(?P^get_ipython\(\)\.magic\(u'pinfo[\w\s]+'\))", + script = p.sub(b"get_ipython().magic(u'matplotlib auto')", script) + p = re.compile(b"(?P^get_ipython\(\)\.magic\(u'pinfo[\w\s]+'\))", re.MULTILINE) - script = p.sub("# \\1", script) + script = p.sub(b"# \\1", script) return script @@ -31,7 +33,7 @@ def run_notebook(notebook): with cd(os.path.dirname(notebook)): script = convert_notebook(os.path.basename(notebook)) _, script_file = tempfile.mkstemp(prefix='.', suffix='.py', dir='.') - with open(script_file, 'w') as fp: + with open(script_file, 'wb') as fp: fp.write(script) try: subprocess.check_call(['ipython', script_file]) @@ -64,6 +66,11 @@ def main(): print('Failed notebooks:') print(os.linesep.join(failures)) + if failures: + print('FAILED (failures={nfails})'.format(nfails=len(failures))) + else: + print('OK Ran {ntests} tests'.format(ntests=len(passed))) + return len(failures) From 29042de366594663f50506a3ca46ff2943b89c38 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 22:35:51 -0600 Subject: [PATCH 12/52] Fix finding inline magic in Python 3. --- run_notebook.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/run_notebook.py b/run_notebook.py index d6f1a6d..514269d 100755 --- a/run_notebook.py +++ b/run_notebook.py @@ -19,12 +19,13 @@ def convert_notebook(notebook): script = check_output(['jupyter', 'nbconvert', '--to', 'python', '--stdout', notebook]) - p = re.compile(b"^get_ipython\(\)\.magic\(u'matplotlib (?P\w+)'\)", + script = script.decode('utf-8') + p = re.compile("^get_ipython\(\)\.magic\(u?'matplotlib (?P\w+)'\)", re.MULTILINE) - script = p.sub(b"get_ipython().magic(u'matplotlib auto')", script) - p = re.compile(b"(?P^get_ipython\(\)\.magic\(u'pinfo[\w\s]+'\))", + script = p.sub("get_ipython().magic(u'matplotlib auto')", script) + p = re.compile("(?P^get_ipython\(\)\.magic\(u'pinfo[\w\s]+'\))", re.MULTILINE) - script = p.sub(b"# \\1", script) + script = p.sub("# \\1", script) return script @@ -33,7 +34,7 @@ def run_notebook(notebook): with cd(os.path.dirname(notebook)): script = convert_notebook(os.path.basename(notebook)) _, script_file = tempfile.mkstemp(prefix='.', suffix='.py', dir='.') - with open(script_file, 'wb') as fp: + with open(script_file, 'w') as fp: fp.write(script) try: subprocess.check_call(['ipython', script_file]) From 007023268554840a0d4da9537eea2bc6a9ee73cf Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 22:41:24 -0600 Subject: [PATCH 13/52] Fix print statement. --- python_intro/Python_intro.ipynb | 182 ++++++--------------- python_intro/Python_intro_unexpanded.ipynb | 182 ++++++--------------- 2 files changed, 94 insertions(+), 270 deletions(-) diff --git a/python_intro/Python_intro.ipynb b/python_intro/Python_intro.ipynb index b6b6a7b..e122842 100644 --- a/python_intro/Python_intro.ipynb +++ b/python_intro/Python_intro.ipynb @@ -83,9 +83,7 @@ { "cell_type": "code", "execution_count": 1, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -111,9 +109,7 @@ { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -165,9 +161,7 @@ { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -202,9 +196,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -222,9 +214,7 @@ { "cell_type": "code", "execution_count": 6, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -253,9 +243,7 @@ { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -276,9 +264,7 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -296,9 +282,7 @@ { "cell_type": "code", "execution_count": 9, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -316,9 +300,7 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -336,9 +318,7 @@ { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -356,9 +336,7 @@ { "cell_type": "code", "execution_count": 12, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -379,9 +357,7 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -400,9 +376,7 @@ { "cell_type": "code", "execution_count": 14, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "ename": "KeyError", @@ -434,9 +408,7 @@ { "cell_type": "code", "execution_count": 15, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -456,9 +428,7 @@ { "cell_type": "code", "execution_count": 16, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -507,9 +477,7 @@ { "cell_type": "code", "execution_count": 18, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -535,9 +503,7 @@ { "cell_type": "code", "execution_count": 19, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -557,9 +523,7 @@ { "cell_type": "code", "execution_count": 20, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -586,9 +550,7 @@ { "cell_type": "code", "execution_count": 21, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -609,9 +571,7 @@ { "cell_type": "code", "execution_count": 22, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -629,9 +589,7 @@ { "cell_type": "code", "execution_count": 23, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -649,9 +607,7 @@ { "cell_type": "code", "execution_count": 24, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -672,9 +628,7 @@ { "cell_type": "code", "execution_count": 25, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -699,9 +653,7 @@ { "cell_type": "code", "execution_count": 26, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "x = range(10) # …see?" @@ -717,9 +669,7 @@ { "cell_type": "code", "execution_count": 27, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "def myfunction(arg1, arg2, **kwds):\n", @@ -737,9 +687,7 @@ { "cell_type": "code", "execution_count": 28, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -750,15 +698,13 @@ } ], "source": [ - "print 'first time ', myfunction(3.,4.)" + "print('first time ' + myfunction(3.,4.))" ] }, { "cell_type": "code", "execution_count": 29, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -784,9 +730,7 @@ { "cell_type": "code", "execution_count": 30, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -879,9 +823,7 @@ { "cell_type": "code", "execution_count": 33, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -899,9 +841,7 @@ { "cell_type": "code", "execution_count": 34, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -919,9 +859,7 @@ { "cell_type": "code", "execution_count": 35, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -940,9 +878,7 @@ { "cell_type": "code", "execution_count": 36, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -960,9 +896,7 @@ { "cell_type": "code", "execution_count": 37, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -990,9 +924,7 @@ { "cell_type": "code", "execution_count": 38, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1025,9 +957,7 @@ { "cell_type": "code", "execution_count": 39, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1052,9 +982,7 @@ { "cell_type": "code", "execution_count": 40, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1071,9 +999,7 @@ { "cell_type": "code", "execution_count": 41, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1093,9 +1019,7 @@ { "cell_type": "code", "execution_count": 42, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1120,9 +1044,7 @@ { "cell_type": "code", "execution_count": 43, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1145,9 +1067,7 @@ { "cell_type": "code", "execution_count": 44, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1173,9 +1093,7 @@ { "cell_type": "code", "execution_count": 45, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "f_list = range(1000)\n", @@ -1192,9 +1110,7 @@ { "cell_type": "code", "execution_count": 46, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1213,9 +1129,7 @@ { "cell_type": "code", "execution_count": 47, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1242,9 +1156,7 @@ { "cell_type": "code", "execution_count": 48, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1302,9 +1214,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.13" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } diff --git a/python_intro/Python_intro_unexpanded.ipynb b/python_intro/Python_intro_unexpanded.ipynb index 36639ef..16c37f1 100644 --- a/python_intro/Python_intro_unexpanded.ipynb +++ b/python_intro/Python_intro_unexpanded.ipynb @@ -82,9 +82,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "import math # comments with a hash\n", @@ -102,9 +100,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "from numpy import cos, pi # numpy, numeric python, also has these functions\n", @@ -148,9 +144,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "type(pi)" @@ -174,9 +168,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "mytuple = (0,1,2,3)\n", @@ -186,9 +178,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print ('…but not reassign…')\n", @@ -198,9 +188,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "mylist = [0,1,2,3]\n", @@ -212,9 +200,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "myset = set([0,1,2,3])\n", @@ -224,9 +210,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "myset.add(\"string!\") # you can use both ' and \" to declare a string\n", @@ -236,9 +220,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "myset.add(0)\n", @@ -248,9 +230,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "mydict = {'firstkey':1, 'secondkey':2, 3:'three'}\n", @@ -260,9 +240,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print (mydict['firstkey'])\n", @@ -273,9 +251,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print ('Get the keys (note lack of ordering): %s' % mydict.keys())\n", @@ -285,9 +261,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print ('This will fail: %s' % mydict[2])" @@ -307,9 +281,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "x = range(10)\n", @@ -320,9 +292,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print ('x[8:] gives %s' % x[8:])\n", @@ -361,9 +331,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print ('truncate: %d' % (13//4))\n", @@ -380,9 +348,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "len(range(0,100)) # in Matlab this would be 101" @@ -391,9 +357,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "[x for x in range(5)]" @@ -409,9 +373,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "x = [0] * 3\n", @@ -423,9 +385,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "x = y\n", @@ -435,9 +395,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "y[1] = 100\n", @@ -447,9 +405,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "# force a copy with [:]\n", @@ -461,9 +417,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "y[1] = 1000000\n", @@ -480,9 +434,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "x = range(10) # …see?" @@ -498,9 +450,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "def myfunction(arg1, arg2, **kwds):\n", @@ -518,20 +468,16 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ - "print('first time ', myfunction(3.,4.))" + "print('first time ' + myfunction(3.,4.))" ] }, { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print ('second time…')\n", @@ -548,9 +494,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", @@ -622,9 +566,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "a = np.zeros(10, dtype=int)\n", @@ -634,9 +576,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "b = np.ones(5, dtype=bool)\n", @@ -646,9 +586,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "c = np.random.rand(10)\n", @@ -658,9 +596,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "d = np.arange(5.)\n", @@ -670,9 +606,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "e = np.empty((3,3), dtype=float)\n", @@ -690,9 +624,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print ('shape: %s' % (e.shape,))\n", @@ -703,9 +635,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "f = c.copy()\n", @@ -722,9 +652,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print (d[2:])" @@ -733,9 +661,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ " e[1,1] = 5.\n", @@ -745,9 +671,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print (e[1:,1:])" @@ -763,9 +687,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "bool1 = np.array([True, True, False, False])\n", @@ -778,9 +700,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print ('ANY: %s' % np.any(bool1))\n", @@ -797,9 +717,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "f_list = range(1000)\n", @@ -816,9 +734,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print ('time for list:')\n", @@ -828,9 +744,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "print ('time for array:')\n", @@ -847,9 +761,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "#NOT THIS:\n", @@ -899,9 +811,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.13" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } From 9b7165fabdefcce93f4344f8d9004ad6eb5d4a99 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 5 Apr 2017 22:53:37 -0600 Subject: [PATCH 14/52] Use byte strings for search and replace. --- run_notebook.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/run_notebook.py b/run_notebook.py index 514269d..e8ca3f9 100755 --- a/run_notebook.py +++ b/run_notebook.py @@ -19,13 +19,12 @@ def convert_notebook(notebook): script = check_output(['jupyter', 'nbconvert', '--to', 'python', '--stdout', notebook]) - script = script.decode('utf-8') - p = re.compile("^get_ipython\(\)\.magic\(u?'matplotlib (?P\w+)'\)", + p = re.compile(b"^get_ipython\(\)\.magic\(u?'matplotlib (?P\w+)'\)", re.MULTILINE) - script = p.sub("get_ipython().magic(u'matplotlib auto')", script) - p = re.compile("(?P^get_ipython\(\)\.magic\(u'pinfo[\w\s]+'\))", + script = p.sub(b"get_ipython().magic(u'matplotlib auto')", script) + p = re.compile(b"(?P^get_ipython\(\)\.magic\(u'pinfo[\w\s]+'\))", re.MULTILINE) - script = p.sub("# \\1", script) + script = p.sub(b"# \\1", script) return script @@ -34,7 +33,7 @@ def run_notebook(notebook): with cd(os.path.dirname(notebook)): script = convert_notebook(os.path.basename(notebook)) _, script_file = tempfile.mkstemp(prefix='.', suffix='.py', dir='.') - with open(script_file, 'w') as fp: + with open(script_file, 'wb') as fp: fp.write(script) try: subprocess.check_call(['ipython', script_file]) From 7099c3d043b25d1bc5b187fde8dc4d05cb83e7f3 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 6 Apr 2017 11:08:10 -0600 Subject: [PATCH 15/52] Add print_function import. --- mappers/mappers.ipynb | 44 +++++++++++++------- mappers/mappers_unexpanded.ipynb | 71 +++++++++++++++++++++++++------- 2 files changed, 85 insertions(+), 30 deletions(-) diff --git a/mappers/mappers.ipynb b/mappers/mappers.ipynb index 3a10cab..a936e49 100644 --- a/mappers/mappers.ipynb +++ b/mappers/mappers.ipynb @@ -37,9 +37,23 @@ { "cell_type": "code", "execution_count": 1, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ + "from __future__ import print_function" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from __future__ import print_function\n", "from landlab import RasterModelGrid\n", "import numpy as np\n", "mg = RasterModelGrid((3, 4), 100.0)\n", @@ -56,7 +70,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -69,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -95,7 +109,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -138,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -186,7 +200,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -228,7 +242,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -276,7 +290,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -304,7 +318,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -331,7 +345,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -375,7 +389,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -421,7 +435,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -456,7 +470,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -499,7 +513,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -547,7 +561,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": {}, "outputs": [ { diff --git a/mappers/mappers_unexpanded.ipynb b/mappers/mappers_unexpanded.ipynb index 0dc8fc4..076ed3f 100644 --- a/mappers/mappers_unexpanded.ipynb +++ b/mappers/mappers_unexpanded.ipynb @@ -36,7 +36,20 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from __future__ import print_function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "from landlab import RasterModelGrid\n", @@ -56,7 +69,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "def show_node_values(mg, u):\n", @@ -69,7 +84,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "show_node_values(mg, h)" @@ -85,7 +102,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "for i in range(mg.number_of_links):\n", @@ -104,7 +123,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "h_edge = mg.map_mean_of_link_nodes_to_link('surface_water__depth')\n", @@ -128,7 +149,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "h_edge = mg.map_min_of_link_nodes_to_link('surface_water__depth')\n", @@ -146,7 +169,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "h_edge = mg.map_max_of_link_nodes_to_link('surface_water__depth')\n", @@ -170,7 +195,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "z = mg.add_zeros('node', 'topographic__elevation')\n", @@ -188,7 +215,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "w = z + h\n", @@ -205,7 +234,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "h_edge = mg.map_value_at_max_node_to_link(w, h)\n", @@ -225,7 +256,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "h_edge = mg.map_value_at_min_node_to_link(w, h)\n", @@ -247,7 +280,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "h_edge = mg.map_link_head_node_to_link('surface_water__depth')\n", @@ -258,7 +293,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "h_edge = mg.map_link_tail_node_to_link('surface_water__depth')\n", @@ -277,7 +314,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "gamma = 25000.0 # unit weight of fluid, N/m2\n", @@ -301,7 +340,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "h_edge = mg.map_value_at_max_node_to_link(w, h)\n", From 7b782c566ea4cafd1605e7c957f239c6574f77ad Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 6 Apr 2017 11:20:09 -0600 Subject: [PATCH 16/52] Add skip argument. --- run_notebook.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/run_notebook.py b/run_notebook.py index e8ca3f9..b456f47 100755 --- a/run_notebook.py +++ b/run_notebook.py @@ -7,6 +7,7 @@ import tempfile import subprocess import re +from fnmatch import fnmatch import six @@ -48,11 +49,15 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument('notebook', type=str, nargs='+', help='Notebook to test.') + parser.add_argument('--skip', type=str, default='', + help='Notebooks to skip.') args = parser.parse_args() + notebooks = [nb for nb in args.notebook if not fnmatch(nb, args.skip)] + failures, passed = [], [] - for notebook in args.notebook: + for notebook in notebooks: try: run_notebook(notebook) except subprocess.CalledProcessError: From 7c01679e1b8b5bbd432ad8da8c1b373ce6870c54 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 6 Apr 2017 11:20:48 -0600 Subject: [PATCH 17/52] Skip all unexpanded notebooks. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1889c72..937323f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,6 @@ install: - conda install landlab jupyter -c landlab - conda info -a && conda list script: -- ./run_notebook.py **/*.ipynb +- ./run_notebook.py **/*.ipynb --skip='*_unexpanded*' virtualenv: system_site_packages: false From 65528e5b9afc24e0fdf19c022662591cc22533c7 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 6 Apr 2017 12:22:41 -0600 Subject: [PATCH 18/52] Add multiple skip options. --- run_notebook.py | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/run_notebook.py b/run_notebook.py index b456f47..d016c7d 100755 --- a/run_notebook.py +++ b/run_notebook.py @@ -13,7 +13,7 @@ from scripting.unix import system, check_output from scripting.contexts import cd -from scripting.prompting import success, error +from scripting.prompting import success, error, status def convert_notebook(notebook): @@ -49,32 +49,48 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument('notebook', type=str, nargs='+', help='Notebook to test.') - parser.add_argument('--skip', type=str, default='', + parser.add_argument('--skip', type=str, action='append', help='Notebooks to skip.') args = parser.parse_args() - notebooks = [nb for nb in args.notebook if not fnmatch(nb, args.skip)] + skip = set() + for pattern in args.skip: + skip |= set([nb for nb in args.notebook if fnmatch(nb, pattern)]) - failures, passed = [], [] - for notebook in notebooks: - try: - run_notebook(notebook) - except subprocess.CalledProcessError: - error(notebook) - failures.append(notebook) + summary = [] + for notebook in args.notebook: + if notebook in skip: + summary.append((notebook, 'SKIP')) + status('SKIP: ' + notebook) else: + try: + run_notebook(notebook) + except subprocess.CalledProcessError: + summary.append((notebook, 'FAIL')) + error(notebook) + else: + summary.append((notebook, 'PASS')) + success(notebook) + + print('-' * 70) + print('Summary:') + for notebook, result in summary: + if result == 'FAIL': + error(notebook) + elif result == 'PASS': success(notebook) - passed.append(notebook) + elif result == 'SKIP': + status('SKIP: ' + notebook) + print('-' * 70) - if failures: - print('Failed notebooks:') - print(os.linesep.join(failures)) + failures = [name for name, result in summary if result == 'FAIL'] + passes = [name for name, result in summary if result == 'PASS'] if failures: print('FAILED (failures={nfails})'.format(nfails=len(failures))) else: - print('OK Ran {ntests} tests'.format(ntests=len(passed))) + print('OK Ran {ntests} tests'.format(ntests=len(passes))) return len(failures) From 68cf2af6200282168b2c39ddb2fd8aa3bf4ed340 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 6 Apr 2017 12:23:05 -0600 Subject: [PATCH 19/52] Remove linux builds. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 937323f..208fee3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ env: - CONDA_PREFIX=$HOME/miniconda - MINICONDA_URL_BASE="https://repo.continuum.io/miniconda/Miniconda3-latest" os: -- linux + # - linux - osx sudo: false before_install: From 50eee0604ea5bdc0283ee9167549e3d5d1ef8f23 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 6 Apr 2017 13:20:36 -0600 Subject: [PATCH 20/52] Skip notebooks that are not passing yet. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 208fee3..cacea23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,6 @@ install: - conda install landlab jupyter -c landlab - conda info -a && conda list script: -- ./run_notebook.py **/*.ipynb --skip='*_unexpanded*' +- ./run_notebook.py **/*.ipynb --skip='*_unexpanded*' --skip='*intro*' --skip='flow*' --skip='fields*' virtualenv: system_site_packages: false From 063198538dcee3ce7f850407dd8462079134b59a Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 6 Apr 2017 13:23:52 -0600 Subject: [PATCH 21/52] Add try/except to catch error. --- fields/working_with_fields.ipynb | 89 ++++++++++---------------------- 1 file changed, 27 insertions(+), 62 deletions(-) diff --git a/fields/working_with_fields.ipynb b/fields/working_with_fields.ipynb index 85f60ed..106566b 100644 --- a/fields/working_with_fields.ipynb +++ b/fields/working_with_fields.ipynb @@ -37,13 +37,11 @@ { "cell_type": "code", "execution_count": 1, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", - "from landlab import RasterModelGrid\n", + "from landlab import RasterModelGrid, FieldError\n", "from landlab.components import LinearDiffuser\n", "\n", "mg = RasterModelGrid((3, 4), 1.)" @@ -59,9 +57,7 @@ { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -83,9 +79,7 @@ { "cell_type": "code", "execution_count": 3, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -131,9 +125,7 @@ { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -173,34 +165,27 @@ { "cell_type": "code", "execution_count": 6, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { - "ename": "FieldError", - "evalue": "field__number_one: already exists", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mFieldError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mno_1c\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_field\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'node'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'field__number_one'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minput_array\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0munits\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'm'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m/Users/danhobley/git_landlab/landlab/field/grouped.pyc\u001b[0m in \u001b[0;36madd_field\u001b[0;34m(self, *args, **kwds)\u001b[0m\n\u001b[1;32m 716\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'number of arguments must be 2 or 3'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 717\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 718\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgroup\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_field\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue_array\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwds\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 719\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 720\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mset_units\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgroup\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0munits\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/Users/danhobley/git_landlab/landlab/field/scalar_data_fields.pyc\u001b[0m in \u001b[0;36madd_field\u001b[0;34m(self, name, value_array, units, copy, noclobber, **kwds)\u001b[0m\n\u001b[1;32m 376\u001b[0m \"\"\"\n\u001b[1;32m 377\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mnoclobber\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mname\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 378\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mFieldError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'{name}: already exists'\u001b[0m\u001b[0;34m.\u001b[0m \u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 379\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 380\u001b[0m \u001b[0mvalue_array\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0masarray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue_array\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mFieldError\u001b[0m: field__number_one: already exists" + "name": "stdout", + "output_type": "stream", + "text": [ + "ERROR: The field already exists.\n" ] } ], "source": [ - "no_1c = mg.add_field('node', 'field__number_one', input_array, copy=False, units='m')" + "try:\n", + " no_1c = mg.add_field('node', 'field__number_one', input_array, copy=False, units='m')\n", + "except FieldError:\n", + " print('ERROR: The field already exists.')" ] }, { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -220,9 +205,7 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -254,9 +237,7 @@ { "cell_type": "code", "execution_count": 9, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -283,9 +264,7 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -312,9 +291,7 @@ { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -334,9 +311,7 @@ { "cell_type": "code", "execution_count": 12, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "mg.at_node.clear() # delete all fields at nodes" @@ -345,9 +320,7 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -367,9 +340,7 @@ { "cell_type": "code", "execution_count": 14, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -389,9 +360,7 @@ { "cell_type": "code", "execution_count": 15, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -411,9 +380,7 @@ { "cell_type": "code", "execution_count": 16, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -440,9 +407,7 @@ { "cell_type": "code", "execution_count": 17, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -484,9 +449,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.13" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } From ad157444fb1bdb1f121a4f8d74e1b1a934b91123 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 6 Apr 2017 16:25:38 -0600 Subject: [PATCH 22/52] Clean up code. --- run_notebook.py | 71 ++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/run_notebook.py b/run_notebook.py index d016c7d..89f9cb9 100755 --- a/run_notebook.py +++ b/run_notebook.py @@ -44,12 +44,45 @@ def run_notebook(notebook): os.remove(script_file) +def print_summary(summary): + print('-' * 70) + for notebook, result in summary: + if result is None: + status('SKIP: ' + notebook) + elif result: + success(notebook) + else: + error(notebook) + print('-' * 70) + + +def print_success_or_failure(summary): + failures = [name for name, result in summary if result is False] + passes = [name for name, result in summary if result is True] + + if failures: + print('FAILED (failures={nfails})'.format(nfails=len(failures))) + else: + print('OK Ran {ntests} tests'.format(ntests=len(passes))) + + return len(failures) + + +def check_notebook(notebook): + try: + run_notebook(notebook) + except subprocess.CalledProcessError: + return False + else: + return True + + def main(): import argparse parser = argparse.ArgumentParser() parser.add_argument('notebook', type=str, nargs='+', help='Notebook to test.') - parser.add_argument('--skip', type=str, action='append', + parser.add_argument('--skip', type=str, action='append', default=[], help='Notebooks to skip.') args = parser.parse_args() @@ -61,38 +94,14 @@ def main(): summary = [] for notebook in args.notebook: if notebook in skip: - summary.append((notebook, 'SKIP')) - status('SKIP: ' + notebook) + result = notebook, None else: - try: - run_notebook(notebook) - except subprocess.CalledProcessError: - summary.append((notebook, 'FAIL')) - error(notebook) - else: - summary.append((notebook, 'PASS')) - success(notebook) - - print('-' * 70) - print('Summary:') - for notebook, result in summary: - if result == 'FAIL': - error(notebook) - elif result == 'PASS': - success(notebook) - elif result == 'SKIP': - status('SKIP: ' + notebook) - print('-' * 70) - - failures = [name for name, result in summary if result == 'FAIL'] - passes = [name for name, result in summary if result == 'PASS'] + result = notebook, check_notebook(notebook) + print_summary([result]) + summary.append(result) - if failures: - print('FAILED (failures={nfails})'.format(nfails=len(failures))) - else: - print('OK Ran {ntests} tests'.format(ntests=len(passes))) - - return len(failures) + print_summary(summary) + return print_success_or_failure(summary) if __name__ == '__main__': From 8981e564282a61150bd33efa4b0bf61708cd07f4 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 6 Apr 2017 21:14:36 -0600 Subject: [PATCH 23/52] Add try/except to catch error. --- fields/working_with_fields.ipynb | 89 ++++++++++---------------------- 1 file changed, 27 insertions(+), 62 deletions(-) diff --git a/fields/working_with_fields.ipynb b/fields/working_with_fields.ipynb index 85f60ed..3712f8f 100644 --- a/fields/working_with_fields.ipynb +++ b/fields/working_with_fields.ipynb @@ -37,13 +37,11 @@ { "cell_type": "code", "execution_count": 1, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", - "from landlab import RasterModelGrid\n", + "from landlab import RasterModelGrid, FieldError\n", "from landlab.components import LinearDiffuser\n", "\n", "mg = RasterModelGrid((3, 4), 1.)" @@ -59,9 +57,7 @@ { "cell_type": "code", "execution_count": 2, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -83,9 +79,7 @@ { "cell_type": "code", "execution_count": 3, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -131,9 +125,7 @@ { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -173,34 +165,27 @@ { "cell_type": "code", "execution_count": 6, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { - "ename": "FieldError", - "evalue": "field__number_one: already exists", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mFieldError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mno_1c\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_field\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'node'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'field__number_one'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minput_array\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0munits\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'm'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m/Users/danhobley/git_landlab/landlab/field/grouped.pyc\u001b[0m in \u001b[0;36madd_field\u001b[0;34m(self, *args, **kwds)\u001b[0m\n\u001b[1;32m 716\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'number of arguments must be 2 or 3'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 717\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 718\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgroup\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_field\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue_array\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwds\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 719\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 720\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mset_units\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgroup\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0munits\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/Users/danhobley/git_landlab/landlab/field/scalar_data_fields.pyc\u001b[0m in \u001b[0;36madd_field\u001b[0;34m(self, name, value_array, units, copy, noclobber, **kwds)\u001b[0m\n\u001b[1;32m 376\u001b[0m \"\"\"\n\u001b[1;32m 377\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mnoclobber\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mname\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 378\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mFieldError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'{name}: already exists'\u001b[0m\u001b[0;34m.\u001b[0m \u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 379\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 380\u001b[0m \u001b[0mvalue_array\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0masarray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue_array\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mFieldError\u001b[0m: field__number_one: already exists" + "name": "stdout", + "output_type": "stream", + "text": [ + "ERROR: This field name already exists!\n" ] } ], "source": [ - "no_1c = mg.add_field('node', 'field__number_one', input_array, copy=False, units='m')" + "try:\n", + " no_1c = mg.add_field('node', 'field__number_one', input_array, copy=False, units='m')\n", + "except FieldError:\n", + " print('ERROR: This field name already exists!')" ] }, { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -220,9 +205,7 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -254,9 +237,7 @@ { "cell_type": "code", "execution_count": 9, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -283,9 +264,7 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -312,9 +291,7 @@ { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -334,9 +311,7 @@ { "cell_type": "code", "execution_count": 12, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "mg.at_node.clear() # delete all fields at nodes" @@ -345,9 +320,7 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -367,9 +340,7 @@ { "cell_type": "code", "execution_count": 14, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -389,9 +360,7 @@ { "cell_type": "code", "execution_count": 15, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -411,9 +380,7 @@ { "cell_type": "code", "execution_count": 16, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -440,9 +407,7 @@ { "cell_type": "code", "execution_count": 17, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -484,9 +449,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.13" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } From c2e18d122b62b875c00d46bb387171de295ed221 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 6 Apr 2017 21:15:30 -0600 Subject: [PATCH 24/52] Run the fields notebook. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cacea23..ac72927 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,6 @@ install: - conda install landlab jupyter -c landlab - conda info -a && conda list script: -- ./run_notebook.py **/*.ipynb --skip='*_unexpanded*' --skip='*intro*' --skip='flow*' --skip='fields*' +- ./run_notebook.py **/*.ipynb --skip='*_unexpanded*' --skip='*intro*' --skip='flow*' virtualenv: system_site_packages: false From 3926547beacf33914418ab58dd8a41768bc5e7c5 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 7 Apr 2017 09:00:37 -0600 Subject: [PATCH 25/52] Add a brief CONTRIBUTING doc. --- CONTRIBUTING.md | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..ffb143f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,102 @@ +# Contributing to landlab tutorials + +Thank you for contributing to the landlab tutorials! We appreciate +your help as this is largely as volunteer effort! :heart: :heart: :heart: + +# How to contribute + +## Reporting Bugs + +Before creating a bug report, please do at least a cursory check that the +bug has not already been reported. If it has, add a comment to the existing +issue instead of opening a new one. + +### Submitting a Bug Report + +Bugs are tracked as +[GitHub issues](https://guides.github.com/features/issues/). After you've +determined you've found a new bug, please open a +[new issue](https://github.com/landlab/tutorials/issues). + +Explain the problem and include additional details to help maintainers +reproduce the problem. Here are some items that will make it easier +to track down the source of the problem. + +* **Use a clear and descriptive title** for the issue that identifies the + problem. +* **Describe the exact steps that reproduce the problem**. +* **If possible, provide an example that demonstrates the step** as, + for example, a bash script along with input files. +* **Describe the behavior you are seeing after these steps**. +* **Describe the behavior you expect to see after these steps**. + +Additionally, the answers to the following questions about your run +environment will be helpful. + +* **Which version of landlab are you using?** This could be a specific + git sha or a release number. +* **What is he name and version of you OS?** +* **What compiler are you using?** +* **How did you build landlab (if using the development version)?** + + +## Submitting Changes + +:tada: Whoa! This is great! We love it when folks contibute code! :tada: + +Changes to landlab tutorials should be submitted as +[pull requests](http://help.github.com/pull-requests/)). + +* Create a GitHub issue that describes what you propose to do. +* Create a topic branch that contains your changes. +* Open a new [GitHub pull request](https://github.com/landlab/tutorials/pull/new/master). +* Ensure the PR description clearly describes the problem and solution. + Include the relevant issue number. + +## Styleguides + +Use the [PEP8 style guide](https://www.python.org/dev/peps/pep-0008/). +You may want to use tools like +[Prospector](http://prospector.landscape.io/en/master/) to help out +with this. + +### Git Commit Messages + +* Use the present tense ("Add feature" not "Added feature") +* Use the imperative mood ("Move cursor to..." not "Moves cursor to...") +* Limit the first line to 72 characters or less +* Reference issues and pull requests liberally +* Consider starting the commit message with an applicable emoji: + * :art: `:art:` when improving the format/structure of the code + * :racehorse: `:racehorse:` when improving performance + * :non-potable_water: `:non-potable_water:` when plugging memory leaks + * :memo: `:memo:` when writing docs + * :penguin: `:penguin:` when fixing something on Linux + * :apple: `:apple:` when fixing something on macOS + * :checkered_flag: `:checkered_flag:` when fixing something on Windows + * :bug: `:bug:` when fixing a bug + * :fire: `:fire:` when removing code or files + * :green_heart: `:green_heart:` when fixing the CI build + * :white_check_mark: `:white_check_mark:` when adding tests + * :shirt: `:shirt:` when removing linter warnings + +## Adding new tutorials + +If you would like to create a new tutorial that we have just a few +conventions that we would like you to follow. + +* Create a new folder that will hold your tutorial notebook + and data used by your tutorial. +* Start with the blank tutorial template provided in this repository. +* Notice that your first cell of code should import `print_function` + from `__future__`. Your tutorial will need to be compatible with + both Python 2.7 and 3.4+. +* If you will be plotting anything, be sure to use include ipython + magic command in the first cell to indicate how plots should + be rendered. +* Your tutorial must be able to run without error for the **most + recent landlab release**. + +Thanks! :heart: :heart: :heart: + +The landlab team From 2c0fd4d1ea52c990728c0c082feb3654cedb0787 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 7 Apr 2017 09:02:36 -0600 Subject: [PATCH 26/52] Import print_function from the future. --- tutorial_template.ipynb | 45 ++++++++++------------------------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/tutorial_template.ipynb b/tutorial_template.ipynb index f7dd2b4..4609643 100644 --- a/tutorial_template.ipynb +++ b/tutorial_template.ipynb @@ -2,20 +2,14 @@ "cells": [ { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "\n" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "# Using the Landlab flexure component\n", "\n", @@ -32,10 +26,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "A bit of magic so that we can plot within this notebook." ] @@ -44,22 +35,17 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ - "%matplotlib auto\n", - "import numpy as np" + "from __future__ import print_function\n", + "%matplotlib inline" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "## This\n", "\n", @@ -68,10 +54,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "## That\n", "\n", @@ -80,10 +63,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "## The other thing\n", "\n", @@ -92,10 +72,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "### Click here for more Landlab tutorials" ] @@ -121,5 +98,5 @@ } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } From f96b62dc7c8300525930a68316ed893173ae587e Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 7 Apr 2017 14:06:29 -0600 Subject: [PATCH 27/52] Remove unexpanded notebooks. --- .../set_BCs_from_xy_unexpanded.ipynb | 164 ---- ...t_BCs_on_raster_perimeter_unexpanded.ipynb | 373 -------- .../set_watershed_BCs_raster_unexpanded.ipynb | 361 ------- .../component_tutorial_unexpanded.ipynb | 700 -------------- flexure/lots_of_loads_unexpanded.ipynb | 394 -------- .../gradient_and_divergence_unexpanded.ipynb | 634 ------------- .../grid_object_demo_unexpanded.ipynb | 511 ---------- .../making_components_unexpanded.ipynb | 887 ------------------ mappers/mappers_unexpanded.ipynb | 385 -------- python_intro/Python_intro_unexpanded.ipynb | 819 ---------------- .../reading_dem_into_landlab_unexpanded.ipynb | 439 --------- 11 files changed, 5667 deletions(-) delete mode 100644 boundary_conds/set_BCs_from_xy_unexpanded.ipynb delete mode 100644 boundary_conds/set_BCs_on_raster_perimeter_unexpanded.ipynb delete mode 100644 boundary_conds/set_watershed_BCs_raster_unexpanded.ipynb delete mode 100644 component_tutorial/component_tutorial_unexpanded.ipynb delete mode 100644 flexure/lots_of_loads_unexpanded.ipynb delete mode 100644 gradient_and_divergence/gradient_and_divergence_unexpanded.ipynb delete mode 100644 grid_object_demo/grid_object_demo_unexpanded.ipynb delete mode 100644 making_components/making_components_unexpanded.ipynb delete mode 100644 mappers/mappers_unexpanded.ipynb delete mode 100644 python_intro/Python_intro_unexpanded.ipynb delete mode 100644 reading_dem_into_landlab/reading_dem_into_landlab_unexpanded.ipynb diff --git a/boundary_conds/set_BCs_from_xy_unexpanded.ipynb b/boundary_conds/set_BCs_from_xy_unexpanded.ipynb deleted file mode 100644 index e624325..0000000 --- a/boundary_conds/set_BCs_from_xy_unexpanded.ipynb +++ /dev/null @@ -1,164 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

a toolkit for modeling earth surface processes

" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Setting Boundary Conditions: interior rectangle\n", - "\n", - "This tutorial illustrates how to modify the boundary conditions of an interior rectangle in the grid if you know the x and y coordinates of the rectangle." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from landlab import RasterModelGrid, CLOSED_BOUNDARY\n", - "import numpy as np\n", - "from landlab.plot.imshow import imshow_grid_at_node\n", - "from matplotlib.pyplot import show\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "mg = RasterModelGrid((10, 10), 1.)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Known coordinates of rectangle:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "min_x = 2.5\n", - "max_x = 5.\n", - "min_y = 3.5\n", - "max_y = 7.5" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Define the area inside x and y coordinates:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "x_condition = np.logical_and(mg.node_x < max_x, mg.node_x > min_x)\n", - "y_condition = np.logical_and(mg.node_y < max_y, mg.node_y > min_y)\n", - "my_nodes = np.logical_and(x_condition, y_condition)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Define boundaries as CLOSED:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "mg.status_at_node[my_nodes] = CLOSED_BOUNDARY" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Make a new elevation field for display:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "z = mg.add_zeros('node', 'topographic__elevation')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "imshow_grid_at_node(mg, z)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.11" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/boundary_conds/set_BCs_on_raster_perimeter_unexpanded.ipynb b/boundary_conds/set_BCs_on_raster_perimeter_unexpanded.ipynb deleted file mode 100644 index 0d394c4..0000000 --- a/boundary_conds/set_BCs_on_raster_perimeter_unexpanded.ipynb +++ /dev/null @@ -1,373 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

a toolkit for modeling earth surface processes

" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Setting Boundary Conditions on the Perimeter of a Raster.\n", - "\n", - "
\n", - " For instructions on how to run an interactive iPython notebook, click here: https://github.com/landlab/tutorials/blob/master/README.md
\n", - "For the unexpanded version to download and run, click here: https://nbviewer.jupyter.org/github/landlab/tutorials/blob/master/boundary_conds/set_BCs_on_raster_perimeter_unexpanded.ipynb
\n", - "For more Landlab tutorials, click here: https://github.com/landlab/landlab/wiki/Tutorials\n", - "
\n", - "\n", - "### This tutorial illustrates how to modify the boundary conditions along the perimeter of a rectangular raster." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from landlab import RasterModelGrid, CLOSED_BOUNDARY, FIXED_GRADIENT_BOUNDARY, \\\n", - "FIXED_VALUE_BOUNDARY\n", - "from landlab.plot.imshow import imshow_grid\n", - "import numpy as np\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Instantiate a grid." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "mg = RasterModelGrid((4, 4), 1.)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The node boundary condition options are:\n", - "\n", - "- CORE_NODE (status value = 0; all operations are performed on a CORE_NODE)\n", - "- FIXED_VALUE_BOUNDARY (status value = 1; a boundary node with a fixed value)\n", - "- FIXED_GRADIENT_BOUNDARY (status value = 2; a boundary node with a fixed gradient)\n", - "- TRACKS_CELL_BOUNDARY (status value = 3; a boundary node that is wrap-around)\n", - "- CLOSED_BOUNDARY (status value = 4; closed boundary, or no flux can cross this node, or more accurately, can cross the faces around the node)\n", - "\n", - "Check the status of boundaries immediately after instantiating the grid:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "array([1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1], dtype=int8)" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mg.status_at_node" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The default conditions are for the perimeter to be fixed value (status of 1) and the interior nodes to be core (status of 0).\n", - "\n", - "This is a bit easier to see graphically." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "imshow_grid(mg, mg.status_at_node)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let's choose on node on the perimeter to be closed. \n", - "\n", - "Note that imshow_grid does not illustrate values for closed nodes, so we override that below and show them in blue." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAUgAAAEPCAYAAAAgSV3nAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHqRJREFUeJzt3XuYXVWZ5/HvDwS8gCCC8RIgGrmIo4aoIUxsObRtmyAN\njI2NiI2iY/MwoszYjqjtNMWM8wg02oLiADbS0N222GBjugEBB44MKhFIIuES7gYIEEWIiEFMqt75\nY+8qTk7OPmfXue1VVb/P8+yHc1m119pUPW/W3uvyKiIwM7MtbVV1A8zMUuUAaWZWwAHSzKyAA6SZ\nWQEHSDOzAg6QZmYFKg2QkraTtEzSCkmrJJ3cosyBktZLWp4fn6+irWaWNknnS1on6dY2Zc6SdI+k\nlZLmdTrn8/rbxMmJiGclHRQRGyRtDfxI0pUR8dOmotdHxKFVtNHMpowLgK8CF7X6UtISYG5E7Clp\nf+AcYGG7E1Z+ix0RG/KX25EF7FYz1zW8FpnZVBQRNwBPtilyGHnwjIhlwI6SZrU7Z+UBUtJWklYA\njwHXRMRNLYodkHeJL5e075CbaGbTw6uAhxrer80/K1R5gIyIsYjYD5gN7N8iAN4C7B4R84CvAZcN\nu41mNjNV+gyyUUQ8Jek6YDFwR8PnTze8vlLS1yXtHBFPNJ9DkheWm1UkInp6FDZnzpxYs2ZN2eLr\nIuLlk6xiLbBbw/vZ+WeFqh7F3kXSjvnrFwDvBFY3lZnV8HoBoFbBcVxEDOU4+eSTh1aX63N9qdfX\nD2vWrCFirNQBFD07FMVjFkuBYwAkLQTWR8S6dm2qugf5CuBCSVuRBeuLI+IKSccBERHnAUdIOh7Y\nCDwDHFldc81skHoJtpK+BdSAl0p6EDgZ2JY8luSx5WBJ9wK/BY7tdM6qp/msAua3+PzchtdnA2cP\ns11mVpXuA2REvL9EmRMmc86qe5BTVq1Wc32uz/X1WX77nAz16/lBCiTFdLoes6lCEtHjII2kGB19\ntlTZrbferuf6ynAP0swSklYHxwHSzJKR2h2gA6SZJcQB0sysgAOkmVlLvsU2MyuU1jQfB0gzS4Z7\nkGZmhRwgzcwKOECambXkW2wzs0IOkGZmBdIaxa485YKZ2bhJbJi7BUmLJa2WdLekk1p8v5Ok70r6\nmaQby+S3coA0s4REyWNz+abbXwPeBbweOErSPk3FPgesiIg3AR8EzurUGgdIM0tGDykeFgD3RMSa\niNgIfJsszWujfYFr83ruAuZI2rVdexwgzSwh3fUg2TKl68NsmdL1Z8B7YCK/1e5kibsKeZDGzBLS\nehT7+ut/zPXX/6TXk58KnClpObAKWAGMtvuBSncUl7QdcD1ZYp3nAZdExCktyp0FLCFLtPOhiFhZ\ncD7vKG5WgX7tKL5hw8Olyr7whbM3qy/PUjgSEYvz958hS9Z1Wpv6HgDeEA2ppZtVeosdEc8CB0XE\nfsA8YEne9Z0gaQkwNyL2BI4Dzhl+S81sOLq+xb4JeK2kPSRtC7yPLM3rBEk7Stomf/1R4IftgiMk\ncIsdERvyl9uRtaf56g8DLsrLLssvclanfLZmNvVEtL3jbfNzMSrpBOBqso7f+RFxZ1MK6deRpZke\nA24HPtLpvJUHyHx4/hZgLnB2RNzUVKT54eva/DMHSLNpp6e0r98H9m76rDGF9I3N33dS+Sh2RIzl\nt9izgf3LTN40s+mph2k+A1F5D3JcRDwl6TpgMXBHw1drgd0a3s/OP2tpZGRk4nWtVpuy+YHNUlav\n16nX6wM4c1qDrFWPYu8CbIyIX0t6AXAVcGpEXNFQ5mDgYxHx7nyk6isRsbDgfB7FNqtAv0axn376\n3lJlt9/+tTMiL/YryB6abkV2u39xRFzR+GA1f3+wpHvJpvkcW2WDzWxwUuvgVNqD7Df3IM2q0a8e\n5G9+s7pU2R122GdG9CDNzCak1sFxgDSzhDhAmpkVcIA0M2vJt9hmZoUcIM3MCqSVk8YB0sySUZRv\npioOkGaWkLRusSvfrMLMbNyAsxq+WNJSSSslrZL0oU7tcYA0s4QMNKvhx4DbI2IecBDwJUlt76Id\nIM0sGQPOahjADvnrHYBfRcSmdu3xM0gzS0jXzyBbZTVc0FTma8BSSY8A2wNHdjqpA6SZJaT188Ub\nbljODTcs7/Xk7wJWRMQfSpoLXCPpje3y0jhAmlkyigZgFi2ax6JF8yben376+c1F1pLluR7XamPt\nY4EvZvXEfXlWw32Am4va42eQZpaQwWU1BNYAfwQgaRawF3B/u9a4B2lmyeh2onjJrIZfAP5e0q35\nj306Ip5od15vmGtmPevXhrmPP/7DUmV32eVAb5hrZjNNWh0cB0gzS0Zqa7ErHaSRNFvStZJuz5f+\nfKJFmQMlrZe0PD8+X0VbzWwYuh6kGYiqe5CbgE9GxEpJ2wO3SLo6Ipoz91wfEYdW0D4zG6KI0aqb\nsJlKe5AR8VhErMxfPw3cSTYjvtnAH8aaWQrS6kEmMw9S0hxgHrCsxdcH5DtwXC5p36E2zMyGpoe1\n2ANR9S02APnt9SXAiS2W/dwC7B4RGyQtAS4jm+DZ0sjIyMTrWq1GrVbre3vNZrp6vU69Xh/AmdMa\npKl8HmS+3dC/A1dGxJklyj8AvLnVBM/pPA9yD/kpw1S1Zpr+TTbq1zzIdesuL1V21qx3z5h5kN8E\n7igKjpJmRcS6/PUCsqDedva7mU1NqXVwKg2QkhYBRwOrJK0ge/r6OWAPnlsedISk44GNwDOU2KLI\nzKYoB8jnRMSPgK07lDkbOHs4LTKzKrkHaWZWJK346ABpZulIrQeZzDxIM7Ne5omXyGr4KUkr8iXL\nqyRtkrRTu+Y4QJpZOiLKHU3KZDWMiDMiYr+ImA98FqhHxPp2zXGANLNkdBkfoVxWw0ZHAf/cqT0O\nkGaWju4jZKushq32dUDSC4DFwKWdmuNBGjNLxpAGaf4EuKHT7TU4QJpZSgri449vvI2f3Hhbu58s\nk9Vw3PsocXsNCazF7ievxbYUeS126XPEw/d1vOsFYPbcP92sPklbA3cB7wAeBX4KHBURdzbVsSNZ\nJsPZEfFMp3rcgzSzZHT7b0nJrIYAhwNXlQmO4B7klOEe5NTlHmTpc8RD91xSquxuex4xY3bzMTMD\nkturwgHSzBIyllaEdIA0s2REYrtVOECaWTrSio8OkGaWkMQeQjpAmlkyEouPDpBmlpDEIqQDpJkl\nI7H4WO1uPpJmS7pW0u35BpafKCh3lqR7JK2UNG/Y7TSzIRmLcseQVN2D3AR8MiJWStoeuEXS1RGx\neryApCXA3IjYU9L+wDnAworaa2YDlNpKuEp7kBHxWESszF8/DdzJlnu4HQZclJdZBuwoadZQG2pm\nw9FDyoVBqLoHOUHSHGAesKzpq+aNMNfmn60bSsPMbGhS60EmESDz2+tLgBPznmTXRkZGJl7XajVq\ntVpPbTOzLdXrder1ev9PnFZ8rH43H0nPA/4duDIizmzx/TnAdRFxcf5+NXBgRGzRg/RuPpYi7+ZT\n+hxx383/WKrs3Ld8YIv6JC0GvsJz252d1qKOGvC3wDbALyPioHb1pJCT5pvAHa2CY24pcAyApIXA\n+lbB0cymvm5T0pTJaphvlns2cEhE/AfgvZ3aU+kttqRFwNHAKkkryDrYnwP2IN/kMiKukHSwpHuB\n3wLHVtdiMxuo7qfwTGQ1BJA0ntVwdUOZ9wOXRsRagIh4vNNJKw2QEfEjYOsS5U4YQnPMrGI9PCJr\nldVwQVOZvYBtJF0HbA+cFRH/0O6kSQzSmJkBgx6keR4wH/hD4EXATyT9JCLubfcDZmZJKOpBLlt+\nJ8uWr275Xa5MVsOHgccj4nfA7yRdD7wJKAyQlY9i95NHsS1FHsUufY64+0cXliq716IPTjqrYT5o\n81VgMbAd2ZzrIyPijqJ6JtWDlPQi4HcRMTqZnzMzK6XLf0zKZDWMiNWSrgJuBUaB89oFR+gQIPOh\n8/eRjTS/FXgW2E7S48DlwLnt7t/NzCajl852RHwf2Lvps3Ob3p8BnFH2nJ3mQV4HzAU+C7w8InaL\niJcBbwNuBE6T9IGylZmZtRNjUeoYlk632H8UERubP4yIJ4BLgUslbTOQlpnZzJPY89q2PcjG4Cjp\nbZKOzV/vKunVzWXMzHoyFXfzkXQy8Bay+/sLyNYx/iOwaHBNM7OZJrVZKGVHsf8TsB+wHCAiHpG0\nw8BaZWYz0xQNkL+PiJAUMDHdx8ysrxKLj6V38/mOpHOBnSR9FPgB8I3BNcvMZqSpmJMmIs6Q9E7g\nKbLnkH8dEdcMtGVmNuNM1WeQ5AHRQdHMBiet+FjuFlvSe/K0q7+W9JSk30h6atCNM7OZJSJKHcNS\ntgd5OvAnjQu/zcz6LrEeZNkAuc7B0cwGboo+g7xZ0sXAZWQbVgAQEd8dSKvMbEaaqoM0LwY2AH/c\n8FkADpBm1jfD3IiijLLTfAaWKEvS+cAhZLfxb2zx/YHA94D784++GxFfGFR7zKxCY93/aKe0r93E\nkrJrsWeT7cQ7vvb6/wEnRsTD5Ztf6IL83Be1KXN9RBzah7rMLGVd3mI3pH19B/AIcJOk70VEc56G\nScWSsitpLiDLT/3K/Pi3/LOeRcQNwJMdijnfgNkM0G1ebBrSvuY7jI2nfW02qVhSNkDuGhEXRMSm\n/Ph7YNfJVNSjAyStlHS5pH2HWK+ZDVP3EbJV2tdXtSg3qVhSdpDmV/nO4f+cvz8K+FXJn+3VLcDu\nEbFB0hKykfS9igqPjIxMvK7VatRqtUG3z2zGqdfr1Ov1vp+36A77ptvu5ubb7+n19JOKJVAyq6Gk\nPcieEx5ANnr9Y+ATEfFgry1uOP+/tRqkaVH2AeDN+a7mzd85q6Elx1kNS58jVv7LV0uVnffejzdn\nNVwIjETE4vz9Z8iSdZ1WdI52sWRc2VHsNcAgB0lEwbMBSbMiYl3+egFZUC+8IDObumK0639MbgJe\nm3e2HiVLNnhUY4FuYkmnrIZ/3ebriIj/VablHer4FlADXirpQeBkYNv8/OcBR0g6HtgIPAMc2Wud\nZpaoAaZ9pYtY0vYWW9Jftvj4RcBHgJdGxPaTv5TB8S22pci32KXPEcu/dWapsvPff2LP9ZXRtgcZ\nEV8af52nWDgROJZsCP1LRT9nZtaVxP4x6fgMUtLOwCeBo4ELgfkR0WneopnZ5E2lACnpb4D3AOcB\nb4iIp4fSKjObkaKHpYaD0Gmi+F+SrZz5PPBIvlmuN8w1s8HoYSnNIHR6Bll2pY2ZWc9S282nbQCU\n1HGUukwZM7MyUku50KmH+D1JX5L09sZc2JJeI+kjkq4CFg+2iWY2Y4yVPIak0y32OyQdDBwHLJL0\nEmATcBdwOfDBiHhs8M00sxlhKo1iA0TEFcAVQ2iLmc1wicXH8nmxzcwGLrFBGgdIM0tGakuFO41i\nXyFpznCaYmYz3liUO4ak0yj2BcDVkv5K0jbDaJCZzVwxFqWOYWkbICPiX4D5ZGlfb5b0KUmfHD+G\n0kIzmzmi5NGCpMWSVku6W9JJRVVIequkjZLe06k5ZZ5B/h74LbAdsANDnYVkZjNJt88gy2Y1zMud\nClxV5rydNqtYDHyZLKPh/IjY0EXbzczK6b77NZHVEEDSeFbD5rSvHwcuAd5a5qSdepB/Bbw3Im6f\nXFvNzCavh1HsVlkNFzQWkPRK4PCIOChPudBRp5U0fzDZVpqZda37nDRlfAVofDbZcUdyz4M0s2QU\n9SCX3/cAK+57oN2PrgV2b3g/O/+s0VuAb0sSsAuwRNLGiFhadNLKA6Sk84FDgHVFaV8lnQUsIRss\n+lBErBxiE81sWAqm8Mx/9Rzmv3rOxPtv/uC65iIdsxpGxGvGX0u6gCzVdGFwhM7zIIfhAuBdRV/m\nCb7nRsSeZJtmnDOshpnZcHW7X25EjALjWQ1vB749ntVQ0l+0qqpMeyrvQUbEDXnUL3IYcFFedpmk\nHRvz25rZNNLDJPCI+D6wd9Nn5xaU/XCZc1YeIEtoHp1am3/mAGk2zaS2FnsqBMhJGRkZmXhdq9Wo\n1WqVtcVsuqrX69Tr9f6fOLFlKFMhQK4Fdmt432p0akJjgDSzwWjufJxyyil9OW+MphUhUxikgWw+\nUtGcpKXAMQCSFgLr/fzRbJrqYS32IFTeg5T0LaAGvFTSg8DJwLZARMR5EXGFpIMl3Us2zefY6lpr\nZoPkZ5BNIuL9JcqcMIy2mFm1HCDNzAqk9QTSAdLMEuIepJlZAQdIM7MCYw6QZmatuQdpZlbAAdLM\nrEBa4TGdlTRmZkREqaOVTlkNJR0q6WeSVkj6qaRFndrjHqSZJWPAWQ1/ML5BrqQ3AN8BXtfuvO5B\nmlkyeliKPZHVMCI2AuNZDZ879+ZZWbenxLx09yDNLBljY12vpemY1RBA0uHAF4FdgXd3Oql7kGaW\njF6eQZY8/2UR8TrgcOALncq7B2lmySjqP9720EPc9tBDBd8C5bIaTshTvbxG0s4R8URROQdIM0tG\nUe/w9bNn8/rZsyfeX3zjjc1FOmY1lDQ3Iu7LX88Htm0XHMEB0swS0u3tc0SMShrPargVcP54VkPy\nvWWBP5V0DPB74Bngzzqd1wHSzJLR4/PFtlkNI+J04PTJnNMB0sySkdpKGgdIM0tGD9N8BsIB0syS\nkdp2Z5XPgyyxfvJASeslLc+Pz1fRTjMbvMSSGlbbgyy5fhLg+og4dOgNNLOhSm27s6p7kB3XT+aK\ncmab2TQy6JU0k1V1gGy1fvJVLcodIGmlpMsl7TucppnZsKUWIKfCIM0twO4RsUHSEuAyYK+iwiMj\nIxOva7UatVpt0O0bijWJ3Xr0m3yPMKXU63Xq9Xrfzzua2Ci2qrznl7QQGImIxfn7z5DNej+tzc88\nALy51RIhSZHaMwwrZzoHyJnwJymJiOjptygpLjjuuFJljz333J7rK6PqW+yJ9ZOStiVbP7m0sYCk\nWQ2vF5AF9bbrJ81savItdoOS6yePkHQ8sJFs/eSR1bXYzAYptXmQlT+DLLF+8mzg7GG3y8yGL7VH\nZJUHSDOzcQ6QZmYFUguQVQ/SmJlNGI0odbRSYtny+/O0rz+TdEOe2bAt9yDNLBkDTvt6P/D2iPi1\npMXAN4CF7c7rAGlmyehhFHti2TKApPFlyxMBMiIa8zTcSOtVe5vxLbaZJaOHeZBlly2P+8/AlZ3a\n4x6kmSWj6Bb7nsce49516/pSh6SDgGOBt3Uq6wBpZskousWeO2sWc2dNLKrj+7fe2lykVNpXSW8E\nzgMWR8STndrjW2wzS0YPt9hlli3vDlwK/Pl4+tdO3IM0s2R0u5tPyWXL/wPYGfi6JAEbI2JBu/M6\nQJpZMgac9vWjwEcnc04HSDNLhjerMDMrkNpSQwdIM0uGe5BmZgXcgzQzK+AepJlZgdSSdjlAmlky\nfIttZlYgtVvsypcadtrkMi9zlqR7JK2UNG/YbTSz4Ugtq2GlAbJhk8t3Aa8HjpK0T1OZJcDciNgT\nOA44Z+gNNbOhGIsodQxL1T3IiU0uI2IjML7JZaPDgIsAImIZsGNjrmwzmz4cIDdXZpPL5jJrW5Qx\ns2kgtVvsaTdIMzIyMvG6VqtRq9Uqa4vZdFWv16nX630/7yZP89lMmU0u1wK7dSgzoTFAmtlgNHc+\nTjnllL6cN3oIkHkirq/w3HZnpzV9vzdwATAf+FxEfLnTOau+xe64yWX+/hgASQuB9RHRn73XzSwp\n3T6DLDPgC/wK+DjwN2XbU2kPsswmlxFxhaSDJd0L/JYsl4SZTUMDzmr4OPC4pEPKnrTqW+yOm1zm\n708YaqPMrBI9BMhWA75tdwsvo/IAaWY2bqzgGeTaJ5/kkSc75tjqOwdIM0tG0RSeV+60E6/caaeJ\n9zf//OfNRUplNZwsB0gzS8am0dFuf3RiwBd4lGzA96g25VXmpA6QZpaMbp9BlhnwzVfg3QzsAIxJ\nOhHYNyKeLjqvA6SZJaOXZYQlshquY/M51R05QJpZMooGaariAGlmyRhNbD9IB0gzS4Z7kGZmBXoY\nxR4IB0gzS4aTdpmZFUgtJ40DpJklwz1IM7MCHqQxMyvgHqSZWQEHSDOzAhs3baq6CZtxgDSzZHge\npJlZgdHEAmRlSbskvUTS1ZLuknSVpB0Lyv1c0s8krZD002G308yGZ9PYWKmjFUmLJa2WdLekkwrK\nnCXpHkkrJc3r1J4qsxp+BvhBROwNXAt8tqDcGFCLiP0iouccE/0yiJzAM7k+mN71Tf/fX3+Mjo6W\nOpqVyWooaQkwNyL2BI4DzunUnioD5GHAhfnrC4HDC8qJ6tPTbmG6/8E7QPa5tmn/++uPjc8+W+po\nYSKrYURsBMazGjY6DLgIICKWATvmm+gWqvIZ5MvG81tHxGOSXlZQLoBrJI0C50XEN4bWQjMbqo2/\n/323P1omq2FzmbX5Z+uKTjrQACnpGqAxQoss4H2+RfGiRZiLIuJRSbuSBco7I+KGPjfVzBKw4Te/\nqboJm4uISg7gTmBW/vrlwJ0lfuZk4JNtvg8fPnxUc/QhJvx8EvU91vSzC4HvN7z/DHBSU5lzgCMb\n3q8mj0FFR5W32EuBDwGnAR8EvtdcQNILga0i4mlJLwL+GDil6IQRUSpTmZmlJyLm9PDjZbIaLgU+\nBlwsaSGwfvwxX5EqA+RpwHckfRhYA/wZgKRXAN+IiEPIbs//VVKQtfWfIuLqqhpsZmkqk9UwIq6Q\ndLCke4HfAsd2Oq+KEnWbmc10yU2fKWtYE80HMfm0l/okHShpvaTl+dFqwKtsXedLWifp1jZl+nlt\nbevr57Xl55st6VpJt0taJekTBeX6co1l6uvz7287Scvyv+1Vkk4uKNev6+tYX79/h5WrapCmDw90\nTwM+nb8+CTi1oNz9wEu6rGMr4F5gD2AbYCWwT1OZJcDl+ev9gRt7uKYy9R0ILO3T/8O3AfOAWwu+\n79u1layvb9eWn+/lwLz89fbAXQP+/ZWpr9/X+ML8v1sDNwILBvw77FRfX6+v6mPK9iAZzkTzgUw+\n7bE+yK6pZ5FNl3qyTZF+XluZ+qBP15bX91hErMxfP002c+JVTcX6do0l64P+XuOG/OV2ZM/pm5+Z\n9ft32Kk+6OP1VW0qB8jNJpoDnSaa3yTpo5Oso9Xk0+Y/+KLJp90oUx/AAfnt0uWS9u2yrm7a08u1\nlTWQa5M0h6z3uqzpq4FcY5v6oI/XKGkrSSuAx4BrIuKmpiJ9vb4S9cHw/j4HLundfDzRvKVbgN0j\nYkO+tvQyYK+K29QvA7k2SdsDlwAn5j27gepQX1+vMSLGgP0kvRi4TNK+EXFHt+frQ33T6u8z6R5k\nRLwzIt7YcLwh/+9SYN34rYKklwO/KDjHo/l/fwn8K1suP2pnLbB7w/vZ+WfNZXbrUKZv9UXE0+O3\nORFxJbCNpJ27rK9Me/p1bR0N4tokPY8sWP1DRGwx15Y+X2On+gb1+4uIp4DrgMVNXw3kd1hU35D/\nPgcu6QDZwfhEc2gz0Tz/1xw9N9H8tknUMTH5VNK2ZJNPl7ZoxzF5HaUmn/ZSX+PzI0kLyKZqPdFl\nfZD1youeGfXz2jrWN4BrA/gmcEdEnFnwfb+vsW19/bxGSbson70h6QXAO8lWhzTq2/WVqW9Av8PK\nJH2L3cHAJ5rHgCaf9lIfcISk44GNwDPAkd3WJ+lbQA14qaQHyZZybjuIaytTH328try+RcDRwKr8\nuVkAnyObJdD3ayxTH/29xlcAFyrb6msr4OL8egby91mmvj5fX+U8UdzMrMBUvsU2MxsoB0gzswIO\nkGZmBRwgzcwKOECamRVwgDQzK+AAaWZWwAHSJkXZnof3S9opf/+S/P3uLco+X1JdmT0kjUn6WMP3\nX5V0TJ/bt4ukK/t5Tpu5HCBtUiLiYeDrZCuZAE4FzomIB1sU/zBwaTy3GuEXwIn5euVBte9x4BFJ\nBwyqDps5HCCtG18B9pd0IvAfgS8VlDuazdfI/xL4vzy3hn6CpHmSfpJvk3Vpw5rf6ySdqmwn69X5\ncr7xbbdOzz9fqc23svse8IGer9JmPAdIm7SI2AR8Gvhbsi29RpvLSNoGeHVTzzLIep6fktS8YcWF\nwH+PiHlkG4o0bue/dUTsD/w3YCT/7CNkGy/sT7ZD018oy2gHcDPwBz1cohngAGndOxh4BHhDwfe7\nAOubP4yIn5Nt1X/0+Gf53oI7NuzTeSHw9oYf+27+31vINn6AbGemY/JNIZYBOwN75t/9gmxjBbOe\nTOXdfKwiyhI/vYMsWfuPJH27xRZazwDPLzjFF8n2TKw3nrZNlc/m/x3lub9ZAR+PiGtalH9+Xr9Z\nT9yDtG58nezW+mHgdFo8g4yI9cDW+b6W45R/dxdwB3Bo/v4p4Inx54vAnwM/LKh7PJBeBfyX8QEf\nSXvmexRCtoP1ZPb9NGvJAdImJR8MWRMR1+Yf/R9gH0mtnvldTZbJcFzj3nr/m81zo3wIOEPSSuBN\nwP9s8TON7/+OLMgul7QKOIfnepcHAZeXvSazIt4P0gZG0n7Af42IDw653jpwWET8epj12vTjHqQN\nTESsAK5rMWI9MJJ2Ab7s4Gj94B6kmVkB9yDNzAo4QJqZFXCANDMr4ABpZlbAAdLMrMD/B7uQFy68\nHeMmAAAAAElFTkSuQmCC\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "mg.status_at_node[2] = CLOSED_BOUNDARY\n", - "mg.status_at_node\n", - "imshow_grid(mg, mg.status_at_node, color_for_closed='blue')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We could set the boundary condition at each node individually, or at groups of nodes (e.g. where the node_x value is greater than some value). But in many cases we just want to set the edges in one way or another. There are some functions for setting the boundary conditions around the perimeter of a raster. (Remember that initially all of the perimeter nodes are fixed value.)\n", - "\n", - "A generic way to do this is to use ** set_status_at_node_on_edges **.\n", - "\n", - "Note that this method takes the node status for whether a boundary should be closed. The order is ** right, top, left, bottom **\n", - "\n", - "You could send it, for example, CLOSED_BOUNDARY, or 4, which is the value for CLOSED_BOUNDARY status.\n", - "\n", - "Below we set the right and left edges as closed and the top and bottom as fixed_value." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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\nVuD/A4BDYRsbL/h3AAAAAElFTkSuQmCC\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "mg.set_status_at_node_on_edges(right=CLOSED_BOUNDARY, top=FIXED_VALUE_BOUNDARY, \\\n", - " left=CLOSED_BOUNDARY, bottom=FIXED_VALUE_BOUNDARY)\n", - "#the same thing could be done as ...\n", - "#mg.set_status_at_node_on_edges(right=4, top=1, left=4, bottom=1)\n", - "imshow_grid(mg, mg.status_at_node, color_for_closed='blue')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There are multiple ways to set edge boundary conditions. If above isn't intuitive to you, keep reading.\n", - "\n", - "** Now let's set the right and left edges as closed boundaries using set_closed_boundaries_at_grid_edges **\n", - "\n", - "Note that this method takes boolean values for whether a boundary should be closed. The order is \n", - "** right, top, left, bottom **\n", - "\n", - "Note that here we instantiate a new grid." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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\nAAAASUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "mg1 = RasterModelGrid((4, 4), 1.)\n", - "mg1.set_closed_boundaries_at_grid_edges(True, False, True, False)\n", - "imshow_grid(mg1, mg1.status_at_node, color_for_closed='blue')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": false - }, - "source": [ - "** Now let's try setting looped boundaries using set_looped_bondaries. **\n", - "\n", - "Note that this method takes boolean values for whether the top and bottom (first) or right and left (second) are looped.\n", - "\n", - "We will set the top and bottom to be looped (status value of 3)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "mg2 = RasterModelGrid((4, 4), 1.)\n", - "mg2.set_looped_boundaries(True, False)\n", - "imshow_grid(mg2, mg2.status_at_node)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that this has the right and left edges as fixed_value (status value of 1). \n", - "\n", - "We can change those to closed if we want." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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\nSUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "mg2.set_closed_boundaries_at_grid_edges(True, False, True, False)\n", - "imshow_grid(mg2, mg2.status_at_node, color_for_closed='Blue')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that there are not methods for setting fixed_gradient conditions on the boundary edges. But we can do that. We could use ** set_status_at_node_on_edges **. Below is another way to do this.\n", - "\n", - "Remember that fixed_gradient has a status value of 2.\n", - "We will set the top and bottom to be fixed gradient." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "mg3 = RasterModelGrid((4, 4), 1.)\n", - "mg3.status_at_node[np.where(mg3.node_y == 0)] = FIXED_GRADIENT_BOUNDARY\n", - "mg3.status_at_node[np.where(mg3.node_y == 3)] = FIXED_GRADIENT_BOUNDARY\n", - "imshow_grid(mg3, mg3.status_at_node, color_for_closed='Blue')\n", - "#there are no closed boundaries so we didn't need the color_for_closed option, \n", - "#but no problem if you accidentally include it!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Click here for more Landlab tutorials" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.11" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/boundary_conds/set_watershed_BCs_raster_unexpanded.ipynb b/boundary_conds/set_watershed_BCs_raster_unexpanded.ipynb deleted file mode 100644 index 0f2142d..0000000 --- a/boundary_conds/set_watershed_BCs_raster_unexpanded.ipynb +++ /dev/null @@ -1,361 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

a toolkit for modeling earth surface processes

" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Setting watershed boundary conditions on a raster grid\n", - "\n", - "- This tutorial ilustrates how to set watershed boundary conditions on a raster grid.\n", - "- Note that a watershed is assumed to have a ring of nodes around the core nodes that are closed boundaries (i.e. no flux can cross these nodes, or more correctly, no flux can cross the faces around the nodes).\n", - "- This means that automatically the nodes on the outer perimeter of the grid will be set to be closed boundary.\n", - "- By definitation a watershed also has one outlet through which fluxes can pass. Here the outlet is set as the node that has the lowets value, is not a nodata_value node, and is adjacent to at least one closed boundary node. \n", - "- This means that an outlet can be on the outer perimeter of the raster. However, the outlet does not need to be on the outer perimeter of the raster." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### The first example uses set_watershed_boundary_condition which finds the outlet for the user.\n", - "- First import what we need." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "from landlab import RasterModelGrid\n", - "import numpy as np\n", - "from landlab.plot.imshow import imshow_grid\n", - "%matplotlib inline " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Now we create a 5 by 5 grid with a spacing (dx and dy) of 1.\n", - "- We also create an elevation field with value of 1. everywhere, except at the outlet, where the elevation is 0. In this case the outlet is in the middle of the bottom row, or at at location (0,2) and has a node id of 2." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "mg1 = RasterModelGrid((5,5), 1.)\n", - "z1 = mg1.add_ones('node','topographic__elevation')\n", - "mg1.at_node['topographic__elevation'][2] = 0.\n", - "mg1.at_node['topographic__elevation']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- The set_watershed_boundary_condition in RasterModelGrid will find the outlet of the watershed.\n", - "- This method takes the node data, in this case z, and, optionally the no_data value.\n", - "- This method sets all nodes that have no_data values to closed boundaries.\n", - "- This example does not have any no_data values, which is fine. \n", - "- In this case, the code will set all of the perimeter nodes as CLOSED_BOUNDARY (boundary status 4) in order to create this boundary around the core nodes. \n", - "- The exception on the perimeter is node 2 (with elevation of 0). Although it is on the perimeter, it has a value and it has the lowest value. So in this case node 2 will be set as FIXED_VALUE_BOUNDARY (boundary status 1).\n", - "- The rest of the nodes are set as a CORE_NODE (boundary status 0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "mg1.set_watershed_boundary_condition(z1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Check to see that node status were set correctly.\n", - "- imshow_grid will default to not plot the value of CLOSED_BOUNDARY nodes, which is why we override this below with the option color_for_closed" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "imshow_grid(mg1, mg1.status_at_node, color_for_closed='blue')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": false - }, - "source": [ - "### The second example uses set_watershed_boundary_condition_outlet_coords \n", - "- In this case the user knows the coordinates of the outlet node.\n", - "- First instantiate a new grid, with new data values." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "mg2 = RasterModelGrid((5,5), 10.)\n", - "z2 = mg2.add_ones('node','topographic__elevation')\n", - "mg2.at_node['topographic__elevation'][1] = 0.\n", - "mg2.at_node['topographic__elevation']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Note that the node with zero elevation, which will be the outlet, is now at location (0,1).\n", - "- Note that even though this grid has a dx & dy of 10., the outlet coords are still (0,1).\n", - "- Set the boundary conditions." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "mg2.set_watershed_boundary_condition_outlet_coords((0,1),z2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Plot grid of boundary status information" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "imshow_grid(mg2, mg2.status_at_node, color_for_closed='blue')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### The third example uses set_watershed_boundary_condition_outlet_id \n", - "- In this case the user knows the node id value of the outlet node.\n", - "- First instantiate a new grid, with new data values." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "mg3 = RasterModelGrid((5,5), 5.)\n", - "z3 = mg3.add_ones('node','topographic__elevation')\n", - "mg3.at_node['topographic__elevation'][5] = 0.\n", - "mg3.at_node['topographic__elevation']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Set boundary conditions with the outlet id.\n", - "- Note that here we know the id of the node that has a value of zero and choose this as the outlet. But the code will not complain if you give it an id value of a node that does not have the smallest data value." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "mg3.set_watershed_boundary_condition_outlet_id(5,z3)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Another plot to illustrate the results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "imshow_grid(mg3, mg3.status_at_node, color_for_closed='blue')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### The final example uses set_watershed_boundary_condition on a watershed that was exported from Arc.\n", - "- First import read_esri_ascii and then import the DEM data.\n", - "- An optional value of halo=1 is used with read_esri_ascii. This puts a perimeter of nodata values around the DEM.\n", - "- This is done just in case there are data values on the edge of the raster. These would have to become closed to set watershed boundary conditions, but in order to avoid that, we add a perimeter to the data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from landlab.io import read_esri_ascii\n", - "(grid_bijou, z_bijou) = read_esri_ascii('west_bijou_gully.asc', halo=1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Let's plot the data to see what the topography looks like." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "imshow_grid(grid_bijou, z_bijou)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- In this case the nodata value is zero. This skews the colorbar, but we can at least see the shape of the watershed.\n", - "- Lets set the boundary condition. Remember we don't know the outlet id." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "grid_bijou.set_watershed_boundary_condition(z_bijou,0)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Now we can look at the boundary status of the nodes to see where the found outlet was." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "imshow_grid(grid_bijou, grid_bijou.status_at_node, color_for_closed='blue')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- This looks sensible.\n", - "- Now that the boundary conditions ae set, we can also look at the topography. \n", - "- imshow_grid will default to show boundaries as black, as illustrated below. But that can be overwridden as we have been doing all along." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "imshow_grid(grid_bijou, z_bijou)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] - } - ], - "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.5.1" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/component_tutorial/component_tutorial_unexpanded.ipynb b/component_tutorial/component_tutorial_unexpanded.ipynb deleted file mode 100644 index 2ae80ed..0000000 --- a/component_tutorial/component_tutorial_unexpanded.ipynb +++ /dev/null @@ -1,700 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

a toolkit for modeling earth surface processes

" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Getting to know the Landlab component library" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - " For instructions on how to run an interactive iPython notebook, click here: https://github.com/landlab/tutorials/blob/master/README.md
\n", - "For the unexpanded version to download and run, click here: http://nbviewer.jupyter.org/github/landlab/tutorials/blob/master/component_tutorial/component_tutorial_unexpanded.ipynb
\n", - "For more Landlab tutorials, click here: https://github.com/landlab/landlab/wiki/Tutorials\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This ipython notebook walks you through the stages of creating and running a Landlab model using the Landlab component library.\n", - "\n", - "We are going to create three models—firstly a single component driver implementing just linear diffusion; then a three-component driver implementing linear diffusion, flow routing, and stream power incision; and finally a similar model, but implementing a storm-interstorm sequence.\n", - "\n", - "# The basics: one component\n", - "\n", - "Let's begin with the one-component diffusion model.\n", - "\n", - "Firstly, import the library elements we'll need. The component classes can all be imported from the `landlab.components` library. They're all formatted in CamelCaseLikeThis. Anything you see in that folder that isn't formatted like this isn't a component!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from landlab.components import LinearDiffuser\n", - "from landlab.plot import imshow_grid\n", - "from landlab import RasterModelGrid, CLOSED_BOUNDARY, FIXED_VALUE_BOUNDARY\n", - "from matplotlib.pyplot import figure, show, plot, xlabel, ylabel, title\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's start by creating the grid that we'll do the first part of this exercise with, and putting some data into its fields. Note that you need to create the fields that a component takes as inputs *before* instantiating a component - though you can put values into the arrays later if you need to (as illustrated below). For more info on working with fields, see the *fields* tutorial." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "mg = RasterModelGrid((80, 80), 5.)\n", - "z = mg.add_zeros('node', 'topographic__elevation')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "How did we know this was a field we needed as an input? Well, firstly because we read the component documentation (**always do this!**), but secondly we can get a reminder using the Landlab Component Standard Interface:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "LinearDiffuser.input_var_names" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note we didn't have to instantiate the component to be able to do this! Other standard properties are `output_var_names` and `optional_var_names`; pass an input or output name to `var_loc`, `var_type`, `var_units`, and `var_definition` to get the centering ('node', 'link', etc), array dtype (float, int), units (meters, etc) and a descriptive string, respectively. `var_help` will dive you a lot of this information at once:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "LinearDiffuser.var_help('topographic__elevation')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It's also a good idea to set the grid boundary conditions before component instantiation. Let's have fixed value top and bottom and closed left and right:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "for edge in (mg.nodes_at_left_edge, mg.nodes_at_right_edge):\n", - " mg.status_at_node[edge] = CLOSED_BOUNDARY\n", - "for edge in (mg.nodes_at_top_edge, mg.nodes_at_bottom_edge):\n", - " mg.status_at_node[edge] = FIXED_VALUE_BOUNDARY" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Landlab components have undergone something of a stylistic overhaul in Landlab version 1. You should now find that all components within landlab share a similar interface. We'll examine how it looks first on the diffusion component.\n", - "\n", - "Landlab components now have a standardised instantiation signature. A key difference to what you may have seen before is that the inputs to the component are now fed in as *dynamic Python objects*, i.e., floats, strings, arrays, rather than being fed in as strings from a text input file (though note, you an still do this, see below). This has two major advantages: firstly, components now have plainly declared default values, that are visible just like they would be in, say, a numpy function; secondly, because the inputs are now Python objects, it's a lot easier to work with spatially variable inputs that need to be passed in as arrays, and also to feed dynamically changing inputs into a component.\n", - "\n", - "The standard signature to instantiate a component looks like this:\n", - "\n", - " MyComponent(grid, input1=default1, input2=default2, input3=default3, ..., **kwds)\n", - "\n", - "Because defaults are provided, you can instantiate a component with default values very simply; the diffuser requires only that a `linear_diffusity` be supplied:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "lin_diffuse = LinearDiffuser(mg, linear_diffusivity=0.2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We'll see some other ways of initializing (e.g., from an input file) below.\n", - "\n", - "Now we're ready to run the component! Run methods are also standardized. Almost all Landlab components have a standard run method named `run_one_step`, and it looks like this:\n", - "\n", - " my_comp.run_one_step([dt], other_inputA=defaultA, ...)\n", - "\n", - "If the component is time-dependent, `dt`, the timestep, will be the first argument. Subsequent keywords will typically be flags that control the way the component runs, and typically can be left as their default values. Note that nothing is returned from a run method like this, but that nonetheless *the grid fields are updated*.\n", - "\n", - "This `dt` is properly thought of as the *external model timestep*; it controls essentially the frequency at which the various Landlab components you're implementing can exchange information with each other and with the driver (e.g., frequency at which uplift steps are added to the grid). If your model has a stability condition which demands a shorter timestep, the external timestep will be subdivided internally down to this shorter timescale.\n", - "\n", - "So let's do it. It's up to you as the component designer to make sure your driver script accounts properly for the total time the model runs. Here, we want to run for 200000 years with a timestep of 1000 years, with an uplift rate of 0.001 m/y. So:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "total_t = 200000.\n", - "dt = 1000.\n", - "uplift_rate = 0.001\n", - "nt = int(total_t // dt)\n", - "# ^note if we didn't know a priori that there are a round number of steps dt in the\n", - "# total time, we'd have to take care to account for the \"extra\" time (see example below)\n", - "for i in range(nt):\n", - " lin_diffuse.run_one_step(dt)\n", - " z[mg.core_nodes] += uplift_rate * dt # add the uplift\n", - " # add some output to let us see we aren't hanging:\n", - " if i % 50 == 0:\n", - " print(i*dt)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that we're using `z` to input the uplift here, which we already bound to the Landlab field `mg.at_node['topographic__elevation]` when we instantiated that field. This works great, but always be careful to update the values *inside* the array, not to reset the variable as equal to something else, i.e., to put new values in the field do::\n", - "\n", - " z[:] = new_values # values copied into the existing field\n", - "\n", - "not\n", - "\n", - " z = new_values # z is now \"new_values\", not the field!\n", - "\n", - "Now plot the output!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# the following line makes figures show up correctly in this document (only needed for iPython notebook)\n", - "%matplotlib inline\n", - "\n", - "# Create a figure and plot the elevations\n", - "figure(1)\n", - "im = imshow_grid(mg, 'topographic__elevation', grid_units = ['m','m'],\n", - " var_name='Elevation (m)')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "figure(2)\n", - "elev_rast = mg.node_vector_to_raster(z)\n", - "ycoord_rast = mg.node_vector_to_raster(mg.node_y)\n", - "ncols = mg.number_of_node_columns\n", - "im = plot(ycoord_rast[:, int(ncols // 2)], elev_rast[:, int(ncols // 2)])\n", - "xlabel('horizontal distance (m)')\n", - "ylabel('vertical distance (m)')\n", - "title('topographic__elevation cross section')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, let's repeat this exercise, but illustrating the way we can input fields as some parameters for components. We're going to make the diffusivity spatially variable., falling by a factor of ten as we move across the grid." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "z[:] = 0. # reset the elevations to zero\n", - "k_diff = mg.zeros('node', dtype=float)\n", - "k_diff.fill(1.)\n", - "k_diff *= (mg.node_x.max() - 0.9*mg.node_x)/mg.node_x.max()\n", - "k_field = mg.add_field('node', 'linear_diffusivity', k_diff, noclobber=False)\n", - "imshow_grid(mg, k_diff, var_name='k_diff', cmap='winter') # check it looks good" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we re-initialize the component instance to bind the k_diff field to the component:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "lin_diffuse = LinearDiffuser(mg, linear_diffusivity='linear_diffusivity')\n", - "# we could also have passed in `k_diff` in place of the string" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "...and run just as before. Note this will be slower than before; the internal timestep is shorter because we've modified the diffusivities." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "for i in range(nt):\n", - " lin_diffuse.run_one_step(dt)\n", - " z[mg.core_nodes] += uplift_rate * dt # add the uplift\n", - " # add some output to let us see we aren't hanging:\n", - " if i % 50 == 0:\n", - " print(i*dt)\n", - "figure(3)\n", - "im = imshow_grid(mg, 'topographic__elevation', grid_units = ['m','m'],\n", - " var_name='Elevation (m)')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Running two or more components\n", - "\n", - "Now we're going to take a similar approach but this time combine the outputs of three distinct Landlab components: the diffuser, the monodirectional flow router, and the stream power incisor. For clarity, we're going to repeat the whole process from the start.\n", - "\n", - "So first, let's import everything we don't already have:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from landlab.components import FlowRouter, FastscapeEroder\n", - "from landlab import load_params" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "More components means more input parameters. So this time, we're going to make our lives easier by instantiating our components from an [input file](./coupled_params.txt). Note also that we've now switched length units to km from m.\n", - "\n", - "We're going to handle our input file using the very powerful `load_params` Landlab function. This function can read input text files formatted in a variety of different ways, including both the Landlab-native style and also the yaml standard. It automatically types the values it finds in the input file (i.e., makes them int, float, string, etc.), and returns them as a Python dictionary. However, feel free to use your own way of reading in a text file. The important thing is that you end up with a **dictionary** that you can pass into the components that contains `'input_parameter_name': parameter_value` pairs.\n", - "\n", - "Once we have the MPD, we're going to pull the parameters we need to make the grid and drive the components out of it (in part, to show that the MPD is a Python dictionary)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "input_file = './coupled_params.txt'\n", - "inputs = load_params(input_file) # load the data into a dictionary\n", - "\n", - "nrows = inputs['nrows']\n", - "ncols = inputs['ncols']\n", - "dx = inputs['dx']\n", - "uplift_rate = inputs['uplift_rate']\n", - "total_t = inputs['total_time']\n", - "dt = inputs['dt']\n", - "\n", - "nt = int(total_t // dt) #this is how many loops we'll need\n", - "uplift_per_step = uplift_rate * dt\n", - "\n", - "# illustrate what the MPD looks like:\n", - "print(inputs)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now instantiate the grid, set the initial conditions, and set the boundary conditions:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "mg = RasterModelGrid((nrows, ncols), dx)\n", - "z = mg.add_zeros('node', 'topographic__elevation')\n", - "# add some roughness, as this lets \"natural\" channel planforms arise\n", - "initial_roughness = np.random.rand(z.size)/100000.\n", - "z += initial_roughness\n", - "for edge in (mg.nodes_at_left_edge, mg.nodes_at_right_edge):\n", - " mg.status_at_node[edge] = CLOSED_BOUNDARY\n", - "for edge in (mg.nodes_at_top_edge, mg.nodes_at_bottom_edge):\n", - " mg.status_at_node[edge] = FIXED_VALUE_BOUNDARY" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "So far, so familiar.\n", - "\n", - "Now we're going to instantiate all our components, using the MPD. We can do this using a bit of Python magic that lets you pass dictionaries into functions as sets of keywords. We do this by passing the dictionary as the final input, with to asterisks - `**` in front of it:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "fr = FlowRouter(mg, **inputs)\n", - "sp = FastscapeEroder(mg, **inputs)\n", - "lin_diffuse = LinearDiffuser(mg, **inputs)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "What's happening here is that the component is looking inside the dictionary for any keys that match its keywords, and using them. Each will ignore any keys in the dictionary that it does not recognise. Values in the dictionary will override component defaults, but note that you cannot provide a keyword manually that is also defined in a supplied dictionary, i.e., this would result in a TypeError:\n", - "\n", - " >>> lin_diffuse = LinearDiffuser(mg, linear_diffusivity=1.,\n", - " **{'linear_diffusivity': 1.})\n", - " TypeError\n", - "\n", - "And now we run! We're going to run once with the diffusion and once without." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "for i in range(nt):\n", - " # lin_diffuse.run_one_step(dt) no diffusion this time\n", - " fr.run_one_step() # route_flow isn't time sensitive, so it doesn't take dt as input\n", - " sp.run_one_step(dt)\n", - " mg.at_node['topographic__elevation'][mg.core_nodes] += uplift_per_step # add the uplift\n", - " if i % 20 == 0:\n", - " print ('Completed loop %d' % i)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "You'll need to give the above code a few seconds to run, but note because this is Jean Braun's Fastscape algorithm, it's very tolerant of long time steps." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "figure('topo without diffusion')\n", - "imshow_grid(mg, 'topographic__elevation', grid_units=['km','km'], var_name='Elevation (km)')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "And now let's reset the grid elevations and do everything again, but this time, with the diffusion turned *on*:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "z[:] = initial_roughness\n", - "for i in range(nt):\n", - " lin_diffuse.run_one_step(dt) # no diffusion this time\n", - " fr.run_one_step() # route_flow isn't time sensitive, so it doesn't take dt as input\n", - " sp.run_one_step(dt)\n", - " mg.at_node['topographic__elevation'][mg.core_nodes] += uplift_per_step # add the uplift\n", - " if i % 20 == 0:\n", - " print ('Completed loop %d' % i)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "figure('topo with diffusion')\n", - "imshow_grid(mg, 'topographic__elevation', grid_units=['km','km'],\n", - " var_name='Elevation (km)')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "Beautiful! We've smoothed away the fine-scale channel roughness, as expected, and produced some lovely convex-up hillslopes in its place. Note that even though the initial conditions were identical in both cases, including the roughness, the channel positions have been moved significantly by the hillslope diffusion into the channel." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As a final step, we're going to show off some of Landlab's fancier functionality. We're going to repeat the above coupled model run, but this time we're going to plot some evolving channel profiles, and we're going to drive the simulation with a sequence of storms, not just a fixed timestep. We'll also peoduce a slope-area plot for the final conditions.\n", - "\n", - "Working with timesteps of varying length requires a bit more bookkeeping, but the principle is the same as what we've seen before.\n", - "\n", - "So, load the new landlab objects we'll need, then reset the initial conditions:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "from landlab.plot import channel_profile as prf\n", - "from landlab.components.uniform_precip import PrecipitationDistribution\n", - "from matplotlib.pyplot import loglog" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "z[:] = initial_roughness" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Instantiate the storm generator. This time, we're going to mix an input file for some components with manual definition of others (that we already defined above)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "dt = 0.1\n", - "total_t = 250.\n", - "# re-instantiate the FastscapeEroder, so we can \n", - "\n", - "storm_inputs = load_params('./coupled_params_storms.txt')\n", - "precip = PrecipitationDistribution(total_t=total_t, delta_t=dt, **storm_inputs)\n", - "print(storm_inputs)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now run:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "scrolled": false - }, - "outputs": [], - "source": [ - "out_interval = 20.\n", - "last_trunc = total_t # we use this to trigger taking an output plot\n", - "for (interval_duration, rainfall_rate) in precip.yield_storm_interstorm_duration_intensity():\n", - " if rainfall_rate > 0.:\n", - " # note diffusion also only happens when it's raining...\n", - " fr.route_flow()\n", - " sp.run_one_step(interval_duration)\n", - " lin_diffuse.run_one_step(interval_duration)\n", - " z[mg.core_nodes] += uplift_rate * interval_duration\n", - " this_trunc = precip.elapsed_time // out_interval\n", - " if this_trunc != last_trunc: # time to plot a new profile!\n", - " print ('made it to time %d' % (out_interval * this_trunc))\n", - " last_trunc = this_trunc\n", - " figure(\"long_profiles\")\n", - " profile_IDs = prf.channel_nodes(mg, mg.at_node['topographic__steepest_slope'],\n", - " mg.at_node['drainage_area'],\n", - " mg.at_node['flow__receiver_node'])\n", - " dists_upstr = prf.get_distances_upstream(\n", - " mg, len(mg.at_node['topographic__steepest_slope']),\n", - " profile_IDs, mg.at_node['flow__link_to_receiver_node'])\n", - " plot(dists_upstr[0], z[profile_IDs[0]])\n", - " # no need to track elapsed time, as the generator will stop automatically\n", - "# make the figure look nicer:\n", - "figure(\"long_profiles\")\n", - "xlabel('Distance upstream (km)')\n", - "ylabel ('Elevation (km)')\n", - "title('Long profiles evolving through time')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that the \"wobbles\" in the long profile here are being created by the stochastic storm sequence. We could reduce their impact by reducing the storm-interstorm timescales, or allowing diffusion while it's not raining, but we've chosen not to here to show that the storms are having an effect." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "figure('topo with diffusion and storms')\n", - "imshow_grid(mg, 'topographic__elevation', grid_units=['km','km'], var_name='Elevation (km)')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "figure('final slope-area plot')\n", - "loglog(mg.at_node['drainage_area'], mg.at_node['topographic__steepest_slope'],'.')\n", - "xlabel('Drainage area (km**2)')\n", - "ylabel('Local slope')\n", - "title('Slope-Area plot for whole landscape')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "That's a nice set of figures, eh? You can easily spend more time with pylab prettifying them if you want." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Click here for more Landlab tutorials" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.11" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/flexure/lots_of_loads_unexpanded.ipynb b/flexure/lots_of_loads_unexpanded.ipynb deleted file mode 100644 index 6a86f2b..0000000 --- a/flexure/lots_of_loads_unexpanded.ipynb +++ /dev/null @@ -1,394 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Using the Landlab flexure component\n", - "\n", - "
\n", - " For instructions on how to run an interactive iPython notebook, click here: https://github.com/landlab/tutorials/blob/master/README.md
\n", - "For more Landlab tutorials, click here: https://github.com/landlab/landlab/wiki/Tutorials\n", - "
\n", - "\n", - "In this example we will:\n", - "* create a Landlab component that solves the flexure equation\n", - "* apply randomly distributed point loads\n", - "* run the component\n", - "* plot some output" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A bit of magic so that we can plot within this notebook." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create the grid\n", - "\n", - "We are going to build a uniform rectilinear grid with a node spacing of 10 km in the *y*-direction and 20 km in the *x*-direction on which we will solve the flexure equation.\n", - "\n", - "First we nee to import *RasterModelGrid*. We also import the Landlab plotting function *imshow_grid* to view the grids." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from landlab import RasterModelGrid\n", - "from landlab.plot.imshow import imshow_grid" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Create a rectilinear grid with a spacing of 10 km between rows and 20 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": { - "collapsed": false - }, - "outputs": [], - "source": [ - "grid = RasterModelGrid((200, 400), spacing=(10e3, 20e3))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "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": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from landlab.components.flexure import Flexure" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The Flexure 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 `intput_var_names` attribute of the component *class*." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "Flexure.input_var_names" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We see that flexure uses just 1 data field: the change in lithospheric loading. landlab component classes can provide additional information about each of these fields. For instance, to the the units for a field, use the `var_units` method." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "Flexure.var_units('lithosphere__overlying_pressure_increment')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To print a more detailed description of a field, use `var_help`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "Flexure.var_help('lithosphere__overlying_pressure_increment')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "What about the data that `Flexure` provides? Use the `output_var_names` attribute." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "Flexure.output_var_names" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "Flexure.var_help('lithosphere_surface__elevation_increment')" - ] - }, - { - "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": { - "collapsed": false - }, - "outputs": [], - "source": [ - "flex = Flexure(grid, method='flexure')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Add some loading\n", - "We will add loads to the grid. As we saw above, for this component, the name of the variable that hold the applied loads is call, `lithosphere__overlying_pressure`. We add loads of random magnitude at every node of the grid." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "load = np.random.normal(0, 100 * 2650. * 9.81, grid.number_of_nodes)\n", - "grid.at_node['lithosphere__overlying_pressure_increment'] = load" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "imshow_grid(grid, 'lithosphere__overlying_pressure_increment', symmetric_cbar=True,\n", - " cmap='spectral', show=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Update the component to solve for deflection\n", - "If you have more than one processor on your machine you may want to use several of them." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "flex.update(n_procs=4)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As we saw above, the flexure component creates an output field (`lithosphere_surface__elevation_increment`) that contains surface deflections for the applied loads." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Plot the output" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We now plot these deflections with the `imshow` method, which is available to all landlab components." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "scrolled": false - }, - "outputs": [], - "source": [ - "imshow_grid(grid, 'lithosphere_surface__elevation_increment', symmetric_cbar=True,\n", - " cmap='spectral', show=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Maintain the same loading distribution but double the effective elastic thickness." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "flex.eet *= 2.\n", - "flex.update(n_procs=4)\n", - "imshow_grid(grid, 'lithosphere_surface__elevation_increment', symmetric_cbar=True,\n", - " cmap='spectral', show=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let's add a vertical rectangular load to the middle of the grid. We plot the load grid first to make sure we did this correctly." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "load[np.where(np.logical_and(grid.node_x>3000000, grid.node_x<5000000))]= \\\n", - " load[np.where(np.logical_and(grid.node_x>3000000, grid.node_x<5000000))]+1e7\n", - "imshow_grid(grid, 'lithosphere__overlying_pressure_increment', symmetric_cbar=True,\n", - " cmap='spectral', show=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "flex.update(n_procs=4)\n", - "imshow_grid(grid, 'lithosphere_surface__elevation_increment', symmetric_cbar=True,\n", - " cmap='spectral', show=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Click here for more Landlab tutorials" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.11" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/gradient_and_divergence/gradient_and_divergence_unexpanded.ipynb b/gradient_and_divergence/gradient_and_divergence_unexpanded.ipynb deleted file mode 100644 index 5a6ab4c..0000000 --- a/gradient_and_divergence/gradient_and_divergence_unexpanded.ipynb +++ /dev/null @@ -1,634 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Using Landlab's gradient and flux divergence functions\n", - "\n", - "
\n", - " (Note: for instructions on how to run an interactive iPython notebook, click here: https://github.com/landlab/tutorials/blob/master/README.md
\n", - "For more Landlab tutorials, click here: https://github.com/landlab/landlab/wiki/Tutorials)\n", - "
\n", - "\n", - "Models of geophysical flow phenomena very commonly include gradient terms and flux divergence terms in their governing equations. Consider the example of conductive heat diffusion in two dimensions. The *flux* of heat, $q$, at a point (in energy per time per area) depends on the *gradient* in temperature:\n", - "\n", - "$q_x = -k \\frac{\\partial T}{\\partial x}$\n", - "\n", - "$q_y = -k \\frac{\\partial T}{\\partial y}$\n", - "\n", - "where the subscripts denote the two directions. The time rate of change of thermal energy depends on the derivative of flux, or *flux divergence*:\n", - "\n", - "$\\frac{dT}{dt} \\propto -\\left( \\frac{\\partial q_x}{\\partial x} + \\frac{\\partial q_y}{\\partial y} \\right)$\n", - "\n", - "In a finite-difference or finite-volume solution, the quantities $T$ and $q$ are solved at discrete points. Staggered-grid schemes will place the scalar quantity ($T$) at one set of grid locations, and the vector quantity ($q$) at \"in-between\" locations.\n", - "\n", - "In Landlab, such a staggered grid is easy to implement by locating scalar quantities at nodes, and locating vector quantities at either links. Landlab also provides a set of \"one-liner\" functions to calculate the gradients in a quantity located at nodes or cells, as well as to calculate the net flux or flux divergence in a vector quantity located at faces or links. This tutorial shows you examples of how to use these.\n", - "\n", - "We'll start with a tiny grid, so it's easy to see what the various flavors of the gradient and flux functions do. Then we'll try them out on the example of a landform undergoing soil creep, which is the same example used in an introductory Landlab tutorial.\n", - "\n", - "## Tiny grid example\n", - "\n", - "We'll start with a 3-row by 4-column raster grid, with 10-meter node spacing." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "import numpy\n", - "from landlab import RasterModelGrid\n", - "mg = RasterModelGrid((3, 4), 10.0)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Create a scalar field called `z`, representing elevation of the land surface, at the grid nodes:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "z = mg.add_zeros('node', 'topographic__elevation')\n", - "z[5] = 5.0\n", - "z[6] = 3.6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Nodes 5 and 6 are the only core nodes; the rest are (so far) open boundaries. \n", - "\n", - "Here are the values. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "z" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Nodes in a raster grid are numbered by row, starting from the bottom. In the array above, the first four are the bottom row, the next four are the middle row, and the last four are the top row. (Note that in general, nodes in any Landlab grid will be numbered in increasing order by their $y$ coordinates; nodes with equal $y$ coordinates, as in the case of rows in a raster grid, will then be numbered in order by $x$)\n", - "\n", - "Let's take a graphical look at the elevation grid we've created. To do so, we'll use the Pylab graphics library (imported under the name `plt`). We also have to tell the iPython Notebook to display plots right here on the page. Finally, we will import Landlab's `imshow_grid` function to display our gridded values." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "from landlab.plot.imshow import imshow_grid" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's plot the elevation values:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "imshow_grid(mg, 'topographic__elevation')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There are elevation values associated with all 12 of the nodes on the grid. The ones shown in black are **boundary nodes**; the two in the middle are **core nodes**. This is our *scalar field*." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Links and gradients\n", - "\n", - "Next, we will calculate the gradient in this field of elevation values. We want to find the gradient between each pair of adjacent nodes, and store that value at the associated **link** between them.\n", - "\n", - "### What are links?\n", - "\n", - "For each pair of adjacent nodes in a Landlab grid, there is a corresponding **link**. Links are directed line segments whose endpoints are the coordinates of the nodes. A link can be illustrated like this:\n", - "\n", - " o---->o\n", - "\n", - "Here, each o represents a node, and the arrow is the link. A \"vertical\" link looks like this:\n", - "\n", - " o\n", - " ^\n", - " |\n", - " |\n", - " o\n", - "\n", - "The tip of the arrow is known as the **link head**; the base of the arrow is known as the **link tail**. By default, links always \"point\" within the upper-right quadrange.\n", - "\n", - "With this definition of links in mind, we can sketch our grid like so, with the ID numbers of the nodes shown by the numbers:\n", - "\n", - "\n", - " 8 ----> 9 ----> 10----> 11\n", - " ^ ^ ^ ^\n", - " | | | |\n", - " | | | |\n", - " 4 ----> 5 ----> 6 ----> 7\n", - " ^ ^ ^ ^\n", - " | | | |\n", - " | | | |\n", - " 0 ----> 1 ----> 2 ----> 3\n", - "\n", - "\n", - "If we label each node with its elevation value, it looks like this:\n", - "\n", - "\n", - " 0 ----> 0 ----> 0 ----> 0\n", - " ^ ^ ^ ^\n", - " | | | |\n", - " | | | |\n", - " 0 ---->5.0---->3.6----> 0\n", - " ^ ^ ^ ^\n", - " | | | |\n", - " | | | |\n", - " 0 ----> 0 ----> 0 ----> 0\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Calculating the gradient of a node field at links\n", - "\n", - "To calculate the gradient of a node field, with one gradient value for each link, use the function `calc_grad_at_link`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "dzdx = mg.calc_grad_at_link(z)\n", - "dzdx" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here's a crude graphical representation of gradient array:\n", - "\n", - "\n", - " o ---0--> o ---0--> o ---0--> o\n", - " ^ ^ ^ ^\n", - " 0 -0.5 -0.36 0\n", - " | | | |\n", - " o +0.5 > o -0.14 > o -0.36 > o\n", - " ^ ^ ^ ^\n", - " 0 +0.5 +0.36 0\n", - " | | | |\n", - " o ---0--> o ---0--> 0 ---0--> 0\n", - "\n", - "Links are listed in order by the $(x, y)$ coordinates of their midpoints. The ID numbering scheme for our links looks like this:\n", - "\n", - "\n", - " o --14--> o --15--> o --16--> o\n", - " ^ ^ ^ ^\n", - " 10 11 12 13\n", - " | | | |\n", - " o ---7--> o ---8--> o ---9--> o\n", - " ^ ^ ^ ^\n", - " 3 4 5 6\n", - " | | | |\n", - " o ---0--> o ---1--> 0 ---2--> 0\n", - "\n", - "Let's explore how the geometry and the values in the ID array of gradients correspond. Here are the gradients first three are the horizontal links along the bottom edge of the grid:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "dzdx[0:3]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next come four vertical links that connect the bottom to the middle rows of nodes. Two of these values are positive, indicating an *uphill gradient in the direction of the links*:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "dzdx[3:7]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now the middle row of horizontal links:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "dzdx[7:10]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The next row of vertical links. The middle two of these are negative, indicating a downhill slope in the direction of the links:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "dzdx[10:14]" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": false - }, - "source": [ - "Finally, the top row of horizontal links:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "dzdx[14:17]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "So far, we've seen how to perform a centered-difference gradient calculation using Landlab's `calc_grad_at_link` function. Next, let's look at the flux divergence operation: adding up all the incoming and outgoing fluxes at a location.\n", - "\n", - "## Cells and flux divergence\n", - "\n", - "### A quick look at finite-volume numerical methods\n", - "\n", - "The *finite-volume method* is a type of numerical approach that is similar to the more familiar finite-difference method. For many problems that are discretized on a regular grid, the two methods turn out to be equivalent. For our next step, we'll take a finite-volume approach, which turns out to be fairly intuitive.\n", - "\n", - "Consider a rectangular *cell* of dimensions $\\Delta x$ by $\\Delta y$:\n", - "\n", - " o-------o\n", - " | |\n", - " | |\n", - " | |\n", - " o-------o\n", - "\n", - "Imagine that the cell represents a patch of ground on a hill. Along each edge of the rectangle, soil is gradually flowing either into or out of the cell. If more soil flows in than flows out, the cell's elevation will rise (we are assuming the soil bulk density is constant). If more soil flows out than flows in, the cell's elevation will shrink.\n", - "\n", - "Suppose we know the average soil flux along each side of the cell. If we use the compass directions *N, S, E, W* to denote the four sides, we might represent these average fluxes as follows: $q_N, q_S, q_E, q_W$.\n", - "\n", - "Let's take the convention that flow is always *positive* when it is going north or east, and negative when it is going south or west. With that in mind, we could compute the *net outflux of soil* as follows:\n", - "\n", - "$Q_{net} = -q_E \\Delta y - q_N \\Delta x + q_W \\Delta y + q_S \\Delta x$\n", - "\n", - "The *rate* at which the cell's average elevation is rising or falling could be expressed as:\n", - "\n", - "$\\frac{dz}{dt} = -\\frac{Q_{net}}{\\Delta x \\Delta y}$\n", - "\n", - "The term on the right side is a finite-volume approximation of the flux divergence. In commonly used symbols,\n", - "\n", - "$\\nabla \\mathbf{q} = \\left( \\frac{\\partial q_x}{\\partial x} + \\frac{\\partial q_y}{\\partial y} \\right) \\approx \\frac{Q_{net}}{\\Delta x \\Delta y}$\n", - "\n", - "This is the quantity we would like to calculate for the nodes in our grid.\n", - "\n", - "### More on grid geometry: nodes and cells\n", - "\n", - "In a Landlab grid, a *cell* is a polygon that contains a single *node*, which is a point. Every cell has one and only one node. However, not every node has a cell: the grid's perimeter consists of nodes without cells.\n", - "\n", - "In our tiny grid example, there are 12 nodes. Ten of these lie on the grid's perimeter. Therefore, our grid has only two cells: one containing node 5, and one containing node 6. The geometry is crudely sketched here:\n", - "\n", - "\n", - " b b b b\n", - "\n", - " .-------.-------.\n", - " | | |\n", - " b | c | c | b\n", - " | | |\n", - " .-------.-------.\n", - "\n", - " b b b b\n", - "\n", - "\n", - "Here, the letter `b` represents boundary nodes (10 of them), the letter `c` represents core nodes (2 of them), and the lines are the *faces* of the two cells. (The periods are called *corners*; we won't deal with them further in this tutorial.)\n", - "\n", - "Our aim is to calculate a *soil flux* across each cell face, and then add up all in the incoming and outgoing fluxes.\n", - "\n", - "Before we do this, notice that each face is crossed by a link. For example, there is a link running from the left core node to the right core node. Our strategy, therefore, will be to calculate a flux value for each link in the grid. The model we'll use will be the soil-transport law (sometimes known as Gilbert's Law):\n", - "\n", - "$\\mathbf{q} = -D \\nabla z$\n", - "\n", - "Here, $\\nabla z$ is simply the gradient. We have already discretized the gradient, placing the gradient between each pair of adjacent nodes at the corresponding link. *This means we have already defined values of the gradient across each cell face* (as well as several links along the grid perimeter that don't cross cell faces).\n", - "\n", - "We can calculate fluxes along grid links with a single expression: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "D = 0.01\n", - "q = -D * dzdx\n", - "q" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, in order to calculate the flux divergence at our two cells, we need to do the following steps:\n", - "\n", - "1 - For each cell, multiply the four flux values by the width of the cell (which is the same for every face in this grid).\n", - "\n", - "2 - Add up the incoming fluxes and subtract the outgoing fluxes.\n", - "\n", - "3 - Divide by the area of the cell.\n", - "\n", - "The result will be a numerical approximation of the flux-divergene term.\n", - "\n", - "It turns out that you can do with with a single Landlab function call:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "dqda = mg.calc_flux_div_at_node(q)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "At this point, you might be wondering why the function name says `_at_node` rather than `at_cell`. This is because Landlab assigns a value to each node. For the perimeter nodes, the value will be zero, because they have no cells and the calculation is meaningless. However, the two *core nodes*, which do have cells, **will** have meaningful values. Let's look at these values:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "dqda" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Flux-divergence values for the two core nodes are 0.00164 and 0.00094, respectively. Let's look at how these values came to be. For node 5, the fluxes per unit width (\"unit fluxes\") along the faces of its cell are as follows:\n", - "\n", - "$q_E = -0.005$ m$^2$/yr\n", - "\n", - "$q_N = -0.005$ m$^2$/yr\n", - "\n", - "$q_W = -0.0014$ m$^2$/yr\n", - "\n", - "$q_S = -0.005$ m$^2$/yr\n", - "\n", - "So, this cell is leaking soil in every direction. The *total* fluxes along each cell, which we'll represent with the symbol $Q$, are obtained by multiplying each unit flux by the width of the face, which in this case is 10 meters:\n", - "\n", - "$Q_E = -0.05$ m$^3$/yr\n", - "\n", - "$Q_N = -0.05$ m$^3$/yr\n", - "\n", - "$Q_W = -0.014$ m$^3$/yr\n", - "\n", - "$Q_S = -0.05$ m$^3$/yr\n", - "\n", - "The total volume loss rate from the cell is 0.164 m$^3$/yr. Dividing this by the cell's surface area of 100 m$^2$, the cell's rate of change in average elevation is 0.00164 m/yr.\n", - "\n", - "For node 6, the unit fluxes are:\n", - "\n", - "$q_E = -0.0036$ m$^2$/yr\n", - "\n", - "$q_N = -0.0036$ m$^2$/yr\n", - "\n", - "$q_W = +0.0014$ m$^2$/yr\n", - "\n", - "$q_S = -0.0036$ m$^2$/yr\n", - "\n", - "So the cell at node 6 is leaking soil in three directions, but gaining a little bit from the higher cell to its west.\n", - "Its total fluxes are:\n", - "\n", - "$Q_E = -0.036$ m$^3$/yr\n", - "\n", - "$Q_N = -0.036$ m$^3$/yr\n", - "\n", - "$Q_W = +0.014$ m$^3$/yr\n", - "\n", - "$Q_S = -0.036$ m$^3$/yr\n", - "\n", - "This gives a net flux of 0.094 m$^3$/yr, and a rate of elevation change of 0.00094 m/yr.\n", - "\n", - "If you want the net flux rather than flux divergence, you can get this with the `calc_net_flux_at_node` function:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "mg.calc_net_flux_at_node(q)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Notice that it correctly returns the values we computed above.\n", - "\n", - "## Not just for raster grids\n", - "\n", - "The grid functions `calc_grad_at_link` and `calc_flux_div_at_node` functions also work on hexagonal and irregular grids. Under the hood, Landlab takes account of the differences in face width, link length, cell area, and so on.\n", - "\n", - "## Optimizing performance\n", - "\n", - "With the usage illustrated above, Landlab will create and populate a new return array each time you call one of these functions. This costs computing time. To speed things up, you can pre-allocate your arrays and pass them in as arguments using the `out` keywork. For example, an alternative way to do our gradient calculation is as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Do this step ONCE, on initialization\n", - "dzdx = mg.add_zeros('link', 'topographic__gradient_of_elevation')\n", - "\n", - "# Do this step many times, in a loop\n", - "mg.calc_grad_at_link(z, out=dzdx)\n", - "dzdx" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this case the Landlab will places the results of the calculation in the array you passed, rather than allocating memory for a new array. The same applies to `calc_flux_div_at_node` and `calc_net_flux_at_node`.\n", - "\n", - "In the example above, we created `dzdx` as a grid field, but you can alternatively pass in an empty or zero-valued NumPy array:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from numpy import zeros\n", - "\n", - "# Do this step ONCE, on initialization\n", - "dzdx = zeros(mg.number_of_links)\n", - "\n", - "# Do this step many times, in a loop\n", - "mg.calc_grad_at_link(z, out=dzdx)\n", - "dzdx" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Where to learn more\n", - "\n", - "- The **fault scarp tutorial** provides an example of `calc_grad_at_link` and `calc_flux_div_at_node`\n", - "\n", - "- See entries for these two functions in Landlab's *Reference Manual and API Documentation*\n", - "\n", - "- The complete code for this tutorial is also available as a stand-alone Python program: https://github.com/landlab/tutorials/blob/master/gradient_and_divergence/gradient_and_divergence.py" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Click here for more Landlab tutorials" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.11" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/grid_object_demo/grid_object_demo_unexpanded.ipynb b/grid_object_demo/grid_object_demo_unexpanded.ipynb deleted file mode 100644 index 3fdc92f..0000000 --- a/grid_object_demo/grid_object_demo_unexpanded.ipynb +++ /dev/null @@ -1,511 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# What happens when you create a grid object?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - " For instructions on how to run an interactive iPython notebook, click here: https://github.com/landlab/tutorials/blob/master/README.md
\n", - "For more Landlab tutorials, click here: https://github.com/landlab/landlab/wiki/Tutorials\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Landlab supports a range of grid types. These include both rasters (with both square and rectangular cells), and a range of structured and unstructured grids based around the interlocking polygons and triangles of a Voronoi-Delaunay tesselation (radial, hexagonal, and irregular grids).\n", - "\n", - "Here, we look at some of the features of both of these types.\n", - "\n", - "We can create **grid** objects with the following lines of code." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "from landlab import RasterModelGrid, VoronoiDelaunayGrid, HexModelGrid\n", - "smg = RasterModelGrid((3, 4), 1.) # a square-cell raster, 3 rows x 4 columns, unit spacing\n", - "rmg = RasterModelGrid((3, 4), (1., 2.)) # a rectangular-cell raster\n", - "hmg = HexModelGrid(3, 4, 1.)\n", - "# ^a hexagonal grid with 3 rows, 4 columns from the base row, & node spacing of 1.\n", - "x = np.random.rand(100) * 100.\n", - "y = np.random.rand(100) * 100.\n", - "vmg = VoronoiDelaunayGrid(x, y)\n", - "# ^a Voronoi-cell grid with 100 randomly positioned nodes within a 100.x100. square" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "All these various `ModelGrid` objects contains various data items (known as *attributes*). These include, for example:\n", - "* number nodes and links in the grid\n", - "* *x* and *y* coordinates of each each node\n", - "* starting (\"tail\") and ending (\"head\") node IDs of each link\n", - "* IDs of links that are active\n", - "* IDs of core nodes\n", - "* etc.\n", - "\n", - "From here on we'll focus on the square raster grid as its geometry is a bit easier to think through, but all of the following applies to all grid types.\n", - "\n", - "## Understanding the topology of Landlab grids\n", - "\n", - "All grids consist of two interlocked sets of *points* joined by *lines* outlining *areas*. If we define data on the points we call **nodes**, then they are joined by **links** which outline **patches**. Each node within the interior of the grid lies at the geometric center of the area of a **cell**. The cell's edges are **faces**, and the point at the edge of each face is a **corner**.\n", - "\n", - "Note that this kind of scheme requires one set of features to be \"dominant\" over the other; i.e., either not every node has a cell, *or* not every link is crossed by a face. Both cannot be true, because one or other set of features has to define the edge of the grid. Landlab assumes that the node set is primary, so there are always more nodes than corners; more links than faces; and more patches than cells.\n", - "\n", - "Each of these sets of *\"elements\"* has its own set of IDs. These IDs are what allow us to index the various Landlab fields which store spatial data. Each feature is ordered by **x, then y**. The origin is always at the bottom left node, unless you choose to move it (`grid.move_origin`)... except in the specific case of a radial grid, where logic and symmetry dictates it must be the central node.\n", - "\n", - "Whenever Landlab needs to order something rotationally (angles; elements around a different element type), it does so following the standard mathematical convention of **counterclockwise from east**. We'll see this in practical terms a bit later in this tutorial.\n", - "\n", - "The final thing to know is that **lines have direction**. This lets us record fluxes on the grid by associating them with, and mapping them onto, the links (or, much less commonly, the faces). All lines point into the **upper right quadrant**. So, on our raster, this means the horizontal links point east an the vertical links point north.\n", - "\n", - "So, for reference, our raster grid looks like this:\n", - "\n", - "\n", - " NODES: LINKS: PATCHES:\n", - " 8 ----- 9 ---- 10 ---- 11 * -14-->* -15-->* -16-->* * ----- * ----- * ----- *\n", - " | | | | ^ ^ ^ ^ | | | |\n", - " | | | | 10 11 12 13 | 3 | 4 | 5 |\n", - " | | | | | | | | | | | |\n", - " 4 ----- 5 ----- 6 ----- 7 * --7-- * --8-- * --9-- * * ----- * ----- * ----- *\n", - " | | | | ^ ^ ^ ^ | | | |\n", - " | | | | 3 4 5 6 | 0 | 1 | 2 |\n", - " | | | | | | | | | | | |\n", - " 0 ----- 1 ----- 2 ----- 3 * --0-->* --1-->* --2-->* * ----- * ----- * ----- *\n", - "\n", - " CELLS: FACES: CORNERS:\n", - " * ----- * ----- * ----- * * ----- * ----- * ----- * * ----- * ----- * ----- *\n", - " | | | | | | | | | | | |\n", - " | . ----- . ----- . | | . --5-->. --6-->. | | 3 ----- 4 ----- 5 |\n", - " | | | | | | ^ ^ ^ | | | | | |\n", - " * --| 0 | 1 |-- * * --2 3 4-- * * --| | |-- *\n", - " | | | | | | | | | | | | | | |\n", - " | . ----- . ----- . | | . --0-->. --1-->. | | 0 ----- 1 ----- 2 |\n", - " | | | | | | | | | | | |\n", - " * ----- * ----- * ----- * * ----- * ----- * ----- * * ----- * ----- * ----- *\n", - "\n", - "\n", - "## Recording and indexing the values at elements\n", - "\n", - "Landlab lets you record values at any element you want. In practice, the most useful places to store data is on the primary elements of nodes, links, and patches, the the nodes being most useful for scalar values (e.g, elevations) and the links for fluxes with direction to them (e.g., discharges).\n", - "\n", - "In order to maintain compatibility across data types, *all* landlab data is stored in *number-of-elements*-long arrays. This includes both user-defined data and the properties of the nodes within the grid. This means that these arrays can be immediately indexed by their element ID. In other words:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# what's the y-coordinates of the pair of nodes in the middle of our 3-by-4 grid?\n", - "# the IDs of these nodes are 5 and 6, so:\n", - "smg.y_of_node[[5, 6]]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you're working with a raster, you can always reshape the value arrays back into two dimensions so you can take Numpy-style slices through it:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# what's the x-coordinates of the middle row?\n", - "smg.x_of_node.reshape(smg.shape)[1, :]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This same data storage pattern is what underlies the Landlab **data fields**, which are simply one dimensional, number-of-elements-long arrays which store user defined spatial data across the grid, attached to the grid itself." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.add_zeros('node', 'elevation', noclobber=False)\n", - "# ^Creates a new field of zero data associated with nodes\n", - "smg.at_node['elevation'] # Note the use of dictionary syntax" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Or, equivalently, at links:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.add_ones('link', 'slope', noclobber=False)\n", - "# ^Creates a new array of data associated with links\n", - "smg.at_link['slope']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The Landlab **components** use fields to share spatial information between themselves. See the *fields* and *components* tutorials for more information.\n", - "\n", - "\n", - "## Getting this information from the grid object\n", - "\n", - "All of this topological information is recorded within our grid objects, and can be used to work with data that is defined over the grid. The grids record the numbers of each element, their positions, and their interrelationships to each other. Let's take a look at some of this information for the raster:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.number_of_nodes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.number_of_links" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The grid contains its geometric information too. Let's look at the *(x,y)* coordinates of the nodes:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "for i in range(smg.number_of_nodes):\n", - " print(i, smg.x_of_node[i], smg.y_of_node[i])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Link connectivity and direction is described by specifying the starting (\"tail\") and ending (\"head\") node IDs for each link (to remember this, think of an arrow: TAIL ===> HEAD)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "for i in range(smg.number_of_links):\n", - " print('Link',i,': node',smg.node_at_link_tail[i],'===> node',smg.node_at_link_head[i])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Boundary conditions are likewise defined on these elements (see also the full boundary conditions tutorial). Landlab is clever enough to ensure that the boundary conditions recorded on, say, the links get updated when you redefine the conditions on, say, the nodes.\n", - "\n", - "Nodes can be *core*, *fixed value*, *fixed gradient*, or *closed* (flux into or out of node is forbidden). Links can be *active* (can carry flux), *fixed* (always carries the same flux; joined to a fixed gradient node) or *inactive* (forbidden from carrying flux). This information is likewise available from the grid:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.core_nodes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.active_links" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# let's demonstrate the auto-updating of boundary conditions:\n", - "from landlab import CLOSED_BOUNDARY\n", - "smg.status_at_node[smg.nodes_at_bottom_edge] = CLOSED_BOUNDARY\n", - "smg.active_links # the links connected to the bottom edge nodes are now inactive" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Element connectivity\n", - "\n", - "Importantly, we can also find out which elements are connected to which other elements. This allows us to do computationally vital operations involving mapping values defined at one element onto another, e.g., the net flux at a node; the mean slope at a patch; the node value at a cell.\n", - "\n", - "In cases where these relationships are one-to-many (e.g., `links_at_node`, `nodes_at_patch`), the shape of the resulting arrays is always (number_of_elements, max-number-of-connected-elements-across-grid). i.e., on a raster, `links_at_node` is (nnodes, 4), because the cells are always square. On an irregular Voronoi-cell grid, `links_at_node` will be (nnodes, X) where X is the number of sides of the side-iest cell, and `nodes_at_patch` will be (npatches, 3) because all the patches are Delaunay triangles. And so on.\n", - "\n", - "Lets take a look. Remember, Landlab orders things **clockwise from east**, so for a raster the order will the EAST, NORTH, WEST, SOUTH." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.links_at_node[5]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.links_at_node.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Undefined directions get recorded as `-1`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.links_at_node[8]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.patches_at_node" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.nodes_at_patch" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Where element-to-element mapping is one-to-one, you get simple, one dimensional arrays:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.node_at_cell # shape is (n_cells, )" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.cell_at_node # shape is (n_nodes, ) with -1s as needed" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A bit of thought reveals that things get a bit more complicated for links and faces, because they have direction. You'll need a convenient way to record whether a given flux (which is positive if it goes with the link's inherent direction, and negative if against) actually is travelling into or out of a given node. The grid provides `link_dirs_at_node` and `active_link_dirs_at_node` to help with this:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.link_dirs_at_node # all links; positive points INTO the node; zero where no link" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# prove there are zeros where links are missing:\n", - "np.all((smg.link_dirs_at_node == 0) == (smg.links_at_node == -1))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "smg.active_link_dirs_at_node # in this one, inactive links get zero too" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Multiply the fluxes indexed by `links_at_node` and sum by axis=1 to have a very convenient way to calculate flux divergences at nodes:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "fluxes_at_node = smg.at_link['slope'][smg.links_at_node]\n", - "# ^...remember we defined the slope field as ones, above\n", - "fluxes_into_node = fluxes_at_node*smg.active_link_dirs_at_node\n", - "flux_div_at_node = fluxes_into_node.sum(axis=1)\n", - "print(flux_div_at_node[smg.core_nodes])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Why? Remember that earlier in this tutorial we already set the bottom edge to `CLOSED_BOUNDARY`. So each of our core nodes has a flux of +1.0 coming in from the left, but two fluxes of -1.0 leaving from both the top and the right. Hence, the flux divergence is -1. at each node.\n", - "\n", - "Note as well that Landlab offers the one-line grid method `calc_flux_div_at_node()` to perform this same operation." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Click here for more Landlab tutorials" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.11" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/making_components/making_components_unexpanded.ipynb b/making_components/making_components_unexpanded.ipynb deleted file mode 100644 index 378e5de..0000000 --- a/making_components/making_components_unexpanded.ipynb +++ /dev/null @@ -1,887 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

a toolkit for modeling earth surface processes

" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# How to write a Landlab component" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - " For instructions on how to run an interactive iPython notebook, click here: https://github.com/landlab/tutorials/blob/master/README.md
\n", - "For more Landlab tutorials, click here: https://github.com/landlab/landlab/wiki/Tutorials\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This ipython notebook walks you through the basic procedure for writing a Landlab component, using the example of a kinematic-wave flow model.\n", - "\n", - "## Overview\n", - "A Landlab component is implemented as a Python `class`. Although every Landlab component is unique in some respects, to be a component, a class must have at least the following standard ingredients:\n", - "\n", - "(1) The class must inherit the base class `Component`.\n", - "\n", - "(2) The class must include a set of standard variables defined in the header (i.e., before the `__init__` method), which describe the data arrays that the component uses.\n", - "\n", - "(3) The class must have an `__init__` method defined, with a semi-standardized parameter list described below.\n", - "\n", - "(4) The class must provide a function that does performs the component's \"action\", typically named `run_one_step()` and this function's parameter list must follow the convention described below.\n", - "\n", - "\n", - "## Class definition and header\n", - "\n", - "A Landlab component is a class that inherits from `Component`. The name of the class should be in CamelCase, and should make sense when used in the sentence: \"A *(component-name)* is a...\". The class definition should be followed by a docstring. The docstring should include a list of parameters for the `__init__` method." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from landlab import Component, FieldError\n", - "import numpy as np\n", - "\n", - "class KinwaveOverlandFlowModel(Component):\n", - " \"\"\"\n", - " Calculate water flow over topography.\n", - " \n", - " Landlab component that implements a two-dimensional \n", - " kinematic wave model.\n", - " \n", - " Construction:\n", - " \n", - " KinwaveOverlandFlowModel(grid, [stuff to be added later])\n", - " \n", - " Parameters\n", - " ----------\n", - " grid : ModelGrid\n", - " A Landlab grid object.\n", - " [others to be added later]\n", - " \"\"\"\n", - " pass # just for now, until we add stuff..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Header information: `_name`\n", - "Every component should have a name, as a string. Normally this will be the same as the class name." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "_name = 'KinwaveOverlandFlowModel'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Header information: `_input_var_names`\n", - "\"Input variables\" here refers to those arrays (fields) that the component needs, and for which initial values must be specified. In our kinematic wave example, we need topography. We'll take elevation, and calculate slope. Therefore, elevation will be an input variable, and slope an output (though we won't modify it). A more advanced model might also need spatially variable precipitation, infiltration capacity, and/or roughness, but here we'll treat these as uniform.\n", - "\n", - "The `_input_var_names` should be a tuple of strings. These strings give the formal names for the fields, and should use standard Landlab semantics. In brief, Landlab's naming scheme follows the pattern of the CSDMS standard names, with the quantity at the end of the string, and any descriptors beforehand, separated from the quantity by two underscores." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "_input_var_names = (\n", - " 'topographic__elevation',\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Header information: `_output_var_names`\n", - "*Output variables* are those arrays (fields) that the component solves for as part of its normal operation. In our kinematic wave example, the component will create fields for topographic gradient, water depth, velocity, and discharge per unit width (a.k.a., specific discharge).\n", - "\n", - "Like `_input_var_names`, `_output_var_names` should be either a tuple of strings with names based on standard Landlab semantics." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "_output_var_names = (\n", - " 'topographic__gradient', \n", - " 'surface_water__depth',\n", - " 'water__velocity',\n", - " 'water__specific_discharge',\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Header information: `_var_units`\n", - "This is a dictionary that defines the units of each variable (both input and output)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "_var_units = {\n", - " 'topographic__elevation': 'm',\n", - " 'topographic__gradient': 'm/m',\n", - " 'surface_water__depth': 'm',\n", - " 'water__velocity': 'm/s',\n", - " 'water__specific_discharge': 'm2/s',\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Header information: `_var_mapping`\n", - "This is a dictionary that describes the grid element to which each field is mapped. In our example, elevation and water depth (both scalars) are mapped to nodes, whereas velocity and discharge (both vectors) are mapped to links." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Header information: `_var_units`\n", - "This is a dictionary that defines the units of each variable (both input and output)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "_var_mapping = {\n", - " 'topographic__elevation': 'node',\n", - " 'topographic__gradient': 'link',\n", - " 'surface_water__depth': 'node',\n", - " 'water__velocity': 'link',\n", - " 'water__specific_discharge': 'link',\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Header information: `_var_doc`\n", - "This final piece of header data provides information about what each variable represents, encoded as a dictionary in which the keys are the field names and values are the descriptions, as strings." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "_var_doc = {\n", - " 'topographic__elevation':\n", - " 'elevation of the ground surface relative to some datum',\n", - " 'topographic__gradient':\n", - " 'gradient of the ground surface',\n", - " 'surface_water__depth':\n", - " 'depth of water',\n", - " 'water__velocity':\n", - " 'flow velocity component in the direction of the link',\n", - " 'water__specific_discharge':\n", - " 'flow discharge component in the direction of the link', \n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Class with complete header information" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "from landlab import Component, FieldError\n", - "import numpy as np\n", - "\n", - "class KinwaveOverlandFlowModel(Component):\n", - " \"\"\"\n", - " Calculate water flow over topography.\n", - " \n", - " Landlab component that implements a two-dimensional \n", - " kinematic wave model.\n", - " \n", - " Construction:\n", - " \n", - " KinwaveOverlandFlowModel(grid, [stuff to be added later])\n", - " \n", - " Parameters\n", - " ----------\n", - " grid : ModelGrid\n", - " A Landlab grid object.\n", - " [others to be added later]\n", - " \"\"\"\n", - "\n", - " _name = 'KinwaveOverlandFlowModel'\n", - "\n", - " _input_var_names = (\n", - " 'topographic__elevation',\n", - " )\n", - "\n", - " _output_var_names = (\n", - " 'topographic__gradient',\n", - " 'surface_water__depth',\n", - " 'water__velocity',\n", - " 'water__specific_discharge',\n", - " )\n", - "\n", - " _var_units = {\n", - " 'topographic__elevation': 'm',\n", - " 'topographic__gradient': 'm/m',\n", - " 'surface_water__depth': 'm',\n", - " 'water__velocity': 'm/s',\n", - " 'water__specific_discharge': 'm2/s',\n", - " }\n", - " \n", - " _var_mapping = {\n", - " 'topographic__elevation': 'node',\n", - " 'topographic__gradient': 'link',\n", - " 'surface_water__depth': 'node',\n", - " 'water__velocity': 'link',\n", - " 'water__specific_discharge': 'link',\n", - " }\n", - "\n", - " _var_doc = {\n", - " 'topographic__elevation':\n", - " 'elevation of the ground surface relative to some datum',\n", - " 'topographic__gradient':\n", - " 'gradient of the ground surface',\n", - " 'surface_water__depth':\n", - " 'depth of water',\n", - " 'water__velocity':\n", - " 'flow velocity component in the direction of the link',\n", - " 'water__specific_discharge':\n", - " 'flow discharge component in the direction of the link', \n", - " }" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The initialization method (`__init__`)\n", - "Every Landlab component should have an `__init__` method. The parameter signature should start with a `ModelGrid` object as the first parameter, and list `**kwds` as the last parameter. In between are component-specific parameters. In our example, the parameters for the kinematic wave model include: precipiation rate, precipitation duration, infiltration rate, and roughness coefficient (Manning's n). (The final `**kwds` is what allows you to pass in a dictionary of input parameters, so make sure it's there).\n", - "\n", - "Two things a component `__init__` method common does are (1) store the component's parameters as class attributes, and (2) create the necessary fields. When creating grid fields, it is important to first check to see whether a field with the same name (and mapping) already exists. For example, a driver or another component might have already created `topographic__elevation` when our kinematic wave component is initialized.\n", - "\n", - "There are a couple of different approaches to creating and working with fields. In the example below, we use the straightforward approach of creating them one at a time by name. We keep a reference to each field as a variable; for example, `self.elev` refers to the grid field `topographic_elevation`. It is also possible to automate the process by looping over all names in, say, `_var_mapping`, checking each to see whether it exists, and creating it if not. The `Component` method `initialize_output_fields()` may help with this, which will already be a member of your component because it inherits from `Component`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def __init__(self, grid, precip_rate=1.0, precip_duration=1.0, \n", - " infilt_rate=0.0, roughness=0.01, **kwds):\n", - " \"\"\"Initialize the KinwaveOverlandFlowModel.\n", - " \n", - " Parameters\n", - " ----------\n", - " grid : ModelGrid\n", - " Landlab ModelGrid object\n", - " precip_rate : float, optional (defaults to 1 mm/hr)\n", - " Precipitation rate, mm/hr\n", - " precip_duration : float, optional (defaults to 1 hour)\n", - " Duration of precipitation, hours\n", - " infilt_rate : float, optional (defaults to 0)\n", - " Maximum rate of infiltration, mm/hr\n", - " roughness : float, defaults to 0.01\n", - " Manning roughness coefficient, s/m^1/3\n", - " \"\"\"\n", - "\n", - " # Store grid and parameters and do unit conversion\n", - " self._grid = grid\n", - " self.precip = precip_rate / 3600000.0 # convert to m/s\n", - " self.precip_duration = precip_duration * 3600.0 # convert to s\n", - " self.infilt = infilt_rate / 3600000.0 # convert to m/s\n", - " self.vel_coef = 1.0 / roughness # do division now to save time\n", - "\n", - " # Create fields...\n", - " # Elevation\n", - " if 'topographic__elevation' in grid.at_node:\n", - " self.elev = grid.at_node['topographic__elevation']\n", - " else:\n", - " raise FieldError(\n", - " 'A topography is required as a component input!')\n", - " # Slope\n", - " if 'topographic__gradient' in grid.at_link:\n", - " self.slope = grid.at_link['topographic__gradient']\n", - " else:\n", - " self.slope = grid.add_zeros('link', 'topographic__gradient')\n", - " # this field is \"nice to have\", but we build it if necessary\n", - " # Water depth\n", - " if 'surface_water__depth' in grid.at_node:\n", - " self.depth = grid.at_node['surface_water__depth']\n", - " else:\n", - " self.depth = grid.add_zeros('node', 'surface_water__depth')\n", - " # Velocity\n", - " if 'water__velocity' in grid.at_link:\n", - " self.vel = grid.at_link['water__velocity']\n", - " else:\n", - " self.vel = grid.add_zeros('link', 'water__velocity')\n", - " # Discharge\n", - " if 'water__specific_discharge' in grid.at_link:\n", - " self.disch = grid.at_link['water__specific_discharge']\n", - " else:\n", - " self.disch = grid.add_zeros('link',\n", - " 'water__specific_discharge')\n", - "\n", - " # Calculate the ground-surface slope (assume it won't change)\n", - " self.slope[self._grid.active_links] = \\\n", - " self._grid.calc_grad_at_link(self.elev)[self._grid.active_links]\n", - " self.sqrt_slope = np.sqrt( self.slope )" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The \"go\" method, `run_one_step()`\n", - "Every Landlab component will have a method that implements the component's action. The go method can have any name you like, but the preferred practice is to use the standard name `run_one_step()`. Landlab assumes that if a component has a method with this name, it will a. be the primary \"go\" method, and b. will be fully standardized as described here.\n", - "\n", - "The first argument in the function signature should always be a duration to run, `dt`; i.e., a timestep length. If the component does not evolve as time passes, this argument may be missing (see, e.g., the FlowRouter, which returns a steady state flow pattern independent of time).\n", - "\n", - "The remainder of the parameters are specific to the component. In this case, the component-specific parameter is the current simulation time, which determines whether it's still raining.\n", - "\n", - "The first step in the algorithm is to calculate water depth *at the links*, where we will be calculating the water discharge. In this particular case, we'll use the depth at the upslope of the two nodes. The grid method to do this, `map_value_at_max_node_to_link`, is one of many mapping functions available.\n", - "\n", - "We then calculate velocity using the Manning equation, and specific discharge by multiplying velocity by depth.\n", - "\n", - "Mass balance for the cells around nodes is computed using the `calc_flux_div_at_node` grid method." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - " def run_one_step(self, dt, current_time=0.0, **kwds):\n", - " \"\"\"Calculate water flow for a time period `dt`.\n", - " \"\"\"\n", - " # Calculate water depth at links.\n", - " H_link = self.grid.map_value_at_max_node_to_link(\n", - " 'topographic__elevation', 'surface_water__depth')\n", - "\n", - " # Calculate velocity\n", - " self.vel = self.vel_coef * H_link**0.66667 * self.sqrt_slope\n", - "\n", - " # Calculate discharge\n", - " self.disch = H_link * self.vel\n", - "\n", - " # Flux divergence\n", - " dqda = self.grid.calc_flux_div_at_node(self.disch)\n", - "\n", - " # Rate of change of water depth\n", - " if current_time < self.precip_duration:\n", - " ppt = self.precip\n", - " else:\n", - " ppt = 0.0\n", - " dHdt = ppt - self.infilt - dqda\n", - "\n", - " # Update water depth\n", - " self.depth[self.grid.core_nodes] += dHdt[self.grid.core_nodes] * dt\n", - "\n", - " # Somewhat crude numerical hack: prevent negative water depth\n", - " self.depth[np.where(self.depth < 0.0)[0]] = 0.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Changes to boundary conditions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Sometimes, as in this example, it proves convenient to hard-code assumptions about boundary conditions into the `__init__` method. In this case, note that the final two lines of `__init__` invoke `grid.active_links` - so if the boundary conditions are updated after we initialize, it's possible `self.depth` will not be correct.\n", - "\n", - "We can resolve this issue by creating an additional component method that updates these components that can be called if the boundary conditions change. Whether the boundary conditions have changed can be assessed with a grid method called `bc_set_code`. This is an `int` which will change if the boundary conditions change." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - " def __init__(self, grid, precip_rate=1.0, precip_duration=1.0, \n", - " infilt_rate=0.0, roughness=0.01, **kwds):\n", - " \"\"\"Initialize the KinwaveOverlandFlowModel.\n", - " ...\n", - " \"\"\"\n", - " # Store grid and parameters and do unit conversion\n", - " self._grid = grid\n", - " self._bc_set_code = self.grid.bc_set_code\n", - " # ...\n", - "\n", - " def updated_boundary_conditions(self):\n", - " \"\"\"Call if boundary conditions are updated.\n", - " \"\"\"\n", - " # Calculate the ground-surface slope (assume it won't change)\n", - " self.slope[self.grid.active_links] = \\\n", - " self.grid.calc_grad_at_link(self.elev)[self.grid.active_links]\n", - " self.sqrt_slope = np.sqrt(self.slope)\n", - "\n", - "\n", - " def run_one_step(self, dt, current_time=0.0, **kwds):\n", - " \"\"\"Calculate water flow for a time period `dt`.\n", - " \"\"\"\n", - " if self._bc_set_code != self.grid.bc_set_code:\n", - " self.updated_boundary_conditions()\n", - " self._bc_set_code = self.grid.bc_set_code\n", - " # Calculate water depth at links.\n", - " # ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The complete component" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from landlab import Component, FieldError\n", - "import numpy as np\n", - "\n", - "class KinwaveOverlandFlowModel(Component):\n", - " \"\"\"\n", - " Calculate water flow over topography.\n", - " \n", - " Landlab component that implements a two-dimensional \n", - " kinematic wave model.\n", - " \n", - " Construction:\n", - " \n", - " KinwaveOverlandFlowModel(grid, precip_rate=1.0, \n", - " precip_duration=1.0, \n", - " infilt_rate=0.0,\n", - " roughness=0.01, **kwds)\n", - " \n", - " Parameters\n", - " ----------\n", - " grid : ModelGrid\n", - " A Landlab grid object.\n", - " precip_rate : float, optional (defaults to 1 mm/hr)\n", - " Precipitation rate, mm/hr\n", - " precip_duration : float, optional (defaults to 1 hour)\n", - " Duration of precipitation, hours\n", - " infilt_rate : float, optional (defaults to 0)\n", - " Maximum rate of infiltration, mm/hr\n", - " roughnes : float, defaults to 0.01\n", - " Manning roughness coefficient, s/m^1/3\n", - " \"\"\"\n", - "\n", - " _name = 'KinwaveOverlandFlowModel'\n", - "\n", - " _input_var_names = (\n", - " 'topographic__elevation',\n", - " )\n", - "\n", - " _output_var_names = (\n", - " 'topographic__gradient',\n", - " 'surface_water__depth',\n", - " 'water__velocity',\n", - " 'water__specific_discharge',\n", - " )\n", - "\n", - " _var_units = {\n", - " 'topographic__elevation' : 'm',\n", - " 'topographic__slope' : 'm/m',\n", - " 'surface_water__depth' : 'm',\n", - " 'water__velocity' : 'm/s',\n", - " 'water__specific_discharge' : 'm2/s',\n", - " }\n", - "\n", - " _var_mapping = {\n", - " 'topographic__elevation' : 'node',\n", - " 'topographic__gradient' : 'link',\n", - " 'surface_water__depth' : 'node',\n", - " 'water__velocity' : 'link',\n", - " 'water__specific_discharge' : 'link',\n", - " }\n", - "\n", - " _var_doc = {\n", - " 'topographic__elevation':\n", - " 'elevation of the ground surface relative to some datum',\n", - " 'topographic__gradient':\n", - " 'gradient of the ground surface',\n", - " 'surface_water__depth':\n", - " 'depth of water',\n", - " 'water__velocity':\n", - " 'flow velocity component in the direction of the link',\n", - " 'water__specific_discharge':\n", - " 'flow discharge component in the direction of the link', \n", - " }\n", - "\n", - " def __init__(self, grid, precip_rate=1.0, precip_duration=1.0, \n", - " infilt_rate=0.0, roughness=0.01, **kwds):\n", - " \"\"\"Initialize the KinwaveOverlandFlowModel.\n", - "\n", - " Parameters\n", - " ----------\n", - " grid : ModelGrid\n", - " Landlab ModelGrid object\n", - " precip_rate : float, optional (defaults to 1 mm/hr)\n", - " Precipitation rate, mm/hr\n", - " precip_duration : float, optional (defaults to 1 hour)\n", - " Duration of precipitation, hours\n", - " infilt_rate : float, optional (defaults to 0)\n", - " Maximum rate of infiltration, mm/hr\n", - " roughnes : float, defaults to 0.01\n", - " Manning roughness coefficient, s/m^1/3\n", - " \"\"\"\n", - "\n", - " # Store grid and parameters and do unit conversion\n", - " self._grid = grid\n", - " self._bc_set_code = self.grid.bc_set_code\n", - " self.precip = precip_rate / 3600000.0 # convert to m/s\n", - " self.precip_duration = precip_duration * 3600.0 # h->s\n", - " self.infilt = infilt_rate / 3600000.0 # convert to m/s\n", - " self.vel_coef = 1.0 / roughness # do division now to save time\n", - "\n", - " # Create fields...\n", - " # Elevation\n", - " if 'topographic__elevation' in grid.at_node:\n", - " self.elev = grid.at_node['topographic__elevation']\n", - " else:\n", - " raise FieldError(\n", - " 'A topography is required as a component input!')\n", - " # Water depth\n", - " if 'surface_water__depth' in grid.at_node:\n", - " self.depth = grid.at_node['surface_water__depth']\n", - " else:\n", - " self.depth = grid.add_zeros('node', 'surface_water__depth')\n", - " # Slope\n", - " if 'topographic__gradient' in grid.at_link:\n", - " self.slope = grid.at_link['topographic__gradient']\n", - " else:\n", - " self.slope = grid.add_zeros('link', 'topographic__gradient')\n", - " # Velocity\n", - " if 'water__velocity' in grid.at_link:\n", - " self.vel = grid.at_link['water__velocity']\n", - " else:\n", - " self.vel = grid.add_zeros('link', 'water__velocity')\n", - " # Discharge\n", - " if 'water__specific_discharge' in grid.at_link:\n", - " self.disch = grid.at_link['water__specific_discharge']\n", - " else:\n", - " self.disch = grid.add_zeros('link',\n", - " 'water__specific_discharge')\n", - "\n", - " # Calculate the ground-surface slope\n", - " self.slope[self._grid.active_links] = \\\n", - " self._grid.calc_grad_at_link(self.elev)[self._grid.active_links]\n", - " self.sqrt_slope = np.sqrt( self.slope )\n", - " self.sign_slope = np.sign( self.slope )\n", - "\n", - " def updated_boundary_conditions(self):\n", - " \"\"\"Call if boundary conditions are updated.\n", - " \"\"\"\n", - " self.slope[self.grid.active_links] = \\\n", - " self.grid.calc_grad_at_link(self.elev)[self.grid.active_links]\n", - " self.sqrt_slope = np.sqrt(self.slope)\n", - " self.sign_slope = np.sign( self.slope )\n", - "\n", - " def run_one_step(self, dt, current_time=0.0, **kwds):\n", - " \"\"\"Calculate water flow for a time period `dt`.\n", - " \"\"\"\n", - "\n", - " if self._bc_set_code != self.grid.bc_set_code:\n", - " self.updated_boundary_conditions()\n", - " self._bc_set_code = self.grid.bc_set_code\n", - "\n", - " # Calculate water depth at links\n", - " H_link = self._grid.map_value_at_max_node_to_link(\n", - " 'topographic__elevation', 'surface_water__depth')\n", - "\n", - " # Calculate velocity\n", - " self.vel = -self.sign_slope * self.vel_coef * H_link**0.66667 \\\n", - " * self.sqrt_slope\n", - "\n", - " # Calculate discharge\n", - " self.disch = H_link * self.vel\n", - "\n", - " # Flux divergence\n", - " dqda = self._grid.calc_flux_div_at_node(self.disch)\n", - "\n", - " # Rate of change of water depth\n", - " if current_time < self.precip_duration:\n", - " ppt = self.precip\n", - " else:\n", - " ppt = 0.0\n", - " dHdt = ppt - self.infilt - dqda\n", - "\n", - " # Update water depth\n", - " self.depth[self._grid.core_nodes] += dHdt[self._grid.core_nodes] * dt\n", - "\n", - " # Somewhat crude numerical hack: prevent negative water depth\n", - " self.depth[np.where(self.depth < 0.0)[0]] = 0.0" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from landlab import RasterModelGrid\n", - "nr = 3\n", - "nc = 4\n", - "rg = RasterModelGrid((nr, nc), 10.0)\n", - "rg.add_empty('node', 'topographic__elevation')\n", - "rg.at_node['topographic__elevation'][:] = rg.node_x.copy() #np.arange(nr * nc)\n", - "kinflow = KinwaveOverlandFlowModel(rg, precip_rate=100.0, precip_duration=100.0)\n", - "for i in range(100):\n", - " kinflow.run_one_step(1.0)\n", - "print('The discharge from node 6 to node 5 should be -0.000278 m2/s:')\n", - "print(kinflow.disch[8])\n", - "print('The discharge from node 5 to node 4 should be -0.000556 m2/s:')\n", - "print(kinflow.disch[7])\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, we'll test the component on a larger grid and a larger domain." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "nr = 62\n", - "nc = 42\n", - "rg = RasterModelGrid(nr, nc, 10.0)\n", - "rg.add_empty('node', 'topographic__elevation')\n", - "rg.at_node['topographic__elevation'] = 0.01 * rg.node_y\n", - "kinflow = KinwaveOverlandFlowModel(rg, precip_rate=100.0, precip_duration=100.0)\n", - "for i in range(1800):\n", - " kinflow.run_one_step(1.0)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Plot the topography:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "from landlab.plot import imshow_grid\n", - "imshow_grid(rg, 'topographic__elevation')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The steady solution should be as follows. The unit discharge at the bottom edge should equal the precipitation rate, 100 mm/hr, times the slope length.\n", - "\n", - "The slope length is the distance from the bottom edge of the bottom-most row of cells, to the top edge of the top-most row of cells. The base row of nodes are at y = 0, and the cell edges start half a cell width up from that, so y = 5 m. The top of the upper-most row of cells is half a cell width below the top grid edge, which is 610 m, so the top of the cells is 605 m. Hence the interior (cell) portion of the grid is 600 m long.\n", - "\n", - "Hence, discharge out the bottom should be 100 mm/hr x 600 m = 0.1 m/hr x 600 m = 60 m2/hr. Let's convert this to m2/s:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "q_out = 0.1 * 600 / 3600.0\n", - "q_out" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The water depth should be just sufficient to carry this discharge with the given slope and roughness. We get this by inverting the Manning equation:\n", - "\n", - "$$q = (1/n) H^{5/3} S^{1/2}$$\n", - "\n", - "$$H^{5/3} = n q S^{-1/2}$$\n", - "\n", - "$$H = (n q)^{3/5} S^{-3/10}$$\n", - "\n", - "The slope gradient is 0.01 (because we set elevation to be 0.01 times the y coordinate). The discharge, as we've already established, is about 0.0167 m2/s, and the roughness is 0.01 (the default value). Therefore," - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "n = 0.01\n", - "q = 0.0167\n", - "S = 0.01\n", - "H_out = (n * q)**0.6 * S**-0.3\n", - "H_out" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "imshow_grid(rg, 'surface_water__depth', cmap='Blues')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This looks pretty good. Let's check the values:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "rg.at_node['surface_water__depth'][42:84] # bottom row of core nodes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We see that the depth agrees with the analytical solution to within three decimal places: not bad. Ideally, we would build the above tests into the component as doctests or unit tests. We could also test the transient solutions: rising hydrograph, falling hydrograph. Finally, we haven't tested all the ingredients; for example, we haven't tested what happens when infiltration rate is greater than zero.\n", - "\n", - "Nonetheless, the above example illustrates the basics of component-making. A great next step would be to create a unit test based on this example." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Click here for more Landlab tutorials" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.12" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/mappers/mappers_unexpanded.ipynb b/mappers/mappers_unexpanded.ipynb deleted file mode 100644 index 076ed3f..0000000 --- a/mappers/mappers_unexpanded.ipynb +++ /dev/null @@ -1,385 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Mapping values between grid elements\n", - "\n", - "
\n", - " (Note: for instructions on how to run an interactive iPython notebook, click here: https://github.com/landlab/tutorials/blob/master/README.md
\n", - "For more Landlab tutorials, click here: https://github.com/landlab/landlab/wiki/Tutorials)\n", - "
\n", - "\n", - "Imagine that you're using Landlab to write a model of shallow water flow over terrain. A natural approach is to place your scalar fields, such as water depth, at the nodes. You then place your vector fields, such as water surface gradient, flow velocity, and discharge, at the links. But your velocity depends on both slope and depth, which means you need to know the depth at the links too. How do you do this?\n", - "\n", - "This tutorial introduces *mappers*: grid functions that map quantities defined on one set of elements (such as nodes) onto another set of elements (such as links). As you'll see, there are a variety of mappers available.\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Mapping from nodes to links\n", - "\n", - "For the sake of example, we'll start with a simple 3-row by 4-column raster grid. The grid will contain a scalar field called `water__depth`, abbreviated `h`. We'll populate it with some example values, as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "from __future__ import print_function" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "from landlab import RasterModelGrid\n", - "import numpy as np\n", - "mg = RasterModelGrid((3, 4), 100.0)\n", - "h = mg.add_zeros('node', 'surface_water__depth')\n", - "h[:] = 7 - np.abs(6 - np.arange(12))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For the sake of visualizing values at nodes on our grid, we'll define a handy little function:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def show_node_values(mg, u):\n", - " for r in range(mg.number_of_node_rows - 1, -1, -1):\n", - " for c in range(mg.number_of_node_columns):\n", - " print(int(u[c + (mg.number_of_node_columns * r)]), end=' ')\n", - " print()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "show_node_values(mg, h)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's review the numbering of nodes and links. The lines below will print a list that shows, for each link ID, the IDs of the nodes at the link's tail and head:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "for i in range(mg.number_of_links):\n", - " print(i, mg.node_at_link_tail[i], mg.node_at_link_head[i])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Finding the mean value between two nodes on a link\n", - "\n", - "Suppose we want to have a *link-based* array, called *h_edge*, that contains water depth at locations between adjacent pairs of nodes. For each link, we'll simply take the average of the depth at the link's two nodes. To accomplish this, we can use the `map_mean_of_link_nodes_to_link` grid method. At link 8, for example, we'll average the *h* values at nodes 5 and 6, which should give us a depth of (6 + 7) / 2 = 6.5:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "h_edge = mg.map_mean_of_link_nodes_to_link('surface_water__depth')\n", - "for i in range(mg.number_of_links):\n", - " print(i, h_edge[i])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What's in a name?\n", - "\n", - "The mapping function has a long name, which is designed to make it as clear as possible to understand what the function does. All the mappers start with the verb *map*. Then the relationship is given; in this case, we are looking at the *mean*. Then the elements from which a quantity is being mapped: we are taking values from *link nodes*. Finally, the element to which the new values apply: *link*.\n", - "\n", - "### Mapping minimum or maximum values\n", - "\n", - "We can also map the minimum value of *h*:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "h_edge = mg.map_min_of_link_nodes_to_link('surface_water__depth')\n", - "for i in range(mg.number_of_links):\n", - " print(i, h_edge[i])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "... or the maximum:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "h_edge = mg.map_max_of_link_nodes_to_link('surface_water__depth')\n", - "for i in range(mg.number_of_links):\n", - " print(i, h_edge[i])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Upwind and downwind\n", - "\n", - "Numerical schemes often use *upwind differencing* or *downwind differencing*. For example, finite difference schemes for equations that include advection may use \"upwind\" rather than centered differences, in which a scalar quantity (our *h* for example) is taken from whichever side is upstream in the flow field.\n", - "\n", - "How do we know the flow direction? If the flow is driven by the gradient in some scalar field, such as pressure or elevation, one approach is to look at the values of this scalar on either end of the link: the end with the higher value is upwind, and the end with the lower value is downwind.\n", - "\n", - "Suppose for example that our water flow is driven by the water-surface slope (which is often a good approximation for the *energy slope*, though it omits the kinetic energy). Let's define a bed-surface elevation field *z*:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "z = mg.add_zeros('node', 'topographic__elevation')\n", - "z[:] = 16 - np.abs(7 - np.arange(12))\n", - "show_node_values(mg, z)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The water-surface elevation is then the sum of *h* and *z*:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "w = z + h\n", - "show_node_values(mg, w)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For every link, we can assign the value of *h* from whichever end of the link has the greater *w*:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "h_edge = mg.map_value_at_max_node_to_link(w, h)\n", - "for i in range(mg.number_of_links):\n", - " print(i, h_edge[i])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Consider the middle two nodes (5 and 6). Node 6 is higher (22 versus 20). Therefore, the link between them (link 8) should be assigned the value of *h* at node 6. This value happens to be 7.0.\n", - "\n", - "Of course, we could also take the value from the *lower* of the two nodes, which gives link 8 a value of 6.0:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "h_edge = mg.map_value_at_min_node_to_link(w, h)\n", - "for i in range(mg.number_of_links):\n", - " print(i, h_edge[i])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "### Heads or tails?\n", - "\n", - "It is also possible to map the scalar quantity at either the head node or the tail node to the link:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "h_edge = mg.map_link_head_node_to_link('surface_water__depth')\n", - "for i in range(mg.number_of_links):\n", - " print(i, h_edge[i])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "h_edge = mg.map_link_tail_node_to_link('surface_water__depth')\n", - "for i in range(mg.number_of_links):\n", - " print(i, h_edge[i])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Simple example using centered water depth\n", - "The following implements one time-step of a linear-viscous flow model, in which flow velocity is calculated with depth at the links is taken as the mean of depth at the two bounding nodes. To make the flow a little tamer, we'll have our fluid be basaltic lava instead of water, with a dynamic viscosity of 100 Pa s." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "gamma = 25000.0 # unit weight of fluid, N/m2\n", - "viscosity = 100.0 # dynamic viscosity in Pa s\n", - "grad = mg.calc_grad_at_link(w)\n", - "h_edge = mg.map_mean_of_link_nodes_to_link(h)\n", - "vel = -(gamma / viscosity) * h_edge * h_edge * grad\n", - "for ln in range(mg.number_of_links):\n", - " print(ln, h_edge[ln], grad[ln], vel[ln])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "I'm not sure I love the idea of a 5-m thick lava flow moving at over 100 m/s! (I guess we can take some comfort from the thought that turbulence would probably slow it down)\n", - "\n", - "How different would the numerical solution be using an upwind scheme for flow depth? Let's find out:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "h_edge = mg.map_value_at_max_node_to_link(w, h)\n", - "vel = -(gamma / viscosity) * h_edge * h_edge * grad\n", - "for ln in range(mg.number_of_links):\n", - " print(ln, h_edge[ln], grad[ln], vel[ln])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Still pretty scary.\n", - "\n", - "In any event, this example illustrates how you can use Landlab's mapping functions to build mass-conservation models in which the flow rate depends on a gradient and a scalar, both of which can be evaluated at links." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 1 -} diff --git a/python_intro/Python_intro_unexpanded.ipynb b/python_intro/Python_intro_unexpanded.ipynb deleted file mode 100644 index 16c37f1..0000000 --- a/python_intro/Python_intro_unexpanded.ipynb +++ /dev/null @@ -1,819 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# A super-brief intro to Python and NumPy" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - " For instructions on how to run an interactive iPython notebook, click here: https://github.com/landlab/tutorials/blob/master/README.md
\n", - "For more Landlab tutorials, click here: https://github.com/landlab/landlab/wiki/Tutorials\n", - "
\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python is:\n", - "* interpreted (high level)\n", - "* readable\n", - "* concise\n", - "* cross-platform\n", - "* dynamically typed\n", - "* object oriented\n", - "* automatically memory-managed\n", - "\n", - "Almost all of the below is explained much more fully at various places online. For a nice entry level tutorial set, try: https://nbviewer.jupyter.org/github/jrjohansson/scientific-python-lectures/tree/master/ or the Software Carpentry intros:\n", - "http://swcarpentry.github.io/python-novice-inflammation/\n", - "\n", - "The main Python documentation is also an extremely readable source of knowledge. Just Google!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## PROGRAM FILES AND INTERACTIVE ENVIRONMENTS\n", - "Put Python code in .py text files (AKA \"scripts\").\n", - "Run these from a shell, as:\n", - "\n", - "> python myscript.py\n", - "\n", - "OR\n", - "\n", - "Use one of Python's interactive environments (e.g., iPython)!\n", - "\n", - "> ipython\n", - "\n", - "In an interactive environment:\n", - "\n", - "* Run code line-by-line, preserving variables\n", - "* Run your scripts, using the magic command `%run` (and preserve the variables)\n", - "\n", - "This iPython notebook is an interactive environment." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## MODULES\n", - "Python has some built-in functions, but everything else comes in a library module.\n", - "\n", - "* See the built-in functions here: https://docs.python.org/2/library/functions.html\n", - "\n", - "Modules are *imported*, then the functions they hold run with a *dot* syntax:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import math # comments with a hash\n", - "x = math.cos(2. * math.pi)\n", - "print (x) # print is a built-in function" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "OR import the functions and properties individually:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from numpy import cos, pi # numpy, numeric python, also has these functions\n", - "x = cos(2. * pi)\n", - "print (x)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Get help in an interactive shell with a trailing ``?``, quit it with ``q``" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "pi?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## TYPES\n", - "Python distinguishes:\n", - "* integer (int)\n", - "* float (float)\n", - "* boolean (bool)\n", - "* complex (complex)\n", - "* strings (str)\n", - "\n", - "You may also encounter NumPy types, like `numpy.float64`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "type(pi)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Typecasting is automatic where possible, but can be time-expensive.\n", - "\n", - "Python's inbuilt *data structures* are:\n", - "* tuples, with *parentheses*—immutable\n", - "* lists, with *square brackets*—mutable\n", - "* sets, as set()—unordered collection with no duplicates\n", - "* dictionaries, with *curly brackets*—associated pairs of key:value\n", - "\n", - "Note that all these data structures let you happily mix data types… But the cost is that Python runs slower than, e.g., C++." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mytuple = (0,1,2,3)\n", - "print ('You can index: %d' % mytuple[1]) # this uses interpolation which replaces %d with the item following %" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print ('…but not reassign…')\n", - "mytuple[0] = 100" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mylist = [0,1,2,3]\n", - "print ('This time reassignment works:')\n", - "mylist[0] = 'I can store a string!'\n", - "print (mylist)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "myset = set([0,1,2,3])\n", - "print (myset)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "myset.add(\"string!\") # you can use both ' and \" to declare a string\n", - "print ('Adding is easy: %s' % myset)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "myset.add(0)\n", - "print (\"But remember, duplicates don't count! %s\" % myset)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "mydict = {'firstkey':1, 'secondkey':2, 3:'three'}\n", - "print (mydict)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print (mydict['firstkey'])\n", - "print (mydict['secondkey'])\n", - "print (mydict[3])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print ('Get the keys (note lack of ordering): %s' % mydict.keys())\n", - "print ('Get the values: %s' % mydict.values())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print ('This will fail: %s' % mydict[2])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## INDEXING\n", - "* Indexing starts from 0\n", - "* Index with square brackets [start : stop : step]\n", - "* \"stop\" is *exclusive* of the named index\n", - "* Colon alone means \"all of these\" or \"to the start/end\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = range(10)\n", - "print ('x[3] gives %d' % x[3])\n", - "print ('x[1:5:2] gives %s' % x[1:5:2])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print ('x[8:] gives %s' % x[8:])\n", - "print ('x[:7] gives %s' % x[:7])\n", - "print ('x[::3] gives %s' % x[::3])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## PYTHON IS LIKE, BUT ISN'T, MATLAB\n", - "- This is a *power*:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "x = 10.0**2 # …or…\n", - "import numpy as np\n", - "x = np.square(10.) # NEVER 10.^2." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Likewise, it's also useful to know about the \"truncation\" (``//``) and \"remainder\" (``%``) division operators:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print ('truncate: %d' % (13//4))\n", - "print ('remainder: %d' % (13%4))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- End indices are NOT inclusive" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "len(range(0,100)) # in Matlab this would be 101" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "[x for x in range(5)]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Intelligent memory management means Python will pass objects *by reference* where possible:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = [0] * 3\n", - "y = [1,2,3]\n", - "print ('x starts as %s' % x)\n", - "print ('y starts as %s' % y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = y\n", - "print ('After setting equal, x is %s' % x)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y[1] = 100\n", - "print ('After modifying y, x is %s' % x)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# force a copy with [:]\n", - "x = y[:]\n", - "print (x)\n", - "print (y)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "y[1] = 1000000\n", - "print ('After forcing a copy, x is still %s but y is now %s' % (x, y))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- In Matlab, assigning a value to a variable triggers output unless you suppress it with a semi-colon at the end of the line; this isn't necessary in Python:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = range(10) # …see?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Python doesn't use brackets to delineate code blocks. It uses *indentation* with a fixed number of spaces (normally 4). This also applies to ``for`` loops, ``while`` loops, ``if`` statements, ``try/except`` statements, class declarations, function declarations, etc." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def myfunction(arg1, arg2, **kwds):\n", - " # **kwds is a special (optional) dictionary input type,\n", - " # that you can use as an input \"wildcard\"\n", - " try:\n", - " print_this = kwds['printy']\n", - " except KeyError:\n", - " x = arg1 * arg2\n", - " return x # ...no brackets needed; both lines have 4 space indents\n", - " else:\n", - " print (print_this)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print('first time ' + myfunction(3.,4.))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print ('second time…')\n", - "myfunction(5,6,printy='Printed this time!')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Python's plotting is a blatant clone of matlab's, and lives in the library matplotlib.pyplot:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "# that command tells this notebook to put plots into the notebook\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "x = np.arange(10) # like range()\n", - "y = np.random.rand(10) # ten random floats, 0->1\n", - "plt.plot(x,y, '*--')\n", - "plt.xlabel('xaxis')\n", - "plt.ylabel('yaxis')\n", - "plt.title('my plot!')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "## NumPy and Landlab" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "Landlab makes extensive use of the NumPy (Numeric Python) libraries. These allow significant acceleration of standard Python processes on matrix-like data arrays. Here we look at some of the key features and differences with pure Python along with some NumPy best-practice." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Initialize NumPy arrays from standard Python iterables (lists, tuples):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "myarray = np.array([0,1,3,6,18])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "…or with one of the standard array creation methods in NumPy. Particularly useful ones are:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a = np.zeros(10, dtype=int)\n", - "print ('a: %s' % a)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "b = np.ones(5, dtype=bool)\n", - "print ('b: %s' % b)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c = np.random.rand(10)\n", - "print ('c: %s' % c)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "d = np.arange(5.)\n", - "print ('d: %s' % d)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "e = np.empty((3,3), dtype=float)\n", - "e.fill(100.)\n", - "print ('e: %s' % e)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Arrays also have some built-in methods and properties. We see 'fill' above, but also noteworthy are:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print ('shape: %s' % (e.shape,))\n", - "print ('size: %d ' % e.size) # preferred to len()\n", - "c.max(), c.min(), c.mean(), c.sum()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f = c.copy()\n", - "print ('flatten: %s' % e.flatten())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Slicing works like (better than?) in pure Python:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print (d[2:])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - " e[1,1] = 5.\n", - "print (e)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print (e[1:,1:])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that logical operations with NumPy tend to require NumPy-native functions, rather than pure Python `and`, `or`, `not` etc." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "bool1 = np.array([True, True, False, False])\n", - "bool2 = np.array([True, False, True, False])\n", - "print ('AND: %s' % np.logical_and(bool1, bool2))\n", - "print ('OR: %s' % np.logical_or(bool1, bool2))\n", - "print ('NOT: %s' % np.logical_not(bool1))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print ('ANY: %s' % np.any(bool1))\n", - "print ('ALL: %s' % np.all(bool1))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, let's demonstrate the speed of NumPy over pure Python:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "f_list = range(1000)\n", - "f_array = np.arange(1000, dtype=int)\n", - "\n", - "def addone_py(list_in):\n", - " for i in list_in:\n", - " i += 1\n", - "\n", - "def addone_np(array_in):\n", - " array_in += 1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print ('time for list:')\n", - "%timeit addone_py(f_list)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print ('time for array:')\n", - "%timeit addone_np(f_array)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In particular, never loop to do a logical test:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#NOT THIS:\n", - "myoutput_slow = np.zeros(10, dtype=float)\n", - "for i in range(len(c)): #c is our random number array\n", - " if c[i] > 0.5:\n", - " myoutput_slow[i] = c[i]\n", - "\n", - "#DO THIS INSTEAD:\n", - "myoutput_fast = np.zeros(10, dtype=float)\n", - "greater_than_half = c>0.5\n", - "myoutput_fast[greater_than_half] = c[greater_than_half]\n", - "\n", - "print (np.all(np.equal(myoutput_slow, myoutput_fast)))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "The online NumPy help is actually an extremely readable resource, and is highly recommended to find out more about the family of available NumPy methods." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Click here for more Landlab tutorials" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 1 -} diff --git a/reading_dem_into_landlab/reading_dem_into_landlab_unexpanded.ipynb b/reading_dem_into_landlab/reading_dem_into_landlab_unexpanded.ipynb deleted file mode 100644 index ff04564..0000000 --- a/reading_dem_into_landlab/reading_dem_into_landlab_unexpanded.ipynb +++ /dev/null @@ -1,439 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

a toolkit for modeling earth surface processes

" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How to read a DEM as a Landlab grid" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The starting point is to obtain a Digital Elevation Model (DEM) in ESRI's Ascii Grid format, or convert it to this format. The format consists of a 6-line header followed by elevation values. Here we'll work with a small example DEM file 'west_bijou_gully.asc'. The header for this file is as follows:\n", - "\n", - "``ncols 43\n", - "nrows 89\n", - "xllcorner 559705.000000000000\n", - "yllcorner 4380220.000000000000\n", - "cellsize 3\n", - "NODATA_value 0``\n", - "\n", - "Here, our objective is to translate the contents of this file into a Landlab RasterModelGrid. We'll do this using the ``read_esri_ascii`` function. Here's how it works:\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from landlab.io import read_esri_ascii" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the line above, we go to Landlab's input/output library (\"io\") and import the function. Next, let's look at the basic documentation:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "read_esri_ascii?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Ok, this tells us we need to supply the name of the file. If we want the data as a 2D array, we also specify ``reshape = True``. If we want to attach the elevation data to the grid as a field, we also give a name for the field as the ``name`` parameter. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "(mg, z) = read_esri_ascii('west_bijou_gully.asc', name='topographic__elevation')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's plot the grid:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "from landlab.plot.imshow import imshow_grid" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\nQmCC\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%matplotlib inline\n", - "imshow_grid(mg, 'topographic__elevation')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This plot illustrates the shape of the watershed, but we can't see the topography because the nodata values have a value of zero which is skewing the colormap. We can change the range of the colormap but first we need to figure out what the range of data values are. \n", - "\n", - "(Uncomment the commented line if you want to see all the options available in imshow_grid)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\nUHAAAAAASUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import numpy as np\n", - "min_z = np.min(z[np.where(z>0)])\n", - "max_z = np.max(z[np.where(z>0)])\n", - "#help(imshow_grid)\n", - "imshow_grid(mg, 'topographic__elevation', limits=(min_z,max_z))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can also query a bit of information:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "89" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mg.number_of_node_rows" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "43" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mg.number_of_node_columns" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The rest of this tutorial illustrates setting boundary conditions on DEMs and using the halo option for reading in DEMs without nodata values around the edges.\n", - "\n", - "Because this is a watershed, we probably want to set watershed boundary conditions. For more on setting watershed boundary conditions on rasters, see this tutorial: https://nbviewer.jupyter.org/github/landlab/tutorials/blob/master/boundary_conds/set_watershed_BCs_raster.ipynb\n", - "\n", - "We also replot the watershed, this time coloring by the node status, which illustrates the boundary condition at each node." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\nAAAAAElFTkSuQmCC\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "mg.set_watershed_boundary_condition(z, 0)\n", - "imshow_grid(mg, mg.status_at_node, color_for_closed='blue')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "All of the closed boundary nodes are shown in blue. Without the color_for_closed option they would plot as the minimum value, or black. A value of 0 node status means that the node is a core node, or operational, and a value of 1 means that the node is a fixed value boundary." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Now we illustrate reading in a DEM that is not a watershed, and use of the halo option." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "(mg1, z1) = read_esri_ascii('synthetic_landscape.asc', name='topographic__elevation')\n", - "imshow_grid(mg1, z1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This landscape has data values at all of it's points. (Note that the nodata_value is -9, but all of the values plotted here are >= 0.)\n", - "\n", - "If we set an open boundary on the bottom or south side, and the rest of the boundaries as closed, as illustrated below, some of our data values will become closed boundaries, and operations will not be carried out at these nodes. This is illustrated in the map of boundary status values, which has the three blue sides.\n", - "\n", - "Note that the default is that the perimeter will have fixed value node status, or a value of 1." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "mg1.set_closed_boundaries_at_grid_edges(True, True, True, False)\n", - "imshow_grid(mg1, mg1.status_at_node, color_for_closed='blue')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The implication of this map is that the right, top and left edges are closed now, and therefore these node values will not be operated on. Similarly the bottom row is fixed value, so it also won't be operated on.\n", - "\n", - "Supposed we want to include some or all of these values in model operations. We need to set them as core nodes, but we can't have core nodes on the perimeter of a grid. In this case we need to add a halo around the grid. The halo option adds a perimater of nodes around the data that are read in from the esri_ascii file. This is helpful when there are data values at the edges of a grid. By default, the halo perimeter nodes will have the nodata value." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\nAABJRU5ErkJggg==\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "(mg2, z2) = read_esri_ascii('synthetic_landscape.asc', name='topographic__elevation', halo=1)\n", - "imshow_grid(mg2, z2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It is helpful to know the no data value and other values in the header. Sure you could just open the file, but it might be huge. Here is how to access those values." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'cellsize': 5.0,\n", - " 'ncols': 10,\n", - " 'nodata_value': -9.0,\n", - " 'nrows': 10,\n", - " 'xllcorner': 0.0,\n", - " 'yllcorner': 0.0}" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from landlab.io import read_asc_header\n", - "fop = open('synthetic_landscape.asc', 'r')\n", - "hdr = read_asc_header(fop)\n", - "hdr" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This illustrates that the nodata value is -9." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Now setting the boundary conditions ... \n", - "\n", - "In this case, in this case I will set all of the edges as closed. I will set the bottom of the two channels (points x=15, y=5 and x=35, y=5) as fixed value boundaries. One could also set all of the data values in the second row from the bottom as fixed value. Appropriate boundary conditions obviously depend on the environmental conditions that one is modeling.\n", - "\n", - "Note there are multiple ways to do this. I happen to know that the node id of the two channel bottoms are 15 and 19. So I will set those as fixed value individually. I will also illustrate another useful boundary condition function, which sets all nodata values to closed. " - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\nQmCC\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "mg2.set_nodata_nodes_to_closed(z2, -9.)\n", - "from landlab import FIXED_VALUE_BOUNDARY\n", - "mg2.status_at_node[15]=FIXED_VALUE_BOUNDARY\n", - "mg2.status_at_node[19]=FIXED_VALUE_BOUNDARY\n", - "imshow_grid(mg2, mg2.status_at_node, color_for_closed='blue')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There are lots of ways we could have done this. In a more complicated DEM we would probably want to search for the smallest z values in the second row in order to figure out which should be fixed values. For more on setting raster boundary conditions see this tutorial: https://nbviewer.jupyter.org/github/landlab/tutorials/blob/master/boundary_conds/set_BCs_on_raster_perimeter.ipynb" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.13" - } - }, - "nbformat": 4, - "nbformat_minor": 1 -} From 8dc3f334956125129748e0effa8271204eca862a Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 7 Apr 2017 14:09:37 -0600 Subject: [PATCH 28/52] Remove redundant python scripts. --- boundary_conds/set_BCs_from_xy.py | 25 - fault_scarp/landlab-fault-scarp.py | 121 ----- flexure/lots_of_loads.py | 146 ------ .../gradient_and_divergence.py | 487 ------------------ grid_object_demo/grid_object_demo.py | 317 ------------ mappers/mappers.py | 216 -------- 6 files changed, 1312 deletions(-) delete mode 100644 boundary_conds/set_BCs_from_xy.py delete mode 100644 fault_scarp/landlab-fault-scarp.py delete mode 100644 flexure/lots_of_loads.py delete mode 100644 gradient_and_divergence/gradient_and_divergence.py delete mode 100644 grid_object_demo/grid_object_demo.py delete mode 100644 mappers/mappers.py diff --git a/boundary_conds/set_BCs_from_xy.py b/boundary_conds/set_BCs_from_xy.py deleted file mode 100644 index f08e712..0000000 --- a/boundary_conds/set_BCs_from_xy.py +++ /dev/null @@ -1,25 +0,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() \ No newline at end of file diff --git a/fault_scarp/landlab-fault-scarp.py b/fault_scarp/landlab-fault-scarp.py deleted file mode 100644 index dc75ac1..0000000 --- a/fault_scarp/landlab-fault-scarp.py +++ /dev/null @@ -1,121 +0,0 @@ -# Creating a simple 2D scarp diffusion model with Landlab - -# This tutorial illustrates how you can use Landlab to construct a simple -# two-dimensional numerical model on a regular (raster) grid, using a simple -# forward-time, centered-space numerical scheme. The example is the erosional -# degradation of an earthquake fault scarp, and which evolves over time in -# response to the gradual downhill motion of soil. Here we use a simple -# "geomorphic diffusion" model for landform evolution, in which the downhill -# flow of soil is assumed to be proportional to the (downhill) gradient of the -# land surface multiplied by a transport coefficient. - -# We start by importing the NumPy library, which we'll use for some array -# calculations: -import numpy - -# We will create a grid for our model using Landlab's *RasterModelGrid* class, -# which we need to import. -from landlab import RasterModelGrid - -# The syntax in the next line says: create a new RasterModelGrid object called -# mg, with 25 rows, 40 columns, and a grid spacing of 10 m. -mg = RasterModelGrid((25, 40), 10.0) - -# Now we'll add a data field to the grid, to represent the elevation values at -# grid nodes. The "dot" syntax indicates that we are calling a function (or -# method) that belongs to the RasterModelGrid class, and will act on data -# contained in mg. The arguments indicate that we want the data elements -# attached to grid nodes (rather than links, for example), and that we want to -# name this data field land_surface__elevation. The add_zeros method returns -# the newly created NumPy array. -z = mg.add_zeros('node', 'land_surface__elevation') - -# Let's take a look at the grid we've created. To do so, we'll use the -# Matplotlib graphics library (imported under the name plt). -import matplotlib.pyplot as plt - -# Let's plot the positions of all the grid nodes. The nodes' (x,y) positions -# are stored in the arrays mg.node_x and mg.node_y, respectively. -plt.figure(1) -plt.plot(mg.x_of_node, mg.y_of_node, '.') -plt.show() - -# There are 1000 grid nodes (25 x 40). The `z` array also has 1000 entries: -# one per grid node. -len(z) - -# 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 -# soil flux. In the function call below, the first argument tells Landlab that -# we want one value for each grid link, while the second argument provides a -# name for this data field: -qs = mg.add_zeros('link', 'sediment_flux') - -# And now for some landform evolution. We will loop through 25 iterations, -# representing 50,000 years. On each pass through the loop, we do the -# following: -# -# Calculate, and store in the array g, the gradient between each neighboring -# pair of nodes. These calculations are done on links. The gradient value is -# a positive number when the gradient is "uphill" in the direction of the -# link, and negative when the gradient is "downhill" in the direction of the -# link. On a raster grid, link directions are always in the direction of -# increasing x ("horizontal" links) or increasing y ("vertical" links). -# -# Calculate, and store in the array qs, the sediment flux between each -# adjacent pair of nodes by multiplying their gradient by the transport -# coefficient. We will only do this for the active links (those not -# connected to a closed boundary, and not connecting two boundary nodes of -# any type); others will remain as zero. -# -# Calculate, and store in dqsdx, the resulting net flux at each node -# (positive=net outflux, negative=net influx). -# -# The rate of change of node elevation, dzdt, is simply -dqsdx. -# -# Update the elevations for the new time step. -# -for i in range(25): - g = mg.calc_grad_at_link(z) - qs[mg.active_links] = -D * g[mg.active_links] - dqsdx = mg.calc_flux_div_at_node(qs) - dzdt = -dqsdx - z[mg.core_nodes] += dzdt[mg.core_nodes] * dt - -# Show how our fault scarp has evolved. -plt.figure(3) -imshow_grid_at_node(mg, 'land_surface__elevation') -plt.show() - -# Notice that we have just created and run a 2D model of fault-scarp creation -# and diffusion with fewer than two dozen lines of code. How long would this -# have taken to write in C or Fortran? \ No newline at end of file diff --git a/flexure/lots_of_loads.py b/flexure/lots_of_loads.py deleted file mode 100644 index 4f9b90a..0000000 --- a/flexure/lots_of_loads.py +++ /dev/null @@ -1,146 +0,0 @@ - -# # Using the Landlab flexure component -# - -# In this example we will: -# * create a Landlab component that solves the flexure equation -# * apply randomly distributed point loads -# * run the component -# * plot some output - - -import numpy as np - - -# ## Create the grid -# -# We are going to build a uniform rectilinear grid with a node spacing of 10 km in the *y*-direction and 20 km in the *x*-direction on which we will solve the flexure equation. -# -# First we nee to import *RasterModelGrid*. We also import the Landlab plotting function *imshow_grid* to view the grids. - - -from landlab import RasterModelGrid -from landlab.plot.imshow import imshow_grid - - -# Create a rectilinear grid with a spacing of 10 km between rows and 20 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)`. - - -grid = RasterModelGrid((200, 400), spacing=(10e3, 20e3)) - - - -grid.dy, grid.dx - - -# ## Create the component - -# 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. - - - -from landlab.components.flexure import Flexure - - -# The Flexure 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 `intput_var_names` attribute of the component *class*. - - - -Flexure.input_var_names - - -# We see that flexure uses just 1 data field: the change in lithospheric loading. landlab component classes can provide additional information about each of these fields. For instance, to the the units for a field, use the `var_units` method. - - - -Flexure.var_units('lithosphere__overlying_pressure_increment') - - -# To print a more detailed description of a field, use `var_help`. - - - -Flexure.var_help('lithosphere__overlying_pressure_increment') - - -# What about the data that `Flexure` provides? Use the `output_var_names` attribute. - - - -Flexure.output_var_names - - - - -Flexure.var_help('lithosphere_surface__elevation_increment') - - -# Now that we understand the component a little more, create it using our grid. - - - -flex = Flexure(grid, method='flexure') - - -# ## Add some loading -# We will add loads to the grid. As we saw above, for this component, the name of the variable that hold the applied loads is call, `lithosphere__overlying_pressure`. We add loads of random magnitude at every node of the grid. - - - -load = np.random.normal(0, 100 * 2650. * 9.81, grid.number_of_nodes) -grid.at_node['lithosphere__overlying_pressure_increment'] = load - - - - -imshow_grid(grid, 'lithosphere__overlying_pressure_increment', symmetric_cbar=True, - cmap='spectral', show=True) - - -# ## Update the component to solve for deflection -# If you have more than one processor on your machine you may want to use several of them. - - - -flex.update(n_procs=4) - - -# As we saw above, the flexure component creates an output field (`lithosphere_surface__elevation_increment`) that contains surface deflections for the applied loads. - -# # Plot the output - -# We now plot these deflections with the `imshow` method, which is available to all landlab components. - - - -imshow_grid(grid, 'lithosphere_surface__elevation_increment', symmetric_cbar=True, - cmap='spectral', show=True) - - -# Maintain the same loading distribution but double the effective elastic thickness. - - - -flex.eet *= 2. -flex.update(n_procs=4) -imshow_grid(grid, 'lithosphere_surface__elevation_increment', symmetric_cbar=True, - cmap='spectral', show=True) - - -# Now let's add a vertical rectangular load to the middle of the grid. We plot the load grid first to make sure we did this correctly. - - - -load[np.where(np.logical_and(grid.node_x>3000000, grid.node_x<5000000))]= load[np.where(np.logical_and(grid.node_x>3000000, grid.node_x<5000000))]+1e7 -imshow_grid(grid, 'lithosphere__overlying_pressure_increment', symmetric_cbar=True, - cmap='spectral', show=True) - - - - -flex.update(n_procs=4) -imshow_grid(grid, 'lithosphere_surface__elevation_increment', symmetric_cbar=True, - cmap='spectral', show=True) - - -# ### Click here for more Landlab tutorials diff --git a/gradient_and_divergence/gradient_and_divergence.py b/gradient_and_divergence/gradient_and_divergence.py deleted file mode 100644 index 116b6a6..0000000 --- a/gradient_and_divergence/gradient_and_divergence.py +++ /dev/null @@ -1,487 +0,0 @@ -# Using Landlab's gradient and flux divergence functions -# -# Models of geophysical flow phenomena very commonly include gradient terms and -# flux divergence terms in their governing equations. Consider the example of -# conductive heat diffusion in two dimensions. The *flux* of heat, $q$, at a -# point (in energy per time per area) depends on the *gradient* in temperature: -# -# $q_x = -k \frac{\partial T}{\partial x}$ -# -# $q_y = -k \frac{\partial T}{\partial y}$ -# -# where the subscripts denote the two directions. The time rate of change of -# thermal energy depends on the derivative of flux, or *flux divergence*: -# -# $\frac{dT}{dt} \propto -\left( \frac{\partial q_x}{\partial x} + -# \frac{\partial q_y}{\partial y} \right)$ -# -# In a finite-difference or finite-volume solution, the quantities $T$ and $q$ -# are solved at discrete points. Staggered-grid schemes will place the scalar -# quantity ($T$) at one set of grid locations, and the vector quantity ($q$) at -# "in-between" locations. -# -# In Landlab, such a staggered grid is easy to implement by locating scalar -# quantities at nodes, and locating vector quantities at either links. Landlab -# also provides a set of "one-liner" functions to calculate the gradients in a -# quantity located at nodes or cells, as well as to calculate the net flux or -# flux divergence in a vector quantity located at faces or links. This tutorial -# shows you examples of how to use these. -# -# We'll start with a tiny grid, so it's easy to see what the various flavors of -# the gradient and flux functions do. Then we'll try them out on the example of -# a landform undergoing soil creep, which is the same example used in an -# introductory Landlab tutorial. -# -# ## Tiny grid example -# -# We'll start with a 3-row by 4-column raster grid, with 10-meter node spacing. - -# In[ ]: - -import numpy -from landlab import RasterModelGrid -mg = RasterModelGrid((3, 4), 10.0) - - -# Create a scalar field called `z`, representing elevation of the land surface, -# at the grid nodes: - -# In[ ]: - -z = mg.add_zeros('node', 'topographic__elevation') -z[5] = 5.0 -z[6] = 3.6 - - -# Nodes 5 and 6 are the only core nodes; the rest are (so far) open boundaries. -# -# Here are the values. - -# In[ ]: - -z - - -# Nodes in a raster grid are numbered by row, starting from the bottom. In the -# array above, the first four are the bottom row, the next four are the middle -# row, and the last four are the top row. (Note that in general, nodes in any -# Landlab grid will be numbered in increasing order by their $y$ coordinates; -# nodes with equal $y$ coordinates, as in the case of rows in a raster grid, -# will then be numbered in order by $x$) -# -# Let's take a graphical look at the elevation grid we've created. To do so, -# we'll use the Pylab graphics library (imported under the name `plt`). -# Finally, we will import Landlab's `imshow_grid` function to display our -# gridded values. - -# In[ ]: - -import matplotlib.pyplot as plt -from landlab.plot.imshow import imshow_grid - - -# Let's plot the elevation values: - -# In[ ]: - -imshow_grid(mg, 'topographic__elevation') - - -# There are elevation values associated with all 12 of the nodes on the grid. -# The ones shown in black are **boundary nodes**; the two in the middle are -# **core nodes**. This is our *scalar field*. - -# ## Links and gradients -# -# Next, we will calculate the gradient in this field of elevation values. We -# want to find the gradient between each pair of adjacent nodes, and store that -# value at the associated **link** between them. -# -# ### What are links? -# -# For each pair of adjacent nodes in a Landlab grid, there is a corresponding -# **link**. Links are directed line segments whose endpoints are the -# coordinates of the nodes. A link can be illustrated like this: -# -# o---->o -# -# Here, each o represents a node, and the arrow is the link. A "vertical" link -# looks like this: -# -# o -# ^ -# | -# | -# o -# -# The tip of the arrow is known as the **link head**; the base of the arrow is -# known as the **link tail**. By default, links always "point" within the -# upper-right quadrange. -# -# With this definition of links in mind, we can sketch our grid like so, with -# the ID numbers of the nodes shown by the numbers: -# -# ` -# 8 ----> 9 ----> 10----> 11 -# ^ ^ ^ ^ -# | | | | -# | | | | -# 4 ----> 5 ----> 6 ----> 7 -# ^ ^ ^ ^ -# | | | | -# | | | | -# 0 ----> 1 ----> 2 ----> 3 -# ` -# -# If we label each node with its elevation value, it looks like this: -# -# ` -# 0 ----> 0 ----> 0 ----> 0 -# ^ ^ ^ ^ -# | | | | -# | | | | -# 0 ---->5.0---->3.6----> 0 -# ^ ^ ^ ^ -# | | | | -# | | | | -# 0 ----> 0 ----> 0 ----> 0 -# ` -# - -# ### Calculating the gradient of a node field at links -# -# To calculate the gradient of a node field, with one gradient value for each -# link, use the function `calc_grad_at_link`: - -# In[ ]: - -dzdx = mg.calc_grad_at_link(z) -dzdx - - -# Here's a crude graphical representation of gradient array: -# -# ` -# o ---0--> o ---0--> o ---0--> o -# ^ ^ ^ ^ -# 0 -0.5 -0.36 0 -# | | | | -# o +0.5 > o -0.14 > o -0.36 > o -# ^ ^ ^ ^ -# 0 +0.5 +0.36 0 -# | | | | -# o ---0--> o ---0--> 0 ---0--> 0 -# ` -# -# Links are listed in order by the $(x, y)$ coordinates of their midpoints. The -# ID numbering scheme for our links looks like this: -# -# ` -# o --14--> o --15--> o --16--> o -# ^ ^ ^ ^ -# 10 11 12 13 -# | | | | -# o ---7--> o ---8--> o ---9--> o -# ^ ^ ^ ^ -# 3 4 5 6 -# | | | | -# o ---0--> o ---1--> 0 ---2--> 0 -# ` -# -# Let's explore how the geometry and the values in the ID array of gradients -# correspond. Here are the gradients first three are the horizontal links along -# the bottom edge of the grid: - -# In[ ]: - -dzdx[0:3] - - -# Next come four vertical links that connect the bottom to the middle rows of -# nodes. Two of these values are positive, indicating an *uphill gradient in -# the direction of the links*: - -# In[ ]: - -dzdx[3:7] - - -# Now the middle row of horizontal links: - -# In[ ]: - -dzdx[7:10] - - -# The next row of vertical links. The middle two of these are negative, -# indicating a downhill slope in the direction of the links: - -# In[ ]: - -dzdx[10:14] - - -# Finally, the top row of horizontal links: - -# In[ ]: - -dzdx[14:17] - - -# So far, we've seen how to perform a centered-difference gradient calculation -# using Landlab's `calc_grad_at_link` function. Next, let's look at the flux -# divergence operation: adding up all the incoming and outgoing fluxes at a -# location. -# -# ## Cells and flux divergence -# -# ### A quick look at finite-volume numerical methods -# -# The *finite-volume method* is a type of numerical approach that is similar to -# the more familiar finite-difference method. For many problems that are -# discretized on a regular grid, the two methods turn out to be equivalent. For -# our next step, we'll take a finite-volume approach, which turns out to be -# fairly intuitive. -# -# Consider a rectangular *cell* of dimensions $\Delta x$ by $\Delta y$: -# -# ` -# o-------o -# | | -# | | -# | | -# o-------o -# ` -# -# Imagine that the cell represents a patch of ground on a hill. Along each edge -# of the rectangle, soil is gradually flowing either into or out of the cell. -# If more soil flows in than flows out, the cell's elevation will rise (we are -# assuming the soil bulk density is constant). If more soil flows out than -# flows in, the cell's elevation will shrink. -# -# Suppose we know the average soil flux along each side of the cell. If we use -# the compass directions *N, S, E, W* to denote the four sides, we might -# represent these average fluxes as follows: $q_N, q_S, q_E, q_W$. -# -# Let's take the convention that flow is always *positive* when it is going -# north or east, and negative when it is going south or west. With that in -# mind, we could compute the *net outflux of soil* as follows: -# -# $Q_{net} = -q_E \Delta y - q_N \Delta x + q_W \Delta y + q_S \Delta x$ -# -# The *rate* at which the cell's average elevation is rising or falling could -# be expressed as: -# -# $\frac{dz}{dt} = -\frac{Q_{net}}{\Delta x \Delta y}$ -# -# The term on the right side is a finite-volume approximation of the flux -# divergence. In commonly used symbols, -# -# $\nabla \mathbf{q} = \left( \frac{\partial q_x}{\partial x} -# + \frac{\partial q_y}{\partial y} \right) \approx \frac{Q_{net}}{\Delta x \Delta y}$ -# -# This is the quantity we would like to calculate for the nodes in our grid. -# -# ### More on grid geometry: nodes and cells -# -# In a Landlab grid, a *cell* is a polygon that contains a single *node*, which -# is a point. Every cell has one and only one node. However, not every node has -# a cell: the grid's perimeter consists of nodes without cells. -# -# In our tiny grid example, there are 12 nodes. Ten of these lie on the grid's -# perimeter. Therefore, our grid has only two cells: one containing node 5, and one containing node 6. The geometry is crudely sketched here: -# -# -# `~ b b b b -# ~ -# ~ .-------.-------. -# ~ | | | -# ~ b | c | c | b -# ~ | | | -# ~ .-------.-------. -# ~ -# ~ b b b b` -# -# -# Here, the letter `b` represents boundary nodes (10 of them), the letter `c` -# represents core nodes (2 of them), and the lines are the *faces* of the two -# cells. (The periods are called *corners*; we won't deal with them further in -# this tutorial. The tildas are there just to trick the notebook into -# formatting this correctly) -# -# Our aim is to calculate a *soil flux* across each cell face, and then add up -# all in the incoming and outgoing fluxes. -# -# Before we do this, notice that each face is crossed by a link. For example, -# there is a link running from the left core node to the right core node. Our -# strategy, therefore, will be to calculate a flux value for each link in the -# grid. The model we'll use will be the soil-transport law (sometimes known as -# Gilbert's Law): -# -# $\mathbf{q} = -D \nabla z$ -# -# Here, $\nabla z$ is simply the gradient. We have already discretized the -# gradient, placing the gradient between each pair of adjacent nodes at the -# corresponding link. *This means we have already defined values of the -# gradient across each cell face* (as well as several links along the grid -# perimeter that don't cross cell faces). -# -# We can calculate fluxes along grid links with a single expression: - -# In[ ]: - -D = 0.01 -q = -D * dzdx -q - - -# Now, in order to calculate the flux divergence at our two cells, we need to -# do the following steps: -# -# 1 - For each cell, multiply the four flux values by the width of the cell -# (which is the same for every face in this grid). -# -# 2 - Add up the incoming fluxes and subtract the outgoing fluxes. -# -# 3 - Divide by the area of the cell. -# -# The result will be a numerical approximation of the flux-divergene term. -# -# It turns out that you can do with with a single Landlab function call: - -# In[ ]: - -dqda = mg.calc_flux_div_at_node(q) - - -# At this point, you might be wondering why the function name says `_at_node` -# rather than `at_cell`. This is because Landlab assigns a value to each node. -# For the perimeter nodes, the value will be zero, because they have no cells -# and the calculation is meaningless. However, the two *core nodes*, which do -# have cells, **will** have meaningful values. Let's look at these values: - -# In[ ]: - -dqda - - -# Flux-divergence values for the two core nodes are 0.00164 and 0.00094, -# respectively. Let's look at how these values came to be. For node 5, the -# fluxes per unit width ("unit fluxes") along the faces of its cell are as -# follows: -# -# $q_E = -0.005$ m$^2$/yr -# -# $q_N = -0.005$ m$^2$/yr -# -# $q_W = -0.0014$ m$^2$/yr -# -# $q_S = -0.005$ m$^2$/yr -# -# So, this cell is leaking soil in every direction. The *total* fluxes along -# each cell, which we'll represent with the symbol $Q$, are obtained by -# multiplying each unit flux by the width of the face, which in this case is -# 10 meters: -# -# $Q_E = -0.05$ m$^3$/yr -# -# $Q_N = -0.05$ m$^3$/yr -# -# $Q_W = -0.014$ m$^3$/yr -# -# $Q_S = -0.05$ m$^3$/yr -# -# The total volume loss rate from the cell is 0.164 m$^3$/yr. Dividing this by -# the cell's surface area of 100 m$^2$, the cell's rate of change in average -# elevation is 0.00164 m/yr. -# -# For node 6, the unit fluxes are: -# -# $q_E = -0.0036$ m$^2$/yr -# -# $q_N = -0.0036$ m$^2$/yr -# -# $q_W = +0.0014$ m$^2$/yr -# -# $q_S = -0.0036$ m$^2$/yr -# -# So the cell at node 6 is leaking soil in three directions, but gaining a -# little bit from the higher cell to its west. -# Its total fluxes are: -# -# $Q_E = -0.036$ m$^3$/yr -# -# $Q_N = -0.036$ m$^3$/yr -# -# $Q_W = +0.014$ m$^3$/yr -# -# $Q_S = -0.036$ m$^3$/yr -# -# This gives a net flux of 0.094 m$^3$/yr, and a rate of elevation change of -# 0.00094 m/yr. -# -# If you want the net flux rather than flux divergence, you can get this with -# the `calc_net_flux_at_node` function: - -# In[ ]: - -mg.calc_net_flux_at_node(q) - - -# Notice that it correctly returns the values we computed above. -# -# ## Not just for raster grids -# -# The grid functions `calc_grad_at_link` and `calc_flux_div_at_node` functions -# also work on hexagonal and irregular grids. Under the hood, Landlab takes -# account of the differences in face width, link length, cell area, and so on. -# -# ## Optimizing performance -# -# With the usage illustrated above, Landlab will create and populate a new -# return array each time you call one of these functions. This costs computing -# time. To speed things up, you can pre-allocate your arrays and pass them in -# as arguments using the `out` keywork. For example, an alternative way to do -# our gradient calculation is as follows: - -# In[ ]: - -# Do this step ONCE, on initialization -dzdx = mg.add_zeros('link', 'topographic__gradient_of_elevation') - -# Do this step many times, in a loop -mg.calc_grad_at_link(z, out=dzdx) -dzdx - - -# In this case the Landlab will places the results of the calculation in the -# array you passed, rather than allocating memory for a new array. The same -# applies to `calc_flux_div_at_node` and `calc_net_flux_at_node`. -# -# In the example above, we created `dzdx` as a grid field, but you can -# alternatively pass in an empty or zero-valued NumPy array: - -# In[ ]: - -from numpy import zeros - -# Do this step ONCE, on initialization -dzdx = zeros(mg.number_of_links) - -# Do this step many times, in a loop -mg.calc_grad_at_link(z, out=dzdx) -dzdx - - -# ## Where to learn more -# -# - The **fault scarp tutorial** provides an example of `calc_grad_at_link` and -# `calc_flux_div_at_node` -# -# - See entries for these two functions in Landlab's *Reference Manual and API -# Documentation* -# -# - The complete code for this tutorial is also available as a stand-alone -# Python program: https://github.com/landlab/tutorials/blob/master/gradient_and_divergence/gradient_and_divergence.py - -# ### Click here for more Landlab tutorials diff --git a/grid_object_demo/grid_object_demo.py b/grid_object_demo/grid_object_demo.py deleted file mode 100644 index 8d9b318..0000000 --- a/grid_object_demo/grid_object_demo.py +++ /dev/null @@ -1,317 +0,0 @@ -# # What happens when you create a grid object? - -# Landlab supports a range of grid types. These include both rasters (with both -# square and rectangular cells), and a range of structured and unstructured -# grids based around the interlocking polygons and triangles of a -# Voronoi-Delaunay tesselation (radial, hexagonal, and irregular grids). -# -# Here, we look at some of the features of both of these types. -# -# We can create **grid** objects with the following lines of code. - -# In[ ]: - -import numpy as np -from landlab import RasterModelGrid, VoronoiDelaunayGrid, HexModelGrid -# a square-cell raster, 3 rows x 4 columns, unit spacing -smg = RasterModelGrid((3, 4), 1.) -rmg = RasterModelGrid((3, 4), (1., 2.)) # a rectangular-cell raster -hmg = HexModelGrid(3, 4, 1.) -# ^a hexagonal grid with 3 rows, 4 columns from the base row, & node spacing of -# 1. -x = np.random.rand(100) * 100. -y = np.random.rand(100) * 100. -vmg = VoronoiDelaunayGrid(x, y) -# ^a Voronoi-cell grid with 100 randomly positioned nodes within a 100.x100. -# square - - -# All these various `ModelGrid` objects contains various data items (known as -# *attributes*). These include, for example: * number nodes and links in the -# grid * *x* and *y* coordinates of each each node * starting ("tail") and -# ending ("head") node IDs of each link * IDs of links that are active * IDs of -# core nodes * etc. -# -# From here on we'll focus on the square raster grid as its geometry is a bit -# easier to think through, but all of the following applies to all grid types. -# -# ## Understanding the topology of Landlab grids -# -# All grids consist of two interlocked sets of *points* joined by *lines* -# outlining *areas*. If we define data on the points we call **nodes**, then -# they are joined by **links** which outline **patches**. Each node within the -# interior of the grid lies at the geometric center of the area of a **cell**. -# The cell's edges are **faces**, and the point at the edge of each face is a -# **corner**. -# -# Note that this kind of scheme requires one set of features to be "dominant" -# over the other; i.e., either not every node has a cell, *or* not every link is -# crossed by a face. Both cannot be true, because one or other set of features -# has to define the edge of the grid. Landlab assumes that the node set is -# primary, so there are always more nodes than corners; more links than faces; -# and more patches than cells. -# -# Each of these sets of *"elements"* has its own set of IDs. These IDs are what -# allow us to index the various Landlab fields which store spatial data. Each -# feature is ordered by **x, then y**. The origin is always at the bottom left -# node, unless you choose to move it (`grid.move_origin`)... except in the -# specific case of a radial grid, where logic and symmetry dictates it must be -# the central node. -# -# Whenever Landlab needs to order something rotationally (angles; elements -# around a different element type), it does so following the standard -# mathematical convention of **counterclockwise from east**. We'll see this in -# practical terms a bit later in this tutorial. -# -# The final thing to know is that **lines have direction**. This lets us record -# fluxes on the grid by associating them with, and mapping them onto, the links -# (or, much less commonly, the faces). All lines point into the **upper right -# quadrant**. So, on our raster, this means the horizontal links point east an -# the vertical links point north. -# -# So, for reference, our raster grid looks like this: -# -# -# NODES: LINKS: PATCHES: -# 8 ----- 9 ---- 10 ---- 11 * -14-->* -15-->* -16-->* * ----- * ----- * ----- * -# | | | | ^ ^ ^ ^ | | | | -# | | | | 10 11 12 13 | 3 | 4 | 5 | -# | | | | | | | | | | | | -# 4 ----- 5 ----- 6 ----- 7 * --7-- * --8-- * --9-- * * ----- * ----- * ----- * -# | | | | ^ ^ ^ ^ | | | | -# | | | | 3 4 5 6 | 0 | 1 | 2 | -# | | | | | | | | | | | | -# 0 ----- 1 ----- 2 ----- 3 * --0-->* --1-->* --2-->* * ----- * ----- * ----- * -# -# CELLS: FACES: CORNERS: -# * ----- * ----- * ----- * * ----- * ----- * ----- * * ----- * ----- * ----- * -# | | | | | | | | | | | | -# | . ----- . ----- . | | . --5-->. --6-->. | | 3 ----- 4 ----- 5 | -# | | | | | | ^ ^ ^ | | | | | | -# * --| 0 | 1 |-- * * --2 3 4-- * * --| | |-- * -# | | | | | | | | | | | | | | | -# | . ----- . ----- . | | . --0-->. --1-->. | | 0 ----- 1 ----- 2 | -# | | | | | | | | | | | | -# * ----- * ----- * ----- * * ----- * ----- * ----- * * ----- * ----- * ----- * -# -# -# ## Recording and indexing the values at elements -# -# Landlab lets you record values at any element you want. In practice, the most -# useful places to store data is on the primary elements of nodes, links, and -# patches, the the nodes being most useful for scalar values (e.g, elevations) -# and the links for fluxes with direction to them (e.g., discharges). -# -# In order to maintain compatibility across data types, *all* landlab data is -# stored in *number-of-elements*-long arrays. This includes both user-defined -# data and the properties of the nodes within the grid. This means that these -# arrays can be immediately indexed by their element ID. In other words: - -# In[ ]: - -# what's the y-coordinates of the pair of nodes in the middle of our 3-by-4 -# grid? the IDs of these nodes are 5 and 6, so: -smg.y_of_node[[5, 6]] - - -# If you're working with a raster, you can always reshape the value arrays back -# into two dimensions so you can take Numpy-style slices through it: - -# In[ ]: - -# what's the x-coordinates of the middle row? -smg.x_of_node.reshape(smg.shape)[1, :] - - -# This same data storage pattern is what underlies the Landlab **data fields**, -# which are simply one dimensional, number-of-elements-long arrays which store -# user defined spatial data across the grid, attached to the grid itself. - -# In[ ]: - -smg.add_zeros('node', 'elevation', noclobber=False) -# ^Creates a new field of zero data associated with nodes -smg.at_node['elevation'] # Note the use of dictionary syntax - - -# Or, equivalently, at links: - -# In[ ]: - -smg.add_ones('link', 'slope', noclobber=False) -# ^Creates a new array of data associated with links -smg.at_link['slope'] - - -# The Landlab **components** use fields to share spatial information between -# themselves. See the *fields* and *components* tutorials for more information. -# -# -# ## Getting this information from the grid object -# -# All of this topological information is recorded within our grid objects, and -# can be used to work with data that is defined over the grid. The grids record -# the numbers of each element, their positions, and their interrelationships to -# each other. Let's take a look at some of this information for the raster: - -# In[ ]: - -smg.number_of_nodes - - -# In[ ]: - -smg.number_of_links - - -# The grid contains its geometric information too. Let's look at the *(x,y)* -# coordinates of the nodes: - -# In[ ]: - -for i in range(smg.number_of_nodes): - print(i, smg.x_of_node[i], smg.y_of_node[i]) - - -# Link connectivity and direction is described by specifying the starting -# ("tail") and ending ("head") node IDs for each link (to remember this, think -# of an arrow: TAIL ===> HEAD). - -# In[ ]: - -for i in range(smg.number_of_links): - print('Link',i,': node',smg.node_at_link_tail[i],'===> node',smg.node_at_link_head[i]) - - -# Boundary conditions are likewise defined on these elements (see also the full -# boundary conditions tutorial). Landlab is clever enough to ensure that the -# boundary conditions recorded on, say, the links get updated when you redefine -# the conditions on, say, the nodes. -# -# Nodes can be *core*, *fixed value*, *fixed gradient*, or *closed* (flux into -# or out of node is forbidden). Links can be *active* (can carry flux), *fixed* -# (always carries the same flux; joined to a fixed gradient node) or *inactive* -# (forbidden from carrying flux). This information is likewise available from -# the grid: - -# In[ ]: - -smg.core_nodes - - -# In[ ]: - -smg.active_links - - -# In[ ]: - -# let's demonstrate the auto-updating of boundary conditions: -from landlab import CLOSED_BOUNDARY -smg.status_at_node[smg.nodes_at_bottom_edge] = CLOSED_BOUNDARY -smg.active_links # the links connected to the bottom edge nodes are now inactive - - -# ### Element connectivity -# -# Importantly, we can also find out which elements are connected to which other -# elements. This allows us to do computationally vital operations involving -# mapping values defined at one element onto another, e.g., the net flux at a -# node; the mean slope at a patch; the node value at a cell. -# -# In cases where these relationships are one-to-many (e.g., `links_at_node`, -# `nodes_at_patch`), the shape of the resulting arrays is always -# (number_of_elements, max-number-of-connected-elements-across-grid). i.e., on a -# raster, `links_at_node` is (nnodes, 4), because the cells are always square. -# On an irregular Voronoi-cell grid, `links_at_node` will be (nnodes, X) where X -# is the number of sides of the side-iest cell, and `nodes_at_patch` will be -# (npatches, 3) because all the patches are Delaunay triangles. And so on. -# -# Lets take a look. Remember, Landlab orders things **clockwise from east**, so -# for a raster the order will the EAST, NORTH, WEST, SOUTH. - -# In[ ]: - -smg.links_at_node[5] - - -# In[ ]: - -smg.links_at_node.shape - - -# Undefined directions get recorded as `-1`: - -# In[ ]: - -smg.links_at_node[8] - - -# In[ ]: - -smg.patches_at_node - - -# In[ ]: - -smg.nodes_at_patch - - -# Where element-to-element mapping is one-to-one, you get simple, one -# dimensional arrays: - -# In[ ]: - -smg.node_at_cell # shape is (n_cells, ) - - -# In[ ]: - -smg.cell_at_node # shape is (n_nodes, ) with -1s as needed - - -# A bit of thought reveals that things get a bit more complicated for links and -# faces, because they have direction. You'll need a convenient way to record -# whether a given flux (which is positive if it goes with the link's inherent -# direction, and negative if against) actually is travelling into or out of a -# given node. The grid provides `link_dirs_at_node` and -# `active_link_dirs_at_node` to help with this: - -# In[ ]: - -smg.link_dirs_at_node # all links; positive points INTO the node; zero where no link - - -# In[ ]: - -# prove there are zeros where links are missing: -np.all((smg.link_dirs_at_node == 0) == (smg.links_at_node == -1)) - - -# In[ ]: - -smg.active_link_dirs_at_node # in this one, inactive links get zero too - - -# Multiply the fluxes indexed by `links_at_node` and sum by axis=1 to have a -# very convenient way to calculate flux divergences at nodes: - -# In[ ]: - -fluxes_at_node = smg.at_link['slope'][smg.links_at_node] -# ^...remember we defined the slope field as ones, above -fluxes_into_node = fluxes_at_node*smg.active_link_dirs_at_node -flux_div_at_node = fluxes_into_node.sum(axis=1) -print(flux_div_at_node[smg.core_nodes]) - - -# Why? Remember that earlier in this tutorial we already set the bottom edge to -# `CLOSED_BOUNDARY`. So each of our core nodes has a flux of +1.0 coming in from -# the left, but two fluxes of -1.0 leaving from both the top and the right. -# Hence, the flux divergence is -1. at each node. -# -# Note as well that Landlab offers the one-line grid method -# `calc_flux_div_at_node()` to perform this same operation. - -# ### Click here for more Landlab tutorials diff --git a/mappers/mappers.py b/mappers/mappers.py deleted file mode 100644 index 8c60540..0000000 --- a/mappers/mappers.py +++ /dev/null @@ -1,216 +0,0 @@ -# # Mapping values between grid elements -# -# Imagine that you're using Landlab to write a model of shallow water flow over -# terrain. A natural approach is to place your scalar fields, such as water -# depth, at the nodes. You then place your vector fields, such as water surface -# gradient, flow velocity, and discharge, at the links. But your velocity -# depends on both slope and depth, which means you need to know the depth at -# the links too. How do you do this? -# -# This tutorial introduces *mappers*: grid functions that map quantities -# defined on one set of elements (such as nodes) onto another set of elements -# (such as links). As you'll see, there are a variety of mappers available. -# -# - -# ## Mapping from nodes to links -# -# For the sake of example, we'll start with a simple 3-row by 4-column raster -# grid. The grid will contain a scalar field called `water__depth`, abbreviated -# `h`. We'll populate it with some example values, as follows: - -# In[1]: - -from __future__ import print_function -from landlab import RasterModelGrid -import numpy as np -mg = RasterModelGrid((3, 4), 100.0) -h = mg.add_zeros('node', 'surface_water__depth') -h[:] = 7 - np.abs(6 - np.arange(12)) - - -# For the sake of visualizing values at nodes on our grid, we'll define a handy -# little function: - -# In[2]: - -def show_node_values(mg, u): - for r in range(mg.number_of_node_rows - 1, -1, -1): - for c in range(mg.number_of_node_columns): - print(int(u[c + (mg.number_of_node_columns * r)]), end=' ') - print() - - -# In[3]: - -show_node_values(mg, h) - - -# Let's review the numbering of nodes and links. The lines below will print a -# list that shows, for each link ID, the IDs of the nodes at the link's tail -# and head: -# -# In[4]: - -for i in range(mg.number_of_links): - print(i, mg.node_at_link_tail[i], mg.node_at_link_head[i]) - - -# ### Finding the mean value between two nodes on a link -# -# Suppose we want to have a *link-based* array, called *h_edge*, that contains -# water depth at locations between adjacent pairs of nodes. For each link, -# we'll simply take the average of the depth at the link's two nodes. To -# accomplish this, we can use the `map_mean_of_link_nodes_to_link` grid method. -# At link 8, for example, we'll average the *h* values at nodes 5 and 6, which -# should give us a depth of (6 + 7) / 2 = 6.5: - -# In[5]: - -h_edge = mg.map_mean_of_link_nodes_to_link('surface_water__depth') -for i in range(mg.number_of_links): - print(i, h_edge[i]) - - -# ### What's in a name? -# -# The mapping function has a long name, which is designed to make it as clear -# as possible to understand what the function does. All the mappers start with -# the verb *map*. Then the relationship is given; in this case, we are looking -# at the *mean*. Then the elements from which a quantity is being mapped: we -# are taking values from *link nodes*. Finally, the element to which the new -# values apply: *link*. -# -# ### Mapping minimum or maximum values -# -# We can also map the minimum value of *h*: - -# In[6]: - -h_edge = mg.map_min_of_link_nodes_to_link('surface_water__depth') -for i in range(mg.number_of_links): - print(i, h_edge[i]) - - -# ... or the maximum: - -# In[7]: - -h_edge = mg.map_max_of_link_nodes_to_link('surface_water__depth') -for i in range(mg.number_of_links): - print(i, h_edge[i]) - - -# ### Upwind and downwind -# -# Numerical schemes often use *upwind differencing* or *downwind differencing*. -# For example, finite difference schemes for equations that include advection -# may use "upwind" rather than centered differences, in which a scalar quantity -# (our *h* for example) is taken from whichever side is upstream in the flow -# field. -# -# How do we know the flow direction? If the flow is driven by the gradient in -# some scalar field, such as pressure or elevation, one approach is to look at -# the values of this scalar on either end of the link: the end with the higher -# value is upwind, and the end with the lower value is downwind. -# -# Suppose for example that our water flow is driven by the water-surface slope -# (which is often a good approximation for the *energy slope*, though it omits -# the kinetic energy). Let's define a bed-surface elevation field *z*: - -# In[8]: - -z = mg.add_zeros('node', 'topographic__elevation') -z[:] = 16 - np.abs(7 - np.arange(12)) -show_node_values(mg, z) - - -# The water-surface elevation is then the sum of *h* and *z*: - -# In[9]: - -w = z + h -show_node_values(mg, w) - - -# For every link, we can assign the value of *h* from whichever end of the link -# has the greater *w*: - -# In[10]: - -h_edge = mg.map_value_at_max_node_to_link(w, h) -for i in range(mg.number_of_links): - print(i, h_edge[i]) - - -# Consider the middle two nodes (5 and 6). Node 6 is higher (22 versus 20). -# Therefore, the link between them (link 8) should be assigned the value of *h* -# at node 6. This value happens to be 7.0. -# -# Of course, we could also take the value from the *lower* of the two nodes, -# which gives link 8 a value of 6.0: - -# In[11]: - -h_edge = mg.map_value_at_min_node_to_link(w, h) -for i in range(mg.number_of_links): - print(i, h_edge[i]) - - -# ### Heads or tails? -# -# It is also possible to map the scalar quantity at either the head node or the -# tail node to the link: - -# In[12]: - -h_edge = mg.map_link_head_node_to_link('surface_water__depth') -for i in range(mg.number_of_links): - print(i, h_edge[i]) - - -# In[13]: - -h_edge = mg.map_link_tail_node_to_link('surface_water__depth') -for i in range(mg.number_of_links): - print(i, h_edge[i]) - - -# ### Simple example using centered water depth -# The following implements one time-step of a linear-viscous flow model, in -# which flow velocity is calculated with depth at the links is taken as the -# mean of depth at the two bounding nodes. To make the flow a little tamer, -# we'll have our fluid be basaltic lava instead of water, with a dynamic -# viscosity of 100 Pa s. - -# In[14]: - -gamma = 25000.0 # unit weight of fluid, N/m2 -viscosity = 100.0 # dynamic viscosity in Pa s -grad = mg.calc_grad_at_link(w) -h_edge = mg.map_mean_of_link_nodes_to_link(h) -vel = -(gamma / viscosity) * h_edge * h_edge * grad -for ln in range(mg.number_of_links): - print(ln, h_edge[ln], grad[ln], vel[ln]) - - -# I'm not sure I love the idea of a 5-m thick lava flow moving at over 100 m/s! -# (I guess we can take some comfort from the thought that turbulence would -# probably slow it down) -# -# How different would the numerical solution be using an upwind scheme for flow -# depth? Let's find out: - -# In[15]: - -h_edge = mg.map_value_at_max_node_to_link(w, h) -vel = -(gamma / viscosity) * h_edge * h_edge * grad -for ln in range(mg.number_of_links): - print(ln, h_edge[ln], grad[ln], vel[ln]) - - -# Still pretty scary. -# -# In any event, this example illustrates how you can use Landlab's mapping -# functions to build mass-conservation models in which the flow rate depends on -# a gradient and a scalar, both of which can be evaluated at links. From 3d8d0684197308f3b51da5d1bc78a2c1dcb2b0a0 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 7 Apr 2017 14:11:12 -0600 Subject: [PATCH 29/52] Do not skip *_unexpanded.ipynb - they don't exist. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ac72927..11c0b22 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,6 @@ install: - conda install landlab jupyter -c landlab - conda info -a && conda list script: -- ./run_notebook.py **/*.ipynb --skip='*_unexpanded*' --skip='*intro*' --skip='flow*' +- ./run_notebook.py **/*.ipynb --skip='*intro*' --skip='flow*' virtualenv: system_site_packages: false From 7670c71b7f798742c22ca72b3d461a7f9e5c401f Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 7 Apr 2017 14:57:28 -0600 Subject: [PATCH 30/52] Add Travis CI badge [skip ci]. --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index accdc0f..80f7b20 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +[![Build +Status](https://travis-ci.org/landlab/tutorials.svg?branch=master)](https://travis-ci.org/landlab/tutorials) + [![Landlab header](./landlab_header.png)](http://landlab.github.io) Most of these Landlab tutorials can either be read as text files or run as interactive IPython notebooks (recommended!). From d327df564590c7af203040c850f4b2d10af18ad3 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sun, 9 Apr 2017 21:05:41 -0600 Subject: [PATCH 31/52] Add option to read notebooks from a file. --- run_notebook.py | 58 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/run_notebook.py b/run_notebook.py index 89f9cb9..ac5d1ed 100755 --- a/run_notebook.py +++ b/run_notebook.py @@ -68,35 +68,75 @@ def print_success_or_failure(summary): return len(failures) -def check_notebook(notebook): +def check_notebook(notebook, dry_run=False): try: - run_notebook(notebook) + dry_run or run_notebook(notebook) except subprocess.CalledProcessError: return False else: return True +def match_by_pattern(strings, patterns): + """Match strings by patterns. + + Parameters + ---------- + strings : iterable of str + Collection of strings. + patterns : iterable of str + List of glob-style patterns to remove. + + Returns + ------- + list of str + All strings that match any of the patterns. + """ + def string_matches_one_of(string, patterns): + for pattern in patterns: + if fnmatch(string, pattern): + return True + return False + + matches = [] + for string in strings: + if string_matches_one_of(string, patterns): + matches.append(string) + + return matches + + +def read_notebooks_from_file(file_like): + if file_like: + return [nb.strip() for nb in file_like if nb.strip()] + else: + return [] + + def main(): import argparse - parser = argparse.ArgumentParser() - parser.add_argument('notebook', type=str, nargs='+', + parser = argparse.ArgumentParser( + description='Run Jupyter notebooks.') + parser.add_argument('notebook', type=str, nargs='*', help='Notebook to test.') parser.add_argument('--skip', type=str, action='append', default=[], help='Notebooks to skip.') + parser.add_argument('--dry-run', action='store_true', + help='Find notebooks but do not do anything') + parser.add_argument('--file', type=argparse.FileType('r'), + help='Read notebooks from a file.') args = parser.parse_args() - skip = set() - for pattern in args.skip: - skip |= set([nb for nb in args.notebook if fnmatch(nb, pattern)]) + notebooks = read_notebooks_from_file(args.file) + args.notebook + skip = match_by_pattern(notebooks, args.skip) summary = [] - for notebook in args.notebook: + for notebook in notebooks: if notebook in skip: result = notebook, None else: - result = notebook, check_notebook(notebook) + result = notebook, check_notebook(notebook, dry_run=args.dry_run) print_summary([result]) summary.append(result) From 13f0b433f86e4c846062e6b60f28a7964b584528 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sun, 9 Apr 2017 21:06:03 -0600 Subject: [PATCH 32/52] Add script to find notebooks. --- find_notebooks.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100755 find_notebooks.py diff --git a/find_notebooks.py b/find_notebooks.py new file mode 100755 index 0000000..6807311 --- /dev/null +++ b/find_notebooks.py @@ -0,0 +1,53 @@ +#! /usr/bin/env python +from __future__ import print_function + +import os +from six.moves import shlex_quote + + +def find_notebooks(base): + """Find Jupyter notebooks. + + Parameters + ---------- + base : str + Path to search for notebooks under. + + Returns + ------- + list of str + Paths to discovered notebooks. + """ + notebooks = [] + for root, dirs, files in os.walk(base, topdown=True): + for dir in dirs: + if dir.startswith('.'): + dirs.remove(dir) + for fname in files: + file_path = os.path.join(root, fname) + if file_path.endswith('.ipynb'): + notebooks.append(file_path) + return notebooks + + +def main(): + import argparse + parser = argparse.ArgumentParser( + description='Find Jupyter notebooks under a given base path') + parser.add_argument('path', help='Path to search for notebooks.') + parser.add_argument('--sort', action='store_true', + help='Sort notebooks alphabetically.') + + args = parser.parse_args() + + notebooks = find_notebooks(args.path) + + if args.sort: + notebooks.sort() + + # print(os.linesep.join([shlex_quote(nb) for nb in notebooks])) + print(os.linesep.join([nb for nb in notebooks])) + + +if __name__ == '__main__': + main() From ae9148fa3a96d527fed8fdb7de82b47fdc67866e Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sun, 9 Apr 2017 21:07:07 -0600 Subject: [PATCH 33/52] Use new script to find notebooks. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 11c0b22..b9e3dd0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,6 @@ install: - conda install landlab jupyter -c landlab - conda info -a && conda list script: -- ./run_notebook.py **/*.ipynb --skip='*intro*' --skip='flow*' +- ./find_notebooks.py . | ./run_notebook.py --file=- --skip=*intro* --skip=*flow_direction* virtualenv: system_site_packages: false From ed70ecf12100539ec3de14f286496b4475058a85 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sun, 9 Apr 2017 21:57:32 -0600 Subject: [PATCH 34/52] Remove unexpanded notebooks. --- ..._automaton_vegetation_DEM_unexpanded.ipynb | 514 ------------------ ...automaton_vegetation_flat_unexpanded.ipynb | 493 ----------------- 2 files changed, 1007 deletions(-) delete mode 100644 ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM_unexpanded.ipynb delete mode 100644 ecohydrology/cellular_automaton_vegetation_flat_surface/cellular_automaton_vegetation_flat_unexpanded.ipynb diff --git a/ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM_unexpanded.ipynb b/ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM_unexpanded.ipynb deleted file mode 100644 index b970a5e..0000000 --- a/ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM_unexpanded.ipynb +++ /dev/null @@ -1,514 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Tutorial For Cellular Automaton Vegetation Model Coupled With Ecohydrologic Model" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - " For instructions on how to run an interactive iPython notebook, click here: https://github.com/landlab/tutorials/blob/master/README.md
\n", - "For the unexpanded version to download and run, click here: http://nbviewer.jupyter.org/github/landlab/tutorials/blob/master/ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM_unexpanded.ipynb
\n", - "For more Landlab tutorials, click here: https://github.com/landlab/landlab/wiki/Tutorials\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This tutorial demonstrates implementation of the Cellular Automaton Tree-GRass-Shrub Simulator (CATGRaSS) [Zhou et al., 2013] on a digital elevation model (DEM). This model is built using components from the Landlab component library. CATGRaSS is a spatially explicit model of plant coexistence. It simulates local ecohydrologic dynamics (soil moisture, transpiration, biomass) and spatial evolution of tree, grass, and shrub Plant Functional Types (PFT) driven by rainfall and solar radiation. \n", - "\n", - "Each cell in the model grid can hold a single PFT or remain empty. Tree and shrub plants disperse seeds to their neighbors. Grass seeds are assumed to be available at each cell. Establishment of plants in empty cells is determined probabilistically based on water stress for each PFT. Plants with lower water stress have higher probability of establishment. Plant mortality is simulated probabilistically as a result of aging and drought stress. Fires and grazing will be added to this model soon. \n", - "\n", - "This model (driver) contains:\n", - "- A local vegetation dynamics model that simulates storm and inter-storm water balance and ecohydrologic fluxes (ET, runoff), and plant biomass dynamics by coupling the following components:\n", - " - PrecipitationDistribution\n", - " - Radiation\n", - " - PotentialEvapotranspiration\n", - " - SoilMoisture\n", - " - Vegetation\n", - "\n", - "- A spatially explicit probabilistic cellular automaton component that simulates plant competition by tracking establishment and mortality of plants based on soil moisture stress:\n", - " - VegCA\n", - " \n", - "To run this Jupyter notebook, please make sure that the following files are in the same folder:\n", - " - cellular_automaton_vegetation_DEM.ipynb (this notebook)\n", - " - Inputs_Vegetation_CA.txt (Input parameters for the model)\n", - " - Ecohyd_functions_DEM.py (Utility functions)\n", - " \n", - "[Ref: Zhou, X, E. Istanbulluoglu, and E.R. Vivoni. \"Modeling the ecohydrological role of aspect-controlled radiation on tree-grass-shrub coexistence in a semiarid climate.\" Water Resources Research 49.5 (2013): 2872-2895]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this tutorial, we are going to work with a landscape in central New Mexico, USA, where aspect controls the organization of PFTs. The climate in this area is semi-arid with Mean Annual Precipitation (MAP) of 254 mm [Zhou et. al 2013]. \n", - "We will do the following: \n", - "- Import a landscape \n", - "- Initialize the landscape with random distribution of PFTs\n", - "- Run the coupled Ecohydrology and cellular automata plant competition model for 50 years\n", - "- Visualize and examine outputs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Let's walk through the code:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Import the required libraries:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "import time\n", - "import numpy as np\n", - "from landlab.io import read_esri_ascii\n", - "from landlab import RasterModelGrid as rmg\n", - "from Ecohyd_functions_DEM import (txt_data_dict, Initialize_, Empty_arrays,\n", - " Create_PET_lookup, Save_, Plot_)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note: 'Ecohyd_functions_DEM.py' is a utility script that contains 'functions', which instantiates components and manages inputs and outputs, and help keep this driver concise. Contents of 'Ecohyd_functions_DEM.py' can be a part of this driver (current file), however left out to keep driver concise." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We will use two grids in this driver. One grid will represent the actual landscape or domain (e.g., created from a DEM). Another grid, with one cell for each of the plant functional types (PFTs), will be used to create Potential Evapotranspiration (PET) lookup tables.\n", - "\n", - "- grid: This grid represents the actual landscape. Each cell can be occupied by a single PFT such as tree, shrub, grass, or can be empty (bare). In this example we assume that the elevation field and the vegetation field has the same resolution.\n", - "\n", - "- grid1: This grid will be used to compute plant-specific PET at a point. Spatially distributed PET Lookup arrays (for all days of the year) will be created for each PFT based on these point values.\n", - "\n", - "Note: In this tutorial, the physical ecohydrological components and cellular automata plant competition will be run on grids with same resolution. To develop differential spatial resolutions for the two models, see the tutorial 'cellular_automaton_vegetation_flat.ipynb'." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "(grid, elevation) = read_esri_ascii('DEM_10m.asc') # Read the DEM\n", - "grid1 = rmg((5, 4), spacing=(5., 5.)) # Representative grid" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Include the input file that contains all input parameters needed for all components. This file can either be a Python dictionary or a text file that can be converted into a Python dictionary. If a text file is provided, it will be converted to a Python dictionary. Here we use an existing text file prepared for this exercise." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "InputFile = 'Inputs_Vegetation_CA_DEM.txt'\n", - "data = txt_data_dict(InputFile) # Creates dictionary that holds the inputs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Instantiate Landlab components to simulate corresponding attributes. In this example, we shall demonstrate the use of seasonal rainfall and PFT-specific potential evapotranspiration. The instantiated objects are:\n", - "- PD_D: object for dry season rainfall, \n", - "- PD_W: object for wet season rainfall, \n", - "- Rad: Radiation object computes radiation factor defined as the ratio of total shortwave radiation incident on a sloped surface to total shortwave radiation incident on a flat surface. \n", - "- Rad_PET: Representative radiation object which is used only as an input for PET.\n", - "- PET_PFT: Plant specific PET objects (we use a cosine function, fitted to calculated PET, as a function of Day Of the Year (DOY) to reduce computation overhead). This value is spatially distributed by using a radiation factor.\n", - "- SM: Soil Moisture object simulates root-zone average soil moisture at each cell using inputs of potential evapotranspiration, live leaf area index, and vegetation cover.\n", - "- VEG: Vegetation dynamics object simulates net primary productivity and biomass and thus leaf area index at each cell based on inputs of root-zone average soil moisture.\n", - "- vegca: Cellular Automaton plant competition object. This object simulates the spatial dynamics of PFTs. It is run once every year at the end of the growing season. This object is initialized with a random cellular field of PFT. Each year, this object updates the field of PFTs based on probabilistic establishment and mortality rules employed at each cell of the modeled DEM.\n", - "\n", - "Note: Almost every component in Landlab is coded as a 'class' (to harness the advantages of object oriented programming). An 'object' is the instantiation of the 'class' (for more information, please refer any object oriented programming book). A 'field' refers to a Landlab field (please refer to the [Landlab documentation](https://github.com/landlab/landlab/wiki/Grid#adding-data-to-a-landlab-grid-element-using-fields) to learn more about Landlab fields)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let's instantiate all Landlab components that we are going to use for this tutorial:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "PD_D, PD_W, Rad, Rad_PET, PET_Tree, PET_Shrub, PET_Grass, SM, VEG, vegca = (\n", - " Initialize_(data, grid, grid1, elevation))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Lets look at the initial organization of PFTs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "from landlab.plot import imshow_grid\n", - "import matplotlib as mpl\n", - "cmap = mpl.colors.ListedColormap(\n", - " ['green', 'red', 'black', 'white', 'red', 'black'])\n", - "bounds = [-0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5]\n", - "norm = mpl.colors.BoundaryNorm(bounds, cmap.N)\n", - "description = 'green: grass; red: shrub; black: tree; white: bare'\n", - "plt.figure(101)\n", - "imshow_grid(grid, 'vegetation__plant_functional_type', values_at='cell',\n", - " cmap=cmap, grid_units=('m', 'm'), norm=norm, limits=[0, 5],\n", - " allow_colorbar=False)\n", - "plt.figtext(0.2, 0.0, description,\n", - " weight='bold', fontsize=10)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Specify an approximate number of years for the model to run.\n", - "\n", - "IMPORTANT: \n", - "This code in numerically extensive. It might take an hour or more to run this simulation for 300 years. It is suggested to run the simulation for 50 years which might take less than 7 minutes to execute." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "n_years = 50 # Approx number of years for model to run\n", - "# Calculate approximate number of storms per year\n", - "fraction_wet = (data['doy__end_of_monsoon']-data['doy__start_of_monsoon'])/365.\n", - "fraction_dry = 1 - fraction_wet\n", - "no_of_storms_wet = (8760 * (fraction_wet)/(data['mean_interstorm_wet'] +\n", - " data['mean_storm_wet']))\n", - "no_of_storms_dry = (8760 * (fraction_dry)/(data['mean_interstorm_dry'] +\n", - " data['mean_storm_dry']))\n", - "n = int(n_years * (no_of_storms_wet + no_of_storms_dry))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Create empty arrays to store spatio-temporal data over multiple iterations. The captured data can be used for plotting model outputs." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "P, Tb, Tr, Time, VegType, PET_, Rad_Factor, EP30, PET_threshold = (\n", - " Empty_arrays(n, n_years, grid, grid1))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To reduce computational overhead, we shall create a lookup array for plant-specific PET values for each day of the year, and slope and aspect grid." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "Create_PET_lookup(Rad, PET_Tree, PET_Shrub, PET_Grass, PET_, Rad_Factor,\n", - " EP30, Rad_PET, grid)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Specify current_time (in years). current_time is the current time in the simulation." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# # Represent current time in years\n", - "current_time = 0 # Start from first day of Jan\n", - "\n", - "# Keep track of run time for simulation—optional\n", - "Start_time = time.clock() # Recording time taken for simulation\n", - "\n", - "# declaring few variables that will be used in storm loop\n", - "time_check = 0. # Buffer to store current_time at previous storm\n", - "yrs = 0 # Keep track of number of years passed\n", - "WS = 0. # Buffer for Water Stress\n", - "Tg = 365 # Growing season in days" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The loop below couples the components introduced above in a for loop until all \"n\" number of storms are generated. Time is advanced by the soil moisture object based on storm and interstorm durations that are estimated by the strom generator object. The ecohydrologic model is run on each storm whereas cellular automaton vegetation component is run once every year.\n", - "\n", - "Note: This loop might take around 10 minutes (depending on your computer) to run for a 50 year simulation. Ignore any warnings you might see." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# # Run storm Loop\n", - "for i in range(0, n):\n", - " # # Update objects\n", - " # Calculate Day of Year (DOY)\n", - " Julian = np.int(np.floor((current_time - np.floor(current_time)) * 365.))\n", - " # Generate seasonal storms\n", - " # for Dry season\n", - " if Julian < data['doy__start_of_monsoon'] or Julian > data[\n", - " 'doy__end_of_monsoon']:\n", - " PD_D.update()\n", - " P[i] = PD_D.get_storm_depth()\n", - " Tr[i] = PD_D.get_precipitation_event_duration()\n", - " Tb[i] = PD_D.get_interstorm_event_duration()\n", - " # Wet Season—Jul to Sep—NA Monsoon\n", - " else:\n", - " PD_W.update()\n", - " P[i] = PD_W.get_storm_depth()\n", - " Tr[i] = PD_W.get_precipitation_event_duration()\n", - " Tb[i] = PD_W.get_interstorm_event_duration()\n", - "\n", - " # Spatially distribute PET and its 30-day-mean (analogous to degree day)\n", - " grid['cell']['surface__potential_evapotranspiration_rate'] = (\n", - " (np.choose(grid['cell']['vegetation__plant_functional_type'],\n", - " PET_[Julian])) * Rad_Factor[Julian])\n", - " grid['cell']['surface__potential_evapotranspiration_30day_mean'] = (\n", - " (np.choose(grid['cell']['vegetation__plant_functional_type'],\n", - " EP30[Julian])) * Rad_Factor[Julian])\n", - "\n", - " # Assign spatial rainfall data\n", - " grid['cell']['rainfall__daily_depth'] = P[i] * np.ones(grid.number_of_cells)\n", - "\n", - " # Update soil moisture component\n", - " current_time = SM.update(current_time, Tr=Tr[i], Tb=Tb[i])\n", - "\n", - " # Decide whether its growing season or not\n", - " if Julian != 364:\n", - " if EP30[Julian+1, 0] > EP30[Julian, 0]:\n", - " PET_threshold = 1\n", - " # 1 corresponds to ETThresholdup (begin growing season)\n", - " else:\n", - " PET_threshold = 0\n", - " # 0 corresponds to ETThresholddown (end growing season)\n", - "\n", - " # Update vegetation component\n", - " VEG.update(PETthreshold_switch=PET_threshold, Tb=Tb[i], Tr=Tr[i])\n", - "\n", - " # Update yearly cumulative water stress data\n", - " WS += (grid['cell']['vegetation__water_stress'])*Tb[i]/24.\n", - "\n", - " # Record time (optional)\n", - " Time[i] = current_time\n", - "\n", - " # Cellular Automata\n", - " if (current_time - time_check) >= 1.:\n", - " if yrs % 5 == 0:\n", - " print 'Elapsed time = ', yrs, ' years'\n", - " VegType[yrs] = grid['cell']['vegetation__plant_functional_type']\n", - " grid['cell']['vegetation__cumulative_water_stress'] = WS/Tg\n", - " vegca.update()\n", - " SM.initialize()\n", - " VEG.initialize()\n", - " time_check = current_time\n", - " WS = 0\n", - " yrs += 1\n", - "VegType[yrs] = grid['cell']['vegetation__plant_functional_type']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Time_Consumed is an optional variable that gives information about computer running time" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "Final_time = time.clock()\n", - "Time_Consumed = (Final_time - Start_time)/60. # in minutes\n", - "print 'Time_consumed = ', Time_Consumed, ' minutes'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Save the outputs using ``numpy.save()``. These files have '.nc' extension, which can be loaded using ``numpy.load()``." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# # Saving\n", - "sim = 'VegCA_DEM_26Jul16_'\n", - "# Save_(sim, Tb, Tr, P, VegType, yrs, Time_Consumed, Time)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Lets look at outputs.\n", - "\n", - "Plots of the cellular field of PFT at specified year step can be found below where:\n", - "\n", - "GRASS = Green; SHRUB = Red; TREE = Black; BARE = White;\n", - "\n", - "At the end, percentage cover for each PFT is plotted with respect to time." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "Plot_(grid, VegType, yrs, yr_step=10)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### If you run this model for around 900 years, you will observe patterns of PFTs. For example, you will find more trees on north facing slopes and mostly shrubs and grass on south facing slopes, as shown below:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from IPython.display import Image\n", - "Image(filename = 'presentation.png')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you want to explore this model further, open 'Inputs_Vegetation_CA.txt' and change the input parameters (e.g., initial PFT distribution percentages, storm characteristics, etc..)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Click here for more Landlab tutorials" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.11" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/ecohydrology/cellular_automaton_vegetation_flat_surface/cellular_automaton_vegetation_flat_unexpanded.ipynb b/ecohydrology/cellular_automaton_vegetation_flat_surface/cellular_automaton_vegetation_flat_unexpanded.ipynb deleted file mode 100644 index 72f6e8f..0000000 --- a/ecohydrology/cellular_automaton_vegetation_flat_surface/cellular_automaton_vegetation_flat_unexpanded.ipynb +++ /dev/null @@ -1,493 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Tutorial For Cellular Automaton Vegetation Model Coupled With Ecohydrologic Model" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - " For instructions on how to run an interactive iPython notebook, click here: https://github.com/landlab/tutorials/blob/master/README.md
\n", - "For the unexpanded version to download and run, click here: http://nbviewer.jupyter.org/github/landlab/tutorials/blob/master/ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM_unexpanded.ipynb
\n", - "For more Landlab tutorials, click here: https://github.com/landlab/landlab/wiki/Tutorials\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This tutorial demonstrates implementation of the Cellular Automaton Tree-GRass-Shrub Simulator (CATGRaSS) [Zhou et al., 2013] on a flat domain. This model is built using components from the Landlab component library. CATGRaSS is spatially explicit model of plant coexistence. It simulates local ecohydrologic dynamics (soil moisture, transpiration, biomass) and spatial evolution of tree, grass, and shrub Plant Functional Types (PFT) driven by rainfall and solar radiation. \n", - "\n", - "Each cell in the model grid can hold a single PFT or remain empty. Tree and shrub plants disperse seeds to their neighbors. Grass seeds are assumed to be available at each cell. Establishment of plants in empty cells is determined probabilistically based on water stress of each PFT. Plants with lower water stress have higher probability of establishment. Plant mortality is simulated probabilistically as a result of aging and drought stress. Fires and grazing will be added to this model soon. \n", - "\n", - "This model (driver) contains:\n", - " - A local vegetation dynamics model that simulates storm and inter-storm water balance and ecohydrologic fluxes (ET, runoff), and plant biomass dynamics by coupling the following components:\n", - " - PrecipitationDistribution\n", - " - Radiation\n", - " - PotentialEvapotranspiration\n", - " - SoilMoisture\n", - " - Vegetation\n", - "\n", - " - A spatially explicit probabilistic cellular automaton component that simulates plant competition by tracking establishment and mortality of plants based on soil moisture stress:\n", - " - VegCA\n", - " \n", - "To run this Jupyter notebook, please make sure that the following files are in the same folder:\n", - " - cellular_automaton_vegetation_flat_domain.ipynb (this notebook)\n", - " - Inputs_Vegetation_CA.txt (Input parameters for the model)\n", - " - Ecohyd_functions_flat.py (Utility functions)\n", - "\n", - "[Ref: Zhou, X, E. Istanbulluoglu, and E.R. Vivoni. \"Modeling the ecohydrological role of aspect-controlled radiation on tree-grass-shrub coexistence in a semiarid climate.\" Water Resources Research 49.5 (2013): 2872-2895]\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this tutorial, we are going to work with a landscape in central New Mexico, USA, where aspect controls the organization of PFTs. The climate in this area is semi-arid with Mean Annual Precipitation (MAP) of 254 mm [Zhou et. al 2013]. \n", - "We will do the following: \n", - "- Import a landscape \n", - "- Initialize the landscape with random distribution of PFTs\n", - "- Run the coupled Ecohydrology and cellular automata plant competition model for 50 years\n", - "- Visualize and examine outputs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Let us walk through the code:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Import the required libraries" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "import time\n", - "import numpy as np\n", - "from landlab import RasterModelGrid as rmg\n", - "from Ecohyd_functions_flat import (txt_data_dict, Initialize_, Empty_arrays,\n", - " Create_PET_lookup, Save_, Plot_)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note: 'Ecohyd_functions_flat.py' is a utility script that contains 'functions', which instantiates components and manages inputs and outputs, and help keep this driver concise. Contents of 'Ecohyd_functions_flat.py' can be a part of this driver (current file), however left out to keep driver concise." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To minimize computation time, we will use two grids in this driver. One grid will represent a flat landscape or domain (i.e., landscape with same elevation), on which the cellular automata plant competition will be simulated at an yearly time step. Another grid, with enough cells to house one cell for each of the plant functional types (PFTs), will be used to simulate soil moisture decay and local vegetation dynamics, in between successive storms (i.e. time step = one storm). Cumulative water stress (stress experienced by plants due to lack of enough soil moisture) will be calculated over an year and mapped to the other grid.\n", - "\n", - "- grid: This grid represents the actual landscape. Each cell can be occupied by a single PFT such as tree, shrub, grass, or can be empty (bare). Initial PFT distribution is randomnly generated from inputs of percentage of cells occupied by each PFT.\n", - "\n", - "- grid1: This grid allows us to calculate PFT specific cumulative water stress (cumulated over each storm in the year) and mapped with 'grid'.\n", - "\n", - "Note: In this tutorial, the physical ecohydrological components and cellular automata plant competition will be run on grids with different resolution. To use grids with same resolution, see the tutorial 'cellular_automaton_vegetation_DEM.ipynb'." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "grid1 = rmg((100, 100), spacing=(5., 5.))\n", - "grid = rmg((5, 4), spacing=(5., 5.))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Include the input file that contains all input parameters needed for all components. This file can either be a python dictionary or a text file that can be converted into a python dictionary. If a text file is provided, it will be converted to a Python dictionary. Here we use an existing text file prepared for this exercise." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "InputFile = 'Inputs_Vegetation_CA_flat.txt'\n", - "data = txt_data_dict(InputFile) # Create dictionary that holds the inputs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Instantiate landlab components to simulate corresponding attributes. In this example, we shall demonstrate the use of seasonal rainfall and PFT-specific potential evapotranspiration. The instantiated objects are:\n", - "- PD_D: object for dry season rainfall, \n", - "- PD_W: object for wet season rainfall, \n", - "- Rad: Radiation object computes radiation factor defined as the ratio of total shortwave radiation incident on a sloped surface to total shortwave radiation incident on a flat surface. Note: in this example a flat domain is considered. Radiation factor returned will be a cellular field of ones. This component is included because potential evaporanspiration (PET) component receives an input of radiation factor as a field.\n", - "- PET_PFT: Plant specific PET objects. PET is upper boundary to ET. For long-term simulations PET is represented using a cosine function as a function of day of year. Parameters of this function were obtained from P-M model application at a weather station. PET is spatially distributed by using the radiation factor.\n", - "- SM: Soil Moisture object simulates depth-averaged soil moisture at each cell using inputs of potential evapotranspiration, live leaf area index and vegetation cover.\n", - "- VEG: Vegetation dynamics object simulates net primary productivity, biomass and leaf area index (LAI) at each cell based on inputs of root-zone average soil moisture.\n", - "- vegca: Cellular Automaton plant competition object is run once every year. This object is initialized with a random cellular field of PFT. Every year, this object updates the cellular field of PFT based on probabilistic establishment and mortality of PFT at each cell.\n", - "\n", - "Note: Almost every component in landlab is coded as a 'class' (to harness the advantages of objective oriented programming). An 'object' is the instantiation of the 'class' (for more information, please refer any objective oriented programming book). A 'field' refers to a Landlab field (please refer to the [Landlab documentation](https://github.com/landlab/landlab/wiki/Grid#adding-data-to-a-landlab-grid-element-using-fields) to learn more about Landlab fields)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let's instantiate all Landlab components that we are going to use for this tutorial:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "PD_D, PD_W, Rad, PET_Tree, PET_Shrub, PET_Grass, SM, VEG, vegca = Initialize_(\n", - " data, grid, grid1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Lets look at the initial organization of PFTs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "from landlab.plot import imshow_grid\n", - "import matplotlib as mpl\n", - "cmap = mpl.colors.ListedColormap(\n", - " ['green', 'red', 'black', 'white', 'red', 'black'])\n", - "bounds = [-0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5]\n", - "norm = mpl.colors.BoundaryNorm(bounds, cmap.N)\n", - "description = 'green: grass; red: shrub; black: tree; white: bare'\n", - "plt.figure(101)\n", - "imshow_grid(grid1, 'vegetation__plant_functional_type', values_at='cell', cmap=cmap,\n", - " grid_units=('m', 'm'), norm=norm, limits=[0, 5],\n", - " allow_colorbar=False)\n", - "plt.figtext(0.2, 0.0, description,\n", - " weight='bold', fontsize=10)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Specify an approximate number of years for the model to run. For this example, we will run the simulation for 600 years. It might take less than 2+ minutes to run." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "n_years = 600 # Approx number of years for model to run\n", - "# Calculate approximate number of storms per year\n", - "fraction_wet = (data['doy__end_of_monsoon']-data['doy__start_of_monsoon'])/365.\n", - "fraction_dry = 1 - fraction_wet\n", - "no_of_storms_wet = (8760 * (fraction_wet)/(data['mean_interstorm_wet'] +\n", - " data['mean_storm_wet']))\n", - "no_of_storms_dry = (8760 * (fraction_dry)/(data['mean_interstorm_dry'] +\n", - " data['mean_storm_dry']))\n", - "n = int(n_years * (no_of_storms_wet + no_of_storms_dry))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Create empty arrays to store spatio-temporal data over multiple iterations. The captured data can be used for plotting model outputs." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "P, Tb, Tr, Time, VegType, PET_, Rad_Factor, EP30, PET_threshold = Empty_arrays(\n", - " n, grid, grid1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To reduce computational overhead, we shall create a lookup array for plant-specific PET values for each day of the year." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "Create_PET_lookup(Rad, PET_Tree, PET_Shrub, PET_Grass, PET_, Rad_Factor,\n", - " EP30, grid)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Specify current_time (in years). current_time is the current time in the simulation." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# # Represent current time in years\n", - "current_time = 0 # Start from first day of Jan\n", - "\n", - "# Keep track of run time for simulation - optional\n", - "Start_time = time.clock() # Recording time taken for simulation\n", - "\n", - "# declaring few variables that will be used in the storm loop\n", - "time_check = 0. # Buffer to store current_time at previous storm\n", - "yrs = 0 # Keep track of number of years passed\n", - "WS = 0. # Buffer for Water Stress\n", - "Tg = 270 # Growing season in days" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The loop below couples the components introduced above in a for loop until all \"n\" number of storms are generated. Time is advanced by the soil moisture object based on storm and interstorm durations that are estimated by the strom generator object. The ecohydrologic model is run each storm whereas cellular automaton vegetation component is run once every year.\n", - "\n", - "Note: This loop might take less than 2 minutes (depending on your computer) to run for 600 year simulation. Ignore any warnings you might see." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# # Run storm Loop\n", - "for i in range(0, n):\n", - " # Update objects\n", - "\n", - " # Calculate Day of Year (DOY)\n", - " Julian = np.int(np.floor((current_time - np.floor(current_time)) * 365.))\n", - "\n", - " # Generate seasonal storms\n", - " # for Dry season\n", - " if Julian < data['doy__start_of_monsoon'] or Julian > data[\n", - " 'doy__end_of_monsoon']:\n", - " PD_D.update()\n", - " P[i] = PD_D.storm_depth\n", - " Tr[i] = PD_D.storm_duration\n", - " Tb[i] = PD_D.interstorm_duration\n", - " # Wet Season - Jul to Sep - NA Monsoon\n", - " else:\n", - " PD_W.update()\n", - " P[i] = PD_W.storm_depth\n", - " Tr[i] = PD_W.storm_duration\n", - " Tb[i] = PD_W.interstorm_duration\n", - "\n", - " # Spatially distribute PET and its 30-day-mean (analogous to degree day)\n", - " grid['cell']['surface__potential_evapotranspiration_rate'] = PET_[Julian]\n", - " grid['cell']['surface__potential_evapotranspiration_30day_mean'] = EP30[\n", - " Julian]\n", - "\n", - " # Assign spatial rainfall data\n", - " grid['cell']['rainfall__daily_depth'] = P[i] * np.ones(grid.number_of_cells)\n", - "\n", - " # Update soil moisture component\n", - " current_time = SM.update(current_time, Tr=Tr[i], Tb=Tb[i])\n", - "\n", - " # Decide whether its growing season or not\n", - " if Julian != 364:\n", - " if EP30[Julian+1, 0] > EP30[Julian, 0]:\n", - " PET_threshold = 1\n", - " # 1 corresponds to ETThresholdup (begin growing season)\n", - " else:\n", - " PET_threshold = 0\n", - " # 0 corresponds to ETThresholddown (end growing season)\n", - "\n", - " # Update vegetation component\n", - " VEG.update(PETThreshold_switch=PET_threshold, Tb=Tb[i], Tr=Tr[i])\n", - "\n", - " # Update yearly cumulative water stress data\n", - " WS += (grid['cell']['vegetation__water_stress'])*Tb[i]/24.\n", - "\n", - " # Record time (optional)\n", - " Time[i] = current_time\n", - "\n", - " # Update spatial PFTs with Cellular Automata rules\n", - " if (current_time - time_check) >= 1.:\n", - " if yrs % 100 == 0:\n", - " print 'Elapsed time = ', yrs, ' years'\n", - " VegType[yrs] = grid1['cell']['vegetation__plant_functional_type']\n", - " WS_ = np.choose(VegType[yrs], WS)\n", - " grid1['cell']['vegetation__cumulative_water_stress'] = WS_/Tg\n", - " vegca.update()\n", - " time_check = current_time\n", - " WS = 0\n", - " yrs += 1\n", - "\n", - "VegType[yrs] = grid1['cell']['vegetation__plant_functional_type']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Time_Consumed is an optional variable that gives information about computer running time" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "Final_time = time.clock()\n", - "Time_Consumed = (Final_time - Start_time)/60. # in minutes\n", - "print 'Time_consumed = ', Time_Consumed, ' minutes'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Save the outputs using ``numpy.save()``. These files have '.nc' extension, which can be loaded using ``numpy.load()``." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# # Saving\n", - "sim = 'Sim_26Jul16_'\n", - "#Save_(sim, Tb, Tr, P, VegType, yrs, Time_Consumed, Time)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's look at outputs.\n", - "\n", - "Plots of the cellular field of PFT at specified year step can be found below where:\n", - "\n", - "GRASS = green; SHRUB = red; TREE = black; BARE = white; \n", - "\n", - "At the end, percentage cover of each PFT is plotted with respect to time." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "Plot_(grid1, VegType, yrs, yr_step=100)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": false - }, - "source": [ - "If you want to explore this model further, open 'Inputs_Vegetation_CA.txt' and change the input parameters (e.g., initial PFT distribution percentages, storm characteristics, etc..)." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": true - }, - "source": [ - "### Click here for more Landlab tutorials" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.11" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} From fe82461a90661c1b68454bed3471a579c95b8273 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sun, 9 Apr 2017 21:58:15 -0600 Subject: [PATCH 35/52] Use print function. --- .../cellular_automaton_vegetation_DEM.ipynb | 59 +++++++++---------- ...lar_automaton_vegetation_flat_domain.ipynb | 59 +++++++++---------- 2 files changed, 58 insertions(+), 60 deletions(-) diff --git a/ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM.ipynb b/ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM.ipynb index 010a1de..dc3ba0d 100644 --- a/ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM.ipynb +++ b/ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM.ipynb @@ -80,10 +80,20 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": true }, + "outputs": [], + "source": [ + "from __future__ import print_function\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, "outputs": [ { "name": "stderr", @@ -99,7 +109,6 @@ } ], "source": [ - "%matplotlib inline\n", "import time\n", "import numpy as np\n", "from landlab.io import read_esri_ascii\n", @@ -132,7 +141,7 @@ "cell_type": "code", "execution_count": 2, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -151,7 +160,7 @@ "cell_type": "code", "execution_count": 3, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -187,7 +196,7 @@ "cell_type": "code", "execution_count": 4, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -205,9 +214,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -261,7 +268,7 @@ "cell_type": "code", "execution_count": 6, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -287,7 +294,7 @@ "cell_type": "code", "execution_count": 7, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -306,7 +313,7 @@ "cell_type": "code", "execution_count": 8, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -325,7 +332,7 @@ "cell_type": "code", "execution_count": 9, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -354,9 +361,7 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -445,7 +450,7 @@ " # Cellular Automata\n", " if (current_time - time_check) >= 1.:\n", " if yrs % 5 == 0:\n", - " print 'Elapsed time = ', yrs, ' years'\n", + " print('Elapsed time = {time} years'.format(time=yrs))\n", " VegType[yrs] = grid['cell']['vegetation__plant_functional_type']\n", " grid['cell']['vegetation__cumulative_water_stress'] = WS/Tg\n", " vegca.update()\n", @@ -467,9 +472,7 @@ { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -482,7 +485,7 @@ "source": [ "Final_time = time.clock()\n", "Time_Consumed = (Final_time - Start_time)/60. # in minutes\n", - "print 'Time_consumed = ', Time_Consumed, ' minutes'" + "print('Time_consumed = {time} minutes'.format(time=Time_Consumed))" ] }, { @@ -496,7 +499,7 @@ "cell_type": "code", "execution_count": 12, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -521,9 +524,7 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -608,9 +609,7 @@ { "cell_type": "code", "execution_count": 14, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -660,9 +659,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.13" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } diff --git a/ecohydrology/cellular_automaton_vegetation_flat_surface/cellular_automaton_vegetation_flat_domain.ipynb b/ecohydrology/cellular_automaton_vegetation_flat_surface/cellular_automaton_vegetation_flat_domain.ipynb index 93b0f6b..8bf24b0 100644 --- a/ecohydrology/cellular_automaton_vegetation_flat_surface/cellular_automaton_vegetation_flat_domain.ipynb +++ b/ecohydrology/cellular_automaton_vegetation_flat_surface/cellular_automaton_vegetation_flat_domain.ipynb @@ -80,10 +80,20 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": true }, + "outputs": [], + "source": [ + "from __future__ import print_function\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, "outputs": [ { "name": "stderr", @@ -99,7 +109,6 @@ } ], "source": [ - "%matplotlib inline\n", "import time\n", "import numpy as np\n", "from landlab import RasterModelGrid as rmg\n", @@ -131,7 +140,7 @@ "cell_type": "code", "execution_count": 2, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -150,7 +159,7 @@ "cell_type": "code", "execution_count": 3, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -185,7 +194,7 @@ "cell_type": "code", "execution_count": 4, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -203,9 +212,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "data": { @@ -256,7 +263,7 @@ "cell_type": "code", "execution_count": 6, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -282,7 +289,7 @@ "cell_type": "code", "execution_count": 7, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -301,7 +308,7 @@ "cell_type": "code", "execution_count": 8, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -320,7 +327,7 @@ "cell_type": "code", "execution_count": 9, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -349,9 +356,7 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -435,7 +440,7 @@ " # Update spatial PFTs with Cellular Automata rules\n", " if (current_time - time_check) >= 1.:\n", " if yrs % 100 == 0:\n", - " print 'Elapsed time = ', yrs, ' years'\n", + " print('Elapsed time = {time} years'.format(time=yrs))\n", " VegType[yrs] = grid1['cell']['vegetation__plant_functional_type']\n", " WS_ = np.choose(VegType[yrs], WS)\n", " grid1['cell']['vegetation__cumulative_water_stress'] = WS_/Tg\n", @@ -457,9 +462,7 @@ { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -472,7 +475,7 @@ "source": [ "Final_time = time.clock()\n", "Time_Consumed = (Final_time - Start_time)/60. # in minutes\n", - "print 'Time_consumed = ', Time_Consumed, ' minutes'" + "print('Time_consumed = {time} minutes'.format(time=Time_Consumed))" ] }, { @@ -486,7 +489,7 @@ "cell_type": "code", "execution_count": 12, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -511,9 +514,7 @@ { "cell_type": "code", "execution_count": 13, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -600,9 +601,7 @@ }, { "cell_type": "markdown", - "metadata": { - "collapsed": false - }, + "metadata": {}, "source": [ "If you want to explore this model further, open 'Inputs_Vegetation_CA.txt' and change the input parameters (e.g., initial PFT distribution percentages, storm characteristics, etc..)." ] @@ -633,9 +632,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.13" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } From 6f45664938b720a5c9fb5ace05f6a12158dd9ad3 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sun, 9 Apr 2017 22:13:17 -0600 Subject: [PATCH 36/52] Use print function. --- .../Ecohyd_functions_DEM.py | 6 +++--- .../Ecohyd_functions_flat.py | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ecohydrology/cellular_automaton_vegetation_DEM/Ecohyd_functions_DEM.py b/ecohydrology/cellular_automaton_vegetation_DEM/Ecohyd_functions_DEM.py index 3e0970d..43cb346 100644 --- a/ecohydrology/cellular_automaton_vegetation_DEM/Ecohyd_functions_DEM.py +++ b/ecohydrology/cellular_automaton_vegetation_DEM/Ecohyd_functions_DEM.py @@ -1,4 +1,4 @@ - +from __future__ import print_function # Authors: Sai Nudurupati & Erkan Istanbulluoglu, 21May15 # Edited: 15Jul16 - to conform to Landlab version 1. import numpy as np @@ -159,8 +159,8 @@ def Plot_(grid, VegType, yrs, yr_step=10): ['green', 'red', 'black', 'white', 'red', 'black']) bounds = [-0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5] norm = mpl.colors.BoundaryNorm(bounds, cmap.N) - print 'Plotting cellular field of Plant Functional Type' - print 'Green - Grass; Red - Shrubs; Black - Trees; White - Bare' + print('Plotting cellular field of Plant Functional Type') + print('Green - Grass; Red - Shrubs; Black - Trees; White - Bare') # # Plot images to make gif. for year in range(0, yrs, yr_step): filename = 'Year = ' + "%05d" % year diff --git a/ecohydrology/cellular_automaton_vegetation_flat_surface/Ecohyd_functions_flat.py b/ecohydrology/cellular_automaton_vegetation_flat_surface/Ecohyd_functions_flat.py index c5650d3..4f7f7e4 100644 --- a/ecohydrology/cellular_automaton_vegetation_flat_surface/Ecohyd_functions_flat.py +++ b/ecohydrology/cellular_automaton_vegetation_flat_surface/Ecohyd_functions_flat.py @@ -1,3 +1,4 @@ +from __future__ import print_function # Authors: Sai Nudurupati & Erkan Istanbulluoglu, 21May15 # Edited: 15Jul16 - to conform to Landlab version 1. @@ -159,8 +160,8 @@ def Plot_(grid, VegType, yrs, yr_step=10): ['green', 'red', 'black', 'white', 'red', 'black']) bounds = [-0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5] norm = mpl.colors.BoundaryNorm(bounds, cmap.N) - print 'Plotting cellular field of Plant Functional Type' - print 'Green - Grass; Red - Shrubs; Black - Trees; White - Bare' + print('Plotting cellular field of Plant Functional Type') + print('Green - Grass; Red - Shrubs; Black - Trees; White - Bare') # # Plot images to make gif. for year in range(0, yrs, yr_step): filename = 'Year = ' + "%05d" % year From 3f3841310ebb9de93378b0978e09ed327b947026 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sun, 9 Apr 2017 22:14:01 -0600 Subject: [PATCH 37/52] Remove pyc files. --- .../Ecohyd_functions_DEM.pyc | Bin 6863 -> 0 bytes .../Ecohyd_functions_flat.pyc | Bin 6804 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 ecohydrology/cellular_automaton_vegetation_DEM/Ecohyd_functions_DEM.pyc delete mode 100644 ecohydrology/cellular_automaton_vegetation_flat_surface/Ecohyd_functions_flat.pyc diff --git a/ecohydrology/cellular_automaton_vegetation_DEM/Ecohyd_functions_DEM.pyc b/ecohydrology/cellular_automaton_vegetation_DEM/Ecohyd_functions_DEM.pyc deleted file mode 100644 index e959c94493b707871fe1911270a1bf30650b22e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6863 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 Pf@7#~qj0V;Ss3^)+QMdz diff --git a/ecohydrology/cellular_automaton_vegetation_flat_surface/Ecohyd_functions_flat.pyc b/ecohydrology/cellular_automaton_vegetation_flat_surface/Ecohyd_functions_flat.pyc deleted file mode 100644 index 21c278d2193de4f796562e2603fcb6b5770873eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6804 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 From b82c995e67a679fe824a0f1271cb2c25327b554f Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sun, 9 Apr 2017 22:41:06 -0600 Subject: [PATCH 38/52] Fix bug when notebook doesn't have a dir part. --- run_notebook.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/run_notebook.py b/run_notebook.py index ac5d1ed..2e8cf7c 100755 --- a/run_notebook.py +++ b/run_notebook.py @@ -31,7 +31,7 @@ def convert_notebook(notebook): def run_notebook(notebook): - with cd(os.path.dirname(notebook)): + with cd(os.path.dirname(notebook) or '.'): script = convert_notebook(os.path.basename(notebook)) _, script_file = tempfile.mkstemp(prefix='.', suffix='.py', dir='.') with open(script_file, 'wb') as fp: @@ -117,7 +117,7 @@ def main(): import argparse parser = argparse.ArgumentParser( description='Run Jupyter notebooks.') - parser.add_argument('notebook', type=str, nargs='*', + parser.add_argument('notebook', type=str, nargs='*', default=[], help='Notebook to test.') parser.add_argument('--skip', type=str, action='append', default=[], help='Notebooks to skip.') @@ -129,6 +129,7 @@ def main(): args = parser.parse_args() notebooks = read_notebooks_from_file(args.file) + args.notebook + skip = match_by_pattern(notebooks, args.skip) summary = [] From 98d01cc6c028ffb758b80efeb1d36cb2c0651790 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sun, 9 Apr 2017 22:48:16 -0600 Subject: [PATCH 39/52] Use load_params function to read input. --- .../cellular_automaton_vegetation_DEM.ipynb | 5 +++-- .../cellular_automaton_vegetation_flat_domain.ipynb | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM.ipynb b/ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM.ipynb index dc3ba0d..93f5b91 100644 --- a/ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM.ipynb +++ b/ecohydrology/cellular_automaton_vegetation_DEM/cellular_automaton_vegetation_DEM.ipynb @@ -113,7 +113,8 @@ "import numpy as np\n", "from landlab.io import read_esri_ascii\n", "from landlab import RasterModelGrid as rmg\n", - "from Ecohyd_functions_DEM import (txt_data_dict, Initialize_, Empty_arrays,\n", + "from landlab import load_params\n", + "from Ecohyd_functions_DEM import (Initialize_, Empty_arrays,\n", " Create_PET_lookup, Save_, Plot_)" ] }, @@ -165,7 +166,7 @@ "outputs": [], "source": [ "InputFile = 'Inputs_Vegetation_CA_DEM.txt'\n", - "data = txt_data_dict(InputFile) # Creates dictionary that holds the inputs" + "data = load_params(InputFile) # Creates dictionary that holds the inputs" ] }, { diff --git a/ecohydrology/cellular_automaton_vegetation_flat_surface/cellular_automaton_vegetation_flat_domain.ipynb b/ecohydrology/cellular_automaton_vegetation_flat_surface/cellular_automaton_vegetation_flat_domain.ipynb index 8bf24b0..1450dae 100644 --- a/ecohydrology/cellular_automaton_vegetation_flat_surface/cellular_automaton_vegetation_flat_domain.ipynb +++ b/ecohydrology/cellular_automaton_vegetation_flat_surface/cellular_automaton_vegetation_flat_domain.ipynb @@ -112,7 +112,8 @@ "import time\n", "import numpy as np\n", "from landlab import RasterModelGrid as rmg\n", - "from Ecohyd_functions_flat import (txt_data_dict, Initialize_, Empty_arrays,\n", + "from landlab import load_params\n", + "from Ecohyd_functions_flat import (Initialize_, Empty_arrays,\n", " Create_PET_lookup, Save_, Plot_)" ] }, @@ -164,7 +165,7 @@ "outputs": [], "source": [ "InputFile = 'Inputs_Vegetation_CA_flat.txt'\n", - "data = txt_data_dict(InputFile) # Create dictionary that holds the inputs" + "data = load_params(InputFile) # Create dictionary that holds the inputs" ] }, { From 714c8156fdf4091627be1830a768337d6a1a8553 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 10 Apr 2017 07:56:51 -0600 Subject: [PATCH 40/52] Change name of skip option to exclude. --- run_notebook.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/run_notebook.py b/run_notebook.py index 2e8cf7c..b48281c 100755 --- a/run_notebook.py +++ b/run_notebook.py @@ -119,22 +119,23 @@ def main(): description='Run Jupyter notebooks.') parser.add_argument('notebook', type=str, nargs='*', default=[], help='Notebook to test.') - parser.add_argument('--skip', type=str, action='append', default=[], - help='Notebooks to skip.') + parser.add_argument('-e', '--exclude', metavar='PATTERN', type=str, + action='append', default=[], + help='Notebooks to exclude.') parser.add_argument('--dry-run', action='store_true', help='Find notebooks but do not do anything') - parser.add_argument('--file', type=argparse.FileType('r'), + parser.add_argument('-f', '--file', type=argparse.FileType('r'), help='Read notebooks from a file.') args = parser.parse_args() notebooks = read_notebooks_from_file(args.file) + args.notebook - skip = match_by_pattern(notebooks, args.skip) + excluded = match_by_pattern(notebooks, args.exclude) summary = [] for notebook in notebooks: - if notebook in skip: + if notebook in excluded: result = notebook, None else: result = notebook, check_notebook(notebook, dry_run=args.dry_run) From 62ec2eb16ff71dec8b5eb5e5a31faf34fc29c135 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 10 Apr 2017 08:02:33 -0600 Subject: [PATCH 41/52] Remove unused ci files. --- .ci/header.txt | 3 -- .ci/notebook_to_script.py | 19 ----------- .ci/run_tutorials.py | 66 ------------------------------------ .ci/travis/install_python.sh | 18 ---------- 4 files changed, 106 deletions(-) delete mode 100644 .ci/header.txt delete mode 100644 .ci/notebook_to_script.py delete mode 100644 .ci/run_tutorials.py delete mode 100644 .ci/travis/install_python.sh diff --git a/.ci/header.txt b/.ci/header.txt deleted file mode 100644 index 4de25b5..0000000 --- a/.ci/header.txt +++ /dev/null @@ -1,3 +0,0 @@ -import matplotlib -matplotlib.use('Agg') - diff --git a/.ci/notebook_to_script.py b/.ci/notebook_to_script.py deleted file mode 100644 index 7d4578b..0000000 --- a/.ci/notebook_to_script.py +++ /dev/null @@ -1,19 +0,0 @@ -import argparse -import json - - - -def extract_code(file_like): - cells = json.load(file_like) - for cell in cells: - - -def main(): - parser = argparse.ArgumentParser( - 'Extract commands from an iPython notebook.') - parser.add_argument('NOTEBOOK', type=argparse.FileType('r'), - help='An iPython notebook.') - - parser.parse_args() - - diff --git a/.ci/run_tutorials.py b/.ci/run_tutorials.py deleted file mode 100644 index 774a739..0000000 --- a/.ci/run_tutorials.py +++ /dev/null @@ -1,66 +0,0 @@ -from __future__ import print_function - -import os -import sys -import importlib -import subprocess -from glob import glob -import collections - - -THIS_DIR = os.path.abspath(os.path.dirname(__file__)) - - -def find_tutorials(basedir): - return glob(os.path.join(basedir, '**/*.py')) - - -def run_tutorials(paths): - status = collections.defaultdict(list) - for path in paths: - try: - print('{name}: running tutorial'.format(name=path)) - run_tutorial(path) - except subprocess.CalledProcessError: - print('{name}: unable to successfully run tutorial'.format( - name=path)) - status['fail'].append(path) - else: - status['pass'].append(path) - print('{name}: success'.format(name=path)) - - return status - - -def run_tutorial(path): - here = os.path.abspath(os.getcwd()) - - (dirname, script) = os.path.split(path) - os.chdir(dirname) - - header = os.path.join(THIS_DIR, 'header.txt') - - cat = ['cat', header, script] - try: - proc = subprocess.Popen(cat, stdout=subprocess.PIPE) - with open('stdout.out', 'w') as fp: - subprocess.check_call(['python'], stdin=proc.stdout, stdout=fp) - except subprocess.CalledProcessError: - raise - finally: - os.chdir(here) - - -def main(): - errors = run_tutorials(find_tutorials('.')) - - try: - print(errors['fail']) - except KeyError: - sys.exit(0) - else: - sys.exit(-1) - - -if __name__ == '__main__': - main() diff --git a/.ci/travis/install_python.sh b/.ci/travis/install_python.sh deleted file mode 100644 index f52eb53..0000000 --- a/.ci/travis/install_python.sh +++ /dev/null @@ -1,18 +0,0 @@ -#! /bin/bash - -if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - OS="MacOSX-x86_64"; -else - OS="Linux-x86_64"; -fi -if [[ "$TRAVIS_PYTHON_VERSION" == 2.* ]]; then - wget http://repo.continuum.io/miniconda/Miniconda-latest-$OS.sh -O miniconda.sh; -else - wget http://repo.continuum.io/miniconda/Miniconda3-latest-$OS.sh -O miniconda.sh; -fi -bash miniconda.sh -b -p $HOME/miniconda -export PATH="$HOME/miniconda/bin:$PATH" -hash -r -conda config --set always_yes yes --set changeps1 no -conda info -a -conda install python=$TRAVIS_PYTHON_VERSION From 481c613ff63175af5930df6fab4fb13ac73c31a9 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 10 Apr 2017 08:06:26 -0600 Subject: [PATCH 42/52] Use --exclude option. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b9e3dd0..27bf7ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,6 @@ install: - conda install landlab jupyter -c landlab - conda info -a && conda list script: -- ./find_notebooks.py . | ./run_notebook.py --file=- --skip=*intro* --skip=*flow_direction* +- ./find_notebooks.py . | ./run_notebook.py --file=- --exclude=*intro* --exlude=*flow_direction* virtualenv: system_site_packages: false From c527c1b8ff0d7fa30ef1e688e7f04c7934410612 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 10 Apr 2017 08:41:44 -0600 Subject: [PATCH 43/52] Combine scripts. --- find_notebooks.py | 53 ------------------------------- run_notebook.py | 79 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 68 deletions(-) delete mode 100755 find_notebooks.py diff --git a/find_notebooks.py b/find_notebooks.py deleted file mode 100755 index 6807311..0000000 --- a/find_notebooks.py +++ /dev/null @@ -1,53 +0,0 @@ -#! /usr/bin/env python -from __future__ import print_function - -import os -from six.moves import shlex_quote - - -def find_notebooks(base): - """Find Jupyter notebooks. - - Parameters - ---------- - base : str - Path to search for notebooks under. - - Returns - ------- - list of str - Paths to discovered notebooks. - """ - notebooks = [] - for root, dirs, files in os.walk(base, topdown=True): - for dir in dirs: - if dir.startswith('.'): - dirs.remove(dir) - for fname in files: - file_path = os.path.join(root, fname) - if file_path.endswith('.ipynb'): - notebooks.append(file_path) - return notebooks - - -def main(): - import argparse - parser = argparse.ArgumentParser( - description='Find Jupyter notebooks under a given base path') - parser.add_argument('path', help='Path to search for notebooks.') - parser.add_argument('--sort', action='store_true', - help='Sort notebooks alphabetically.') - - args = parser.parse_args() - - notebooks = find_notebooks(args.path) - - if args.sort: - notebooks.sort() - - # print(os.linesep.join([shlex_quote(nb) for nb in notebooks])) - print(os.linesep.join([nb for nb in notebooks])) - - -if __name__ == '__main__': - main() diff --git a/run_notebook.py b/run_notebook.py index b48281c..d5eb1ab 100755 --- a/run_notebook.py +++ b/run_notebook.py @@ -9,7 +9,7 @@ import re from fnmatch import fnmatch -import six +from six.moves import shlex_quote from scripting.unix import system, check_output from scripting.contexts import cd @@ -113,22 +113,41 @@ def read_notebooks_from_file(file_like): return [] -def main(): - import argparse - parser = argparse.ArgumentParser( - description='Run Jupyter notebooks.') - parser.add_argument('notebook', type=str, nargs='*', default=[], - help='Notebook to test.') - parser.add_argument('-e', '--exclude', metavar='PATTERN', type=str, - action='append', default=[], - help='Notebooks to exclude.') - parser.add_argument('--dry-run', action='store_true', - help='Find notebooks but do not do anything') - parser.add_argument('-f', '--file', type=argparse.FileType('r'), - help='Read notebooks from a file.') +def find_notebooks(base): + """Find Jupyter notebooks. + + Parameters + ---------- + base : str + Path to search for notebooks under. + + Returns + ------- + list of str + Paths to discovered notebooks. + """ + notebooks = [] + for root, dirs, files in os.walk(base, topdown=True): + for dir in dirs: + if dir.startswith('.'): + dirs.remove(dir) + for fname in files: + file_path = os.path.join(root, fname) + if file_path.endswith('.ipynb'): + notebooks.append(file_path) + return notebooks - args = parser.parse_args() +def find_command(args): + notebooks = find_notebooks(args.path) + + if args.sort: + notebooks.sort() + + print(os.linesep.join([nb for nb in notebooks])) + + +def run_command(args): notebooks = read_notebooks_from_file(args.file) + args.notebook excluded = match_by_pattern(notebooks, args.exclude) @@ -146,5 +165,35 @@ def main(): return print_success_or_failure(summary) +def main(): + import argparse + parser = argparse.ArgumentParser(description='Run Jupyter notebooks.') + + subparsers = parser.add_subparsers(title='subcommands', + description='valid subcommands', + help='additional help') + + parser_find = subparsers.add_parser('find', help='Find notebooks.') + parser_find.set_defaults(func=find_command) + parser_find.add_argument('path', help='Path to search for notebooks.') + parser_find.add_argument('--sort', action='store_true', + help='Sort notebooks alphabetically.') + + parser_run = subparsers.add_parser('run', help='Run notebooks.') + parser_run.set_defaults(func=run_command) + parser_run.add_argument('notebook', type=str, nargs='*', default=[], + help='Notebook to test.') + parser_run.add_argument('-e', '--exclude', metavar='PATTERN', type=str, + action='append', default=[], + help='Notebooks to exclude.') + parser_run.add_argument('--dry-run', action='store_true', + help='Find notebooks but do not do anything') + parser_run.add_argument('-f', '--file', type=argparse.FileType('r'), + help='Read notebooks from a file.') + + args = parser.parse_args() + args.func(args) + + if __name__ == '__main__': sys.exit(main()) From 6170d65382c74aae9812184e2491ed8fe842c874 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 10 Apr 2017 08:48:18 -0600 Subject: [PATCH 44/52] Add script to find and run all tests. --- .travis.yml | 2 +- run-all-tests.sh | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100755 run-all-tests.sh diff --git a/.travis.yml b/.travis.yml index 27bf7ee..cd228d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,6 @@ install: - conda install landlab jupyter -c landlab - conda info -a && conda list script: -- ./find_notebooks.py . | ./run_notebook.py --file=- --exclude=*intro* --exlude=*flow_direction* +- ./run-all-tests.sh virtualenv: system_site_packages: false diff --git a/run-all-tests.sh b/run-all-tests.sh new file mode 100755 index 0000000..73c498e --- /dev/null +++ b/run-all-tests.sh @@ -0,0 +1,5 @@ +#! /bin/bash + +EXCLUDES="--exclude=*intro* --exclude=*flow_direction*" + +./run_notebook.py find . | ./run_notebook.py run --file=- $EXCLUDES From 58d31d52aebe7aa135fa2d58b6d9cd23f6ce0305 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 10 Apr 2017 15:28:32 -0600 Subject: [PATCH 45/52] Set backend to Agg in matplotlibrc; Build on linux. --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cd228d3..e5bed1e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,9 @@ env: global: - CONDA_PREFIX=$HOME/miniconda - MINICONDA_URL_BASE="https://repo.continuum.io/miniconda/Miniconda3-latest" + - MPLCONFIGDIR=$HOME/.config/matplotlib os: - # - linux +- linux - osx sudo: false before_install: @@ -35,6 +36,7 @@ install: - conda install landlab jupyter -c landlab - conda info -a && conda list script: +- mkdir -p $MPLCONFIGDIR && echo "backend: Agg" > $MPLCONFIGDIR/matplotlibrc - ./run-all-tests.sh virtualenv: system_site_packages: false From 0dda346704990c9b4c0089237d79de15bcee1aa3 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 10 Apr 2017 15:34:47 -0600 Subject: [PATCH 46/52] Comment out matplotlib magic. --- run_notebook.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run_notebook.py b/run_notebook.py index d5eb1ab..d1f6b8e 100755 --- a/run_notebook.py +++ b/run_notebook.py @@ -22,7 +22,7 @@ def convert_notebook(notebook): p = re.compile(b"^get_ipython\(\)\.magic\(u?'matplotlib (?P\w+)'\)", re.MULTILINE) - script = p.sub(b"get_ipython().magic(u'matplotlib auto')", script) + script = p.sub(b"# get_ipython().magic(u'matplotlib auto')", script) p = re.compile(b"(?P^get_ipython\(\)\.magic\(u'pinfo[\w\s]+'\))", re.MULTILINE) script = p.sub(b"# \\1", script) From dcb623db3783581b8d3aad7c5d29a238e067c0bf Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 10 Apr 2017 15:39:23 -0600 Subject: [PATCH 47/52] Make MPLCONFIGDIR then create matplotlibrc. --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e5bed1e..e575a34 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,7 +36,8 @@ install: - conda install landlab jupyter -c landlab - conda info -a && conda list script: -- mkdir -p $MPLCONFIGDIR && echo "backend: Agg" > $MPLCONFIGDIR/matplotlibrc +- mkdir -p $MPLCONFIGDIR +- echo "backend: Agg" > $MPLCONFIGDIR/matplotlibrc - ./run-all-tests.sh virtualenv: system_site_packages: false From e3d8160724ae22226ac5b9afe6edb7705de4b433 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 10 Apr 2017 15:50:00 -0600 Subject: [PATCH 48/52] Quote line that contains a colon. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e575a34..80d2083 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,7 +37,7 @@ install: - conda info -a && conda list script: - mkdir -p $MPLCONFIGDIR -- echo "backend: Agg" > $MPLCONFIGDIR/matplotlibrc +- "echo backend: Agg > $MPLCONFIGDIR/matplotlibrc" - ./run-all-tests.sh virtualenv: system_site_packages: false From cdabc916271ccf410833ccec9c10353a4c86066c Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 10 Apr 2017 16:01:50 -0600 Subject: [PATCH 49/52] Track png files. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 83f22a5..88b1161 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,4 @@ .DS_Store *.out -*.png *.pyc From 35485155d1ed56c093ca6106c5ae74ec72abef6f Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 10 Apr 2017 22:04:07 -0600 Subject: [PATCH 50/52] Add build for Python 3.6. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 80d2083..6573a7b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ env: matrix: - TRAVIS_PYTHON_VERSION="2.7" - - TRAVIS_PYTHON_VERSION="3.4" - TRAVIS_PYTHON_VERSION="3.5" + - TRAVIS_PYTHON_VERSION="3.6" global: - CONDA_PREFIX=$HOME/miniconda - MINICONDA_URL_BASE="https://repo.continuum.io/miniconda/Miniconda3-latest" From a4d8429fc436b3a29c3d05bd6ec006fba5d248ce Mon Sep 17 00:00:00 2001 From: mcflugen Date: Tue, 11 Apr 2017 15:19:34 -0600 Subject: [PATCH 51/52] Remove unexpanded notebook. --- .../landlab-fault-scarp-unexpanded.ipynb | 397 ------------------ 1 file changed, 397 deletions(-) delete mode 100644 fault_scarp/landlab-fault-scarp-unexpanded.ipynb diff --git a/fault_scarp/landlab-fault-scarp-unexpanded.ipynb b/fault_scarp/landlab-fault-scarp-unexpanded.ipynb deleted file mode 100644 index 6cdc89f..0000000 --- a/fault_scarp/landlab-fault-scarp-unexpanded.ipynb +++ /dev/null @@ -1,397 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Creating a simple 2D scarp diffusion model with Landlab" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - " For instructions on how to run an interactive IPython notebook, click here: https://github.com/landlab/tutorials/blob/master/README.md
\n", - "For more Landlab tutorials, click here: https://github.com/landlab/landlab/wiki/Tutorials\n", - "
\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This tutorial illustrates how you can use Landlab to construct a simple two-dimensional numerical model on a regular (raster) grid, using a simple forward-time, centered-space numerical scheme. The example is the erosional degradation of an earthquake fault scarp, and which evolves over time in response to the gradual downhill motion of soil. Here we use a simple \"geomorphic diffusion\" model for landform evolution, in which the downhill flow of soil is assumed to be proportional to the (downhill) gradient of the land surface multiplied by a transport coefficient.\n", - "\n", - "We start by importing the *NumPy* library, which we'll use for some array calculations:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "import numpy" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We will create a grid for our model using Landlab's *RasterModelGrid* class, which we need to import." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from landlab import RasterModelGrid" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The syntax in the next line says: create a new *RasterModelGrid* object called **mg**, with 25 rows, 40 columns, and a grid spacing of 10 m." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "mg = RasterModelGrid((25, 40), 10.0)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we'll add a *data field* to the grid, to represent the elevation values at grid nodes. The \"dot\" syntax indicates that we are calling a function (or *method*) that belongs to the *RasterModelGrid* class, and will act on data contained in **mg**. The arguments indicate that we want the data elements attached to grid nodes (rather than links, for example), and that we want to name this data field `topographic__elevation`. The `add_zeros` method returns the newly created NumPy array." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "z = mg.add_zeros('node', 'topographic__elevation')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's take a look at the grid we've created. To do so, we'll use the Matplotlib graphics library (imported under the name `plt`). We also have to tell the iPython Notebook to display plots right here on the page." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's plot the positions of all the grid nodes. The nodes' *(x,y)* positions are stored in the arrays `mg.x_of_node` and `mg.y_of_node`, respectively." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "plt.plot(mg.x_of_node, mg.y_of_node, '.')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If we bothered to count, we'd see that there are 1000 grid nodes (25 x 40). The `z` array also has 1000 entries: one per grid cell." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "len(z)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now for some tectonics. Let's say there's a fault trace that angles roughly east-northeast. We can describe the trace with the equation for a line. One trick here: by using `mg.node_x`, we are calculating a *y* (i.e., north-south) position of the fault trace for each grid node---meaning that this is the *y* coordinate of the trace at the *x* coordinate of a given node." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "fault_trace_y = 50.0 + 0.25 * mg.x_of_node" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We find the ID numbers of the nodes north of the fault trace with help from Numpy's `where()` function." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "upthrown_nodes = numpy.where(mg.y_of_node > fault_trace_y)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here comes the earthquake. For all the nodes that we identified as being north of the fault, we'll add elevation equal to 10 meters plus a centimeter for every meter east along the grid (just to make it interesting)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "z[upthrown_nodes] += 10.0 + 0.01 * mg.x_of_node[upthrown_nodes]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's look at our newly created initial topography using Landlab's *imshow_node_grid* plotting function (which we first need to import)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "from landlab.plot.imshow import imshow_grid_at_node\n", - "imshow_grid_at_node(mg, 'topographic__elevation')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "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.)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "D = 0.01 # m2/yr transport coefficient\n", - "dt = 0.2 * mg.dx * mg.dx / D\n", - "dt" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "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)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "mg.set_closed_boundaries_at_grid_edges(True, False, True, False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "*A note on boundaries:* with a Landlab raster grid, all the perimeter nodes are boundary nodes. In this example, there are 24 + 24 + 39 + 39 = 126 boundary nodes. The previous line of code set those on the east and west edges to be **closed boundaries**, while those on the north and south are **open boundaries** (the default). All the remaining nodes are known as **core** nodes. In this example, there are 1000 - 126 = 874 core nodes:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "len(mg.core_nodes)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "One more thing before we run the time loop: we'll create an array to contain soil flux. In the function call below, the first argument tells Landlab that we want one value for each grid link, while the second argument provides a name for this data *field*:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "qs = mg.add_zeros('link', 'sediment_flux')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And now for some landform evolution. We will loop through 25 iterations, representing 50,000 years. On each pass through the loop, we do the following:\n", - "\n", - "1. Calculate, and store in the array `g`, the gradient between each neighboring pair of nodes. These calculations are done on **links**. The gradient value is a positive number when the gradient is \"uphill\" in the direction of the link, and negative when the gradient is \"downhill\" in the direction of the link. On a raster grid, link directions are always in the direction of increasing $x$ (\"horizontal\" links) or increasing $y$ (\"vertical\" links).\n", - "\n", - "2. Calculate, and store in the array `qs`, the sediment flux between each adjacent pair of nodes by multiplying their gradient by the transport coefficient. We will only do this for the **active links** (those not connected to a closed boundary, and not connecting two boundary nodes of any type); others will remain as zero.\n", - "\n", - "3. Calculate, and store in `dqsdx`, the resulting net flux at each node (positive=net outflux, negative=net influx).\n", - "\n", - "4. The rate of change of node elevation, `dzdt`, is simply `-dqsdx`.\n", - "\n", - "5. Update the elevations for the new time step." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "for i in range(25):\n", - " g = mg.calc_grad_at_link(z)\n", - " qs[mg.active_links] = -D * g[mg.active_links]\n", - " dqsdx = mg.calc_flux_div_at_node(qs)\n", - " dzdt = -dqsdx\n", - " z[mg.core_nodes] += dzdt[mg.core_nodes] * dt" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's look at how our fault scarp has evolved." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "imshow_grid_at_node(mg, 'topographic__elevation')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Notice that we have just created and run a 2D model of fault-scarp creation and diffusion with fewer than two dozen lines of code. How long would this have taken to write in C or Fortran?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Complete code can be found here: https://github.com/landlab/tutorials/blob/master/fault_scarp/landlab-fault-scarp.py" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Click here for more Landlab tutorials" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.11" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} From 9051417ad43472f342bab1f93dcc4a3049afbc99 Mon Sep 17 00:00:00 2001 From: Nicole M Gasparini Date: Tue, 11 Apr 2017 16:22:46 -0500 Subject: [PATCH 52/52] delete untitled.txt --- boundary_conds/untitled.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 boundary_conds/untitled.txt diff --git a/boundary_conds/untitled.txt b/boundary_conds/untitled.txt deleted file mode 100644 index e69de29..0000000