{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Coastline Evolution Model + Waves\n",
"\n",
"* Link to this notebook: https://github.com/csdms/pymt/blob/master/notebooks/cem_and_waves.ipynb\n",
"* Install command: `$ conda install notebook pymt_cem`\n",
"\n",
"This example explores how to use a BMI implementation to couple the Waves component with the Coastline Evolution Model component.\n",
"\n",
"### Links\n",
"* [CEM source code](https://github.com/csdms/cem-old): Look at the files that have *deltas* in their name.\n",
"* [CEM description on CSDMS](http://csdms.colorado.edu/wiki/Model_help:CEM): Detailed information on the CEM model."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Interacting with the Coastline Evolution Model BMI using Python"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some magic that allows us to view images within the notebook."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import numpy as np"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Import the `Cem` class, and instantiate it. In Python, a model with a BMI will have no arguments for its constructor. Note that although the class has been instantiated, it's not yet ready to be run. We'll get to that later!"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[33;01m➡ models: Cem, Waves\u001b[39;49;00m\n"
]
}
],
"source": [
"from pymt import models"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"cem, waves = models.Cem(), models.Waves()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Even though we can't run our waves model yet, we can still get some information about it. *Just don't try to run it.* Some things we can do with our model are get the names of the input variables."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"('sea_surface_water_wave__min_of_increment_of_azimuth_angle_of_opposite_of_phase_velocity',\n",
" 'sea_surface_water_wave__azimuth_angle_of_opposite_of_phase_velocity',\n",
" 'sea_surface_water_wave__mean_of_increment_of_azimuth_angle_of_opposite_of_phase_velocity',\n",
" 'sea_surface_water_wave__max_of_increment_of_azimuth_angle_of_opposite_of_phase_velocity',\n",
" 'sea_surface_water_wave__height',\n",
" 'sea_surface_water_wave__period')"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"waves.get_output_var_names()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"('sea_surface_water_wave__azimuth_angle_of_opposite_of_phase_velocity',\n",
" 'land_surface_water_sediment~bedload__mass_flow_rate',\n",
" 'sea_surface_water_wave__period',\n",
" 'sea_surface_water_wave__height',\n",
" 'land_surface__elevation',\n",
" 'model__time_step')"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cem.get_input_var_names()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can also get information about specific variables. Here we'll look at some info about wave direction. This is the main input of the Cem model. Notice that BMI components always use [CSDMS standard names](http://csdms.colorado.edu/wiki/CSDMS_Standard_Names). The CSDMS Standard Name for wave angle is,\n",
"\n",
" \"sea_surface_water_wave__azimuth_angle_of_opposite_of_phase_velocity\"\n",
"\n",
"Quite a mouthful, I know. With that name we can get information about that variable and the grid that it is on (it's actually not a one)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"OK. We're finally ready to run the model. Well not quite. First we initialize the model with the BMI **initialize** method. Normally we would pass it a string that represents the name of an input file. For this example we'll pass **None**, which tells Cem to use some defaults."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"args = cem.setup(number_of_rows=100, number_of_cols=200, grid_spacing=200.0)\n",
"cem.initialize(*args)\n",
"args = waves.setup()\n",
"waves.initialize(*args)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here I define a convenience function for plotting the water depth and making it look pretty. You don't need to worry too much about it's internals for this tutorial. It just saves us some typing later on."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def plot_coast(spacing, z):\n",
" import matplotlib.pyplot as plt\n",
"\n",
" xmin, xmax = 0.0, z.shape[1] * spacing[1] * 1e-3\n",
" ymin, ymax = 0.0, z.shape[0] * spacing[0] * 1e-3\n",
"\n",
" plt.imshow(z, extent=[xmin, xmax, ymin, ymax], origin=\"lower\", cmap=\"ocean\")\n",
" plt.colorbar().ax.set_ylabel(\"Water Depth (m)\")\n",
" plt.xlabel(\"Along shore (km)\")\n",
" plt.ylabel(\"Cross shore (km)\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It generates plots that look like this. We begin with a flat delta (green) and a linear coastline (y = 3 km). The bathymetry drops off linearly to the top of the domain."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"