{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Setting Boundary Conditions on the Perimeter of a Raster.\n", "\n", "
\n", "For more Landlab tutorials, click here: https://landlab.readthedocs.io/en/latest/user_guide/tutorials.html\n", "
\n", "\n", "### This tutorial illustrates how to modify the boundary conditions along the perimeter of a rectangular raster." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from landlab import RasterModelGrid\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": null, "metadata": {}, "outputs": [], "source": [ "mg = RasterModelGrid((4, 4))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The node boundary condition options are:\n", "\n", "- mg.BC_NODE_IS_CORE (status value = 0; all operations are performed on a mg.BC_NODE_IS_CORE)\n", "- mg.BC_NODE_IS_FIXED_VALUE (status value = 1; a boundary node with a fixed value)\n", "- mg.BC_NODE_IS_FIXED_GRADIENT (status value = 2; a boundary node with a fixed gradient)\n", "- mg.BC_NODE_IS_LOOPED (status value = 3; a boundary node that is wrap-around)\n", "- mg.BC_NODE_IS_CLOSED (status value = 4; closed boundary, or no flux can cross this node, or more accurately, can cross the faces around the node)\n", "\n", "(Note that these options are designed for the convenience in writing Landlab applications, and are not \"automatically enforced\" in internal Landlab functions. For example, if you add two node fields together, as in `my_field1 + my_field2`, *all* values will be added, not just core nodes; to take advantage of boundary coding, you would use a syntax like `my_field1[grid.core_nodes] + my_field2[grid.core_nodes]`.)\n", "\n", "Check the status of boundaries immediately after instantiating the grid:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "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": null, "metadata": {}, "outputs": [], "source": [ "imshow_grid(mg, mg.status_at_node)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's choose one node on the perimeter to be closed. \n", "\n", "Note that `imshow_grid` by default does not illustrate values for closed nodes, so we override that below and show them in blue." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mg.status_at_node[2] = mg.BC_NODE_IS_CLOSED\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 `x_of_node` value is greater than some specified 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 mg.BC_NODE_IS_FIXED_VALUE by default.)\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, mg.BC_NODE_IS_CLOSED, or 4, which is the value for mg.BC_NODE_IS_CLOSED 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": null, "metadata": {}, "outputs": [], "source": [ "mg.set_status_at_node_on_edges(right=mg.BC_NODE_IS_CLOSED,\n", " top=mg.BC_NODE_IS_FIXED_VALUE,\n", " left=mg.BC_NODE_IS_CLOSED,\n", " bottom=mg.BC_NODE_IS_FIXED_VALUE)\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": null, "metadata": {}, "outputs": [], "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": {}, "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": null, "metadata": {}, "outputs": [], "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 mg.BC_NODE_IS_FIXED_VALUE (status value of 1). \n", "\n", "We can change those to closed if we want." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "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 mg.BC_NODE_IS_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 mg.BC_NODE_IS_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": null, "metadata": {}, "outputs": [], "source": [ "mg3 = RasterModelGrid((4, 4), 1.)\n", "mg3.status_at_node[mg3.y_of_node == 0] = mg.BC_NODE_IS_FIXED_GRADIENT\n", "mg3.status_at_node[mg3.y_of_node == 3] = mg.BC_NODE_IS_FIXED_GRADIENT\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 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.8.0" } }, "nbformat": 4, "nbformat_minor": 1 }