Skip to content

Commit

Permalink
Merge pull request #67 from noaa-oar-arl/develop
Browse files Browse the repository at this point in the history
Merge latest develop to stable.
  • Loading branch information
drnimbusrain authored May 18, 2023
2 parents 4264f16 + 80c84d7 commit acb42ec
Show file tree
Hide file tree
Showing 20 changed files with 1,686 additions and 153 deletions.
3 changes: 3 additions & 0 deletions .binder/apt.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
gfortran
make
libnetcdff-dev
19 changes: 19 additions & 0 deletions .binder/environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: canopy-app
channels:
- conda-forge
- nodefaults
dependencies:
- python=3.10
#
# Core
- f90nml
- netcdf4
- numpy
- pandas
- xarray
#
# Examples
- cartopy
- ipympl
- ipywidgets
- matplotlib
1 change: 1 addition & 0 deletions .binder/postBuild
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FC=gfortran DEBUG=0 NETCDF=1 make -C src
34 changes: 25 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ jobs:
strategy:
matrix:
compiler: [gfortran-9, gfortran-10, gfortran-11]
defaults:
run:
shell: bash -l {0}

steps:
- uses: actions/checkout@v3
Expand All @@ -26,24 +29,23 @@ jobs:
sudo apt-get update
sudo apt-get install libnetcdff-dev
- name: Setup Python (for f90nml)
uses: actions/setup-python@v4
- name: Set up Python (micromamba)
uses: mamba-org/provision-with-micromamba@v15
with:
python-version: '3.10'

- name: Install Python dependencies
run: |
python -m pip install -U pip setuptools wheel
python -m pip install f90nml
environment-file: python/environment.yml
cache-env: true
extra-specs: |
python=3.10
- name: Check that default input is nc
run: |
python -c '
import f90nml
with open("input/namelist.canopy") as f:
nml = f90nml.read(f)
assert nml["filenames"]["file_vars"].endswith((".nc", ".ncf")), "nc input by default, like build"
assert nml["userdefs"]["infmt_opt"] == 0, "necessary to read 2-D"
shell: python
'
- name: Debug compile and run
run: |
Expand All @@ -54,6 +56,20 @@ jobs:
DEBUG: 1
FC: ${{ matrix.compiler }}

- name: Run Python module as script
run: |
cd python
python canopy_app.py
cd -
- name: Run Python example nbs
run: |
cd python
for f in *.ipynb; do
jupyter nbconvert --to notebook --execute $f
done
cd -
- name: Non-debug compile and run
run: |
make -C src clean
Expand Down
165 changes: 165 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
output*.txt
test_*.txt
test*.nc
.vscode/
test*/

# Prerequisites
*.d
Expand Down Expand Up @@ -35,3 +37,166 @@ test*.nc
*.exe
*.out
*.app

# Python below

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
31 changes: 30 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: "v4.3.0"
rev: "v4.4.0"
hooks:
- id: trailing-whitespace
args: ['--markdown-linebreak-ext=md,markdown']
Expand All @@ -14,3 +14,32 @@ repos:
- id: wfindent-pypi
args: ['-i4']
additional_dependencies: ['findent<4.2.6']

- repo: https://github.com/asottile/pyupgrade
rev: "v3.3.1"
hooks:
- id: pyupgrade
args: [--py37-plus]

- repo: https://github.com/PyCQA/isort
rev: "5.12.0"
hooks:
- id: isort
args: [--line-length=90, --profile=black]

- repo: https://github.com/psf/black
rev: "23.3.0"
hooks:
- id: black-jupyter
args: [--line-length=90]

- repo: https://github.com/PyCQA/flake8
rev: "6.0.0"
hooks:
- id: flake8
args: [--max-line-length=90, "--ignore=E203,E402,E501,W503,E226"]

