diff --git a/README.rst b/README.rst index a07fdfbe..6a90a7a6 100644 --- a/README.rst +++ b/README.rst @@ -48,9 +48,11 @@ Executing the model We recommend you check out our `pyDeltaRCM in 10 minutes tutorial `_, which is part of our documentation. +Beyond that breif tutorial, we have a comprehensive `User Documentation `_ and `Developer Documentation `_ to check out. + Additional notes ################ -This model repository no longer includes support for the `Basic Model Interface (BMI) `_. -We have separated BMI support for pyDeltaRCM to another repository (`the BMI_pyDeltaRCM model `_). +This repository no longer includes the `Basic Model Interface (BMI) `_ wrapper to the DeltaRCM model. +*pyDeltaRCM* maintains BMI compatibility through another repository (`the BMI_pyDeltaRCM model `_). diff --git a/docs/source/_resources/joss/figures/figures.py b/docs/source/_resources/joss/figures/figures.py index 8e270fae..8c341ef5 100644 --- a/docs/source/_resources/joss/figures/figures.py +++ b/docs/source/_resources/joss/figures/figures.py @@ -62,7 +62,7 @@ nt = 4 ts = np.linspace(0, data['eta'].shape[0]-1, - num=nt, dtype=np.int) # linearly interpolate ts + num=nt, dtype=int) # linearly interpolate ts # make the timeseries plot fig, ax = plt.subplots(1, nt, figsize=(11, 2), dpi=300) diff --git a/docs/source/examples/simple_example.ipynb b/docs/source/examples/simple_example.ipynb new file mode 100644 index 00000000..51deffab --- /dev/null +++ b/docs/source/examples/simple_example.ipynb @@ -0,0 +1,173 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "70c593eb-e479-4b4c-ad52-2d578bfad177", + "metadata": { + "tags": [] + }, + "source": [ + "# Simple model run example\n", + "\n", + "This Jupyter Notebook shows how to configure and run a model simulation, and how to examine the model outputs.\n", + "\n", + "This document supplements the [10-minute tutorial](https://deltarcm.org/pyDeltaRCM/guides/10min.html) and [User Guide](https://deltarcm.org/pyDeltaRCM/guides/user_guide.html), but is not a complete guide to the model." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ac5919f8-0779-4ac1-b728-bb6c1361ef82", + "metadata": {}, + "outputs": [], + "source": [ + "import pyDeltaRCM" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2d7db35-4f4b-4111-8269-e40478378ac8", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import numpy as np\n", + "import netCDF4\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "id": "7121c3ca-4c8b-4d5e-9642-b76b35f68a72", + "metadata": {}, + "source": [ + "First, we will configure a YAML file to input to the model." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "169fd14b-3d16-4569-a91f-0523dbbad30d", + "metadata": {}, + "outputs": [], + "source": [ + "%%writefile eg_config.yaml\n", + "\n", + "f_bedload: 0.25\n", + "h0: 2\n", + "u0: 1.1\n", + "save_eta_figs: True\n", + "save_eta_grids: True\n", + "save_velocity_grids: True\n", + "save_dt: 250000" + ] + }, + { + "cell_type": "markdown", + "id": "46e6dd75-bd65-4dc3-81a1-29369eb87c6f", + "metadata": {}, + "source": [ + "In the following cell, we instantiate the model with the yaml file we just created, run the model for 1000 steps, and finalize.\n", + "\n", + "**WARNING** executing the run will likely take 30-40 minutes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a87a3c1d-60bf-4916-b531-1ded37d89050", + "metadata": {}, + "outputs": [], + "source": [ + "mdl = pyDeltaRCM.DeltaModel('eg_config.yaml')\n", + "\n", + "for _ in range(0, 1000):\n", + " mdl.update()\n", + "\n", + "mdl.finalize()" + ] + }, + { + "cell_type": "markdown", + "id": "57bb6af2-d7a4-4f0a-88b1-d6f29594aa02", + "metadata": {}, + "source": [ + "With the model completed, we can see the final state:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a86fd13d-ffb7-4c31-85c7-be3bd4533001", + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "ax.imshow(mdl.eta, cmap='cividis')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "a2488676-78da-4387-b933-4a237da2ca9f", + "metadata": {}, + "source": [ + "We can also access the history of the run in the output NetCDF4 file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7e02e59a-f615-4f58-b100-208d466f2df8", + "metadata": {}, + "outputs": [], + "source": [ + "data = netCDF4.Dataset(os.path.join('deltaRCM_Output', 'pyDeltaRCM_output.nc')) # this is the default location for the output file" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32b652fa-6158-412d-a4e8-d0fcdc41c31f", + "metadata": {}, + "outputs": [], + "source": [ + "nt = 3\n", + "ts = np.linspace(0, data['eta'].shape[0]-1,\n", + " num=nt, dtype=int) # linearly interpolate ts\n", + "\n", + "# make the timeseries plot\n", + "fig, ax = plt.subplots(1, nt, figsize=(11, 2), dpi=300)\n", + "for i, t in enumerate(ts):\n", + " ax[i].imshow(data['eta'][t, :, :], cmap='cividis')\n", + " ax[i].axes.get_xaxis().set_ticks([])\n", + " ax[i].axes.get_yaxis().set_ticks([])\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.9.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/source/guides/10min.rst b/docs/source/guides/10min.rst index 2868fa0e..bb72150e 100644 --- a/docs/source/guides/10min.rst +++ b/docs/source/guides/10min.rst @@ -58,8 +58,11 @@ The model with set parameters ----------------------------- To run a simulation with a non-default set of parameters, we use a configuration file written in the YAML markup language named `10min_tutorial.yaml`. -This markup file allows us to specify model boundary conditions and input and output settings. -Anything you set in this file will override the :doc:`default parameters <../reference/model/yaml_defaults>` for the model. +The markup file allows us to specify model boundary conditions and input and output settings, where anything set in the file will override the :doc:`default parameters <../reference/model/yaml_defaults>` for the model, and anything *not* specified will take the default value. + +.. important:: + + The best practice for model configurations is to create a YAML file with only the settings you want to change specified. The YAML configuration file is central to managing *pyDeltaRCM* simulations, so we did not create this file for you; you will need to create the YAML file yourself. To create the YAML file, open up your favorite plain-text editing application (e.g., gedit, notepad). diff --git a/docs/source/guides/advanced_configuration_guide.inc b/docs/source/guides/advanced_configuration_guide.inc index 8e463ab1..67f062d9 100644 --- a/docs/source/guides/advanced_configuration_guide.inc +++ b/docs/source/guides/advanced_configuration_guide.inc @@ -90,6 +90,10 @@ The ensemble expansion can be applied to configuration files that include a matr The above configuration file would produce 6 model runs, 3 with a basin depth (`h0`) of 1.0, and 3 with a basin depth of 2.0. +.. hint:: + + If you are debugging and experimenting, it may be helpful to comment out a line in your YAML, rather than deleting it completely! E.g., ``# ensemble: 3``) would disable ensemble expansion. + .. _set_expansion_tag: Set expansion diff --git a/docs/source/guides/getting_started.rst b/docs/source/guides/getting_started.rst index 13e40ab4..158d1f0b 100644 --- a/docs/source/guides/getting_started.rst +++ b/docs/source/guides/getting_started.rst @@ -5,9 +5,21 @@ Getting Started =============== -This section gives a learn-by-example lesson on how to use pyDeltaRCM. +It's easy to get started using *pyDeltaRCM*. +We recommend starting out with the 10-minute learn-by-example lesson: .. toctree:: :maxdepth: 3 10min + + +Return to the main index :ref:`user_documentation` to see all the other documentation available to help you get started. + +Some other helpful resources: + +* An example `Jupyter Notebook `_ that shows a complete model runs and quick analysis of output file. +* A comprehensive :doc:`user_guide` on how to use and experiment with the model + + +And when you're ready to start developing, check out the :doc:`developer_guide` and the complete model :doc:`API documentation `. diff --git a/docs/source/guides/subsidence_guide.inc b/docs/source/guides/subsidence_guide.inc index 2a85f2b9..0703a6cd 100644 --- a/docs/source/guides/subsidence_guide.inc +++ b/docs/source/guides/subsidence_guide.inc @@ -43,5 +43,5 @@ Subsidence behavior can be easily modified by :ref:`creating a subclass ` for a complete explanation and demonstration for how to modify model behavior. .. + ============================= Advanced model configurations ============================= ** Advanced model configuration guide is imported from another file. ** @@ -277,6 +285,7 @@ See :ref:`our guide for model customization ` for a complet .. + ======================= Working with Subsidence ======================= ** Subsidence guide is imported from another file. ** @@ -284,6 +293,15 @@ See :ref:`our guide for model customization ` for a complet .. include:: subsidence_guide.inc +.. + ======================= + dsfasf + ======================= + ** Subsidence guide is imported from another file. ** + +.. include:: /info/outputfile.rst + + Supporting documentation and files ================================== @@ -294,6 +312,7 @@ Model reference: Examples: + * `Simple simulation in Jupyter Notebook `_ * :doc:`/examples/slight_slope` * :doc:`/examples/subsidence_region` * :doc:`/examples/custom_saving` diff --git a/docs/source/index.rst b/docs/source/index.rst index 099d638c..d3e9d0b7 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -22,6 +22,7 @@ Project information meta/license meta/conduct +.. _user_documentation: User documentation ################## diff --git a/docs/source/info/outputfile.rst b/docs/source/info/outputfile.rst index 61c4c7f0..ea898a78 100644 --- a/docs/source/info/outputfile.rst +++ b/docs/source/info/outputfile.rst @@ -1,11 +1,13 @@ -****************** -Output File Format -****************** +================= +Model Output File +================= + +If configured to save any output data, model outputs are saved using the `netCDF4 `_ file format. -Model outputs are saved using the `netCDF4 `_ file format. Gridded Variables ------------------ +================= + In any given run, the saving parameters "save__grids" control whether or not that 2-D grid variable (e.g. velocity) is saved to the netCDF4 file. In the netCDF4 file, a 3-D array with the dimensions @@ -13,8 +15,10 @@ In the netCDF4 file, a 3-D array with the dimensions to be saved. The appropriate units for these variables are stored as well, such as "meters per second" for the *velocity* grid. + Grid Coordinates ----------------- +================ + To save the model information associated with the domain itself, variables associated with the grid are saved as well. These are the meshed 2-D grids corresponding to the distance of each cell from the boundary in the "Width" @@ -23,8 +27,10 @@ boundary of each cell in the "Length" dimension, as *y* in meters. Similarly, a *time* variable is stored which is a 1-D array (vector) holding the model time values in seconds, associated with each set of saved output data. + Model Metadata --------------- +============== + In addition to the grid coordinates, model metadata is saved as a group of 1-D arrays (vectors) and 0-D arrays (floats and integers). The values that are saved as metadata are the following: @@ -39,11 +45,13 @@ saved as metadata are the following: - Sediment concentration: `C0_percent` - Characteristic Velocity: `u0` - If subsidence is enabled: - - Subsidence start time: `start_subsidence` - - Subsidence rate: `sigma` + - Subsidence start time: `start_subsidence` + - Subsidence rate: `sigma` + Working with Model Outputs --------------------------- +========================== + The resulting netCDF4 output file can be read using any netCDF4-compatible library. These libraries range from the `netCDF4 Python package `_ itself, @@ -52,3 +60,24 @@ to higher-level libraries such as *pyDeltaRCM*, there is also a package under development called `DeltaMetrics `_, that is being designed to help post-process and analyze *pyDeltaRCM* outputs. + + +Here, we show how to read the output NetCDF file with Python package ``netCDF4``. + +.. code:: + + import netCDF4 as nc + + data = nc.Dataset('pyDeltaRCM_output.nc') # the output file path! + +This `data` object is a `Dataset` object that can be sliced the same was as a `numpy` array. +For example, we can slice the final bed elevation and velocity of a model run: + +.. code:: + + final_bed_elevation = data['eta'][-1, :, :] + final_velocity = data['velocity'][-1, :, :] + +These slices look like this, if we were to plot them. + +.. plot:: guides/output_file.py diff --git a/docs/source/pyplots/guides/output_file.py b/docs/source/pyplots/guides/output_file.py new file mode 100644 index 00000000..b022adb9 --- /dev/null +++ b/docs/source/pyplots/guides/output_file.py @@ -0,0 +1,46 @@ +import warnings + +import matplotlib +import matplotlib.pyplot as plt +import numpy as np + +import pyDeltaRCM + + +# filter out the warning raised about no netcdf being found +warnings.filterwarnings("ignore", category=UserWarning) + + +n = 20 +cm = matplotlib.cm.get_cmap('tab10') + + +# init delta model +with pyDeltaRCM.shared_tools._docs_temp_directory() as output_dir: + + delta = pyDeltaRCM.DeltaModel( + out_dir=output_dir, + resume_checkpoint='../../_resources/checkpoint') + + +_shp = delta.eta.shape + +# set up axis +fig, ax = plt.subplots(1, 2, figsize=(6, 3)) +vmin, vmax = delta.eta.min(), delta.eta.max() + +# fill in axis +ax[0].imshow( + delta.eta, vmin=vmin, vmax=vmax, cmap='cividis') +ax[0].set_xticks([]) +ax[0].set_yticks([]) +ax[0].set_title('bed elevation') + +ax[1].imshow( + delta.uw, cmap='plasma') +ax[1].set_xticks([]) +ax[1].set_yticks([]) +ax[0].set_title('velocity') + +plt.tight_layout() +plt.show() diff --git a/docs/source/reference/init_tools/index.rst b/docs/source/reference/init_tools/index.rst index 00619728..091cb54e 100644 --- a/docs/source/reference/init_tools/index.rst +++ b/docs/source/reference/init_tools/index.rst @@ -27,9 +27,9 @@ and then depending on the checkpointing configuration, the following methods may init_tools.load_checkpoint init_tools.init_output_file - pyDeltaRCM.interation_tools.output_data - pyDeltaRCM.interation_tools.output_checkpoint - pyDeltaRCM.interation_tools.log_model_time + pyDeltaRCM.iteration_tools.iteration_tools.output_data + pyDeltaRCM.iteration_tools.iteration_tools.output_checkpoint + pyDeltaRCM.iteration_tools.iteration_tools.log_model_time Public API methods attached to model diff --git a/pyDeltaRCM/model.py b/pyDeltaRCM/model.py index 058a1086..0d06944a 100644 --- a/pyDeltaRCM/model.py +++ b/pyDeltaRCM/model.py @@ -1221,22 +1221,23 @@ def alpha(self, alpha): @property def stepmax(self): """ - stepmax is the maximum number of jumps a parcel can make. + `stepmax` is the maximum number of jumps a parcel can make. - stepmax is the maximum number of jumps a parcel (water or sediment) - can make. If the parcel reaches the oceanic boundary before stepmax is - reached, then this condition is not invoked. However if the parcel - does not reach the oceanic bounary but does reach "stepmax" jumps, - then the parcel will just stop moving and disappear. + The maximum number of jumps a parcel (water or sediment) can take is + determined by `stepmax`. If the parcel reaches the oceanic boundary + before `stepmax` is reached, then this condition is not invoked. + However if the parcel does not reach the oceanic bounary but does + reach `stepmax` jumps, then the parcel will just stop moving and + disappear. - If stepmax is not specified in the yaml, the default value assigned + If `stepmax` is not specified in the yaml, the default value assigned is 2 times the perimeter of the domain (2 * (self.L + self.W)). .. note:: - If stepmax is set too low and many parcels reach the stepmax + If `stepmax` is set too low and many parcels reach the `stepmax` condition during routing, then there may be a considerable amount of sediment 'missing' from the system as any sediment in - a parcel that hits the stepmax threshold disappears from the + a parcel that hits the `stepmax` threshold disappears from the simulation. """ return self._stepmax