- repo: https://github.com/kynan/nbstripout
rev: "0.6.1"
hooks:
- id: nbstripout
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ which is read at runtime.
./canopy
```

You can also [run with Python](./python/README.md).

## Components

Current Canopy-App components:

1. In-Canopy Winds and Wind Adjustment Factor (WAF) for wildfire spread and air quality applications. Based on Massman et al. (2017).

Namelist Option : `ifcanwind` and/or `ifcanwaf` Output Variables: `canwind` (m s-1) `waf` (fraction)
Namelist Option : `ifcanwind` and/or `ifcanwaf` Output Variables: `ws` (m s-1) `waf` (fraction)

- `canopy_wind_mod.F90`
- `canopy_waf_mod.F90`
Expand Down Expand Up @@ -137,7 +139,7 @@ The Canopy-App input data in [Table 2](#table-2-canopy-app-required-input-variab
| `prate_ave` | Average mass precipitation rate (kg m-2 s-1) | UFS NOAA/GFSv16 |
| **External Canopy Variables** | **Variable Description and Units** | **Data Source/Reference (if necessary)** |
| `fh` | Forest canopy height (m) | Fused GEDI/Landsat data. Data Period=2020. ([Potapov et al., 2020](https://doi.org/10.1016/j.rse.2020.112165)) |
| `clu` | Forest clumping index (dimensionless) | GridingMachine/MODIS. Data Period=2001-2017 Climatology. ([Wei et al., 2019](https://doi.org/10.1016/j.rse.2019.111296)). Extended globally for high latitudes using methods described [here](https://gmuedu-my.sharepoint.com/:w:/g/personal/whung_gmu_edu/EdglXmW2kzBDtDj1xV0alGcB1Yo2I8hzdyWGVGB2YOTfgw). |
| `clu` | Forest clumping index (dimensionless) | GriddingMachine/MODIS. Data Period=2001-2017 Climatology. ([Wei et al., 2019](https://doi.org/10.1016/j.rse.2019.111296)). Extended globally for high latitudes using methods described [here](https://gmuedu-my.sharepoint.com/:w:/g/personal/whung_gmu_edu/EdglXmW2kzBDtDj1xV0alGcB1Yo2I8hzdyWGVGB2YOTfgw). |
| `lai` | Leaf area index (m2/m2) | VIIRS-NPP. Data Period=2018-2020 Climatology. ([Myneni 2018](https://doi.org/10.5067/VIIRS/VNP15A2H.001)). Extended globally for high latitudes using methods described [here](https://gmuedu-my.sharepoint.com/:w:/g/personal/whung_gmu_edu/EdglXmW2kzBDtDj1xV0alGcB1Yo2I8hzdyWGVGB2YOTfgw). |
| `ffrac` | Forest fraction (dimensionless) | Based on [VIIRS GVF-NPP](https://www.star.nesdis.noaa.gov/jpss/gvf.php) and GriddingMachine/MODIS FFRAC/FVC from Terra. Data Period=2020. ([DiMiceli et al., 2022](https://doi.org/10.5067/MODIS/MOD44B.061)). Extended globally for high latitudes using methods described [here](https://gmuedu-my.sharepoint.com/:w:/g/personal/whung_gmu_edu/EdglXmW2kzBDtDj1xV0alGcB1Yo2I8hzdyWGVGB2YOTfgw). |
| **Other External Variables** | **Variable Description and Units** | **Data Source/Reference (if necessary)** |
Expand All @@ -163,7 +165,7 @@ Hourly gridded GFSv16 data is available on AWS from March 23, 2021 - Current Day

**Downloading Example Canopy Files from AWS:** Example monthly, global gridded files containing all GFSv16 met/land/soil data from 2022 combined with external canopy and other external variables (regridded to GFSv16 13 km resolution) described above may also be downloaded via AWS S3 location:
```
https://nacc-in-the-cloud.s3.amazonaws.com/inputs/geo-files/canopy.2022MM01.testf000.global.nc
https://nacc-in-the-cloud.s3.amazonaws.com/inputs/geo-files/gfs.canopy.t12z.2022MM01.sfcf000.nc
```

### Table 3. Current User Namelist Options
Expand All @@ -181,9 +183,10 @@ https://nacc-in-the-cloud.s3.amazonaws.com/inputs/geo-files/canopy.2022MM01.test
| `ifcanphot` | logical canopy photolysis option (default: `.FALSE.`) |
| `ifcanbio` | logical canopy biogenic emissions option (default: `.FALSE.`) |
| `href_opt` | integer for using href_set in namelist (= `0`, default) or array from file (= `1`) |
| `href_set` | user-set real value of reference height above canopy associated with input wind speed (m) (only used if `href_opt=0`) |
| `href_set` | user-set real value of reference height above canopy associated with input wind speed (m) (only used if `href_opt=0`) **\*\*\*** |
| `z0ghc` | ratio of ground roughness length to canopy top height (Massman et al., 2017) |
| `lambdars` | Value representing influence of roughness sublayer (Massman et al., 2017) |
| `rsl_opt` | user-set option for either MOST or unified Roughness SubLayer (RSL) effects above and at canopy top (Uc).(= `0`, default: uses MOST and a constant lambdars factor only), (= `1`, under development: will use a more unified RSL approach from Bonan et al. (2018) and Abolafia-Rosenzweig et al., 2021) |
| `lambdars` | Value representing influence of RSL effects (with `rsl_opt=0`) (Massman et al., 2017) |
| `dx_opt` | `0`: Calculation of dx resolution/distance from lon; `1`: user-set dx grid resolution |
| `dx_set` | user-set real value of grid resolution (m) only if `dx_opt=1` |
| `flameh_opt` | `0`: Calculation of flame height from FRP (Byram, 1959); `1`: user-set flameh; `2`: FRP calculation where available (active fires), elsewhere user-set `flameh`; `3`: FlameH override, i.e., only uses fraction of canopy height (`flameh_set` must be <=1.0) as a surrogate for `flameh`; `4`: FRP calculation where available (active fires) and FlameH override elsewhere (same as option 3); `5`: FRP/intensity dependent (i.e., sub-canopy vs. crown fires) calculation where available (active fires) and FlameH override elsewhere (same as option 3). If option 5 is used and crowning is calculated, then the total flame height (i.e., top of canopy=FCH) is used instead of 1/2 flame height. |
Expand All @@ -193,22 +196,35 @@ https://nacc-in-the-cloud.s3.amazonaws.com/inputs/geo-files/canopy.2022MM01.test
| `pai_set` | user-set real value of PAI (default: `4.0`; only used if `pai_opt=3`) |
| `lu_opt` | integer for input model land use type (`0`: VIIRS 17 Cat (default) or `1`: MODIS-IGBP 20 Cat (valid LU types 1-10 and 12); input mapped to Massman et al.) |
| `z0_opt` | integer (`0`: use model input or `1`: vegtype dependent z0 for first estimate) |
| `rsl_opt` | user-set option to include more explicit stability and Roughness SubLayer (RSL) effects in calculation of wind speed at canopy top (Uc) from reference height. `0`: off; `1`: on |
| `bio_cce` | user-set real value of MEGAN biogenic emissions "canopy environment coefficient" used to tune emissions to model inputs/calculations (default: `0.21`, based on Silva et al. 2020) |
| `lai_thresh` | user-set real value of LAI threshold for contiguous canopy (m2/m2) |
| `frt_thresh` | user-set real value of forest fraction threshold for contiguous canopy |
| `fch_thresh` | user-set real value of canopy height threshold for contiguous canopy (m) |

**\*\*** If `modres` >> `flameh` then some error in WAF calculation will be incurred. Suggestion is to use relative fine `modres` (at least <= 0.5 m) compared to average flame heights (e.g., ~ 1.0 m) if WAF is required.

**\*\*\*** If `href_set` becomes small and approaches z0 (or as `href_set` --> 0), only the sub-canopy wind profile is calculated, recommend `href_set` = 10 m.

**Note:** Canopy is parameterized by foliage distribution shape functions and parameters for different vegetation types.

- `canopy_profile_mod.F90`

## Global Canopy-App Example (July 01, 2022 at 1200 UTC)

<img
src="docs/Global_Canopy_App_Example.png"
alt="Alt text"
title="Global Canopy-App Example"
style="display: inline-block; margin: 0 auto">

## References

*Further references contained within the source code.*

- Abolafia-Rosenzweig, R., He, C., Burns, S. P., & Chen, F. (2021). Implementation and evaluation of a unified turbulence parameterization throughout the canopy and roughness sublayer in Noah-MP snow simulations. Journal of Advances in Modeling Earth Systems, 13, e2021MS002665. https://doi.org/10.1029/2021MS002665.

- Bonan, G. B., Patton, E. G., Harman, I. N., Oleson, K. W., Finnigan, J. J., Lu, Y., & Burakowski, E. A. (2018). Modeling canopy-induced turbulence in the Earth system: A unified parameterization of turbulent exchange within plant canopies and the roughness sublayer (CLM-ml v0). Geoscientific Model Development, 11, 1467–1496. https://doi.org/10.5194/gmd-11-1467-2018.

- Clifton, O. E., Patton, E. G., Wang, S., Barth, M., Orlando, J., & Schwantes, R. H. (2022). Large eddy simulation for investigating coupled forest canopy and turbulence influences on atmospheric chemistry. Journal of Advances in Modeling Earth Systems, 14, e2022MS003078. https://doi.org/10.1029/2022MS003078

- Guenther, A. B., Jiang, X., Heald, C. L., Sakulyanontvittaya, T., Duhl, T., Emmons, L. K., and Wang, X.: The Model of Emissions of Gases and Aerosols from Nature version 2.1 (MEGAN2.1): an extended and updated framework for modeling biogenic emissions, Geosci. Model Dev., 5, 1471–1492, https://doi.org/10.5194/gmd-5-1471-2012, 2012.
Expand Down
Binary file added docs/Global_Canopy_App_Example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified input/gfs.t12z.20220701.sfcf000.canopy.nc
Binary file not shown.
Loading

0 comments on commit acb42ec

Please sign in to comment.