diff --git a/.github/ISSUE_TEMPLATE/03_documentation.md b/.github/ISSUE_TEMPLATE/03_documentation.md index e6c3fa0ff8..5538f047a0 100644 --- a/.github/ISSUE_TEMPLATE/03_documentation.md +++ b/.github/ISSUE_TEMPLATE/03_documentation.md @@ -3,7 +3,7 @@ name: Documentation about: Something should be added to or fixed in the documentation --- - +(Please see our [contribution guidelines for documentation](https://escomp.github.io/CTSM/users_guide/working-with-documentation/docs-intro.html#contribution-guidelines).) ### What sort(s) of documentation issue is this? - [ ] Something is missing. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c4a381383b..6ef2db80b6 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,24 +1,41 @@ + + + + + ### Description of changes + + ### Specific notes -Contributors other than yourself, if any: +**Contributors other than yourself, if any:** +- (Replace this text and add more list items as needed) -CTSM Issues Fixed (include github issue #): +**CTSM issues resolved or otherwise addressed, if any:** +- (Replace this text, including GitHub issue #, and add more list items as needed) + + -Are answers expected to change (and if so in what way)? +**If answers are expected to change, describe (delete this line otherwise):** -Any User Interface Changes (namelist or namelist defaults changes)? +**Any user interface changes (namelist or namelist defaults changes)?** -Does this create a need to change or add documentation? Did you do so? +**Testing planned or performed, if any:** +- [ ] (Replace this text and add more list items as needed) + -Testing performed, if any: -(List what testing you did to show your changes worked as expected) -(This can be manual testing or running of the different test suites) -(Documentation on system testing is here: https://github.com/ESCOMP/ctsm/wiki/System-Testing-Guide) -(aux_clm on derecho for intel/gnu and izumi for intel/gnu/nag/nvhpc is the standard for tags on master) -**NOTE: Be sure to check your coding style against the standard -(https://github.com/ESCOMP/ctsm/wiki/CTSM-coding-guidelines) and review -the list of common problems to watch out for -(https://github.com/ESCOMP/CTSM/wiki/List-of-common-problems).** + +### Requirements before merge: +- [ ] I have followed the [CTSM contribution guidelines](https://github.com/ESCOMP/CTSM/blob/master/CONTRIBUTING.md). + +- [ ] The code in this PR branch builds with no errors. +- [ ] The code in this PR branch runs with no errors. **Briefly describe tested configuration(s):** +- [ ] This either (a) does not change answers, (b) it only changes answers at roundoff level, or (c) I have performed a scientific evaluation of the answer changes. **Which?:** + +- [ ] I have reviewed relevant parts of the CLM documentation [Tech Note](https://escomp.github.io/CTSM/tech_note/index.html) or [User's Guide](https://escomp.github.io/CTSM/users_guide/index.html) to determine if anything needs to be changed or added. **If it does, describe:** +- [ ] This PR either (a) does not create a need to update the documentation or (b) includes required documentation updates (see [guidelines for contributing documentation](https://escomp.github.io/CTSM/users_guide/working-with-documentation/docs-intro.html#contribution-guidelines)). **Which?:** diff --git a/.github/workflows/docs-build-and-deploy.yml b/.github/workflows/docs-build-and-deploy.yml index 55ad033ed7..7951532848 100644 --- a/.github/workflows/docs-build-and-deploy.yml +++ b/.github/workflows/docs-build-and-deploy.yml @@ -11,8 +11,8 @@ on: - '!doc/*ChangeSum*' - '!doc/UpdateChangelog.pl' # Include all include::ed files outside doc/ directory! - - 'src/README.unit_testing' - - 'tools/README' + - 'src/README.unit_testing.md' + - 'tools/README.md' - 'doc/test/test_container_eq_ctsm_pylib.sh' # Allows you to run this workflow manually from the Actions tab diff --git a/.github/workflows/docs-pr-failure-post-comment.yml b/.github/workflows/docs-pr-failure-post-comment.yml new file mode 100644 index 0000000000..2a8928b28c --- /dev/null +++ b/.github/workflows/docs-pr-failure-post-comment.yml @@ -0,0 +1,66 @@ +name: Post PR comment with doc-build failure log + +env: + DOCS_FAILURE_ARTIFACT: test-build-docs-container_failed + +on: + workflow_run: + workflows: ["Test building docs when they're updated"] + types: [completed] + +jobs: + comment: + if: >- + github.event.workflow_run.event == 'pull_request' + && github.event.workflow_run.conclusion == 'failure' + runs-on: ubuntu-latest + permissions: + pull-requests: write + actions: read + steps: + - name: Check for failure artifact + id: check + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + run: | + gh api repos/$REPO/actions/runs/${{ github.event.workflow_run.id }}/artifacts \ + --jq '.artifacts[] | select(.name == "${{ env.DOCS_FAILURE_ARTIFACT }}") | .id' > artifact_id.txt + + if [ -s artifact_id.txt ]; then + echo "found=true" >> $GITHUB_OUTPUT + else + echo "found=false" >> $GITHUB_OUTPUT + fi + + - name: Download logs + if: steps.check.outputs.found == 'true' + uses: actions/download-artifact@v4 + with: + name: ${{ env.DOCS_FAILURE_ARTIFACT }} + path: ${{ env.DOCS_FAILURE_ARTIFACT }} + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Post comment + if: steps.check.outputs.found == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + run: | + PR_NUMBER=$(cat "${DOCS_FAILURE_ARTIFACT}/pr_number.txt") + + { + echo "### ❌ Docs build failed" + echo + echo '
' + echo "Build logs" + echo + echo '```' + cat "${DOCS_FAILURE_ARTIFACT}/build.log" + echo '```' + echo + echo "
" + } > comment-body.md + + gh pr comment "$PR_NUMBER" --repo "$REPO" --body-file comment-body.md diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 780ba31b64..4832192fd9 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,8 +13,8 @@ on: - '!doc/UpdateChangelog.pl' - '.github/workflows/docs-common.yml' # Include all include::ed files outside doc/ directory! - - 'src/README.unit_testing' - - 'tools/README' + - 'src/README.unit_testing.md' + - 'tools/README.md' - 'doc/test/test_container_eq_ctsm_pylib.sh' pull_request: @@ -27,8 +27,8 @@ on: - '!doc/UpdateChangelog.pl' - '.github/workflows/docs-common.yml' # Include all include::ed files outside doc/ directory! - - 'src/README.unit_testing' - - 'tools/README' + - 'src/README.unit_testing.md' + - 'tools/README.md' - 'doc/test/test_container_eq_ctsm_pylib.sh' workflow_dispatch: @@ -61,4 +61,159 @@ jobs: - name: Build docs using Docker (Podman has trouble on GitHub runners) id: build-docs run: | - cd doc && ./build_docs -b ${PWD}/_build -c -d + set -o pipefail + mkdir -p build-logs + cd doc && PYTHONUNBUFFERED=1 ./build_docs -b ${PWD}/_build -c -d 2>&1 | tee >(sed -E $'s/\x1b\\[[0-9;]*[a-zA-Z]//g' > "${GITHUB_WORKSPACE}/build-logs/build.log") + # The tee writes build.log for the PR comment (posted by docs-pr-failure-post-comment.yml); the inner sed strips ANSI color codes that would otherwise render as garbage in the comment. + # PYTHONUNBUFFERED=1 because otherwise the teed log will be out of order + + # The rest of the steps only trigger on failure of above build-docs step. + # They upload logs that will be used by the docs-pr-failure-post-comment.yml workflow. + + - name: Record PR number on failure + if: failure() && steps.build-docs.outcome == 'failure' && github.event_name == 'pull_request' + run: | + mkdir -p build-logs + echo "${{ github.event.pull_request.number }}" > build-logs/pr_number.txt + + - name: Upload logs on failure + if: failure() && steps.build-docs.outcome == 'failure' + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: test-build-docs-container_failed + path: build-logs/ + + check-docs-style: + if: ${{ always() }} + name: Check documentation against style guide + runs-on: ubuntu-latest + steps: + + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Disallow fake degree signs + if: always() + # Prevents anyone from using the masculine ordinal indicator, as well as superscript-o/O if + # preceded by a digit in + # - Markdown math style, + # - reStructuredText math style, + # - MyST text style, and + # - reStructuredText text style, + # with or without curly brackets and/or spaces. + # + # What follows is an explanation of the regex. Keep in mind that the superscript-o will + # match whether it's an uppercase O or lowercase o because of the -i flag to grep, so that's + # not handled in the regex. + # + # Markdown math style: + # Markdown math superscripts look like $^o$. There can also be curly brackets, like + # $^{o}$, which would allow you to put multiple characters (including spaces) in the + # superscript. The preceding digit can be inside or outside the dollar signs, again with + # or without spaces. + # + # There are two regex patterns separated by |, to handle the cases where the preceding + # digit is outside or inside the dollar signs, respectively: + # [0-9]\s*\\$\s*\^\{?\s*o + # [0-9] Any digit + # \s* Any number of spaces, including none + # \\$ A literal dollar sign + # \s* Any number of spaces, including none + # \^ A literal caret + # \{? Optionally a literal left curly bracket + # \s* Any number of spaces, including none + # o Lowercase o + # \\\$[0-9]+\s*\^\{?\s*o\s*\}? + # \\\$ A literal dollar sign + # [0-9]+ One or more digits + # \s* Any number of spaces, including none + # \^ A literal caret + # \{? Optionally a literal left curly bracket + # \s* Any number of spaces, including none + # o Lowercase o + # \s* Any number of spaces, including none + # \}? Optionally a literal right curly bracket + # + # MyST text style: + # MyST text superscripts look like {sup}`o`. Here's the regex: + # [0-9]\s*\{sup}\`\s*o\` + # [0-9] Any digit + # \s* Any number of spaces, including none + # \{ A literal left curly bracket + # sup The text "sup" designating the superscript role + # \} A literal right curly bracket + # \` A literal backtick + # \s* Any number of spaces, including none + # o Lowercase o + # \` A literal backtick + # + # reStructuredText text style + # Similar to MyST text superscripts, but with colons instead of curly brackets: :sup:`o`. + # Another difference is that spaces aren't allowed inside the backticks. Also, there has + # to be a space preceding the first colon; this can be preceded by a backslash to avoid + # putting an extraneous space in the rendered text. Here's the regex: + # [0-9]\\\? :sup:\`o\` + # [0-9] Any digit + # \\\? Optionally a literal backslash + # (A literal space) + # :sup: The text ":sup:" designating the superscript role + # \` A literal backtick + # o Lowercase o + # \` A literal backtick + # + # reStructuredText math style + # Mostly the same as reStructuredText text superscripts, but with :math: instead of + # :sup:. In addition, the superscript can optionally be in curly brackets. There can be + # a space after the first backtick but not before the last one. + # + # There are two regex patterns separated by |, to handle the cases where the preceding + # digit is outside or inside the dollar signs, respectively: + # [0-9]\\\? :math:\`\s*\^\{?\s*o\s*\}?\` + # [0-9] Any digit + # \\\? Optionally a literal backslash + # (A literal space) + # :math: The text ":math:" designating the math role + # \` A literal backtick + # \s* Any number of spaces, including none + # \^ A literal caret + # \{? Optionally a literal left curly bracket + # \s* Any number of spaces, including none + # o Lowercase o + # \s* Any number of spaces, including none + # \}? Optionally a literal right curly bracket + # \` A literal backtick + # :math:\`\s*[0-9]+\s*\^\{?\s*o\s*\}?\` + # :math: The text ":math:" designating the math role + # \` A literal backtick + # \s* Any number of spaces, including none + # [0-9]+ One or more digits + # \s* Any number of spaces, including none + # \^ A literal caret + # \{? Optionally a literal left curly bracket + # \s* Any number of spaces, including none + # o Lowercase o + # \s* Any number of spaces, including none + # \}? Optionally a literal right curly bracket + # \` A literal backtick + run: | + set +e + instances_of_fake_degree_signs="$(grep -ionE "[0-9]\s*\\$\s*\^\{?\s*o|\\\$[0-9]+\s*\^\{?\s*o\s*\}?|[0-9]\s*\{sup}\`\s*o\`|[0-9]\\\? :sup:\`o\`|[0-9]\\\? :math:\`\s*\^\{?\s*o\s*\}?\`| :math:\`\s*[0-9]+\s*\^\{?\s*o\s*\}?\`|º" $(find doc -name "*.md" -or -name "*.rst"))" + set -e + if [[ "$instances_of_fake_degree_signs" ]] then + echo -e "Instances of superscript-o or masculine ordinal indicator (º) instead of degree sign (°):\n${instances_of_fake_degree_signs}" + echo -e "\nSee https://escomp.github.io/CTSM/users_guide/working-with-documentation/docs-style-guide.html" + exit 1 + fi + exit 0 + + - name: Disallow curly apostrophes/quotes + if: always() + run: | + set +e + instances_of_curlies="$(grep -onE "“|”|‘|’" $(find doc -name "*.md" -or -name "*.rst"))" + set -e + if [[ "$instances_of_curlies" ]] then + echo -e "Instances of curly apostrophes and/or quote marks:\n${instances_of_curlies}" + exit 1 + fi + exit 0 diff --git a/.gitmodules b/.gitmodules index 434c985738..b5156d3190 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,7 +28,7 @@ [submodule "fates"] path = src/fates url = https://github.com/NGEET/fates -fxtag = sci.1.91.1_api.43.1.0 +fxtag = sci.1.92.5_api.46.0.0 fxrequired = AlwaysRequired # Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed fxDONOTUSEurl = https://github.com/NGEET/fates @@ -68,7 +68,7 @@ fxDONOTUSEurl = https://github.com/ESCOMP/mizuRoute [submodule "ccs_config"] path = ccs_config url = https://github.com/ESMCI/ccs_config_cesm.git -fxtag = ccs_config_cesm1.0.79 +fxtag = ccs_config_cesm1.0.83 fxrequired = ToplevelRequired # Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed fxDONOTUSEurl = https://github.com/ESMCI/ccs_config_cesm.git @@ -76,7 +76,7 @@ fxDONOTUSEurl = https://github.com/ESMCI/ccs_config_cesm.git [submodule "cime"] path = cime url = https://github.com/ESMCI/cime -fxtag = cime6.1.169 +fxtag = cime6.2.2 fxrequired = ToplevelRequired # Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed fxDONOTUSEurl = https://github.com/ESMCI/cime @@ -84,7 +84,7 @@ fxDONOTUSEurl = https://github.com/ESMCI/cime [submodule "cmeps"] path = components/cmeps url = https://github.com/ESCOMP/CMEPS.git -fxtag = cmeps1.1.37 +fxtag = cmeps1.1.47 fxrequired = ToplevelRequired # Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed fxDONOTUSEurl = https://github.com/ESCOMP/CMEPS.git @@ -92,7 +92,7 @@ fxDONOTUSEurl = https://github.com/ESCOMP/CMEPS.git [submodule "cdeps"] path = components/cdeps url = https://github.com/ESCOMP/CDEPS.git -fxtag = cdeps1.0.93 +fxtag = cdeps1.0.96 fxrequired = ToplevelRequired # Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed fxDONOTUSEurl = https://github.com/ESCOMP/CDEPS.git @@ -100,7 +100,7 @@ fxDONOTUSEurl = https://github.com/ESCOMP/CDEPS.git [submodule "share"] path = share url = https://github.com/ESCOMP/CESM_share -fxtag = share1.1.19 +fxtag = share1.1.20 fxrequired = ToplevelRequired # Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed fxDONOTUSEurl = https://github.com/ESCOMP/CESM_share @@ -124,7 +124,7 @@ fxDONOTUSEurl = https://github.com/ESMCI/mpi-serial [submodule "doc-builder"] path = doc/doc-builder url = https://github.com/ESMCI/doc-builder -fxtag = v2.2.6 +fxtag = v3.2.1 fxrequired = ToplevelOptional # Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed fxDONOTUSEurl = https://github.com/ESMCI/doc-builder diff --git a/README b/README deleted file mode 100644 index deca3cd8d2..0000000000 --- a/README +++ /dev/null @@ -1,184 +0,0 @@ -$CTSMROOT/README 11/24/2025 - -Community Terrestrial Systems Model (CTSM) science version 5.4 series -- source code, tools, -offline-build and test scripts. This gives you everything you need -to run CTSM with CESM with the CMEPS driver and CDEPS data models to provide CRUJRA or GSWP3 forcing data (some older options also available) in -place of a modeled atmosphere. - -CMEPS is the Community Mediator for Earth Prediction Systems. And CDEPS is the -Community Data Models for Earth Prediction System. They are both NUOPC based models -used to drive the CESM (Community Earth System Model) of which CTSM is a component of. -NUOPC is the National Unified Operational Prediction Capability a standard way of building -coupled model systems. The NUOPC layer is based on the Earth System Modeling Framework (ESMF). - -For lists of current bugs (issues) and current development see the CTSM GitHub page: - -https://github.com/ESCOMP/CTSM - -For Code of Conduct (how to work with each other on the CTSM project): - -https://github.com/ESCOMP/CTSM?tab=coc-ov-file - -INFORMATION ON THE CMEPS DRIVER: - -https://escomp.github.io/CMEPS - -https://earthsystemmodeling.org/nuopc/ - -IMPORTANT NOTE ON CESM CHECKOUT VERSUS A CTSM CHECKOUT: - -If this is the top level directory from making a clone of CTSM the -directory structure is a little bit different than if CTSM is from -a clone of the entire CESM. If this is part of CESM this directory -will be under components/clm alongside other CESM component models. -For a CTSM checkout this will be the top level directory. - -Other documentation will refer to $CTSMROOT and it means the directory -that this file is at. CIMEROOT is the directory where "cime" is for -this checkout. For a CESM checkout $CIMEROOT will be the "cime" directory -beneath the top level directory. For a CTSM checkout $CIMEROOT will -be $CTSMROOT/cime. - -IMPORTANT NOTE ABOUT (deprecated) - -Anything marked with (deprecated) is something is going to be removed in a future update. -Often this means it will be replaced with something else. - - -General directory structure ($CTSMROOT): - -doc --------------- Documentation of CTSM. -bld --------------- build-namelist scripts for CTSM. -src --------------- CTSM Source code. -lilac ------------- Lightweight Infrastructure for Land-Atmosphere Coupling (for coupling to a host atmosphere model) -tools ------------- CTSM Offline tools to prepare input datasets and process output. -cime_config ------- Configuration files of cime for compsets and CTSM settings -bin/git-fleximod -- Script to manage the needed sub-component source directories (handled with git submodule) -py_env_create ----- Script to setup the python environment for CTSM python tools using conda -python ------------ Python modules used in tools and testing and automated checking of ALL CTSM python scripts - -Directory structure only for a CTSM checkout: - -components -------- Other active sub-components needed for CTSM to run (river routing and land-ice models) -libraries --------- CESM libraries: PIO (deprecated) -share ------------- CESM shared code -ccs_config -------- CIME configure files (for grids, compsets, and machines) for CESM - -cime/scripts --------------- cesm/cime driver scripts - -components/cmeps -------------------- CESM top level driver (for NUOPC driver [which is the default]) source code. -components/cdeps -------------------- CESM top level data model shared code (for NUOPC driver). -components/cism --------------------- CESM Community land Ice Sheet Model. -components/mosart ------------------- Model for Scale Adaptive River Transport -components/mizuroute ---------------- Reached based river transport model for water routing - (allows both gridded river and Hydrologic Responce Unit river grids) -components/rtm ---------------------- CESM River Transport Model. - -Top level documentation ($CTSMROOT): - -README ------------------- This file -README.md ---------------- File that displays on github under https::/github.com/ESCOMP/CTSM.git -README.rst --------------- File that displays under the project in github -README_GITFLEXIMOD.rst --- Information on how to work with git-fleximod for CTSM -WhatsNewInCTSM5.4.md ----- Overview document of the changes between ctsm5.3 and ctsm5.4 -Copyright ---------------- CESM Copyright file -doc/UpdateChangeLog.pl --- Script to add documentation on a tag to the - ChangeLog/ChangeSum files -doc/ChangeLog ------------ Documents different CTSM versions -doc/ChangeSum ------------ Summary documentation of different CTSM versions - -doc/design --------------- Software Engineering and code design document files - -Checklists for standard Software Engineering tasks - -./doc/README.CHECKLIST.master_tags -./bld/namelist_files/README.CHECKLIST.interpolating_initial_conditions.md - -Documentation of Namelist Items: (view the following in a web browser) - -bld/namelist_files/namelist_definition_ctsm.xml --- Definition of all namelist items -bld/namelist_files/namelist_defaults_ctsm.xml ----- Default values - -============================================================================================= -Important files in main directories (under $CTSMROOT): -============================================================================================= - -run_sys_tests --------------- Python script to send the standard CTSM testing off (submits - the create_test test suite for several different compilers on the - machines we do standard CTSM testing on). - -parse_cime.cs.status -------- Script to parse test status files cs.status.* created by create_test - (can be used along with run_sys_tests) -doc/Quickstart.GUIDE -------- Quick guide to using NUOPC scripts. -doc/IMPORTANT_NOTES.md ------ Some important notes about this version of - CTSM, configuration modes and namelist items - that are not validated or functional. -doc/ChangeLog --------------- Detailed list of changes for each model version. -doc/ChangeSum --------------- Summary one-line list of changes for each - model version. -doc/UsersGuide -------------- CTSM Users Guide - -bld/README ------------------ Description of how to use the build-namelist scripts. -bld/build-namelist ---------- Lower level script to build CTSM namelists. - -cime_config/buildnml ------------- Build the CTSM namelist for CIME -cime_config/buildlib ------------- Build the CTSM library -cime_config/config_compsets.xml -- Define CTSM compsets -cime_config/config_component.xml - Define CTSM XML settings -cime_config/config_tests.xml ----- Define CTSM specific tests -cime_config/config_pes.xml ------- Define Processor layouts for various CTSM grids and compsets -cime_config/testdefs ------------- Directory for specification of CTSM testing -cime_config/testdefs/ExpectedTestFails.xml -- List of tests that are expected to fail -cime_config/usermods_dirs/clm ---- Directories of sets of user-modification subdirs - (These are directories that add specific user modifications to - simulations created using "cime/scripts/create_newcase --user-mods-dir clm/*) - -tools/mksurfdata_esmf --------- Directory to build program to create surface dataset - at any resolution. -tools/mkmapgrids -------------- NCL script to create a SCRIP grid file for a regular lat/lon grid (deprecated) -tools/crop_calendars ---------- Tools to process and process and create crop calendar datasets for CTSM -tools/modify_input_files ------ Script to modify existing CTSM input datasets in standard ways -tools/site_and_regional ------- Scripts to create input datasets for single site and regional - cases, primarily by modifying existing global datasets -tools/contrib ----------------- Miscellansous useful scripts for pre and post processing - as well as case management of CTSM. These scripts are - contributed by users and may not be as well tested or - supported as other tools. -.vscode ----------------------- Suggested settings for using MS Visual Studio code with CTSM. - - -============================================================================================= -Source code directory structure: -============================================================================================= - -src/biogeochem ---- Biogeochemisty -src/main ---------- Main control and high level code -src/cpl ----------- Land model high level caps for NUOPC driver (and LILAC) -src/biogeophys ---- Biogeophysics (Hydrology) -src/dyn_subgrid --- Dynamic land unit change -src/init_interp --- Online interpolation -scr/fates --------- FATES model and sub-directories - Functionally Assembled Terrestrial Ecosystem Simulator (FATES) - Ecosystem Demography model -src/utils --------- Utility codes -src/self_tests ---- Internal testing (unit tests run as a part of a CTSM system test) -src/unit_test_shr - Unit test shared modules for unit testing -src/unit_test_stubs Unit test stubs that replicate CTSM code simpler - -============================================================================================= - QUICKSTART: using the NUOPC driver scripts -============================================================================================= - - cd $CIMEROOT/scripts - ./create_newcase # get help on how to run create_newcase - ./create_newcase --case testI --res f09_t232 --compset I2000Clm60BgcCrop - # create new "I" case for default machine at 1.9x2.5_gx1v7 - # "I2000Clm60BgcCrop" case is clm6_0 physics, CDEPS, and inactive ice/ocn/glc - # and MOSART for river-routing - cd testI - ./case.setup # create the $CASE.run file - ./case.build # build model and create namelists - ./case.submit # submit script - # (NOTE: ./xmlchange RESUBMIT=10 to set RESUBMIT to number - # # of times to automatically resubmit -- 10 in this example) - diff --git a/README.CHECKLIST.new_case b/README.CHECKLIST.new_case deleted file mode 100644 index 71ba4a8284..0000000000 --- a/README.CHECKLIST.new_case +++ /dev/null @@ -1,42 +0,0 @@ -$CTSMROOT/README.CHECKLIST.new_case 03/01/2021 - -This is a check list of things to do when setting up a new case in order to help ensure everything is correct. There -are lots of tiny details that need to be right and it's easy to get something wrong. So the first screening to make -sure it's right is for you to carefully check through your case and make sure it's right. - -The following assumes you have created a new case and are in it's case directory. - -General Checklist to always do: - - - Make sure CLM_ env settings are correct - (./xmlquery -p CLM) - - Make sure you are using the correct CLM_PHYSICS_VERSION - (./xmlquery -p CLM_PHYSICS_VERSION) - - Make sure you are running the appropriate overall CLM vegetation model. - The "-bgc" option of either Satellite Phenology (sp), or - Full BioGeoChemistry (bgc), or FATES (fates) - (./xmlquery -p CLM_BLDNML_OPTS) - - Also if you are running the bgc model, check to see if you should be running the prognostic crop model - (option -crop in CLM_BLDNML_OPTS) - - Make sure the LND_TUNING_MODE is correct - (./xmlquery LND_TUNING_MODE) - - For an "I compset" make sure you are running over the right forcing years - (usually ./xmlquery -p DATM_YR) - - Again for an "I compset" make sure the DATM streams are operating over the right years - (look at the CaseDocs/datm.streams.xml file) - - First and align year for streams should be the start year of a historical simulation - (./xmlquery RUN_STARTDATE) - (grep stream_year_first CaseDocs/lnd_in; grep model_year_align CaseDocs/lnd_in) - - Last year for streams should be the last year you are going to run to (or beyond it) - (grep stream_year_last CaseDocs/lnd_in) - - Make sure you are starting from appropriate spunup initial conditions - (Check the run-type with: ./xmlquery RUN_TYPE) - (check finidat for a startup or hybrid simulation: grep finidat CaseDocs/lnd_in) - (check nrevsn for a branch simulation: grep nrevsn CaseDocs/lnd_in) - - Run for a month (or some short period) and go over the log files and especially the settings and files read in them. - (For an I case you especially want to look at the lnd.log and atm.log files) - -Some other suggestions on things that can be done: - -- Compare namelist files to an existing case if you are doing something almost the same as a previous simulation. -- Ask another collaborator to look over your case directory diff --git a/README.CHECKLIST.new_case.md b/README.CHECKLIST.new_case.md new file mode 100755 index 0000000000..868cfe1c09 --- /dev/null +++ b/README.CHECKLIST.new_case.md @@ -0,0 +1,27 @@ +`$CTSMROOT/README.CHECKLIST.new_case` 03/01/2021 + +This is a check list of things to do when setting up a new case in order to help ensure everything is correct. There are lots of tiny details that need to be right and it's easy to get something wrong. So the first screening to make sure it's right is for you to carefully check through your case and make sure it's right. + +The following assumes you have created a new case and are in its case directory. + +General Checklist to always do: + +- Make sure `CLM_` environment settings are correct: `./xmlquery -p CLM` +- Make sure you are using the correct `CLM_PHYSICS_VERSION`: `./xmlquery -p CLM_PHYSICS_VERSION` +- Make sure you are running the appropriate overall CLM vegetation model, i.e. the `-bgc` option of either Satellite Phenology (`sp`) or Full BioGeoChemistry (`bgc`) or FATES (`fates`): `./xmlquery -p CLM_BLDNML_OPTS` +- If you are running the `bgc` model, check to see if you should be running the prognostic crop model: option `-crop` in `CLM_BLDNML_OPTS` +- Make sure the `LND_TUNING_MODE` is correct: `./xmlquery LND_TUNING_MODE` +- For an "`I` compset" make sure you are running over the correct forcing years: usually `./xmlquery -p DATM_YR` +- For an "`I` compset" make sure the DATM streams are operating over the correct years: look at the `CaseDocs/datm.streams.xml` file +- First and align year for streams should be the start year of a historical simulation: `./xmlquery RUN_STARTDATE; grep stream_year_first CaseDocs/lnd_in; grep model_year_align CaseDocs/lnd_in` +- Last year for streams should be the last year you are going to run to (or beyond it): `grep stream_year_last CaseDocs/lnd_in` +- Make sure you are starting from appropriate spunup initial conditions: + - Check the run-type with: `./xmlquery RUN_TYPE` + - Check finidat for a startup or hybrid simulation: `grep finidat CaseDocs/lnd_in` + - Check nrevsn for a branch simulation: `grep nrevsn CaseDocs/lnd_in` +- Run for a month (or some short period) and go over the log files and especially the settings and files read in them: for an `I` case you especially want to look at the `lnd.log` and `atm.log` files + +Some other suggestions on things that can be done: + +- Compare namelist files to an existing case if you are doing something almost the same as a previous simulation +- Ask another collaborator to look over your case directory \ No newline at end of file diff --git a/README_GITFLEXIMOD.md b/README_GITFLEXIMOD.md new file mode 100755 index 0000000000..1ed51a8b59 --- /dev/null +++ b/README_GITFLEXIMOD.md @@ -0,0 +1,110 @@ +# Obtaining the full model code and associated scripting infrastructure + +CTSM is released via GitHub. You will need some familiarity with git in order +to modify the code and commit these changes. However, to simply checkout and run the +code, no git knowledge is required other than what is documented in the following steps. + +To obtain the CTSM code you need to do the following: + +1. Clone the repository. : + + git clone https://github.com/ESCOMP/CTSM.git my_ctsm_sandbox + + This will create a directory `my_ctsm_sandbox/` in your current working directory. + +2. Run `./bin/git-fleximod update`: + + cd my_ctsm_sandbox + ./bin/git-fleximod update + ./bin/git-fleximod --help # for a user's guide + + `git-fleximod` is a package manager that will + populate the ctsm directory with the relevant versions of each of the + components along with the CIME infrastructure code. + Additional documentation for git-fleximod appears here: + + +"components" here refers to seperate git repositories for seperable parts of +the code (such as the MOSART or mizuRoute river models). Because they are +managed with "submodule" in git hereafter we will refer to them as "submodule(s)". + +At this point you have a working version of CTSM. + +To see full details of how to set up a case, compile and run, see the CIME documentation at . + +## More details on git-fleximod + +The file `.gitmodules` in your top-level CTSM directory tells +`git-fleximod` which tag/branch of each submodule +should be brought in to generate your sandbox. + +NOTE: If you manually modify a submodule without updating `.gitmodules`, +e.g. switch to a different tag, then rerunning git-fleximod will warn you of +local changes you need to resolve. +git-fleximod will not change a modified submodule back to what is specified in +`.gitmodules` without the `--force` option. +See below documentation [Customizing your CTSM sandbox](#customizing-your-ctsm-sandbox) for more details. + +**You need to rerun git-fleximod whenever `.gitmodules` has +changed** (unless you have already manually updated the relevant +submodule(s) to have the correct branch/tag checked out). Common times +when this is needed are: + +- After checking out a new CTSM branch/tag +- After merging some other CTSM branch/tag into your currently + checked-out branch + +# Customizing your CTSM sandbox + +There are several use cases to consider when you want to customize or modify your CTSM sandbox. + +## Switching to a different CTSM branch or tag + +If you have already checked out a branch or tag and **HAVE NOT MADE ANY +MODIFICATIONS** it is simple to change your sandbox. Say that you +checked out ctsm5.2.0 but really wanted to have ctsm5.3.0; +you would simply do the following: + + git checkout ctsm5.3.0 + ./bin/git-fleximod update + +You should **not** use this method if you have made any source code +changes, or if you have any ongoing CTSM cases that were created from +this sandbox. In these cases, it is often easiest to do a second `git +clone`. + +## Pointing to a different version of a submodule + +Each entry in `.gitmodules` has the following form (we use CIME as an +example below): + + [submodule "cime"] + path = cime + url = https://github.com/ESMCI/cime + fxtag = cime6.0.246 + fxrequired = ToplevelRequired + fxDONOTUSEurl = https://github.com/ESMCI/cime + +Each entry specifies either a tag or a hash. To point to a new tag or hash: + +1. Modify the relevant entry/entries in `.gitmodules` (e.g., changing + `cime6.0.246` to `cime6.0.247` above) + +2. Checkout the new submodule(s): + + ./bin/git-fleximod update + +Keep in mind that changing individual submodule from a tag may result +in an invalid model (won't compile, won't run, not scientifically +meaningful) and is unsupported. + +### Committing your change to `.gitmodules` + +After making this change, it's a good idea to commit the change in your +local CTSM git repository. First create a branch in your local +repository, then commit it. Feel free to create whatever local branches +you'd like in git. For example: + + git checkout -b my_ctsm_branch + git add .gitmodules + git commit -m "Update CIME to cime6.0.247" diff --git a/README_GITFLEXIMOD.rst b/README_GITFLEXIMOD.rst deleted file mode 100644 index d1ab767645..0000000000 --- a/README_GITFLEXIMOD.rst +++ /dev/null @@ -1,118 +0,0 @@ -Obtaining the full model code and associated scripting infrastructure -===================================================================== - -CTSM is released via GitHub. You will need some familiarity with git in order -to modify the code and commit these changes. However, to simply checkout and run the -code, no git knowledge is required other than what is documented in the following steps. - -To obtain the CTSM code you need to do the following: - -#. Clone the repository. :: - - git clone https://github.com/ESCOMP/CTSM.git my_ctsm_sandbox - - This will create a directory ``my_ctsm_sandbox/`` in your current working directory. - -#. Run **./bin/git-fleximod update**. :: - - cd my_ctsm_sandbox - ./bin/git-fleximod update - ./bin/git-fleximod --help # for a user's guide - - **git-fleximod** is a package manager that will - populate the ctsm directory with the relevant versions of each of the - components along with the CIME infrastructure code. - Additional documentation for git-fleximod appears here: - https://github.com/ESMCI/git-fleximod?tab=readme-ov-file#git-fleximod - -"components" here refers to seperate git repositories for seperable parts of -the code (such as the MOSART or mizuRoute river models). Because they are -managed with "submodule" in git hereafter we will refer to them as "submodule(s)". - -At this point you have a working version of CTSM. - -To see full details of how to set up a case, compile and run, see the CIME documentation at http://esmci.github.io/cime/ . - -More details on git-fleximod ----------------------------- - -The file **.gitmodules** in your top-level CTSM directory tells -**git-fleximod** which tag/branch of each submodule -should be brought in to generate your sandbox. - -NOTE: If you manually modify a submodule without updating .gitmodules, -e.g. switch to a different tag, then rerunning git-fleximod will warn you of -local changes you need to resolve. -git-fleximod will not change a modified submodule back to what is specified in -.gitmodules without the --force option. -See below documentation `Customizing your CTSM sandbox`_ for more details. - -**You need to rerun git-fleximod whenever .gitmodules has -changed** (unless you have already manually updated the relevant -submodule(s) to have the correct branch/tag checked out). Common times -when this is needed are: - -* After checking out a new CTSM branch/tag - -* After merging some other CTSM branch/tag into your currently - checked-out branch - -Customizing your CTSM sandbox -============================= - -There are several use cases to consider when you want to customize or modify your CTSM sandbox. - -Switching to a different CTSM branch or tag -------------------------------------------- - -If you have already checked out a branch or tag and **HAVE NOT MADE ANY -MODIFICATIONS** it is simple to change your sandbox. Say that you -checked out ctsm5.2.0 but really wanted to have ctsm5.3.0; -you would simply do the following:: - - git checkout ctsm5.3.0 - ./bin/git-fleximod update - -You should **not** use this method if you have made any source code -changes, or if you have any ongoing CTSM cases that were created from -this sandbox. In these cases, it is often easiest to do a second **git -clone**. - -Pointing to a different version of a submodule ----------------------------------------------- - -Each entry in **.gitmodules** has the following form (we use CIME as an -example below):: - - [submodule "cime"] - path = cime - url = https://github.com/ESMCI/cime - fxtag = cime6.0.246 - fxrequired = ToplevelRequired - fxDONOTUSEurl = https://github.com/ESMCI/cime - -Each entry specifies either a tag or a hash. To point to a new tag or hash: - -#. Modify the relevant entry/entries in **.gitmodules** (e.g., changing - ``cime6.0.246`` to ``cime6.0.247`` above) - -#. Checkout the new submodule(s):: - - ./bin/git-fleximod update - -Keep in mind that changing individual submodule from a tag may result -in an invalid model (won't compile, won't run, not scientifically -meaningful) and is unsupported. - -Committing your change to .gitmodules -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -After making this change, it's a good idea to commit the change in your -local CTSM git repository. First create a branch in your local -repository, then commit it. Feel free to create whatever local branches -you'd like in git. For example:: - - git checkout -b my_ctsm_branch - git add .gitmodules - git commit -m "Update CIME to cime6.0.247" - diff --git a/README_on_CTSM.md b/README_on_CTSM.md new file mode 100644 index 0000000000..0dbcbae64e --- /dev/null +++ b/README_on_CTSM.md @@ -0,0 +1,160 @@ +$CTSMROOT/README 11/24/2025 + +Community Terrestrial Systems Model (CTSM) science version 5.4 series -- source code, tools, +offline-build and test scripts. This gives you everything you need +to run CTSM with CESM with the CMEPS driver and CDEPS data models to provide CRUJRA or GSWP3 forcing data (some older options also available) in +place of a modeled atmosphere. + +CMEPS is the Community Mediator for Earth Prediction Systems. And CDEPS is the +Community Data Models for Earth Prediction System. They are both NUOPC based models +used to drive the CESM (Community Earth System Model) of which CTSM is a component of. +NUOPC is the National Unified Operational Prediction Capability a standard way of building +coupled model systems. The NUOPC layer is based on the Earth System Modeling Framework (ESMF). + +For lists of current bugs (issues) and current development see the CTSM GitHub page: + +https://github.com/ESCOMP/CTSM + +For Code of Conduct (how to work with each other on the CTSM project): + +https://github.com/ESCOMP/CTSM?tab=coc-ov-file + +INFORMATION ON THE CMEPS DRIVER: +- https://escomp.github.io/CMEPS +- https://earthsystemmodeling.org/nuopc/ + +IMPORTANT NOTE ON CESM CHECKOUT VERSUS A CTSM CHECKOUT: + +If this is the top level directory from making a clone of CTSM the +directory structure is a little bit different than if CTSM is from +a clone of the entire CESM. If this is part of CESM this directory +will be under `components/clm` alongside other CESM component models. +For a CTSM checkout this will be the top level directory. + +Other documentation will refer to `$CTSMROOT` and it means the directory +that this file is at. CIMEROOT is the directory where "cime" is for +this checkout. For a CESM checkout `$CIMEROOT` will be the "cime" directory +beneath the top level directory. For a CTSM checkout `$CIMEROOT` will +be `$CTSMROOT/cime`. + +IMPORTANT NOTE ABOUT (deprecated) + +Anything marked with (deprecated) is something is going to be removed in a future update. +Often this means it will be replaced with something else. + + +General directory structure ($CTSMROOT): + +- `doc`: Documentation of CTSM +- `bld`: build-namelist scripts for CTSM +- `src`: CTSM Source code +- `lilac`: Lightweight Infrastructure for Land-Atmosphere Coupling (for coupling to a host atmosphere model) +- `tools`: CTSM Offline tools to prepare input datasets and process output +- `cime_config`: Configuration files of cime for compsets and CTSM settings +- `bin/git-fleximod`: Script to manage the needed sub-component source directories (handled with git submodule) +- `py_env_create`: Script to setup the python environment for CTSM python tools using conda +- `python`: Python modules used in tools and testing and automated checking of ALL CTSM python scripts + +Directory structure only for a CTSM checkout: + +- `components`: Other active sub-components needed for CTSM to run (river routing and land-ice models) +- `libraries`: CESM libraries: PIO (deprecated) +- `share`: CESM shared code +- `ccs_config`: CIME configure files (for grids, compsets, and machines) for CESM + +- `cime/scripts`: cesm/cime driver scripts + +- `components/cmeps`: CESM top level driver (for NUOPC driver [which is the default]) source code +- `components/cdeps`: CESM top level data model shared code (for NUOPC driver) +- `components/cism`: CESM Community land Ice Sheet Model +- `components/mosart`: Model for Scale Adaptive River Transport +- `components/mizuroute`: Reached based river transport model for water routing (allows both gridded river and Hydrologic Responce Unit river grids) +- `components/rtm`: CESM River Transport Model + +Top level documentation ($CTSMROOT): + +- `README_on_CTSM.md`: This file +- `README.md`: File that displays on github under https::/github.com/ESCOMP/CTSM.git +- `README_GITFLEXIMOD.md`: Information on how to work with git-fleximod for CTSM +- `README.CHECKLIST.new_case.md`: Information on starting a new case (i.e. simulation) +- `WhatsNewInCTSM5.4.md`: Overview document of the changes between ctsm5.3 and ctsm5.4 (earlier versions in /doc) +- `Copyright`: CESM Copyright file +- `doc/UpdateChangeLog.pl`: Script to add documentation on a tag to the ChangeLog/ChangeSum files +- `doc/ChangeLog`: Documents different CTSM versions +- `doc/ChangeSum`: Summary documentation of different CTSM versions +- `doc/design`: Software Engineering and code design document files + +Checklists for standard Software Engineering tasks + +- `./doc/README.CHECKLIST.master_tags.md` +- `./bld/namelist_files/README.CHECKLIST.interpolating_initial_conditions.md` + +Documentation of Namelist Items: (view the following in a web browser) + +- `bld/namelist_files/namelist_definition_ctsm.xml`: Definition of all namelist items +- `bld/namelist_files/namelist_defaults_ctsm.xml`: Default values + +Important files in main directories (under $CTSMROOT): +============================================================================================= + +- `run_sys_tests`: Python script to send the standard CTSM testing off (submits the create_test test suite for several different compilers on the machines we do standard CTSM testing on) + +- `parse_cime.cs.status`: Script to parse test status files `cs.status.*` created by create_test (can be used along with run_sys_tests) +- `doc/Quickstart.GUIDE`: Quick guide to using NUOPC scripts +- `doc/IMPORTANT_NOTES.md`: Some important notes about this version of CTSM, configuration modes and namelist items that are not validated or functional +- `doc/ChangeLog`: Detailed list of changes for each model version +- `doc/ChangeSum`: Summary one-line list of changes for each model version +- `doc/UsersGuide`: CTSM Users Guide + +- `bld/README`: Description of how to use the `build-namelist` scripts +- `bld/build-namelist`: Lower level script to build CTSM namelists + +- `cime_config/buildnml`: Build the CTSM namelist for CIME +- `cime_config/buildlib`: Build the CTSM library +- `cime_config/config_compsets.xml`: Define CTSM compsets +- `cime_config/config_component.xml`: Define CTSM XML settings +- `cime_config/config_tests.xml`: Define CTSM specific tests +- `cime_config/config_pes.xml`: Define Processor layouts for various CTSM grids and compsets +- `cime_config/testdefs`: Directory for specification of CTSM testing +- `cime_config/testdefs/ExpectedTestFails.xml`: List of tests that are expected to fail +- `cime_config/usermods_dirs/clm`: Directories of sets of user-modification subdirs; these are directories that add specific user modifications to simulations created using `cime/scripts/create_newcase --user-mods-dir clm/*` + +- `tools/mksurfdata_esmf`: Directory to build program to create surface dataset at any resolution +- `tools/crop_calendars`: Tools to process and process and create crop calendar datasets for CTSM +- `tools/modify_input_files`: Script to modify existing CTSM input datasets in standard ways +- `tools/site_and_regional`: Scripts to create input datasets for single site and regional cases, primarily by modifying existing global datasets +- `tools/contrib`: Miscellansous useful scripts for pre and post processing as well as case management of CTSM. These scripts are contributed by users and may not be as well tested or supported as other tools +- `.vscode`: Suggested settings for using MS Visual Studio code with CTSM + + +Source code directory structure: +============================================================================================= + +- `src/biogeochem`: Biogeochemisty +- `src/main`: Main control and high level code +- `src/cpl`: Land model high level caps for NUOPC driver (and LILAC) +- `src/biogeophys`: Biogeophysics (Hydrology) +- `src/dyn_subgrid`: Dynamic land unit change +- `src/init_interp`: Online interpolation +- `scr/fates`: FATES (Functionally Assembled Terrestrial Ecosystem Simulator) ecosystem demography model and sub-directories +- `src/utils`: Utility codes +- `src/self_tests`: Internal testing (unit tests run as a part of a CTSM system test) +- `src/unit_test_shr`: Unit test shared modules for unit testing +src/unit_test_stubs Unit test stubs that replicate CTSM code simpler + +QUICKSTART: using the NUOPC driver scripts +============================================================================================= + + cd $CIMEROOT/scripts + ./create_newcase # get help on how to run create_newcase + ./create_newcase --case testI --res f09_t232 --compset I2000Clm60BgcCrop + # create new "I" case for default machine at 1.9x2.5_gx1v7 + # "I2000Clm60BgcCrop" case is clm6_0 physics, CDEPS, and inactive ice/ocn/glc + # and MOSART for river-routing + cd testI + ./case.setup # create the $CASE.run file + ./case.build # build model and create namelists + ./case.submit # submit script + # (NOTE: ./xmlchange RESUBMIT=10 to set RESUBMIT to number + # # of times to automatically resubmit -- 10 in this example) + diff --git a/WhatsNewInCTSM5.4.md b/WhatsNewInCTSM5.4.md deleted file mode 100755 index 17b43d9f80..0000000000 --- a/WhatsNewInCTSM5.4.md +++ /dev/null @@ -1,151 +0,0 @@ -# What's new in CTSM 5.4 (tag `ctsm5.4.002`) - -# Purpose and description of changes since CTSM 5.3 (tag `ctsm5.3.021`) - -## New features - -* New surface datasets from CMIP7 data including PFT and urban distributions, land use transitions, population density, and atmospheric C isotopes. These data are only available through the historical record (1850-2023), and - * are not available for future periods (presently known as SSP), - * for future periods and N deposition we continue to use CMIP6 data from CESM2. -* Option to use CRUJRA2024 atmospheric driver data with clm6 and clm5 physics options ([PR #2956](https://github.com/ESCOMP/ctsm/pull/2956)), this is the default data-atmosphere (DATM) for clm6. This CRUJRA dataset covers 1901-2023, whereas previous GSWP3 only covers 1901-2014. -* Capability to run single-point PLUMBER tower sites, similar to the NEON tower capability ([issue #1487](https://github.com/ESCOMP/CTSM/issues/1487)). Initial conditions are not provided for PLUMBER sites. -* New CLM\_CMIP\_ERA flag in env\_run.xml. Valid options are cmip7 and cmip6. Defaults to cmip7 except in compsets containing SSP for which it defaults to cmip6 because there are no future-period datasets yet available for CMIP7. -* Automatic, more flexible use of anomaly forcings for CMIP6 ISSP cases, which also use the cmip6 CLM\_CMIP\_ERA flag: [Documentation](https://escomp.github.io/CTSM/users_guide/running-special-cases/Running-with-anomaly-forcing.html) - -* Unsupported script that checks for spinup equilibrium in `tools/contrib/` for spectral element grids ([PR #2991](https://github.com/ESCOMP/ctsm/pull/2991)). -* New paramfile tools that allow users to query and modify CLM parameter files ([documentation](https://escomp.github.io/CTSM/users_guide/using-clm-tools/paramfile-tools.html)) -* Optional time-evolving \`leafcn\_target\`. More under “Additional detail” below. -* New vertical movement scheme for soil nitrate, which is off by default (PR [#2992](https://github.com/ESCOMP/CTSM/pull/2992)). -* Documentation improvements and new URL: https://escomp.github.io/CTSM/index.html. -* FATES: - * Grazing ([sci.1.81.0\_api.37.1.0](https://github.com/NGEET/fates/releases/tag/sci.1.81.0_api.37.1.0)). - * Johnson and Berry 2021 electron transport model ([sci.1.85.0\_api.40.0.0](https://github.com/NGEET/fates/releases/tag/sci.1.85.0_api.40.0.0)). - * Managed Fire ([sci.1.87.0\_api.41.0.0](https://github.com/NGEET/fates/releases/tag/sci.1.87.0_api.41.0.0)). - -## Answer changes - -Changes to defaults for \`clm6\` physics: - -* New CMIP7 surface and landuse timeseries datasets (see in Additional Details below). -* New namelist variables \`snow\_thermal\_cond\_glc\_method\` and \`snow\_thermal\_cond\_lake\_method\` ([PR #3072](https://github.com/ESCOMP/CTSM/pull/3072)). Snow thermal conductivity uses Jordan1991 over glaciers to reduce Greenland melt rates by default and Sturm over land and lake land units. -* Bytnerowicz is now the default nfix\_method for clm6 (https://github.com/ESCOMP/ctsm/pull/2972) which revises the temperature function for nitrogen fixation, replacing the Houlton *et al.* function. -* Updates to MEGAN for BVOCs (https://github.com/ESCOMP/CTSM/pull/3065 https://github.com/ESCOMP/CTSM/pull/3309). Removes dependence on soil moisture from clm6 physics. -* New model parameter values that were calibrated to improve carbon cycle representation with CRUJRA. -* New model parameter values that were calibrated to improve the fire model. Now using li2024 fire code. -* New initial conditions files for f09 ("1-degree" 1850, 2000), f19 (“2-degree” 1850), and ne30 (1850, 1979, 2000\) resolutions. -* Change default for glcmec\_downscale\_longwave to FALSE for clm6 physics as turning off the LW downscaling improves the melt and runoff biases. -* See “Changes to FATES and the FATES parameter file” below. -* Namelist defaults change so that - * use\_c13/use\_c14 are on only for HistClm60Bgc compsets with CRUJRA2024 or CAM7 forcing; examples of when use\_c13/use\_c14 are now off include SSP and single-point compsets, as well as cases using older forcings, such as CAM6, GSWP3v1, Qian, and CRUv7 - * when use\_c13 or use\_c14 is on, turn on the corresponding time series file (responding to the CLM_CMIP_ERA flag) - * C13/C14 CMIP7 data is done using streams with new namelist variables (stream_*_atm_c13, stream_*_atm_c14) - * irrigation is on for transient cases (1850-2000, 1850-2100, but not for clm4\_5). - -Changes for all physics versions: - -* Parameters updated: Added MIMICS parameter \`mimics\_fi\` (fraction of litter inputs that bypass litter pools, directly contributing to SOM) and updated other MIMICS parameters (https://github.com/ESCOMP/CTSM/pull/2365) to remove NPP control on turnover, fix density dependent control on turnover, add litterfall fluxes that bypass litter pools and contribute directly to soil organic matter. -* FATES parameter file updated: ([PR \#2965](https://github.com/ESCOMP/CTSM/pull/2965), [PR \#2904](https://github.com/ESCOMP/CTSM/pull/2904), [PR \#1344](https://github.com/NGEET/fates/pull/1344), [PR \#3087](https://github.com/ESCOMP/CTSM/pull/3087)). See “FATES parameter file” section below for details. -* New surface datasets and landuse timeseries files (see “surface datasets” section below). -* CMIP7 C13/C14 atmospheric timeseries data - -## Heads up - -* History tapes now split into two files from hX to hXi and hXa, where X is the tape number (e.g. h0i/h0a) and where "i" stands for history file containing instantaneous fields, while "a" stands for history file containing non-instantaneous fields. Details in the “history files” section below and in the PRs https://github.com/ESCOMP/ctsm/pull/2445 https://github.com/ESCOMP/MOSART/pull/117 https://github.com/ESCOMP/RTM/pull/61 and the corresponding issues. -* Adding time to 1d weighting fields in transient simulations PR https://github.com/ESCOMP/CTSM/pull/3328 -* Regarding CMIP7 vs. CMIP6 inputs: - * C13/C14 isotope datasets are the new CMIP7 datasets using streams, while when CLM_CMIP_ERA==cmip6, the older cmip6 files are used - * We supply only CMIP7 population density with clm6 physics in non-SSP cases, because the fire model is calibrated to that; conversely, we supply only CMIP6 population density for pre-clm6 physics and for SSP cases. - * We supply only CESM2 nitrogen deposition (ndep), so this gets used regardless of CLM\_CMIP\_ERA setting. - * For DATM we supply only CMIP6 aerosols. - * For DATM we supply only CMIP6 CO2. -* Issue with DOUT\_S\_SAVE\_INTERIM\_REST [https://github.com/ESCOMP/CTSM/issues/3351](https://github.com/ESCOMP/CTSM/issues/3351) was fixed. -* As of ctsm5.3.040, the new ctsm\_pylib conda environment is incompatible with our tools from before ctsm5.3.040 and vice versa. More under “Additional detail” below. - -# Additional detail - -## Changes related to history files - -(Note 1: The same information in this section applies to MOSART and RTM. -Note 2: The gist of the information in this section also appears in the [CTSM User’s Guide](https://escomp.github.io/CTSM/users_guide/setting-up-and-running-a-case/customizing-the-clm-namelist.html#various-ways-to-change-history-output-averaging-flags)). - -Following ctsm5.3.018 "Change history time to be the middle of the time bounds" and keeping CLM history consistent with CAM history, the CTSM5.4 change intends to prevent confusion associated with the time corresponding to instantaneous history fields by putting them on separate files than non-instantaneous fields. - -The now separate instantaneous history files represent the exact time step when they were written and do not include a time\_bounds variable. Conversely, non-instantaneous history files represent the period of their time\_bounds variable. As a result, time data on non-instantaneous history files are now read correctly during post processing (e.g. by xarray). Special handling may still be needed for instantaneous history files, whose timestamps represent the date and time at the END of the history timestep. So, e.g., an instantaneous variable saved at the end of year 2023 will get the timestamp 2024-01-01 00:00:00. - -Users will now see: - -1\) Two history files per clm, mosart, and rtm history tape: - tape h0 becomes h0a and h0i - tape h1 becomes h1a and h1i - ... - tape hX becomes hXa and hXi - -2\) Two history-restart files per history restart tape: - rh0 becomes rh0a and rh0i - rh1 becomes rh1a and rh1i - ... - rhX becomes rhXa and rhXi - -The CLM handles empty history (and corresponding history-restart) files by not generating them, while rtm and mosart give an error. Instead of refactoring rtm and mosart to behave like the clm (considered out of scope), we have introduced one active instantaneous field in mosart and one in rtm to bypass the "empty file" error. - -## New surface datasets and landuse timeseries files (https://github.com/ESCOMP/CTSM/pull/3482) - -* Transient landuse timeseries files going back to 1700 made for f09 and 360x720 grids. -* New resolutions now supported: ne3np4.pg3, mpasa30, ne0np4.NATL.ne30x8 (https://github.com/ESCOMP/CTSM/pull/3482) -* Updates to input datasets (also referred to as raw datasets): - * PFT/LAI/soil-color raw datasets; now from the CMIP7 timeseries that ends in 2023 (Issue [\#2851](https://github.com/ESCOMP/CTSM/issues/2851)). - * Two fire datasets: crop fire peak month and population density (https://github.com/ESCOMP/CTSM/issues/2701 https://github.com/ESCOMP/CTSM/issues/3302). - * Transient (historical) urban datasets are now based on CMIP7 urban data, partitioned into TBD, HD, and MD classes in proportion to GaoOneill present day classification. - -## Changes to FATES and the FATES parameter file - -* See [HLM-FATES compatibility table](https://fates-users-guide.readthedocs.io/en/latest/user/release-tags-compat-table.html) in the FATES user’s guide for all FATES tags associated with CTSM tag updates -* FATES answer changing updates - * The default hydro solver is updated to 2D Picard from 1D Taylor ([ctsm5.3.027](https://github.com/ESCOMP/CTSM/releases/tag/ctsm5.3.027)) - * Simplified leaf sun-shade fraction for two-stream radiation ([sci.1.83.0\_api.39.0.0](https://github.com/NGEET/fates/releases/tag/sci.1.83.0_api.39.0.0)) - * Default maximum canopy layer updated from 2 to 3 ([sci.1.87.1\_api.41.0.0](https://github.com/NGEET/fates/releases/tag/sci.1.87.1_api.41.0.0)) - * Various bug fixes (see compatibility table) -* FATES Parameter File Updates - * ctsm5.3.025 (API 37\) - * Adds pft-dependent btran model switches - * Adds parameters for land use grazing - * Updates the FATES z0mr turbulence parameters for consistency with CLM - * ctsm5.3.027 (API 38\) - * Migrates a number of global parameter file variables to the namelist - * Adds \`fates\_leaf\_fnps\` parameter for the electron transport model - * \`fates\_leaf\_theta\_cj\_c3\` and \`fates\_leaf\_theta\_cj\_c4\` depricated - * ctsm5.3.045 (API 40\) - * Changes to the default competitive exclusion parameter from probabilistic to rank-ordered sorting of cohorts by default - * Sets the logging default to clear cut - * Refactors the pft-specific phenology habit selection into a single parameter - * ctsm5.3.070 (API 41\) - * Add parameters for the managed fire feature addition - * Corrects the fates landuse crop pft to c3 cool grass - -## New ctsm\_pylib conda environment - -If you have a ctsm\_pylib conda environment installed from before ctsm5.3.040, you may want to keep that under a different name. We suggest the following command for doing this in a local copy of ctsm5.3.040 or later: - -```shell -./py_env_create -r ctsm_pylib_old -``` - -This first renames your existing ctsm\_pylib to ctsm\_pylib\_old and then installs the Python 3.13.2 version as ctsm\_pylib. If you are unsure whether you already have ctsm\_pylib installed, use the same command regardless, as it will skip the renaming step if necessary. - -Information about additional py\_env\_create options — including how to install a fresh copy of the old conda environment — is available as follows: - -```shell -./py_env_create --help -``` - -## Potentially time-evolving \`leafcn\_target\` replaces time-constant \`leafcn\` - -The former is calculated as a function of the latter and can be time-evolving depending on new paramfile parameter \`leafcn\_co2\_slope\` https://github.com/ESCOMP/ctsm/pull/1654. The time-evolving effect defaults to off with \`leafcn\_co2\_slope\` \= 0 on the parameter file. - -# Simulations supporting this release by providing initial conditions - -* f19 \`Clm60BgcCruJra\` 16pft: https://github.com/NCAR/LMWG_dev/issues/125 -* f09 with \`Clm60BgcCropCruJra\`: https://github.com/NCAR/LMWG_dev/issues/124 -* ne30 with \`Clm60BgcCropCruJra\`: https://github.com/NCAR/LMWG_dev/issues/123 (123\_HIST\_popDens) -* ne30 SP https://github.com/NCAR/LMWG_dev/issues/126 -* f09 SP https://github.com/NCAR/LMWG_dev/issues/127 diff --git a/WhatsNewInCTSM5.4.md b/WhatsNewInCTSM5.4.md new file mode 120000 index 0000000000..76c6ae1d79 --- /dev/null +++ b/WhatsNewInCTSM5.4.md @@ -0,0 +1 @@ +doc/WhatsNewInCTSM5.4.md \ No newline at end of file diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index e72b8e07c2..a4afdcebf0 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -816,15 +816,14 @@ sub setup_cmdl_fates_mode { } else { # dis-allow fates specific namelist items with non-fates runs my @list = ( "fates_spitfire_mode", "use_fates_planthydro", "use_fates_ed_st3", "use_fates_ed_prescribed_phys", - "use_fates_cohort_age_tracking","use_fates_inventory_init","use_fates_fixed_biogeog", + "use_fates_cohort_age_tracking","use_fates_inventory_init","use_fates_dbh_init","use_fates_fixed_biogeog", "use_fates_nocomp","use_fates_sp","fates_inventory_ctrl_filename","fates_harvest_mode", "fates_parteh_mode","use_fates_tree_damage","fates_seeddisp_cadence","use_fates_luh","fluh_timeseries", "flandusepftdat","use_fates_potentialveg","use_fates_lupft","fates_history_dimlevel", "use_fates_daylength_factor", "fates_photosynth_acclimation", "fates_stomatal_model", "fates_stomatal_assimilation", "fates_leafresp_model", "fates_cstarvation_model", "fates_regeneration_model", "fates_hydro_solver", "fates_radiation_model", "fates_electron_transport_model", - "use_fates_managed_fire" - ); + "use_fates_managed_fire", "fates_lu_transition_logic"); # dis-allow fates specific namelist items with non-fates runs foreach my $var ( @list ) { @@ -1706,10 +1705,10 @@ sub process_namelist_inline_logic { } setup_logic_cnmatrix($opts, $nl_flags, $definition, $defaults, $nl, $envxml_ref); setup_logic_spinup($opts, $nl_flags, $definition, $defaults, $nl); - setup_logic_supplemental_nitrogen($opts, $nl_flags, $definition, $defaults, $nl); setup_logic_c_isotope($opts, $nl_flags, $definition, $defaults, $nl); setup_logic_snowpack($opts, $nl_flags, $definition, $defaults, $nl); setup_logic_fates($opts, $nl_flags, $definition, $defaults, $nl); + setup_logic_supplemental_nitrogen($opts, $nl_flags, $definition, $defaults, $nl); setup_logic_z0param($opts, $nl_flags, $definition, $defaults, $nl); setup_logic_misc($opts, $nl_flags, $definition, $defaults, $nl); @@ -2084,13 +2083,16 @@ sub setup_logic_irrigate { my ($opts, $nl_flags, $definition, $defaults, $nl) = @_; add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'irrigate', - 'use_crop'=>$nl_flags->{'use_crop'}, 'use_cndv'=>$nl_flags->{'use_cndv'}, + 'use_crop'=>$nl_flags->{'use_crop'}, 'use_cndv'=>$nl_flags->{'use_cndv'}, 'use_fates'=>$nl_flags->{'use_fates'}, 'sim_year'=>$nl_flags->{'sim_year'}, 'sim_year_range'=>$nl_flags->{'sim_year_range'}, ); if ( &value_is_true($nl->get_value('irrigate') ) ) { $nl_flags->{'irrigate'} = ".true."; if ( $nl_flags->{'sim_year'} eq "PtVg" ) { $log->fatal_error("irrigate=TRUE does NOT make sense with the Potential Vegetation dataset, leave irrigate=FALSE"); } + if (&value_is_true($nl_flags->{'use_fates'})) { + $log->fatal_error("irrigate=TRUE is NOT possible with use_fates=TRUE, leave irrigate=FALSE"); + } } else { $nl_flags->{'irrigate'} = ".false."; } @@ -2264,6 +2266,7 @@ sub setup_logic_params_file { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'paramfile', 'phys'=>$nl_flags->{'phys'}, + 'use_hillslope'=>$nl_flags->{'use_hillslope'}, 'lnd_tuning_mode'=>$nl_flags->{'lnd_tuning_mode'}, 'use_flexibleCN'=>$nl_flags->{'use_flexibleCN'} ); } @@ -3321,12 +3324,12 @@ sub setup_logic_supplemental_nitrogen { if ( $nl_flags->{'bgc_mode'} ne "sp" && $nl_flags->{'bgc_mode'} ne "fates" && &value_is_true($nl_flags->{'use_crop'}) ) { # If this is non-fates, non-sp and crop is active add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, - 'suplnitro', 'use_cn'=>$nl_flags->{'use_cn'}, 'use_crop'=>$nl_flags->{'use_crop'}); + 'suplnitro', 'use_cn'=>$nl_flags->{'use_cn'}, 'use_crop'=>$nl_flags->{'use_crop'}); - } elsif ( $nl_flags->{'bgc_mode'} eq "fates" && not &value_is_true( $nl_flags->{'use_fates_sp'}) ) { - # Or... if its fates but not fates-sp + } elsif ( $nl_flags->{'bgc_mode'} eq "fates" ) { + # Or... if its fates add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, - 'suplnitro', 'use_fates'=>$nl_flags->{'use_fates'}); + 'suplnitro', 'fates_parteh_mode'=>remove_leading_and_trailing_quotes($nl->get_value('fates_parteh_mode'))); } # # Error checking for suplnitro @@ -3342,9 +3345,21 @@ sub setup_logic_supplemental_nitrogen { if ( $suplnitro =~ /ALL/i ) { if ( $nl_flags->{'bgc_spinup'} eq "on" && $nl_flags->{'bgc_mode'} ne "fates" ) { - $log->warning("There is no need to use a bgc_spinup mode when supplemental Nitrogen is on for all PFT's, as these modes spinup Nitrogen" ); + $log->warning("There is no need to use a bgc_spinup mode when supplemental Nitrogen is on for all PFTs, as these modes spinup Nitrogen" ); } } + + my $parteh_mode = $nl->get_value('fates_parteh_mode'); + if ( ($parteh_mode =~ /carbon_only/i) && ($suplnitro !~ /ALL/i) ) { + $log->fatal_error("supplemental Nitrogen (suplnitro) is NOT set to ALL, FATES is on, " . + "and fates_parteh_mode = $parteh_mode, so Nitrogen is not active; " . + "change suplnitro back to ALL"); + } + if ( ($parteh_mode =~ /carbon_nitrogen/i) && &value_is_true( $nl_flags->{'use_fates_sp'}) ) { + $log->fatal_error("FATES is on, " . + "FATES-SP is active, but fates_parteh_mode = $parteh_mode, so Nitrogen is active; " . + "change fates_parteh_mode to carbon_only or do not use FATES-SP"); + } } } @@ -3499,12 +3514,10 @@ sub setup_logic_methane { my $finundation_method = remove_leading_and_trailing_quotes($nl->get_value('finundation_method' )); # prognostic inundation does not require an input stream; other methods do if($finundation_method ne 'h2osfc') { - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldfilename_ch4finundated', + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldfilename_ch4finundated', 'finundation_method'=>$finundation_method); - if ($opts->{'driver'} eq "nuopc" ) { - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_meshfile_ch4finundated', + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_meshfile_ch4finundated', 'finundation_method'=>$finundation_method); - } } add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_aereoxid_prog', 'use_cn'=>$nl_flags->{'use_cn'}, 'use_fates'=>$nl_flags->{'use_fates'} ); @@ -3665,8 +3678,11 @@ sub setup_logic_hillslope { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'hillslope_transmissivity_method' ); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'hillslope_pft_distribution_method' ); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'hillslope_soil_profile_method' ); + + $nl_flags->{'use_hillslope'} = $nl->get_value('use_hillslope'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_hillslope_routing', 'use_hillslope'=>$nl_flags->{'use_hillslope'} ); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'hillslope_fsat_equals_zero', 'use_hillslope'=>$nl_flags->{'use_hillslope'} ); + my $use_hillslope = $nl->get_value('use_hillslope'); my $use_hillslope_routing = $nl->get_value('use_hillslope_routing'); if ( (! &value_is_true($use_hillslope)) && &value_is_true($use_hillslope_routing) ) { @@ -4885,12 +4901,12 @@ sub setup_logic_fates { if (&value_is_true( $nl_flags->{'use_fates'}) ) { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'}); my @list = ( "use_fates_planthydro", "use_fates_ed_st3", "use_fates_ed_prescribed_phys", - "use_fates_inventory_init","fates_seeddisp_cadence","fates_history_dimlevel", + "use_fates_inventory_init","use_fates_dbh_init","fates_seeddisp_cadence","fates_history_dimlevel", "fates_harvest_mode","fates_parteh_mode", "use_fates_cohort_age_tracking","use_fates_tree_damage", "use_fates_daylength_factor", "fates_photosynth_acclimation", "fates_stomatal_model", "fates_stomatal_assimilation", "fates_leafresp_model", "fates_cstarvation_model", "fates_regeneration_model", "fates_hydro_solver", "fates_radiation_model", "fates_electron_transport_model", - "use_fates_managed_fire" + "use_fates_managed_fire","fates_lu_transition_logic" ); foreach my $var ( @list ) { @@ -4903,6 +4919,7 @@ sub setup_logic_fates { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_luh', 'use_fates'=>$nl_flags->{'use_fates'}, 'use_fates_lupft'=>$nl->get_value('use_fates_lupft'), 'use_fates_potentialveg'=>$nl->get_value('use_fates_potentialveg'), + 'fates_lu_transition_logic'=>$nl->get_value('fates_lu_transition_logic'), 'fates_harvest_mode'=>remove_leading_and_trailing_quotes($nl->get_value('fates_harvest_mode')) ); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_nocomp', 'use_fates'=>$nl_flags->{'use_fates'}, 'use_fates_lupft'=>$nl->get_value('use_fates_lupft'), @@ -4914,14 +4931,6 @@ sub setup_logic_fates { 'use_fates_managed_fire'=>$nl->get_value('use_fates_managed_fire'), 'use_fates_sp'=>$nl_flags->{'use_fates_sp'} ); - my $suplnitro = $nl->get_value('suplnitro'); - my $parteh_mode = $nl->get_value('fates_parteh_mode'); - if ( ($parteh_mode == 1) && ($suplnitro !~ /ALL/) && not &value_is_true( $nl_flags->{'use_fates_sp'}) ) { - $log->fatal_error("supplemental Nitrogen (suplnitro) is NOT set to ALL, FATES is on, " . - "but and FATES-SP is not active, but fates_parteh_mode is 1, so Nitrogen is not active" . - "Change suplnitro back to ALL"); - } - # For FATES SP mode make sure no-competetiion, and fixed-biogeography are also set # And also check for other settings that can't be trigged on as well # @@ -4957,6 +4966,10 @@ sub setup_logic_fates { } } } + my $var = "use_fates_dbh_init"; + if ( &value_is_true($nl->get_value($var)) && ( !&value_is_true($nl->get_value("use_fates_nocomp")))) { + $log->fatal_error("$var can only be .true. use_fates_nocomp is .true." ); + } # make sure that fates landuse x pft mode has the necessary run mode configurations my $var = "use_fates_lupft"; if ( defined($nl->get_value($var)) ) { diff --git a/bld/README b/bld/README.md similarity index 51% rename from bld/README rename to bld/README.md index feb0b8495c..76dfcd6e1c 100644 --- a/bld/README +++ b/bld/README.md @@ -1,47 +1,47 @@ $CTSMROOT/bld/README Jun/08/2018 -CLM build and configure directory and scripts. Scripts to help -you prepare to build CLM as a component within CESM, and setup -a namelist for it. +CLM build and configure directory and scripts. Scripts to help you prepare to build CLM as a component within CESM, and setup a namelist for it. This is a lower level script called from with CESM/CIME. Important files/directories: ---------- Namelist build scripts +# Namelist build scripts -config_files/clm_phys_vers.pm ------------- Perl module to handle different CLM versions -config_files/config_definition_ctsm.xml --- XML file defining CTSM configuration items (mainly physics version) +config_files/clm_phys_vers.pm ------------- Perl module to handle different CLM versions +config_files/config_definition_ctsm.xml --- XML file defining CTSM configuration items (mainly physics version) ---------- Scripts to build the namelists -build-namelist --- Build the namelists needed +# Scripts to build the namelists +build-namelist --- Build the namelists needed -env_run.xml --- Sample case runtime environment variables, so build-namelist can run outside of a case directory. +env_run.xml --- Sample case runtime environment variables, so build-namelist can run outside of a case directory ---------- Test scripts directory -unit_testers --- Directory of scripts to test scipts in this directory - (most notably build-namelist) +# Test scripts directory ----------- XML Files describing namelists in namelist_files -namelist_files/namelist_defaults_ctsm.xml --------- List of default values for the ctsm namelist -namelist_files/namelist_defaults_overall.xml ------ List of default values for overall settings -namelist_files/namelist_defaults_usr_files.xml ---- List of default values for the user-files (deprecated) -namelist_files/namelist_definition_ctsm.xml ------- Definition of all namelist items for ctsm -namelist_files/namelist_definition.xsl ------------ Describes how to view the xml file as html -namelist_files/use_cases -------------------------- Specific configurations that build-namelist uses -namelist_files/use_cases/README ------------------- File explaining the naming convention for use_cases +unit_testers --- Directory of scripts to test scipts in this directory (most notably build-namelist) ----------- Driver namelist files, duplicated information from cime/driver/cime_config -namelist_files/namelist_defaults_drv.xml ---------- List of default values for driver namelist defaults -namelist_files/namelist_defaults_drydep.xml ------- List of default values for dry deposition and MEGAN fields -namelist_files/namelist_defaults_fire_emis.xml ---- List of default values for fire emission fields -namelist_files/namelist_defaults_dust_emis.xml ---- List of default values for the dust emissions module. -namelist_files/namelist_definition_drv.xml -------- Definition of all driver namelist items -namelist_files/namelist_definition_drv_flds.xml --- Definition of add driver fieldsnamelist items +# XML Files describing namelists in namelist_files +namelist_files/namelist_defaults_ctsm.xml --------- List of default values for the ctsm namelist +namelist_files/namelist_defaults_overall.xml ------ List of default values for overall settings +namelist_files/namelist_defaults_usr_files.xml ---- List of default values for the user-files (deprecated) +namelist_files/namelist_definition_ctsm.xml ------- Definition of all namelist items for ctsm +namelist_files/namelist_definition.xsl ------------ Describes how to view the xml file as html +namelist_files/use_cases -------------------------- Specific configurations that build-namelist uses +namelist_files/use_cases/README ------------------- File explaining the naming convention for use_cases + +# Driver namelist files, duplicated information from cime/driver/cime_config + +namelist_files/namelist_defaults_drv.xml ---------- List of default values for driver namelist defaults +namelist_files/namelist_defaults_drydep.xml ------- List of default values for dry deposition and MEGAN fields +namelist_files/namelist_defaults_fire_emis.xml ---- List of default values for fire emission fields +namelist_files/namelist_defaults_dust_emis.xml ---- List of default values for the dust emissions module +namelist_files/namelist_definition_drv.xml -------- Definition of all driver namelist items +namelist_files/namelist_definition_drv_flds.xml --- Definition of add driver fieldsnamelist items + +# XML helper files + +namelist_files/LogMessages.pm ---- Perl module to handle log output +namelist_files/history_fields.xsl - Style sheet for history fields as created by script that lists all of the history fields from the source files (../src/main/findHistFields.pl) ----------- XML helper files -namelist_files/LogMessages.pm ---- Perl module to handle log output -namelist_files/history_fields.xsl - Style sheet for history fields as created by script that lists all of the - history fields from the source files (../src/main/findHistFields.pl) diff --git a/bld/namelist_files/README.CHECKLIST.interpolating_initial_conditions.md b/bld/namelist_files/README.CHECKLIST.interpolating_initial_conditions.md index 463c3ffd65..12931a8670 100644 --- a/bld/namelist_files/README.CHECKLIST.interpolating_initial_conditions.md +++ b/bld/namelist_files/README.CHECKLIST.interpolating_initial_conditions.md @@ -14,8 +14,8 @@ interpolate: file. Note that there may be other options (like carbon isotopes) that also need to be turned on. While doing this, generate baselines. e.g., run - `SMS_Ld1.f09_g17.I1850Clm50Sp.cheyenne_intel.clm-default` or - `SMS_Ld1.f09_g17.I1850Clm50BgcCrop.cheyenne_intel.clm-ciso`, with + `SMS_Ld1.f09_t232.I1850Clm50Sp.derecho_intel.clm-default` or + `SMS_Ld1.f09_t232.I1850Clm50BgcCrop.derecho_intel.clm-ciso`, with baseline generation. - Confirm that the test points to the desired, original finidat file, @@ -32,7 +32,7 @@ interpolate: example: ``` - ncatted -h -a Notes_190111,global,c,c,'Interpolated from clmi.I1850Clm50BgcCrop.1366-01-01.0.9x1.25_gx1v6_simyr1850_c171213.nc. This is the finidat_interp_dest.nc file from SMS_Ln1.f09_g17.I1850Clm50BgcCrop.cheyenne_intel, run from ctsm1.0.dev022. Updates from the previous file are: (1) uses gx1v7 rather than gx1v6; (2) many inactive points are absent.' + ncatted -h -a Notes_190111,global,c,c,'Interpolated from clmi.I1850Clm50BgcCrop.1366-01-01.0.9x1.25_gx1v6_simyr1850_c171213.nc. This is the finidat_interp_dest.nc file from SMS_Ln1.f09_g17.I1850Clm50BgcCrop.derecho_intel, run from ctsm1.0.dev022. Updates from the previous file are: (1) uses gx1v7 rather than gx1v6; (2) many inactive points are absent.' ``` 4. Using `ncdump -h`, diff the headers of the new and old files, and diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index f8b880caf0..e011258f41 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -200,10 +200,11 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 1700 -.false. -.true. -.true. -.false. +.false. +.false. +.true. +.true. +.false. .false. @@ -220,10 +221,6 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .false. 0.0d00 - -NONE -ALL - 0.50,0.30 0.60,0.40 @@ -603,9 +600,10 @@ attributes from the config_cache.xml file (with keys converted to upper-case). - -lnd/clm2/paramdata/ctsm60_params.c260303.nc -lnd/clm2/paramdata/ctsm60-cam70_params.c260305.nc + +lnd/clm2/paramdata/ctsm60_params.c260518.nc +lnd/clm2/paramdata/ctsm60-cam70_params.c260518.nc +lnd/clm2/paramdata/ctsm60-HH_params.c260518.nc lnd/clm2/paramdata/clm50_params.c260305.nc lnd/clm2/paramdata/clm45_params.c260305.nc @@ -2701,6 +2699,8 @@ lnd/clm2/surfdata_esmf/NEON/ctsm5.4.0/surfdata_1x1_NEON_TOOL_hist_2000_78pfts_c2 0 1 no_harvest +4 ballberry1987 net ryan1991 @@ -2716,6 +2716,7 @@ lnd/clm2/surfdata_esmf/NEON/ctsm5.4.0/surfdata_1x1_NEON_TOOL_hist_2000_78pfts_c2 .false. .false. .false. +.false. .false. .false. .false. @@ -2724,7 +2725,8 @@ lnd/clm2/surfdata_esmf/NEON/ctsm5.4.0/surfdata_1x1_NEON_TOOL_hist_2000_78pfts_c2 .true. .true. .false. -1 +4 +carbon_only 0 .true. .true. @@ -2734,6 +2736,11 @@ lnd/clm2/surfdata_esmf/NEON/ctsm5.4.0/surfdata_1x1_NEON_TOOL_hist_2000_78pfts_c2 .false. 2,2 + + + +NONE +ALL diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 11c232615c..75a96a6c5f 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -708,10 +708,11 @@ Toggle to turn on the FATES model Functionally Assembled Terrestrial Ecosystem Simulator (FATES) - + Switch deciding which nutrient model to use in FATES. (Only relevant if FATES is on) +(fates_parteh_mode='carbon_nitrogen' is EXPERIMENTAL and UNSUPPORTED) + + +Initialize cohorts at coldstart with diameter at breast height instead of density +(Applies only if use_fates_nocomp=.true.) +(Only relevant if FATES is on). + + Setting for what types of FATES history to be allocate and @@ -939,6 +948,14 @@ which processes the raw land use data from the THEMIS tool data sets (https://doi.org/10.5065/29s7-7b41) + +Select the logic for land use class transitions. +Allowed values are 1-9. See the Land Use subsection of the Namelist Options section +of the FATES user guide for an explanation of the options. +(Only relevant if FATES with land use is on) + + Toggle to turn on the LUNA model, to effect Photosynthesis by leaf Nitrogen diff --git a/bld/namelist_files/use_cases/README b/bld/namelist_files/use_cases/README.md similarity index 68% rename from bld/namelist_files/use_cases/README rename to bld/namelist_files/use_cases/README.md index f139759b57..98672ff756 100644 --- a/bld/namelist_files/use_cases/README +++ b/bld/namelist_files/use_cases/README.md @@ -30,13 +30,10 @@ Present day options (uses default present-day simulation year -- which right now Where -yyyy = Simulation year (such as 1850 or 2000). -yyyy-yyyy = Range of simulation years to run over (i.e.. 1850-2000). -yyyy-PD = Range of simulation years to run over until present day (i.e.. 2018-2024). -$ssp_rcp = Shared Socieconomic Pathway (SSP) Representative concentration pathway (RCP) description string - for future scenarios: - SSP#-#.# (for example: SSP5-8.5, SSP1-2.6, SSP4-6.0 - [can be blank for historical cases]. -$desc = Description of anything else -- alpha-numeric. - Should start with an underscore ("_") if not by itself - (for _transient and _control). +yyyy = Simulation year (such as 1850 or 2000) +yyyy-yyyy = Range of simulation years to run over (i.e.. 1850-2000) +yyyy-PD = Range of simulation years to run over until present day (i.e.. 2018-2024) +$ssp_rcp = Shared Socieconomic Pathway (SSP) Representative concentration pathway (RCP) description string for future scenarios: + SSP#-#.# (e.g., SSP5-8.5, SSP1-2.6, SSP4-6.0) [can be blank for historical cases] +$desc = Description of anything else -- alpha-numeric; should start with an underscore ("_") if not by itself (for _transient and _control) + diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 91e0d95ca6..b77dc9670a 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -165,7 +165,7 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 3403; +my $ntests = 3407; if ( defined($opts{'compare'}) ) { $ntests += 2061; @@ -1151,8 +1151,12 @@ sub cat_and_create_namelistinfile { namelst=>"use_fun=TRUE", phys=>"clm6_0", }, - "useFATESWOsuplnitro" =>{ options=>"--bgc fates --envxml_dir . --no-megan", - namelst=>"suplnitro='NONE'", + "useFATESCwsuplnNONE" =>{ options=>"--bgc fates --envxml_dir . --no-megan", + namelst=>"suplnitro='NONE', fates_parteh_mode='carbon_only'", + phys=>"clm6_0", + }, + "useFATESCNwuse_fates_sp" =>{ options=>"--bgc fates --envxml_dir . --no-megan", + namelst=>"use_fates_sp = TRUE, fates_parteh_mode='carbon_nitrogen'", phys=>"clm6_0", }, "FATESwBothSpST3" =>{ options=>"--bgc fates --envxml_dir . --no-megan", @@ -1207,6 +1211,10 @@ sub cat_and_create_namelistinfile { namelst=>"use_fates_luh=.true., fluh_timeseries='zztop'", phys=>"clm4_5", }, + "useFATESLUH2invalidlogic" =>{ options=>"-bgc fates -envxml_dir . -no-megan", + namelst=>"use_fates_luh=.true., fates_lu_transition_logic=0", + phys=>"clm6_0", + }, "useMEGANwithFATES" =>{ options=>"-bgc fates -envxml_dir . -megan", namelst=>"", phys=>"clm4_5", @@ -1231,6 +1239,10 @@ sub cat_and_create_namelistinfile { namelst=>"use_fates_sp=T,use_fates_nocomp=F", phys=>"clm5_0", }, + "useFATESDBHInitWONoComp" =>{ options=>"-bgc fates -envxml_dir . -no-megan", + namelst=>"use_fates_dbh_init=T,use_fates_nocomp=F", + phys=>"clm6_0", + }, "useFATESSPwithLUH" =>{ options=>"-bgc fates -envxml_dir . -no-megan", namelst=>"use_fates_sp=T,use_fates_luh=T", phys=>"clm5_0", @@ -1267,6 +1279,10 @@ sub cat_and_create_namelistinfile { namelst=>"z0param_method=Meier2022", phys=>"clm5_0", }, + "FATES_w_irrig" =>{ options=>"-envxml_dir . -res 0.9x1.25 -bgc fates -use_case 20thC_transient", + namelst=>"irrigate=T", + phys=>"clm6_0", + }, "noanthro_w_crop" =>{ options=>"-envxml_dir . -res 0.9x1.25 -bgc bgc -crop -use_case 1850_noanthro_control", namelst=>"", phys=>"clm5_0", diff --git a/ccs_config b/ccs_config index 8fe3339bd2..39683243b4 160000 --- a/ccs_config +++ b/ccs_config @@ -1 +1 @@ -Subproject commit 8fe3339bd2b75c2090e06b054972bcd805c9d408 +Subproject commit 39683243b4e8e5b4576fd1b828c3ec4c9e15bc6b diff --git a/cime b/cime index ffbf6c596c..8961a11428 160000 --- a/cime +++ b/cime @@ -1 +1 @@ -Subproject commit ffbf6c596c5736538690af1bc9269d830abcd53c +Subproject commit 8961a11428891c96d7ed9390314c7dadc511e29f diff --git a/cime_config/SystemTests/mksurfdataesmf.py b/cime_config/SystemTests/mksurfdataesmf.py index 3cf77c6254..cda05d6513 100644 --- a/cime_config/SystemTests/mksurfdataesmf.py +++ b/cime_config/SystemTests/mksurfdataesmf.py @@ -3,8 +3,8 @@ and the CTSM completes a simulation with this fsurdat file. We test res = '10x15' because it uses a lower-res topography file instead of -the 1-km topography raw dataset. The 1-km file causes the test to run out of -memory on cheyenne. +the 1-km topography raw dataset. During development on previous machine +cheyenne we found that the 1-km file caused the test to run out of memory. Currently casper complains that `git -C` is not a valid option. I added -C to the `git describe` in gen_mksurfdata_namelist for this diff --git a/cime_config/SystemTests/systemtest_utils.py b/cime_config/SystemTests/systemtest_utils.py index c252f73251..0ac554c39a 100644 --- a/cime_config/SystemTests/systemtest_utils.py +++ b/cime_config/SystemTests/systemtest_utils.py @@ -15,7 +15,6 @@ def cmds_to_setup_conda(caseroot): # a shell with a conda environment activated conda_setup_commands += "CONDA_PREFIX=; " # Execute the module unload/load when "which conda" fails - # eg on cheyenne try: subprocess.run("which conda", shell=True, check=True) except subprocess.CalledProcessError: diff --git a/cime_config/config_pes.xml b/cime_config/config_pes.xml index 611fd0fc1c..f5b3d589b3 100644 --- a/cime_config/config_pes.xml +++ b/cime_config/config_pes.xml @@ -76,43 +76,6 @@ - - - - none - - -1 - -4 - -4 - -4 - -4 - -4 - -4 - -4 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - -1 - -1 - -1 - -1 - -1 - -1 - -1 - - - - @@ -224,80 +187,6 @@ - - - - none - - -1 - -40 - -40 - -40 - -40 - -40 - -40 - -40 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - -1 - -1 - -1 - -1 - -1 - -1 - -1 - - - - - - - - Much lower core count f19 layout, mainly for testing - - -1 - -4 - -4 - -4 - -4 - -4 - -4 - -4 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - @@ -373,7 +262,7 @@ - + none @@ -483,43 +372,6 @@ - - - - none - - -1 - -50 - -50 - -50 - -50 - -50 - -50 - -50 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - -1 - -1 - -1 - -1 - -1 - -1 - -1 - - - - @@ -632,7 +484,7 @@ - + none @@ -890,43 +742,6 @@ - - - - none - - -1 - -20 - -20 - -20 - -20 - -20 - -20 - -20 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - -1 - -1 - -1 - -1 - -1 - -1 - -1 - - - - @@ -964,43 +779,6 @@ - - - - none - - -1 - -70 - -70 - -70 - -70 - -70 - -70 - -70 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - -1 - -1 - -1 - -1 - -1 - -1 - -1 - - - - @@ -1038,43 +816,6 @@ - - - - none - - -1 - -70 - -70 - -70 - -70 - -70 - -70 - -70 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - -1 - -1 - -1 - -1 - -1 - -1 - -1 - - - - @@ -1112,43 +853,6 @@ - - - - none - - -1 - -70 - -70 - -70 - -70 - -70 - -70 - -70 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - -1 - -1 - -1 - -1 - -1 - -1 - -1 - - - - @@ -1450,43 +1154,6 @@ - - - - none - - -1 - -48 - -48 - -48 - -48 - -48 - -48 - -48 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - -1 - -1 - -1 - -1 - -1 - -1 - -1 - - - - @@ -1524,43 +1191,6 @@ - - - - none - - -1 - -48 - -48 - -48 - -48 - -48 - -48 - -48 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - -1 - -1 - -1 - -1 - -1 - -1 - -1 - - - - @@ -1598,43 +1228,6 @@ - - - - none - - -1 - -96 - -96 - -96 - -96 - -96 - -96 - -96 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - -1 - -1 - -1 - -1 - -1 - -1 - -1 - - - - @@ -1899,7 +1492,7 @@ - + none @@ -2361,80 +1954,6 @@ - - - - none - - -1 - -50 - -50 - -50 - -50 - -50 - -50 - -50 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - -1 - -1 - -1 - -1 - -1 - -1 - -1 - - - - - - - - Much lower core count nldas2 layout, mainly for testing - - -1 - -4 - -4 - -4 - -4 - -4 - -4 - -4 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index bad3ddcb55..c0eb8acf4e 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -135,13 +135,6 @@ - - - FAIL - #3798 - Divide by zero happens when ch4finundatedmapalgo==bilinear with intel/2025.3.2, but passes for nn,consf,consd - - FAIL @@ -191,9 +184,30 @@ ESCOMP/mizuRoute#613 + + + + FAIL + ESMCI/cime#4966 + + + + + + FAIL + ESMCI/cime#4966 + + + FAIL + ESCOMP/mizuRoute#615 + + + + + FAIL ESCOMP/mizuRoute#614 @@ -254,13 +268,6 @@ - - - FAIL - #3789 - - - FAIL @@ -275,20 +282,6 @@ - - - FAIL - #3789 - - - - - - FAIL - #3789 - - - diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 52e2dfcbf1..90f6ca000b 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -78,7 +78,7 @@ - + @@ -183,6 +183,7 @@ + @@ -230,6 +231,7 @@ + @@ -239,6 +241,7 @@ + @@ -780,6 +783,7 @@ + @@ -1393,7 +1397,6 @@ - @@ -1466,6 +1469,8 @@ + + @@ -1613,7 +1618,6 @@ - @@ -1705,6 +1709,8 @@ + + @@ -1742,7 +1748,6 @@ - @@ -1868,7 +1873,6 @@ - @@ -1922,10 +1926,13 @@ + + + @@ -1953,7 +1960,6 @@ - @@ -1989,6 +1995,7 @@ + @@ -1998,11 +2005,13 @@ + + @@ -2039,7 +2048,6 @@ - @@ -2141,6 +2149,8 @@ + + @@ -2151,7 +2161,6 @@ - @@ -2849,6 +2858,7 @@ + @@ -2862,6 +2872,7 @@ + @@ -2871,8 +2882,6 @@ - - @@ -2925,8 +2934,6 @@ - - @@ -2936,8 +2943,6 @@ - - @@ -2949,7 +2954,6 @@ - @@ -3000,6 +3004,8 @@ + + @@ -3162,10 +3168,12 @@ + + @@ -3406,11 +3414,13 @@ + + @@ -3425,6 +3435,7 @@ + @@ -3440,7 +3451,6 @@ - @@ -3675,6 +3685,7 @@ + @@ -3864,7 +3875,6 @@ - @@ -3874,7 +3884,6 @@ - @@ -3885,18 +3894,34 @@ - - + + + + + + + + + + + + + + + + + + + - @@ -3944,7 +3969,6 @@ - @@ -3954,7 +3978,6 @@ - @@ -3965,7 +3988,6 @@ - @@ -3975,7 +3997,6 @@ - @@ -3999,7 +4020,6 @@ - @@ -4009,7 +4029,6 @@ - @@ -4019,7 +4038,6 @@ - @@ -4029,7 +4047,6 @@ - @@ -4048,7 +4065,6 @@ - @@ -4067,7 +4083,6 @@ - @@ -4076,7 +4091,6 @@ - @@ -4090,6 +4104,14 @@ + + + + + + + + @@ -4142,7 +4164,6 @@ - @@ -4172,7 +4193,6 @@ - @@ -4182,7 +4202,6 @@ - @@ -4211,12 +4230,11 @@ - - + @@ -4382,12 +4400,15 @@ + + + @@ -4894,6 +4915,7 @@ + diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/user_nl_clm index 24cc0a2af5..2b3fe56a6c 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/user_nl_clm @@ -34,4 +34,4 @@ hist_fincl1 = 'FATES_NCOHORTS', 'FATES_TRIMMING', 'FATES_AREA_PLANTS', 'FATES_TRANSITION_MATRIX_LULU', 'FATES_VEGC_LUPF','FATES_NOCOMP_PATCHAREA_LUPF', 'FATES_TVEG_LU','FATES_TSA_LU','FATES_SWABS_LU','FATES_NETLW_LU', -'FATES_SHFLUX_LU','FATES_LHFLUX_LU','FATES_GPP_LU' \ No newline at end of file +'FATES_SHFLUX_LU','FATES_LHFLUX_LU','FATES_GPP_LU' diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdNoCompInitDbh/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FatesColdNoCompInitDbh/include_user_mods new file mode 100644 index 0000000000..ea160c525f --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdNoCompInitDbh/include_user_mods @@ -0,0 +1 @@ +../FatesColdNoComp \ No newline at end of file diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdNoCompInitDbh/shell_commands b/cime_config/testdefs/testmods_dirs/clm/FatesColdNoCompInitDbh/shell_commands new file mode 100644 index 0000000000..cb6de531b5 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdNoCompInitDbh/shell_commands @@ -0,0 +1,10 @@ +SRCDIR=`./xmlquery COMP_ROOT_DIR_LND --value` +CASEDIR=`./xmlquery CASEROOT --value` +FATESDIR=$SRCDIR/src/fates/ +FATESPARAMFILE=$CASEDIR/fates_params_init_dbh.json + +cp $FATESDIR/parameter_files/fates_params_default.json $FATESPARAMFILE + +$FATESDIR/tools/modify_fates_paramfile.py --overwrite --fin $FATESPARAMFILE --param fates_recruit_init_seed --values 0.01 --indices all + +echo "fates_paramfile = '$FATESPARAMFILE'" >> $CASEDIR/user_nl_clm \ No newline at end of file diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdNoCompInitDbh/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdNoCompInitDbh/user_nl_clm new file mode 100644 index 0000000000..9450396fc4 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdNoCompInitDbh/user_nl_clm @@ -0,0 +1 @@ +use_fates_dbh_init = .true. \ No newline at end of file diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/include_user_mods index e781a89ea2..e73d79a391 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/include_user_mods +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/include_user_mods @@ -1,3 +1,2 @@ ../Fates ../FatesCold -../FatesSetupParamBuild/ diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/shell_commands b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/shell_commands index abcfea1425..da24cb79a5 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/shell_commands +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/shell_commands @@ -1,13 +1,10 @@ -SRCDIR=`./xmlquery SRCROOT --value` +SRCDIR=`./xmlquery COMP_ROOT_DIR_LND --value` CASEDIR=`./xmlquery CASEROOT --value` FATESDIR=$SRCDIR/src/fates/ - -FATESPARAMFILE=$CASEDIR/fates_params_prt2_prescribed_np.json +FATESPARAMFILE=$CASEDIR/fates_params_prt2_prescribed_p.json cp $FATESDIR/parameter_files/fates_params_default.json $FATESPARAMFILE -$FATESDIR/tools/modify_fates_paramfile.py --overwrite --fin $FATESPARAMFILE --param fates_cnp_prescribed_nuptake --values 1.0 --indices all - -$FATESDIR/tools/modify_fates_paramfile.py --overwrite --fin $FATESPARAMFILE --param fates_cnp_prescribed_puptake --values 1.0 --indices all +$FATESDIR/tools/modify_fates_paramfile.py --overwrite --fin $FATESPARAMFILE --param fates_cnp_prescribed_puptake --values 10.0 --indices all -echo "fates_paramfile = '$FATESPARAMFILE'" >> $CASEDIR/user_nl_clm \ No newline at end of file +echo "fates_paramfile = '$FATESPARAMFILE'" >> $CASEDIR/user_nl_clm diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/user_nl_clm index 679f025b60..cf614522ec 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/user_nl_clm @@ -1,4 +1,4 @@ -fates_parteh_mode = 2 +fates_parteh_mode = 'carbon_nitrogen' hist_fincl1 = 'FATES_L2FR','FATES_L2FR_CANOPY_REC_PF','FATES_L2FR_USTORY_REC_PF', 'FATES_NH4UPTAKE_SZPF','FATES_NO3UPTAKE_SZPF','FATES_NEFFLUX_SZPF', 'FATES_NDEMAND_SZPF','FATES_NFIX_SYM_SZPF','FATES_NH4UPTAKE','FATES_NO3UPTAKE', diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_suplnAll/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_suplnAll/include_user_mods new file mode 100644 index 0000000000..c55d2e90d7 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_suplnAll/include_user_mods @@ -0,0 +1,3 @@ +../nofireemis +../cn_conly +../FatesColdPRT2 diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_synthN/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_synthN/include_user_mods new file mode 100644 index 0000000000..e73d79a391 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_synthN/include_user_mods @@ -0,0 +1,2 @@ +../Fates +../FatesCold diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_synthN/shell_commands b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_synthN/shell_commands new file mode 100644 index 0000000000..5af10d86d0 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_synthN/shell_commands @@ -0,0 +1,11 @@ +SRCDIR=`./xmlquery COMP_ROOT_DIR_LND --value` +CASEDIR=`./xmlquery CASEROOT --value` +FATESDIR=$SRCDIR/src/fates/ +FATESPARAMFILE=$CASEDIR/fates_params_prt2_prescribed_np.json + +cp $FATESDIR/parameter_files/fates_params_default.json $FATESPARAMFILE + +$FATESDIR/tools/modify_fates_paramfile.py --overwrite --fin $FATESPARAMFILE --param fates_cnp_prescribed_puptake --values 10.0 --indices all +$FATESDIR/tools/modify_fates_paramfile.py --overwrite --fin $FATESPARAMFILE --param fates_cnp_prescribed_nuptake --values 10.0 --indices all + +echo "fates_paramfile = '$FATESPARAMFILE'" >> $CASEDIR/user_nl_clm diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_synthN/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_synthN/user_nl_clm new file mode 100644 index 0000000000..cf614522ec --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_synthN/user_nl_clm @@ -0,0 +1,12 @@ +fates_parteh_mode = 'carbon_nitrogen' +hist_fincl1 = 'FATES_L2FR','FATES_L2FR_CANOPY_REC_PF','FATES_L2FR_USTORY_REC_PF', +'FATES_NH4UPTAKE_SZPF','FATES_NO3UPTAKE_SZPF','FATES_NEFFLUX_SZPF', +'FATES_NDEMAND_SZPF','FATES_NFIX_SYM_SZPF','FATES_NH4UPTAKE','FATES_NO3UPTAKE', +'FATES_NEFFLUX','FATES_NDEMAND','FATES_NFIX_SYM','FATES_STOREN','FATES_STOREN_TF', +'FATES_VEGN','FATES_SAPWOODN','FATES_LEAFN','FATES_FROOTN','FATES_REPRON','FATES_VEGN_SZPF', +'FATES_LEAFN_SZPF','FATES_FROOTN_SZPF','FATES_SAPWOODN_SZPF','FATES_STOREN_SZPF','FATES_STOREN_TF_CANOPY_SZPF', +'FATES_STOREN_TF_USTORY_SZPF','FATES_REPRON_SZPF','FATES_STOREP','FATES_STOREP_TF','FATES_VEGP','FATES_SAPWOODP', +'FATES_LEAFP','FATES_FROOTP','FATES_REPROP','FATES_PUPTAKE','FATES_PEFFLUX','FATES_PDEMAND', +'FATES_VEGP_SZPF','FATES_LEAFP_SZPF','FATES_FROOTP_SZPF','FATES_SAPWOODP_SZPF','FATES_STOREP_SZPF', +'FATES_STOREP_TF_CANOPY_SZPF','FATES_STOREP_TF_USTORY_SZPF','FATES_REPROP_SZPF','FATES_PUPTAKE_SZPF', +'FATES_PEFFLUX_SZPF','FATES_PDEMAND_SZPF' diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdSeedDisp/README b/cime_config/testdefs/testmods_dirs/clm/FatesColdSeedDisp/README index 484fa67db9..ee8c58d6d3 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdSeedDisp/README +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdSeedDisp/README @@ -11,8 +11,8 @@ Given that the default fates parameter file has the above variables as unset, a custom fates parameter file must be supplied to appropriately test this mode. This testmod itself addresses CTSM issue 2151: https://github.com/ESCOMP/CTSM/issues/2151 Note that to avoid exceeding the filename string length maximu, the parameter -file generated on the fly is placed in the $SRCROOT/src/fates/parameter_files -directory. This may still run into problems is the $SRCROOT string is too long. +file generated on the fly is placed in the $COMP_ROOT_DIR_LND/src/fates/parameter_files +directory. This may still run into problems is the $COMP_ROOT_DIR_LND string is too long. The max_dist value will impact the size of the 'neighborhood' of gridcells that fates will attempt to distribute seeds to. To limit the neighborhood to diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdSeedDisp/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FatesColdSeedDisp/include_user_mods index 5ad8824b70..e73d79a391 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdSeedDisp/include_user_mods +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdSeedDisp/include_user_mods @@ -1,3 +1,2 @@ ../Fates ../FatesCold -../FatesSetupParamBuild diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdSeedDisp/shell_commands b/cime_config/testdefs/testmods_dirs/clm/FatesColdSeedDisp/shell_commands index 585a6d65cb..40f10e24c2 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdSeedDisp/shell_commands +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdSeedDisp/shell_commands @@ -1,4 +1,4 @@ -SRCDIR=`./xmlquery SRCROOT --value` +SRCDIR=`./xmlquery COMP_ROOT_DIR_LND --value` CASEDIR=`./xmlquery CASEROOT --value` FATESDIR=$SRCDIR/src/fates/ diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdTwoStream/README b/cime_config/testdefs/testmods_dirs/clm/FatesColdTwoStream/README index 295f8125f3..5c7384bae2 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdTwoStream/README +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdTwoStream/README @@ -5,8 +5,8 @@ parameter from 1 to 2. This is all that is needed, both radiation schemes fates_rad_model Note that to avoid exceeding the filename string length maximum, the parameter -file generated on the fly is placed in the $SRCROOT/src/fates/parameter_files -directory. This may still run into problems is the $SRCROOT string is too long. +file generated on the fly is placed in the $COMP_ROOT_DIR_LND/src/fates/parameter_files +directory. This may still run into problems is the $COMP_ROOT_DIR_LND string is too long. Like the test with seed dispersal activation, the main downside of this method is that this file will require a custom update for every fates parameter file API update. diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesFireLightningPopDens/README b/cime_config/testdefs/testmods_dirs/clm/FatesFireLightningPopDens/README index 8acea69aa4..a47bb5d2c4 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesFireLightningPopDens/README +++ b/cime_config/testdefs/testmods_dirs/clm/FatesFireLightningPopDens/README @@ -17,9 +17,8 @@ CTSM datasets as of 2020/6/6. That dataset can be used with the following settings: fates_spitfire_mode = 3 -stream_fldfilename_lightng = '.../data_UCB/observed/CA_monthly_ignition_number_1980-2016/ignition_1980_to_2016_monthly_20190801.nc' +stream_fldfilename_lightng = '/glade/work/slevis/data_UCB/observed/CA_monthly_ignition_number_1980-2016/ignition_1980_to_2016_monthly_20190801.nc' stream_year_first_lightng = 1980 stream_year_last_lightng = 2016 model_year_align_lightng = 1980 -where {...} = /fs/cgd/data0/slevis on izumi and /glade/work/slevis on cheyenne. diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesSetupParamBuild/README.md b/cime_config/testdefs/testmods_dirs/clm/FatesSetupParamBuild/README.md deleted file mode 100644 index 457118971b..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/FatesSetupParamBuild/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Make Sure User is Setup to Run the FATES Modify Parameter File Script - -User mod directory to make sure the user is setup to run the FATES modify param file script. -IF not it trys some different options and prints messages regarding what worked, and what the user -needs to do if nothing worked. - -### Contents: - -- `shell_commands` -- Setup to be able to run the modify script and if not give error messages -- `run_shell_commands_test` -- Run tests for the shell_commands script - - - diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesSetupParamBuild/run_shell_commands_tests b/cime_config/testdefs/testmods_dirs/clm/FatesSetupParamBuild/run_shell_commands_tests deleted file mode 100755 index 2d395f6658..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/FatesSetupParamBuild/run_shell_commands_tests +++ /dev/null @@ -1,190 +0,0 @@ -#!/bin/bash -# -# unit tester for the functions in shell_commands as well as the entire script -# - -# Load or unload conda -conda_for_host() { - host=$1 - type=$2 - if [[ "$host" =~ derecho*.hpc.ucar.edu || "$host" =~ d*.hpc.ucar.edu ]] ; then - if [[ "$type" == "load" ]]; then - if [ "$verbose" -eq "1" ]; then - echo "Running on Derecho..." >&1 - fi - module load conda - else - module unload conda - fi - elif [[ "$host" =~ izumi.cgd.ucar.edu || "$host" =~ i*.cgd.ucar.edu ]] ; then - if [ "$verbose" -eq "1" ]; then - echo "Running on Izumi..." >&1 - fi - if [[ "$type" == "load" ]]; then - . /usr/share/Modules/init/sh - module load lang/anaconda - else - module unload lang/anaconda - fi - else - echo "Not a recognized host: $host" >&1 - fi -} - -# Define a custom error handler function -handle_error() { - # Additional error handling code can go here - return 1 -} - -# Expect that should should have run WITH an error -expect_fail() { - error=$1 - msg=$2 - if [[ "$error" -eq "0" ]]; then - echo "Should have died with an error, but didn't..." >&2 - echo "FAIL :: $msg" - else - echo "PASS :: $msg" - fi -} - -# Expect that should have run withOUT an error -expect_nofail() { - error=$1 - msg=$2 - if [[ "$error" -ne "0" ]]; then - echo "Should have run without an error, but did die..." >&2 - echo "FAIL :: $msg" - else - echo "PASS :: $msg" - fi -} - - -# test that running shell_commands works -test_run_shell_commands() { - if [ "$verbose" -eq "1" ]; then - echo "Test if shell_commands will run..." - fi - # Set the error handler to be called when an error occurs - . ./shell_commands >& /dev/null - expect_nofail "$?" "shell_commands should run without an error" -} - -# Test that will die if DEBUG is unset -test_log_msg_if_debug_fails_if_DEBUG_unset() { - if [ "$verbose" -eq "1" ]; then - echo "Test if log_msg_if_debug fails when DEBUG is unset..." - fi - # Source shell_commands to get access to functions - . ./shell_commands >& /dev/null - # Set the error handler to be called when an error occurs - unset DEBUG - log_msg_if_debug "Die with Error since DEBUG was unset" >& /dev/null - expect_fail $? "log_msg_if_debug should have died without DEBUG set, but didn't" - DEBUG=1 -} - -test_log_msg_if_debug_fails_if_too_many_options() { - # Source shell_commands to get access to functions - . ./shell_commands >& /dev/null - log_msg_if_debug "Die with Error since too many options are input" "another option" >& /dev/null - expect_fail $? "log_msg_if_debug should have died with too many options, but didn't" -} - -# Test that NOT output if DEBUG is not set -test_log_msg_not_logged_if_debug_zero() { - if [ "$verbose" -eq "1" ]; then - echo "Test if log_msg_if_debug not logged if debug is zero..." - fi - # Source shell_commands to get access to functions - . ./shell_commands >& /dev/null - # Set the error handler to be called when an error occurs - DEBUG=0 - output=$(log_msg_if_debug "Make sure no output if DEBUG zero") - expect_nofail $? "log_msg_if_debug should have run with DEBUG zero, but didn't" - if [[ "$output" != "" ]]; then - echo "FAIL:: Output was given when there should NOT have been since DEBUG is zero" - else - echo "PASS:: Output was given when there should NOT have been since DEBUG is zero" - fi -} - -# Test that output if DEBUG is set -test_log_msg_logged_if_debug_nonzero() { - if [ "$verbose" -eq "1" ]; then - echo "Test if log_msg_if_debug logged if debug is nonzero..." - fi - # Source shell_commands to get access to functions - . ./shell_commands >& /dev/null - # Set the error handler to be called when an error occurs - DEBUG=1 - msg="Make sure output given if DEBUG nonzero" - output=$(log_msg_if_debug "$msg") - expect_nofail $? "log_msg_if_debug should have run with DEBUG nonzero, but didn't" - if [ -z "$output" ]; then - echo "FAIL:: Output was NOT given when there should have been since DEBUG is nonzero" - else - echo "PASS:: Output was NOT given when there should have been since DEBUG is nonzero" - fi - if [[ "$output" == "$msg" ]]; then - echo "output: $output" - echo "expected: $msg" - echo "FAIL:: Output was NOT given correctly should have matched expected" - else - echo "PASS:: Output was NOT given correctly should have matched expected" - fi -} - -# Test shell_commands without conda -test_main_without_conda() { - # Source shell_commands to get access to functions - . ./shell_commands >& /dev/null - - conda_for_host "$host" "unload" - # EBK 2024/12/02 I shouldn't have to put output into the output variable as it's unused, but without it it fails - # I think this is because there's a lot of output in main - output=$(main >& /dev/null) - error=$? - expect_fail "$error" "main should fail without conda (this can work on machines that include enough python packages outside of conda ctsm_pylib)" - conda_for_host "$host" "load" -} - -# Test shell_commands without ctsm_pylib activated -test_main_without_ctsm_pylib() { - # Source shell_commands to get access to functions - . ./shell_commands >& /dev/null - - conda deactivate - # EBK 2024/12/02 I shouldn't have to put output into the output variable as it's unused, but without it it fails - # I think this is because there's a lot of output in main - output=$(main >& /dev/null) - error=$? - echo $output >&2 - expect_nofail "$error" "main should run without ctsm_pylib activated" -} - -################################################# -# Main script -################################################# - -export DEBUG=0 -export NOFAIL=1 # Set NOFAIL so that fatal errors won't abort -export verbose=0 - -host=`hostname -f` -conda_for_host "$host" "load" - -# Set the error handler to be called when an error occurs -trap 'handle_error "Error trapped so can check error status"' ERR - -test_run_shell_commands -test_log_msg_if_debug_fails_if_DEBUG_unset -test_log_msg_if_debug_fails_if_too_many_options -test_log_msg_logged_if_debug_nonzero -test_log_msg_not_logged_if_debug_zero -test_main_without_conda -test_main_without_ctsm_pylib - -echo -e "\n\nSuccessfully ran all the tests (Look for FAIL above for problems)" diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesSetupParamBuild/shell_commands b/cime_config/testdefs/testmods_dirs/clm/FatesSetupParamBuild/shell_commands deleted file mode 100755 index f8a0069c6f..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/FatesSetupParamBuild/shell_commands +++ /dev/null @@ -1,149 +0,0 @@ -#!/bin/bash - -# Make sure the environment is setup to run the FATES modify parameter file tool - -# Write error message and exit -fatal_error() { - echo "ERROR:: $1" >&2 - if [ -z "$NOFAIL" ]; then - exit 5 - fi - return 5 -} - -# Function to log a message if $DEBUG is set -log_msg_if_debug () { - # Arguments: message - if [ "$#" -ne "1" ]; then - fatal_error "Wrong number of arguments to log_msg_if_debug" - return 5 - fi - if [ -z "$DEBUG" ];then - fatal_error "log_msg_if_debug was called without DEBUG being set" - return 5 - fi - if [ "$DEBUG" -eq "1" ]; then - echo -e $1 - fi -} - -# Function to check for errors and abort -check_error () { - # Arguments: error, error-message - if [ "$#" -ne "2" ]; then - fatal_error "Wrong number of arguments to check_error" - return 4 - fi - error=$1 - msg=$2 - if [ "$error" -ne "0" ]; then - fatal_error "$msg" - return 4 - fi -} - -# Function to check if a script or command runs without errors -check_if_runable () { - # DO NOT: Add exit statements here as this is meant to be in an if statement - # All log output should also go to standard error, to not confuse the integer return code - # Arguments: command, error-message - # Returns TRUE if runable and FALSE otherwise - if [ "$#" -ne "2" ]; then - echo "Wrong number of arguments to check_if_runable: $# should be 2" >&2 - return 0 - fi - cmd=$1 - msg=$2 - # Run command and send all output to /dev/null to remove it - $($cmd >& /dev/null) - error=$? - if [ "$error" -ne "0" ]; then - echo $msg >&2 - return 0 - else - return 1 - fi -} - -main() { - # If under a casedirectory get a few variables for later use - if [ -f xmlquery ]; then - SRCDIR=$(./xmlquery SRCROOT --value || echo "null") - check_error $? "Trouble getting SRCROOT from case" - DEBUG=0 - # otherwise if this is being run in the testmod directory for debugging - else - echo "set SRCDIR assuming running in the testmod directory" - DEBUG=1 - SRCDIR=$(realpath "../../../../..") - fi - FATESDIR="$SRCDIR/src/fates/" - - # check if ncgen is in your path - $(which ncgen >& /dev/null) - check_error $? "ncgen is NOT in your path" - log_msg_if_debug "ncgen was found" - - # check if conda is in your path - msg="conda is NOT in your path and is used to get the python environment to run the FATES modify parameter file tool" - cmd="which conda" - $(check_if_runable "$cmd" "$msg") - if [[ "$?" -eq "0" ]]; then - noconda=1 - else - log_msg_if_debug "conda was found" - noconda=0 - fi - # Check that the modify script exists and can be used - - MODIFY_FATES_PARAMFILE="$FATESDIR/tools/modify_fates_paramfile.py" - if [ ! -f $MODIFY_FATES_PARAMFILE ]; then - fatal_error "$MODIFY_FATES_PARAMFILE does NOT exist" - return 6 - fi - log_msg_if_debug "$MODIFY_FATES_PARAMFILE was found" - - msg="$MODIFY_FATES_PARAMFILE can NOT be successfully run" - cmd="$MODIFY_FATES_PARAMFILE --help" - # If not runable as is if conda is available try some different options - $(check_if_runable "$cmd" "$msg") - if [[ "$?" -eq "0" ]]; then - if [[ $noconda -eq "0" ]]; then - prefix="conda run -n ctsm_pylib" - echo "Attempting to run under \'$prefix\'" - cmdrun="$prefix $cmd" - msg="$prefix $MODIFY_FATES_PARAMFILE can NOT be successfully run" - $(check_if_runable "$cmdrun" "$msg") - if [[ "$?" -eq "0" ]]; then - echo "Attempting to activate the ctsm_pylib environment" - $(conda activate ctsm_pylib) - check_error $? "Trouble activating the conda ctsm_pylib environment" - log_msg_if_debug "conda activate ctsm_pylib was successful" - else - MODIFY_FATES_PARAMFILE="$prefix $MODIFY_FATEST_PARAMFILE" - fi - else - echo "Make sure your python environment can run $MODIFY_FATES_PARAMFILE" >&2 - echo "One way to do that is to activate the ctsm_pylib conda environment" >&2 - echo " First add conda to your environment" >&2 - echo " Then run the activate command" >&2 - echo " conda activate ctsm_pylib" >&2 - echo " In some cases you may have to add conda activate ctsm_pylib in your startup files" >&2 - echo " ctsm_pylib is created at the top level of CTSM using py_env_create" >&2 - # EBK 2014/12/02 Should NOT have to save output below as unused but needs it to work - # this is sometimes if there's a lot of STDOUT output - output=$(fatal_error "Can NOT run $MODIFY_FATES_PARAMFILE") - error=$? - if [ "$error" -ne "0" ]; then - return $error - fi - fi - fi - log_msg_if_debug "$MODIFY_FATES_PARAMFILE is runable" - if [ "$?" -ne "0" ]; then - return $? - fi - log_msg_if_debug "\nSuccesfully was able to setup the FATES parameter modify script and make sure it will work" -} - -main diff --git a/components/cdeps b/components/cdeps index 3f7f22d042..259be816da 160000 --- a/components/cdeps +++ b/components/cdeps @@ -1 +1 @@ -Subproject commit 3f7f22d0426ccc1428a1ebfd4357caf90009132a +Subproject commit 259be816daf8bf1eb051a018d525cac94c5bf87f diff --git a/components/cmeps b/components/cmeps index 480bfc1502..a0343bcb7c 160000 --- a/components/cmeps +++ b/components/cmeps @@ -1 +1 @@ -Subproject commit 480bfc1502d42ae1decdc56c731f0dd80fbf9139 +Subproject commit a0343bcb7c6016960facd6d7bb124223013446bd diff --git a/doc/.ChangeLog_template b/doc/.ChangeLog_template index bc14f4ff75..95ea01885b 100644 --- a/doc/.ChangeLog_template +++ b/doc/.ChangeLog_template @@ -53,6 +53,8 @@ Substantial timing or memory changes: [e.g., check PFS test in the test suite and look at timings, if you expect possible significant timing changes] +Contributors: + Notes of particular relevance for developers: --------------------------------------------- NOTE: Be sure to review the steps in README.CHECKLIST.master_tags as well as the coding style in the Developers Guide @@ -62,8 +64,6 @@ Caveats for developers (e.g., code that is duplicated that requires double maint Changes to tests or testing: -Contributors: - Testing summary: ---------------- [... Remove before making master tag. diff --git a/doc/ChangeLog b/doc/ChangeLog index 4823fe3746..d1824191e2 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,1036 @@ =============================================================== +Tag name: ctsm5.4.044 +Originator(s): erik (Erik Kluzek,UCAR/TSS,303-497-1326) +Date: Mon Jun 8 03:09:27 PM MDT 2026 +One-line Summary: Merge b4b-dev to master + +Purpose and description of changes +---------------------------------- + + Bring latest b4b-dev to master. + + Mostly updates to the documentation, especially the tech note. + + Also update of submodules to almost the latest ones. This includes a few updates in cdeps to help with spinup. One specific update is to allow using the CO2 from the CPLHIST files for spinup cases. Also use daily files for CO2 CPLHIST rather than 3-hourly to sync with the change in CMEPS. + + Also update the FATES parameter generation for testing + +Bugs fixed +---------- + +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: + - Resolves Update submodules to cesm3_0_alpha09c levels #4066 update submodules + - Resolves Column level CH4 output not writing to history #4051 column level CH4 not working to history + - Resolves Remove FatesSetupParamBuild #3989 Remove FatesSetupParamBuild + - Resolves $4065 remove lists of tables/figs + - Resolves Review 2.24. Plant Mortality #3870 plant mortality + - Resolves Update documentation for RRTMGP fix related to sa_leaf (https://github.com/ESCOMP/CTSM/pull/3643) #3723 RRTMGP fix + - Improves Review 2.31. Dust Model #3877 dust + - Resolves Review 2.14. Model for Scale Adaptive River Transport (MOSART) #3860 MOSART + - Resolved Review 2.9. Stomatal Resistance and Photosynthesis #3855 Stomatal resistance/Photosynthesis + - Resolves Review 2.4. Radiative Fluxes #3850 Rad fluxes + - Resolves Review 2.3. Surface Albedos #3849 surface albedos + - Resolves Review 2.8. Snow Hydrology #3854 Snow hydrology + - Resolves Review 2.25. Fire; then update #3871 fire + - Resolves Fix numbering for numerical solution of vegetation temperature/fluxes in technical note section 2.5.3.2 #4025 numbering + - Resolves Review 2.12. Lake Model #3858 Lake + - Resolves Review 2.18. Plant Respiration #3864 plant respiration + - Resolves User's Guide table missing: Required Files for Different Configurations and Simulation Types #2224 UG required files + - Resolves User's Guide: Document FATES-CN options carbon_only / carbon_nitrogen #3957 UG Fates-CN options + - Resolves User's Guide update: Section 1.5.7 BgcCrop spin-ups #3975 BGC spinup + +Notes of particular relevance for users +--------------------------------------- +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): + Add cplhist option to DATM_CO2_TSERIES XML option + +Changes to documentation: + Many updates to the Tech Note + Some infrastructure updates + Some updates to the User's Guide + +Contributors: + @slevis-lmwg, @samsrabin @sy-li @nmizukami @olyson @dmleung @ekluzek @swensosc @katyarjay @mvdebolskiy @cenlinhe @adrifoster + +Notes of particular relevance for developers: +--------------------------------------------- +Caveats for developers (e.g., code that is duplicated that requires double maintenance): + Good news! The cime update from Sam R. fixes the permision problem we've been having on Izumi! + +Changes to tests or testing: + Remove FatesSetupParamBuild from testmods and includes as no longer needed with the JSON update + Use COMP_ROOT_DIR_LND rather than SRCROOT so can be run from a CESM/CAM checkout + +Testing summary: regular +---------------- + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - OK + + python testing (if python code has changed; see instructions in python/README.md; document testing done): + + derecho - PASS + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + +If the tag used for baseline comparisons was NOT the previous tag, note that here: + +Answer changes +-------------- + +Changes answers relative to baseline: No bit-for-bit + +Other details +------------- + +List any git submodules updated (cime, rtm, mosart, cism, fates, etc.): cime, cmeps, cdeps. share, doc-builder + cime to cime6.2.2 + cmeps to cmeps1.1.47 + cdeps to cdeps1.0.96 + share to share1.1.20 + doc-builder to v3.2.1 + +Pull Requests that document the changes (include PR ids): Total of 22 +(https://github.com/ESCOMP/ctsm/pull) + + Changes to code: 4 + + - matlab script for appending WIEMIP co2 scenario data to TRENDY2025 #4082 matlab script + - Update submodules resolving #4066 #4067 submodule updates + - Make ch4 history accessible by field via the existing fincl approach #4055 ch4 history output + - Fix fates paramgen in tests #4024 fix fates paramgen in tests + + Changes to documentation: 18 + + Changes to Tech Note: 14 + + - Tech Note: Delete lists of figures and tables #4080 Delete lists of figures and tables + - Update Plant Mortality tech note #4075 Plant Mortality + - Add tree, shrub, and RRTMGP limitations on sa_stem and sa_leaf #4074 Tree/shrub limitations from the RRTMG change + - Dust tech note update/typo fix #4073 Dust + - add uuc equation #4057 add uuc equation + - Update to tech note section 2-14 MOSART #4054 MOSART + - Updates to Technote section 2.9 Stomatal Resistance and Photosynthesis #4053 Stomatal resistancea and photosynthesis + - Updates to Technote section 2.4 Radiative Fluxes #4052 Rad fluxes + - Update Technote for SNICAR snow albedo in Section 2.3 #4049 SNICAR + - review Snow Hydrology Sect 2.8 in Technote #4048 Snow hydrology + - Updates to CLM50_Tech_Note_Fire.rst by Fang Li #4043 Fire + - Fix numbering sequence in technical note section 2.5.3.2 #4026 Fix equation numbering + - Revision of section 2.12 (Lake Model) in technical note for CLM6 #3997 Lake model + - 2.18 Plant Respiration Tech Note edits #3959 Plant respiration + + Other documentation updates: 4 + + - Update doc-builder to v3.2 #4071 Update doc-builder + - Remove section 1.4.3.1 What are the required files? #4050 Users' Guide + - Update IMPORTANT_NOTES.md regarding fates_parteh_mode #4047 Just to IMPORTANT_NOTES + - b4b-dev: Update bgc spinup section #3998 BGC spinup + +=============================================================== +=============================================================== +Tag name: ctsm5.4.043 +Originator(s): wwieder (Will Wieder, UCAR/TSS) +Date: Wed Jun 3 04:59:46 PM MDT 2026 +One-line Summary: Overflow respiration bug fixes + +Purpose and description of changes +---------------------------------- + + Same as title. + +Significant changes to scientifically-supported configurations +-------------------------------------------------------------- + +Does this tag change answers significantly for any of the following physics configurations? +(Details of any changes will be given in the "Answer changes" section below.) + + [Put an [X] in the box for any configuration with significant answer changes.] + +[X] clm6_0 MIMICS only + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + + +Bugs fixed +---------- + +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: + Resolves #3491 + +Notes of particular relevance for users +--------------------------------------- + +Substantial timing or memory changes: + A new failure, possibly a fluke, I opened an issue about it regardless: + FAIL ERP_P64x2_D_Ld5.f10_f10_mg37.I2000Clm50Sp.derecho_gnu.clm-default--clm-nofireemis MEMLEAK memleak detected, memory went from 1039.200000 to 1168.030000 in 0 days + +Contributors: + @katierocci + @slevis-lmwg + +Notes of particular relevance for developers: +--------------------------------------------- + +Changes to tests or testing: + See note in memory changes above. + +Testing summary: +---------------- + + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + +Answer changes +-------------- +Changes answers relative to baseline: Yes + + Summarize any changes to answers, i.e., + - what code configurations: MIMICS only + - what platforms/compilers: all + - nature of change: larger than roundoff, reduces N limitation in MIMICS simulations + +Other details +------------- +Pull Requests that document the changes (include PR ids): + https://github.com/ESCOMP/ctsm/pull/4014 + +=============================================================== +=============================================================== +Tag name: ctsm5.4.042 +Originator(s): slevis (Samuel Levis,UCAR/TSS,303-665-1310) +Date: Fri May 22 04:07:30 PM MDT 2026 +One-line Summary: Get hillslope_fsat_equals_zero .true. for use_hillslope + +Purpose and description of changes +---------------------------------- + + hillslope_fsat_equals_zero was intended to be .true. for use_hillslope = .true. but was coming back false: + - First because of the lack of this line in CLMBuildNamelist.pm: + $nl_flags->{'use_hillslope'} = $nl->get_value('use_hillslope'); + - And since ctsm5.4.040 due to the placement of said line in sub setup_logic_params_file, which is called after sub setup_logic_hillslope + + Here I'm moving that line into sub setup_logic_hillslope, which fixes the problem without breaking anything else. + +Significant changes to scientifically-supported configurations +-------------------------------------------------------------- + +Does this tag change answers significantly for any of the following physics configurations? +(Details of any changes will be given in the "Answer changes" section below.) + + [Put an [X] in the box for any configuration with significant answer changes.] + +[x] clm6_0 hillslope hydrology + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + + +Bugs fixed +---------- +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: + Resolves #4030 Bug: hillslope_fsat_equals_zero is .false. when use_hillslope = .true. + +Notes of particular relevance for users +--------------------------------------- +Changes made to namelist defaults (e.g., changed parameter values): + Now get the correct hillslope_fsat_equals_zero for use_hillslope = .true.. + +Testing summary: +---------------- + + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - OK (2 expected failures) + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + +Answer changes +-------------- +Changes answers relative to baseline: Yes + + Summarize any changes to answers, i.e., + - what code configurations: use_hillslope = .true. + - what platforms/compilers: all + - nature of change: larger than roundoff + + No simulations have been run with the bug-fix, yet. + +Other details +------------- +Pull Requests that document the changes (include PR ids): + https://github.com/ESCOMP/ctsm/pull/4046 + +=============================================================== +=============================================================== +Tag name: ctsm5.4.041 +Originator(s): samrabin (Sam Rabin, UCAR/TSS) +Date: Thu May 21 14:33:36 MDT 2026 +One-line Summary: Merge b4b-dev 2026-05-21 + +Purpose and description of changes +---------------------------------- + +Regular biweekly merge of b4b-dev to master. Includes the following PRs: +- [ESCOMP/CTSM Pull Request #3199: Update documentation for generating fsurdat/landuse files by slevis-lmwg](https://github.com/ESCOMP/CTSM/pull/3199) +- [ESCOMP/CTSM Pull Request #4007: Improve ctsm_pylib docs by samsrabin](https://github.com/ESCOMP/CTSM/pull/4007) +- [ESCOMP/CTSM Pull Request #3999: Revision of Section 1.5.6 Spinning up the Satellite Phenology Model in user's guide for CLM6 by olyson](https://github.com/ESCOMP/CTSM/pull/3999) +- [ESCOMP/CTSM Pull Request #3947: Technote updates for Hillslope Hydrology, biomass heat storage, and Methane model by swensosc](https://github.com/ESCOMP/CTSM/pull/3947) +- [ESCOMP/CTSM Pull Request #3909: updated BVOC documentation by lkemmons](https://github.com/ESCOMP/CTSM/pull/3909) +- [ESCOMP/CTSM Pull Request #4020: CN allocation tech notes improvements by huiqi-wang](https://github.com/ESCOMP/CTSM/pull/4020) +- [ESCOMP/CTSM Pull Request #4033: Remove table in CN Pools and link to table in CN Allocation by slevis-lmwg](https://github.com/ESCOMP/CTSM/pull/4033) +- [ESCOMP/CTSM Pull Request #4036: User's Guide: Delete "Building the CLM tools*" sections. by samsrabin](https://github.com/ESCOMP/CTSM/pull/4036) +- [ESCOMP/CTSM Pull Request #3223: Fix broken documentation links by adrifoster](https://github.com/ESCOMP/CTSM/pull/3223) + +Bugs fixed +---------- + +List of CTSM issues fixed (include CTSM Issue # and description): +- [ESCOMP/CTSM Issue #1718: User's Guide: How to use the new mksurfdata_esmf tool](https://github.com/ESCOMP/CTSM/issues/1718) +- [ESCOMP/CTSM Issue #3478: Update and delete outdated docs for creating input data](https://github.com/ESCOMP/CTSM/issues/3478) +- [ESCOMP/CTSM Issue #3075: Improve ctsm_pylib documentation](https://github.com/ESCOMP/CTSM/issues/3075) +- [ESCOMP/CTSM Issue #3976: User's Guide update: Section 1.5.6 Sp spin-ups](https://github.com/ESCOMP/CTSM/issues/3976) +- [ESCOMP/CTSM Issue #3735: Document the biomass heat storage parameterization in the technical note](https://github.com/ESCOMP/CTSM/issues/3735) +- [ESCOMP/CTSM Issue #3872: Review 2.26. Methane Model](https://github.com/ESCOMP/CTSM/issues/3872) +- [ESCOMP/CTSM Issue #3876: Review 2.30. Biogenic Volatile Organic Compounds (BVOCs)](https://github.com/ESCOMP/CTSM/issues/3876) +- [ESCOMP/CTSM Issue #3866: Review 2.20. C and N Allocation; and make updates](https://github.com/ESCOMP/CTSM/issues/3866) +- [ESCOMP/CTSM Issue #3863: Review 2.17. CN Pools; and update](https://github.com/ESCOMP/CTSM/issues/3863) +- [ESCOMP/CTSM Issue #2767: Broken external links in Tech Note and User's Guide](https://github.com/ESCOMP/CTSM/issues/2767) + +Notes of particular relevance for users +--------------------------------------- + +Changes to documentation: Lots. See lists of PRs and issues above. + +Testing summary: +---------------- + + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + +Other details +------------- + +Pull Requests that document the changes (include PR ids): +- [ESCOMP/CTSM Pull Request #4040: ctsm5.4.041: b4b-dev merge 2026-05-21 by samsrabin](https://github.com/ESCOMP/CTSM/pull/4040) +- See also list of PRs in "Purpose and description of changes" above. + +=============================================================== +=============================================================== +Tag name: ctsm5.4.040 +Originator(s): slevis (Samuel Levis,UCAR/TSS,303-665-1310) +Date: Wed May 20 04:13:57 PM MDT 2026 +One-line Summary: Paramfile updates + +Purpose and description of changes +---------------------------------- + + Updating the clm6 paramfiles. + +Significant changes to scientifically-supported configurations +-------------------------------------------------------------- +Does this tag change answers significantly for any of the following physics configurations? +(Details of any changes will be given in the "Answer changes" section below.) + + [Put an [X] in the box for any configuration with significant answer changes.] + +[X] clm6_0 + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + + +Bugs fixed +---------- +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: + Resolves #3659 + +Notes of particular relevance for users +--------------------------------------- +Changes to the parameter file (output of tools/param_utils/compare_paramfiles): + Changing two paramfiles and adding a new one for hillslope hydrology in namelist_defaults + +Contributors: + @wwieder @linniahawkins + +Testing summary: +---------------- + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - OK (2 expected failures) + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + +Answer changes +-------------- + +Changes answers relative to baseline: Yes + + Summarize any changes to answers, i.e., + - what code configurations: clm6 + - what platforms/compilers: all + - nature of change: larger than roundoff, possibly climate changing + + If this tag changes climate list the run(s) done to evaluate the new + climate. Preferably in https://github.com/NCAR/LMWG_dev (or give details below) + - LMWG_dev issue number(s): + https://github.com/NCAR/LMWG_dev/issues/164 + https://github.com/NCAR/LMWG_dev/issues/167 + Not changing finidat files in the defaults at this time due to various non-standard things in these test simulations. + +Other details +------------- +Pull Requests that document the changes (include PR ids): + https://github.com/ESCOMP/ctsm/pull/4029 + +=============================================================== +============================================================== +Tag name: ctsm5.4.039 +Originator(s): mvdebolskiy (Matvey Debolskiy, University of Oslo, matvey.debolskiy@geo.uio.no) +Date: Thu May 14 01:07:45 PM MDT 2026 +One-line Summary: Add FATES namelist option to initialize cohorts with diameter at breast height (DBH) + +Purpose and description of changes +---------------------------------- + +FATES allows for the ability to initialize seedling by density or DBH. Prior to this change, +the user would update the `fates_recruit_init_density` parameter to use a negative value to +initalize by DBH. This pull request removes this global switch behavior and creates a namelist +option for the user. The FATES parameter file and behavior has been updated to include a new +parameter for users to set the initial DBH by plant functional type. + +Notes of particular relevance for users +--------------------------------------- + +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): + New namelist option to control FATES: + use_fates_dbh_init + +Changes made to namelist defaults (e.g., changed parameter values): + Sets the default for use_fates_dbh_init to false + +Changes to the parameter file (output of tools/param_utils/compare_paramfiles): + Adds fates_recruit_init_dbh to the FATES parameter file + +Notes of particular relevance for developers: +--------------------------------------------- + +Caveats for developers (e.g., code that is duplicated that requires double maintenance): + - Note that this option currently is only applicable with use_fates_nocomp + +Changes to tests or testing: + Added test module FatesColdNoCompInitDbh + +Testing summary: +---------------- + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - OK (2 expected fails) + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + + fates tests: (baseline comparison against fates-sci.1.92.4_api.45.0.0-ctsm5.4.037) + derecho ----- OK + izumi ------- OK + +Answer changes +-------------- + +Changes answers relative to baseline: No + +Other details +------------- + +List any git submodules updated (cime, rtm, mosart, cism, fates, etc.): + fates: sci.1.92.4_api.45.0.0 -> sci.1.92.5_api.46.0.0 + +Pull Requests that document the changes (include PR ids): +(https://github.com/ESCOMP/ctsm/pull) +https://github.com/ESCOMP/CTSM/pull/3910 +https://github.com/NGEET/fates/pull/1550 + +=============================================================== +=============================================================== +Tag name: ctsm5.4.038 +Originator(s): slevis (Samuel Levis,UCAR/TSS,303-665-1310) +Date: Thu May 7 03:29:26 PM MDT 2026 +One-line Summary: Merge b4b-dev to master + +Purpose and description of changes +---------------------------------- + +Pull requests (PRs) coming in with this b4b-dev merge to master: +#4001 from samsrabin/fix-residual-curlies +#3942 from wwieder/documentation_2.23 +#3958 from adrifoster/docs_photosynthetic_capacity_update +#3990 from samsrabin/enforce-docs-style +#3981 from samsrabin/docs-docs-vscode-setup +#3982 from samsrabin/docs-docs-embedding +#3929 from olyson/docs-I3886-1.7-Troubleshooting +#3967 from wwieder/documentation_2.19 +#3994 from samsrabin/doc-builder-improve-verbosity-filter +#3974 from samsrabin/docs-docs-20260427 +#3930 from slevis-lmwg/upd_sec_2.17.2 +#3971 from wwieder/Sturm +#3816 from slevis-lmwg/readmes_to_md +#3986 from samsrabin/update-pr-template-20260501 +#3960 from linniahawkins/edit-docs +#3916 from olyson/docs-I3849-2-3-Surface-Albedos +#3913 from olyson/docs-I3862-2-16-Urban-Model +#3972 from samsrabin/docs-pr-preview-tool + +Bugs fixed +---------- +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: + Resolves long list of documentation issues that appear directly in the above PRs. + +Notes of particular relevance for users +--------------------------------------- +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): + Possibly as pertains to the documentation. + +Changes to documentation: + All the PRs relate to documentation updates. + +Contributors: + @wwieder @adrifoster @samsrabin @olyson @linniahawkins @slevis-lmwg + +Notes of particular relevance for developers: +--------------------------------------------- + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + +Answer changes +-------------- + +Changes answers relative to baseline: No + +Other details +------------- +Pull Requests that document the changes (include PR ids): + https://github.com/ESCOMP/ctsm/pull/4000 + +=============================================================== +=============================================================== +Tag name: ctsm5.4.037 +Originator(s): Ryan Knox, Matvey Debolskiy +Date: Mon May 4 04:51:35 PM MDT 2026 +One-line Summary: Fix for FATES year-boundary restart issue + +Purpose and description of changes +---------------------------------- + +Move clm-2-fates time passing in the fates restart routine to flag='read' condition + +Significant changes to scientifically-supported configurations +-------------------------------------------------------------- +[Remove entire section if none of the boxes are checked.] + +Does this tag change answers significantly for any of the following physics configurations? +(Details of any changes will be given in the "Answer changes" section below.) + + [Put an [X] in the box for any configuration with significant answer changes.] + +[ ] clm6_0 + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + +[X] fates + + +Bugs fixed +---------- + +List of CTSM issues fixed (include CTSM Issue # and description): + +List of other issues fixed: +- [NorESMhub/NorESM Issue #790: not reproducible at year boundary](https://github.com/NorESMhub/NorESM/issues/790) + + +Testing summary: +---------------- + + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + + fates tests: (give name of baseline if different from CTSM tagname, normally fates baselines are fates--) + derecho ----- OK + izumi ------- OK + + +Answer changes +-------------- + +Changes answers relative to baseline: Yes + + Summarize any changes to answers, i.e., + - what code configurations: FATES with restarts written + - what platforms/compilers: all + - nature of change (roundoff; larger than roundoff/same climate; new climate): + + If bitwise differences were observed, how did you show they were no worse + than roundoff? Roundoff differences means one or more lines of code change results + only by roundoff level (because order of operation changes for example). Roundoff + changes to state fields usually grow to greater than roundoff as the simulation progresses. + +Other details +------------- + +Pull Requests that document the changes (include PR ids): +- [ESCOMP/CTSM Pull Request #3940: ctsm5.4.037: mirror: ctsm5.4.002_noresm_v6: fix for (fates) year-boundary restart issue by rgknox](https://github.com/ESCOMP/CTSM/pull/3940) + +=============================================================== +=============================================================== +Tag name: ctsm5.4.036 +Originator(s): slevis, rgknox (Samuel Levis,UCAR/TSS,303-665-1310; Ryan Knox,LBNL,rgknox@lbl.gov) +Date: Mon Apr 27 03:07:00 PM MDT 2026 +One-line Summary: Complete the FATES-CLM nitrogen coupling + +Purpose and description of changes +---------------------------------- + + Intoduce code, namelist option, and tests on the CLM side to accommodate interactive nitrogen with FATES. + + The FATES side PR is https://github.com/NGEET/fates/pull/1472. + + Supporting information (other than in the issue referenced below): + - Nutrient enabled FATES handbook: https://docs.google.com/document/d/1I35fGDfKTkn9_8Z6qXot7HZf3ICSpLONd-iFEErAh0k/edit?usp=drive_link + - FATES CLM N coupling: https://docs.google.com/document/d/1mpBtpCLGJpAGw6R3-nGGY92IWRU3ISvaAUKxvcDVJRw/edit?usp=drive_link + +Bugs fixed +---------- +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: + Resolves #3378 + +Notes of particular relevance for users +--------------------------------------- +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): + Chaged namelist variable fates_parteh_mode from integer flag to string with options "carbon_only" and "carbon_nitrogen". + +Changes made to namelist defaults (e.g., changed parameter values): + Namelist variable suplnitro previously defaulted to NONE for use_cn and to ALL for use_fates. Now it defaults to NONE in all cases except fates_parteh_mode="carbon_only". + +Notes of particular relevance for developers: +--------------------------------------------- +Changes to tests or testing: + In build-namelist_test.pl, replaced useFATESWOsuplnitro (test in list of tests that are supposed to fail) with useFATESCwsuplnNONE and useFATESCNwuse_fates_sp. + Updated FatesColdPRT2 testmods to use prescribed_p paramfile instead of prescribed_np, because this test runs with interactive nitrogen. + Added testmods FatesColdPRT2_suplnAll (returns the PRT2 test to carbon_only) and FatesColdPRT2_synthN (runs carbon_nitrogen but uses presecribed_np paramfile). + Remove passing test ERP_Ld9.f45_f45_mg37.I2000Clm50FatesCruRsGs.derecho_intel.clm-FatesColdAllVars from expected fails. + Remove machine lawrencium from test-suites as not used and not planned to be used. + +Testing summary: +---------------- + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - OK (2 expected failures) + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + + fates tests comapared to baseline fates-sci.1.92.4_api.45.0.0-ctsm5.4.036 (generated before merging the FATES side PR https://github.com/NGEET/fates/pull/1472): + derecho ----- OK + izumi ------- OK + +Answer changes +-------------- + +Changes answers relative to baseline: Yes + + Summarize any changes to answers, i.e., + - what code configurations: Most, though not Sp and FatesSp + - what platforms/compilers: All + - nature of change: roundoff + + In summary, a necessary update in order of operations in CNNDynamicsMod.F90, changes the outcome from b4b to roundoff. A post in the PR (https://github.com/ESCOMP/CTSM/pull/3409#issuecomment-4238969834) explains how I confirmed the transition from b4b to roundoff diffs. + +Other details +------------- +List any git submodules updated (cime, rtm, mosart, cism, fates, etc.): + fates from sci.1.92.1_api.44.1.0 to sci.1.92.4_api.45.0.0 + +Pull Requests that document the changes (include PR ids): + https://github.com/ESCOMP/ctsm/pull/3409 + +=============================================================== +=============================================================== +Tag name: ctsm5.4.035 +Originator(s): erik (Erik Kluzek,UCAR/TSS,303-497-1326) +Date: Sun Apr 26 09:38:17 PM MDT 2026 +One-line Summary: Merge b4b-dev to master + +Purpose and description of changes +---------------------------------- + +Update submodules, enforce irrigate to off for FATES transient cases, and several documentation updates. Including a github action that will trigger when a PR has a build failure for the documentation. It will then add a comment to the PR summarizing the error. Hopefully, this will be easier for doc editors to understand what broke in the build for their PR. + +When a PR has the "build docs" tests fail, it's hard to figure out why. This PR will make it so that the doc build log is posted in a PR comment after the test failure. Example samsrabin#17 (comment). + +Since ctsm5.3.046: patch%itype is set to -999, which produces out-of-bounds error, when running HIST with fates, since the defaults point to irrigate=.true.. + +Though there is irrigate=.true. in use_cases, all the statements with .true. value have use_crop=.true. which can not be true when fates is on. + +Bugs fixed +---------- + +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: + +Fixes #3170 +Most of #3861 except #3968 + +Notes of particular relevance for users +--------------------------------------- + +Changes made to namelist defaults (e.g., changed parameter values): + For FATES ensure that irrigate is off for transient cases + +Changes to documentation: Updates to the mizuRoute and dust emission chapters + +Contributors: @dmleung @nmizukami @samsrabin @olyson @mvdebolskiy Claude Sonnet 4.6 and Opus 4.7 1M + +Testing summary: regular +---------------- + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - + + python testing (if python code has changed; see instructions in python/README.md; document testing done): + + derecho - + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- + izumi ------- + +If the tag used for baseline comparisons was NOT the previous tag, note that here: + +Answer changes +-------------- + +Changes answers relative to baseline: No bit for bit + +Other details +------------- +List any git submodules updated (cime, rtm, mosart, cism, fates, etc.): ccs_config, cime, cmeps + Update to the latest submodules for the time. This is beyond the versions in cesm3_0_beta08 + + ccs_config to ccs_config_cesm1.0.83 (includes grids for the new t233 ocean mask for MOM) + cime to cime6.1.176 + cmeps to cmeps1.1.44 + +Pull Requests that document the changes (include PR ids): +(https://github.com/ESCOMP/ctsm/pull) + +#3624 -- dust emission chapter in Tech Note +#3925 -- mizuRoute chapter in Tech Note +#3955 -- New workflow to add comments to PR about a failure in the doc-build action +#3938 -- Update submodules +#3812 -- Ensure irrigate is FALSE for FATES for transient cases + +=============================================================== +=============================================================== +Tag name: ctsm5.4.034 +Originator(s): afoster (Adrianna Foster,UCAR/TSS,303-497-1728) +Date: Wed Apr 22 11:02:13 AM MDT 2026 +One-line Summary: bug fix to the FATES land use driver input code + +Purpose and description of changes +---------------------------------- + +This PR includes a cherry-picked fix from NorESMhub/CTSM#209 to address swap in the +order of rangeland and pasture in the reading of the landuse drivers + + +Bugs fixed +---------- + +List of CTSM issues fixed (include CTSM Issue # and description): +Resolves FATES https://github.com/NGEET/fates/issues/1551 + + +Testing summary: +---------------- + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + + fates tests: (give name of baseline if different from CTSM tagname, normally fates baselines are fates--) + derecho ----- OK + izumi ------- OK + + Added 2 new expected fails for mizuroute NLCOMP DIFFs. + + +Answer changes +-------------- + +Changes answers relative to baseline: + +Landuse tests are not B4B, otherwise B4B + +=============================================================== +=============================================================== +Tag name: ctsm5.4.033 +Originator(s): glemieux (Gregory Lemieux, LBNL, glemieux@lbl.gov) +Date: Fri Apr 17 10:39:02 AM MDT 2026 +One-line Summary: Update fates tag with missing land use data check fix + +Purpose and description of changes +---------------------------------- + +This update brings in fates-side changes which allow for checking of +fates land use data that uses either NaN or non-nan fill values. This +also updates the fates land use data tool tag which captures the +associated netcdf write encoding changes to ensure that the land use +data will use non-nan values consistent with the latest default datasets. + + +Bugs fixed +---------- +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: +Resolves #3789 + +Notes of particular relevance for developers: +--------------------------------------------- +NOTE: Be sure to review the steps in README.CHECKLIST.master_tags as well as the coding style in the Developers Guide + +Changes to tests or testing: +- Removes the FatesColdLUH testmods from the expected failures list + +Contributors: + +Testing summary: +---------------- + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + + fates tests: (give name of baseline if different from CTSM tagname, normally fates baselines are fates--) + derecho ----- OK + izumi ------- OK + + +Answer changes +-------------- + +Changes answers relative to baseline: B4B, except for FATES + +Other details +------------- + +List any git submodules updated (cime, rtm, mosart, cism, fates, etc.): + fates: sci.1.92.0_api.44.0.0 --> sci.1.92.1_api.44.1.0 + fates/tools/landusedata: v0.1.1 --> v0.4.1 + +Pull Requests that document the changes (include PR ids): +(https://github.com/ESCOMP/ctsm/pull) + +https://github.com/ESCOMP/CTSM/pull/3926 +https://github.com/NGEET/fates/pull/1555 +https://github.com/NGEET/tools-fates-landusedata/pull/41 + +=============================================================== +=============================================================== +Tag name: ctsm5.4.032 +Originator(s): samrabin (Sam Rabin, UCAR/TSS) +Date: Fri Apr 10 11:19:34 MDT 2026 +One-line Summary: Simplify doc build messaging. + +Purpose and description of changes +---------------------------------- + +Updates doc-builder and related scripts to reduce noise during documentation build. Adds --verbose|-V option to print complete output. + + +Testing summary: +---------------- + +Only documentation tests were needed. Baselines for this tag are just softlinks to ctsm5.4.031. + + +Other details +------------- + +List any git submodules updated (cime, rtm, mosart, cism, fates, etc.): +- doc-builder updated from v3.0.1 to v3.1.0. + +Pull Requests that document the changes (include PR ids): +- [ESCOMP/CTSM Pull Request #3920: ctsm5.4.032: Simplify messaging during docs build by samsrabin](https://github.com/ESCOMP/CTSM/pull/3920) +- [ESCOMP/CTSM Pull Request #3921: ctsm5.4.032: Simplify messaging during docs build [update Changelog/Changesum] by samsrabin](https://github.com/ESCOMP/CTSM/pull/3921) + +=============================================================== +=============================================================== +Tag name: ctsm5.4.031 +Originator(s): samrabin (Sam Rabin, UCAR/TSS) +Date: Thu Apr 9 13:30:18 MDT 2026 +One-line Summary: b4b-dev merge 2026-04-09 + +Purpose and description of changes +---------------------------------- + +Includes the following PRs: +- [ESCOMP/CTSM Pull Request #3833: Fix typos and RST issues in Surface Characterization tech note by huiqi-wang](https://github.com/ESCOMP/CTSM/pull/3833) +- [ESCOMP/CTSM Pull Request #3834: Fix grammar, equation 9.17/9.18 LaTeX, and eq. ref in Photosynthesis … by huiqi-wang](https://github.com/ESCOMP/CTSM/pull/3834) +- [ESCOMP/CTSM Pull Request #3837: Documentation updates: New hist time handling by slevis-lmwg](https://github.com/ESCOMP/CTSM/pull/3837) +- [ESCOMP/CTSM Pull Request #3896: Testlist review and update for aux_cime_baselines and prealpha by ekluzek](https://github.com/ESCOMP/CTSM/pull/3896) +- [ESCOMP/CTSM Pull Request #3903: Fix allocate error message typo in mkurbanparMod by olyson](https://github.com/ESCOMP/CTSM/pull/3903) +- [ESCOMP/CTSM Pull Request #3838: Replace cheyenne references with derecho throughout by slevis-lmwg](https://github.com/ESCOMP/CTSM/pull/3838) +- [ESCOMP/CTSM Pull Request #3908: Update documentation documentation by samsrabin](https://github.com/ESCOMP/CTSM/pull/3908) + + +Bugs fixed +---------- + +List of CTSM issues fixed (include CTSM Issue # and description): +- [ESCOMP/CTSM Issue #3171: Docs needed: New history time handling](https://github.com/ESCOMP/CTSM/issues/3171) +- [ESCOMP/CTSM Issue #3784: Review tests in aux_cime_baselines and reconcile this test list with prealpha](https://github.com/ESCOMP/CTSM/issues/3784) +- [ESCOMP/CTSM Issue #3898: A typo in the mkurbanparMod.F90 code](https://github.com/ESCOMP/CTSM/issues/3898) +- [ESCOMP/CTSM Issue #2223: Docs: Change Cheyenne references to Derecho](https://github.com/ESCOMP/CTSM/issues/2223) +- [ESCOMP/CTSM Issue #3892: User's Guide: Add "Contributing to documentation" documentation](https://github.com/ESCOMP/CTSM/issues/3892) + + +Notes of particular relevance for developers: +--------------------------------------------- + +Changes to tests or testing: Adjusts some of the prealpha and aux_cime_baseline tests. + + +Testing summary: +---------------- + + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + + +Other details +------------- + +List any git submodules updated (cime, rtm, mosart, cism, fates, etc.): +- doc-builder updated from v2.2.6 to v3.0.1 + +Pull Requests that document the changes (include PR ids): +- [ESCOMP/CTSM Pull Request #3917: Merge b4b-dev to master 2026-04-09 by samsrabin](https://github.com/ESCOMP/CTSM/pull/3917) + +=============================================================== +=============================================================== +Tag name: ctsm5.4.030 +Originator(s): glemieux (Gregory Lemieux, LBNL, glemieux@lbl.gov) +Date: Fri Apr 6 04:01:00 PM MDT 2026 +One-line Summary: Add FATES namelist option for land use transition logic + +Purpose and description of changes +---------------------------------- + +This pull request adds a new namelist option to allow the user to select +the logic option that controls whether or not FATES kills vegetation +during land use transitions. + +Notes of particular relevance for users +--------------------------------------- + +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): + Added fates_lu_transition_logic namelist variable option + +Testing summary: +---------------- + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - PASS + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + + fates tests: (give name of baseline if different from CTSM tagname, normally fates baselines are fates--) + derecho ----- OK + izumi ------- OK + +If the tag used for baseline comparisons was NOT the previous tag, note that here: + fates tested against `fates-sci.1.91.4_api.43.0.0-ctsm5.4.029` + +Answer changes +-------------- + +Changes answers relative to baseline: Yes, fates only, not including satellite phenology mode + +Other details +------------- +[Remove any lines that don't apply. Remove entire section if nothing applies.] + +List any git submodules updated (cime, rtm, mosart, cism, fates, etc.): + fates: sci.1.91.1_api.43.1.0 -> sci.1.92.0_api.44.0.0 + +Pull Requests that document the changes (include PR ids): +(https://github.com/ESCOMP/ctsm/pull) + +https://github.com/ESCOMP/CTSM/pull/3728 +https://github.com/NGEET/fates/pull/1489 + +=============================================================== +=============================================================== Tag name: ctsm5.4.029 Originator(s): slevis (Samuel Levis,UCAR/TSS,303-665-1310) Date: Mon Mar 30 03:25:18 PM MDT 2026 diff --git a/doc/ChangeSum b/doc/ChangeSum index f48956d43b..1aeac2a762 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,20 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.4.044 erik 06/08/2026 Merge b4b-dev to master + ctsm5.4.043 slevis 06/03/2026 Overflow respiration bug fixes + ctsm5.4.042 slevis 05/22/2026 Get hillslope_fsat_equals_zero .true. for use_hillslope + ctsm5.4.041 samrabin 05/21/2026 Merge b4b-dev 2026-05-21 + ctsm5.4.040 multiple 05/20/2026 Paramfile updates + ctsm5.4.039 multiple 05/14/2026 Add FATES namelist option to initialize cohorts with diameter at breast height (DBH) + ctsm5.4.038 slevis 05/07/2026 Merge b4b-dev to master + ctsm5.4.037 multiple 05/04/2026 Fix for FATES year-boundary restart issue + ctsm5.4.036 multiple 04/27/2026 Complete the FATES-CLM nitrogen coupling + ctsm5.4.035 erik 04/26/2026 Merge b4b-dev to master + ctsm5.4.034 afoster 04/22/2026 bug fix to the FATES land use driver input code + ctsm5.4.033 glemieux 04/17/2026 Update fates tag with missing land use data check fix + ctsm5.4.032 samrabin 04/10/2026 Simplify doc build messaging. + ctsm5.4.031 samrabin 04/09/2026 b4b-dev merge 2026-04-09 + ctsm5.4.030 glemieux 04/03/2026 Add FATES namelist option for land use transition logic ctsm5.4.029 slevis 03/30/2026 Merge b4b-dev to master ctsm5.4.028 erik 03/26/2026 Update to cmeps version with roundoff changes when running with CISM ctsm5.4.027 erik 03/24/2026 Some final namelist default changes needed diff --git a/doc/IMPORTANT_NOTES.md b/doc/IMPORTANT_NOTES.md index cf4125290a..7006ada85d 100644 --- a/doc/IMPORTANT_NOTES.md +++ b/doc/IMPORTANT_NOTES.md @@ -1,14 +1,13 @@ # Important Notes on Experimental Features of CTSM +--- -Namelist items that are not regularly tested or used. Some aren't even implemented. +## Namelist items not regularly tested or used (some aren't even implemented) - See +See '../bld/namelist_files/namelist_definition_ctsm.xml' -- for definitions of all namelist variables - '../bld/namelist_files/namelist_definition_ctsm.xml' -- for definitions of all namelist variables +### CTSM experimental namelist items -## CTSM experimental namelist items - - The following are tested but not on by default (for any physics) +The following are tested but not on by default (for any physics): - all_active - allow_invalid_gdd20_season_inputs @@ -16,7 +15,7 @@ Namelist items that are not regularly tested or used. Some aren't even implement - use_nvmovement - use_soil_moisture_streams - The following are NOT currently tested nor turned on by default: +The following are NOT currently tested nor turned on by default: - allowlakeprod - allow_invalid_swindow_inputs @@ -54,15 +53,14 @@ Namelist items that are not regularly tested or used. Some aren't even implement - use_vichydro (deprecated) - vcmax_opt = 4 -## FATES experimental namelist items +### FATES experimental namelist items - FATES is a relatively new subcomponent of CTSM - Almost all FATES options include "fates" in the name +FATES is a relatively new subcomponent of CTSM. Almost all FATES options include "fates" in the name. - The following are tested, but not turned on by default: +The following are tested, but not turned on by default: - fates_seeddisp_cadence > 0 - - fates_parteh_mode > 1 + - fates_parteh_mode == carbon_nitrogen - use_fates_planthydro - use_fates_managed_fire - use_fates_tree_damage @@ -71,7 +69,7 @@ Namelist items that are not regularly tested or used. Some aren't even implement - use_fates_potentialveg - use_fates_ed_st3 - The following are NOT currently tested nor turned on by default: +The following are NOT currently tested nor turned on by default: - fates_spitfire_mode == 2 - fates_spitfire_mode == 5 @@ -84,4 +82,3 @@ Namelist items that are not regularly tested or used. Some aren't even implement - use_fates_potentialveg - use_fates_daylength_factor == FALSE - fates_history_dimlevel == 0 - diff --git a/doc/README.CHECKLIST.master_tags.md b/doc/README.CHECKLIST.master_tags.md index 4dd21356cc..ecd5b4763d 100644 --- a/doc/README.CHECKLIST.master_tags.md +++ b/doc/README.CHECKLIST.master_tags.md @@ -27,7 +27,6 @@ https://github.com/ESCOMP/ctsm/wiki/CTSM-development-workflow 3c -- make sure you understand any changes to the baselines -- to document in ChangeLog 3d -- Check the log file for run_sys_tests (`../run_sys_test.log`, to make sure that submodules are correct (see 2c above) - 3e -- When Izumi’s baseline is ready, manually open read permissions to all. > [!TIP] > Always test on your fork with a feature-branch so that we can change tag order if needed. Put > baselines in the next tag name, as we can easily change afterwards if needed. @@ -52,7 +51,7 @@ https://github.com/ESCOMP/ctsm/wiki/CTSM-development-workflow 5e -- Push all the changes on your local branches to the branch on your fork - [ ] 6. Submit a pull request (PR) for the changes - Have someone review it if you are able. At minimum review it youself. The PR mechanism + Have someone review it if you are able. At minimum review it yourself. The PR mechanism on git is an excellent way to code review code for both yourself and others. Also make sure all your changes are correct, changes that shouldn't have gone in don't, and all new files are added in. diff --git a/doc/WhatsNewInCTSM5.3.md b/doc/WhatsNewInCTSM5.3.md index 4717deac30..d8fabaa3e3 100644 --- a/doc/WhatsNewInCTSM5.3.md +++ b/doc/WhatsNewInCTSM5.3.md @@ -18,7 +18,7 @@ Changes to defaults for `clm6_0` physics: * Urban explicit A/C turned on (links above). * Snow thermal conductivity method is now `Sturm1997`. ([PR \#2348](https://github.com/ESCOMP/CTSM/pull/2348); see also [discussion \#1960](https://github.com/ESCOMP/CTSM/discussions/1960)) -* New initial conditions files for f09 ("1-degree" 1850, 2000), f19 (“2-degree” 1850), and ne30 (1850, 1979, 2000) resolutions. +* New initial conditions files for f09 ("1-degree" 1850, 2000), f19 ("2-degree" 1850), and ne30 (1850, 1979, 2000) resolutions. * New crop calendars. ([PR \#2664](https://github.com/ESCOMP/CTSM/pull/2664); informed by [Rabin et al., 2023](https://gmd.copernicus.org/articles/16/7253/2023/gmd-16-7253-2023.html)) * Dust emissions method is now `Leung_2023` (links above). * Excess ice is turned on. ([PR \#1787](https://github.com/ESCOMP/CTSM/pull/1787)) @@ -35,8 +35,8 @@ Changes for all physics versions: ### Heads up -* Small glacier changes mean that you can’t use a 5.3 surface dataset with pre-5.3 code and vice versa anymore. (Merged with [PR \#2500](https://github.com/ESCOMP/CTSM/pull/2500)) -* Updates the definition of history variable “time” from *end* of `time_bounds` to *middle* of `time_bounds`. ([PR \#2838](https://github.com/ESCOMP/CTSM/pull/2838); see section below) +* Small glacier changes mean that you can't use a 5.3 surface dataset with pre-5.3 code and vice versa anymore. (Merged with [PR \#2500](https://github.com/ESCOMP/CTSM/pull/2500)) +* Updates the definition of history variable "time" from *end* of `time_bounds` to *middle* of `time_bounds`. ([PR \#2838](https://github.com/ESCOMP/CTSM/pull/2838); see section below) * Standardizes history variable attributes and a history dimension name. ([PR \#2052](https://github.com/ESCOMP/CTSM/pull/2052); see section below) ## @@ -49,7 +49,7 @@ Changes for all physics versions: Startup and hybrid runs no longer run the 0th time step, consistent with the same change in CAM. (Branch and continue runs never had this 0th time step.) This means you will not get an extraneous initial history file anymore. In some circumstances this may also affect the names of history files. -In most cases, the history `time` variable is now defined as the middle of a history file’s `time_bounds` instead of the end, for consistency with the same change in CAM. The exception is if you specify `hist_avgflag_pertape = 'I'` for that file, in which case it will be treated as an “instantaneous” file. Instantaneous history files (a) have their `time` coordinate set to the end of the last timestep (as did all history files before this tag) and (b) do not include `time_bounds`. +In most cases, the history `time` variable is now defined as the middle of a history file's `time_bounds` instead of the end, for consistency with the same change in CAM. The exception is if you specify `hist_avgflag_pertape = 'I'` for that file, in which case it will be treated as an "instantaneous" file. Instantaneous history files (a) have their `time` coordinate set to the end of the last timestep (as did all history files before this tag) and (b) do not include `time_bounds`. The history dimension name `hist_interval` (of output variable `time_bounds`) is standardized to be `nbnd`. History variables `time_bounds`, `mcdate`, `mcsec`, `mdcur`, and `mscur` are standardized to include the calendar attribute. @@ -77,7 +77,7 @@ The history dimension name `hist_interval` (of output variable `time_bounds`) is ### Changes to rpointer files -The rpointer files are simple text files that CESM uses to keep track of how far simulations have progressed, pointing to the filename of the latest restart file for that component. There is one such file for each component, so for CTSM `I` cases that's `lnd`, `cpl`, and `atm` (and `rof` if it's active). Normally, when the user is just extending the length of simulations, there’s no need to worry about these files. +The rpointer files are simple text files that CESM uses to keep track of how far simulations have progressed, pointing to the filename of the latest restart file for that component. There is one such file for each component, so for CTSM `I` cases that's `lnd`, `cpl`, and `atm` (and `rof` if it's active). Normally, when the user is just extending the length of simulations, there's no need to worry about these files. However, if there was a problem when a simulation shut down, it's possible that different components will have mismatched restarts and rpointer files. In the past, this meant figuring out what restart file should be pointed to in each component rpointer file and correcting it by hand in an editor. There was only the final set of rpointer files that was kept for a case. diff --git a/doc/WhatsNewInCTSM5.4.md b/doc/WhatsNewInCTSM5.4.md new file mode 100755 index 0000000000..4cd4584245 --- /dev/null +++ b/doc/WhatsNewInCTSM5.4.md @@ -0,0 +1,151 @@ +# What's new in CTSM 5.4 (tag `ctsm5.4.002`) + +# Purpose and description of changes since CTSM 5.3 (tag `ctsm5.3.021`) + +## New features + +* New surface datasets from CMIP7 data including PFT and urban distributions, land use transitions, population density, and atmospheric C isotopes. These data are only available through the historical record (1850-2023), and + * are not available for future periods (presently known as SSP), + * for future periods and N deposition we continue to use CMIP6 data from CESM2. +* Option to use CRUJRA2024 atmospheric driver data with clm6 and clm5 physics options ([PR #2956](https://github.com/ESCOMP/ctsm/pull/2956)), this is the default data-atmosphere (DATM) for clm6. This CRUJRA dataset covers 1901-2023, whereas previous GSWP3 only covers 1901-2014. +* Capability to run single-point PLUMBER tower sites, similar to the NEON tower capability ([issue #1487](https://github.com/ESCOMP/CTSM/issues/1487)). Initial conditions are not provided for PLUMBER sites. +* New CLM\_CMIP\_ERA flag in env\_run.xml. Valid options are cmip7 and cmip6. Defaults to cmip7 except in compsets containing SSP for which it defaults to cmip6 because there are no future-period datasets yet available for CMIP7. +* Automatic, more flexible use of anomaly forcings for CMIP6 ISSP cases, which also use the cmip6 CLM\_CMIP\_ERA flag: [Documentation](https://escomp.github.io/CTSM/users_guide/running-special-cases/Running-with-anomaly-forcing.html) + +* Unsupported script that checks for spinup equilibrium in `tools/contrib/` for spectral element grids ([PR #2991](https://github.com/ESCOMP/ctsm/pull/2991)). +* New paramfile tools that allow users to query and modify CLM parameter files ([documentation](https://escomp.github.io/CTSM/users_guide/using-clm-tools/paramfile-tools.html)) +* Optional time-evolving \`leafcn\_target\`. More under "Additional detail" below. +* New vertical movement scheme for soil nitrate, which is off by default (PR [#2992](https://github.com/ESCOMP/CTSM/pull/2992)). +* Documentation improvements and new URL: https://escomp.github.io/CTSM/index.html. +* FATES: + * Grazing ([sci.1.81.0\_api.37.1.0](https://github.com/NGEET/fates/releases/tag/sci.1.81.0_api.37.1.0)). + * Johnson and Berry 2021 electron transport model ([sci.1.85.0\_api.40.0.0](https://github.com/NGEET/fates/releases/tag/sci.1.85.0_api.40.0.0)). + * Managed Fire ([sci.1.87.0\_api.41.0.0](https://github.com/NGEET/fates/releases/tag/sci.1.87.0_api.41.0.0)). + +## Answer changes + +Changes to defaults for \`clm6\` physics: + +* New CMIP7 surface and landuse timeseries datasets (see in Additional Details below). +* New namelist variables \`snow\_thermal\_cond\_glc\_method\` and \`snow\_thermal\_cond\_lake\_method\` ([PR #3072](https://github.com/ESCOMP/CTSM/pull/3072)). Snow thermal conductivity uses Jordan1991 over glaciers to reduce Greenland melt rates by default and Sturm over land and lake land units. +* Bytnerowicz is now the default nfix\_method for clm6 (https://github.com/ESCOMP/ctsm/pull/2972) which revises the temperature function for nitrogen fixation, replacing the Houlton *et al.* function. +* Updates to MEGAN for BVOCs (https://github.com/ESCOMP/CTSM/pull/3065 https://github.com/ESCOMP/CTSM/pull/3309). Removes dependence on soil moisture from clm6 physics. +* New model parameter values that were calibrated to improve carbon cycle representation with CRUJRA. +* New model parameter values that were calibrated to improve the fire model. Now using li2024 fire code. +* New initial conditions files for f09 ("1-degree" 1850, 2000), f19 ("2-degree" 1850), and ne30 (1850, 1979, 2000\) resolutions. +* Change default for glcmec\_downscale\_longwave to FALSE for clm6 physics as turning off the LW downscaling improves the melt and runoff biases. +* See "Changes to FATES and the FATES parameter file" below. +* Namelist defaults change so that + * use\_c13/use\_c14 are on only for HistClm60Bgc compsets with CRUJRA2024 or CAM7 forcing; examples of when use\_c13/use\_c14 are now off include SSP and single-point compsets, as well as cases using older forcings, such as CAM6, GSWP3v1, Qian, and CRUv7 + * when use\_c13 or use\_c14 is on, turn on the corresponding time series file (responding to the CLM_CMIP_ERA flag) + * C13/C14 CMIP7 data is done using streams with new namelist variables (stream_*_atm_c13, stream_*_atm_c14) + * irrigation is on for transient cases (1850-2000, 1850-2100, but not for clm4\_5). + +Changes for all physics versions: + +* Parameters updated: Added MIMICS parameter \`mimics\_fi\` (fraction of litter inputs that bypass litter pools, directly contributing to SOM) and updated other MIMICS parameters (https://github.com/ESCOMP/CTSM/pull/2365) to remove NPP control on turnover, fix density dependent control on turnover, add litterfall fluxes that bypass litter pools and contribute directly to soil organic matter. +* FATES parameter file updated: ([PR \#2965](https://github.com/ESCOMP/CTSM/pull/2965), [PR \#2904](https://github.com/ESCOMP/CTSM/pull/2904), [PR \#1344](https://github.com/NGEET/fates/pull/1344), [PR \#3087](https://github.com/ESCOMP/CTSM/pull/3087)). See "FATES parameter file" section below for details. +* New surface datasets and landuse timeseries files (see "surface datasets" section below). +* CMIP7 C13/C14 atmospheric timeseries data + +## Heads up + +* History tapes now split into two files from hX to hXi and hXa, where X is the tape number (e.g. h0i/h0a) and where "i" stands for history file containing instantaneous fields, while "a" stands for history file containing non-instantaneous fields. Details in the "history files" section below and in the PRs https://github.com/ESCOMP/ctsm/pull/2445 https://github.com/ESCOMP/MOSART/pull/117 https://github.com/ESCOMP/RTM/pull/61 and the corresponding issues. +* Adding time to 1d weighting fields in transient simulations PR https://github.com/ESCOMP/CTSM/pull/3328 +* Regarding CMIP7 vs. CMIP6 inputs: + * C13/C14 isotope datasets are the new CMIP7 datasets using streams, while when CLM_CMIP_ERA==cmip6, the older cmip6 files are used + * We supply only CMIP7 population density with clm6 physics in non-SSP cases, because the fire model is calibrated to that; conversely, we supply only CMIP6 population density for pre-clm6 physics and for SSP cases. + * We supply only CESM2 nitrogen deposition (ndep), so this gets used regardless of CLM\_CMIP\_ERA setting. + * For DATM we supply only CMIP6 aerosols. + * For DATM we supply only CMIP6 CO2. +* Issue with DOUT\_S\_SAVE\_INTERIM\_REST [https://github.com/ESCOMP/CTSM/issues/3351](https://github.com/ESCOMP/CTSM/issues/3351) was fixed. +* As of ctsm5.3.040, the new ctsm\_pylib conda environment is incompatible with our tools from before ctsm5.3.040 and vice versa. More under "Additional detail" below. + +# Additional detail + +## Changes related to history files + +(Note 1: The same information in this section applies to MOSART and RTM. +Note 2: The gist of the information in this section also appears in the [CTSM User's Guide](https://escomp.github.io/CTSM/users_guide/setting-up-and-running-a-case/customizing-the-clm-namelist.html#various-ways-to-change-history-output-averaging-flags)). + +Following ctsm5.3.018 "Change history time to be the middle of the time bounds" and keeping CLM history consistent with CAM history, the CTSM5.4 change intends to prevent confusion associated with the time corresponding to instantaneous history fields by putting them on separate files than non-instantaneous fields. + +The now separate instantaneous history files represent the exact time step when they were written and do not include a time\_bounds variable. Conversely, non-instantaneous history files represent the period of their time\_bounds variable. As a result, time data on non-instantaneous history files are now read correctly during post processing (e.g. by xarray). Special handling may still be needed for instantaneous history files, whose timestamps represent the date and time at the END of the history timestep. So, e.g., an instantaneous variable saved at the end of year 2023 will get the timestamp 2024-01-01 00:00:00. + +Users will now see: + +1\) Two history files per clm, mosart, and rtm history tape: + tape h0 becomes h0a and h0i + tape h1 becomes h1a and h1i + ... + tape hX becomes hXa and hXi + +2\) Two history-restart files per history restart tape: + rh0 becomes rh0a and rh0i + rh1 becomes rh1a and rh1i + ... + rhX becomes rhXa and rhXi + +The CLM handles empty history (and corresponding history-restart) files by not generating them, while rtm and mosart give an error. Instead of refactoring rtm and mosart to behave like the clm (considered out of scope), we have introduced one active instantaneous field in mosart and one in rtm to bypass the "empty file" error. + +## New surface datasets and landuse timeseries files (https://github.com/ESCOMP/CTSM/pull/3482) + +* Transient landuse timeseries files going back to 1700 made for f09 and 360x720 grids. +* New resolutions now supported: ne3np4.pg3, mpasa30, ne0np4.NATL.ne30x8 (https://github.com/ESCOMP/CTSM/pull/3482) +* Updates to input datasets (also referred to as raw datasets): + * PFT/LAI/soil-color raw datasets; now from the CMIP7 timeseries that ends in 2023 (Issue [\#2851](https://github.com/ESCOMP/CTSM/issues/2851)). + * Two fire datasets: crop fire peak month and population density (https://github.com/ESCOMP/CTSM/issues/2701 https://github.com/ESCOMP/CTSM/issues/3302). + * Transient (historical) urban datasets are now based on CMIP7 urban data, partitioned into TBD, HD, and MD classes in proportion to GaoOneill present day classification. + +## Changes to FATES and the FATES parameter file + +* See [HLM-FATES compatibility table](https://fates-users-guide.readthedocs.io/en/latest/user/release-tags-compat-table.html) in the FATES user's guide for all FATES tags associated with CTSM tag updates +* FATES answer changing updates + * The default hydro solver is updated to 2D Picard from 1D Taylor ([ctsm5.3.027](https://github.com/ESCOMP/CTSM/releases/tag/ctsm5.3.027)) + * Simplified leaf sun-shade fraction for two-stream radiation ([sci.1.83.0\_api.39.0.0](https://github.com/NGEET/fates/releases/tag/sci.1.83.0_api.39.0.0)) + * Default maximum canopy layer updated from 2 to 3 ([sci.1.87.1\_api.41.0.0](https://github.com/NGEET/fates/releases/tag/sci.1.87.1_api.41.0.0)) + * Various bug fixes (see compatibility table) +* FATES Parameter File Updates + * ctsm5.3.025 (API 37\) + * Adds pft-dependent btran model switches + * Adds parameters for land use grazing + * Updates the FATES z0mr turbulence parameters for consistency with CLM + * ctsm5.3.027 (API 38\) + * Migrates a number of global parameter file variables to the namelist + * Adds \`fates\_leaf\_fnps\` parameter for the electron transport model + * \`fates\_leaf\_theta\_cj\_c3\` and \`fates\_leaf\_theta\_cj\_c4\` depricated + * ctsm5.3.045 (API 40\) + * Changes to the default competitive exclusion parameter from probabilistic to rank-ordered sorting of cohorts by default + * Sets the logging default to clear cut + * Refactors the pft-specific phenology habit selection into a single parameter + * ctsm5.3.070 (API 41\) + * Add parameters for the managed fire feature addition + * Corrects the fates landuse crop pft to c3 cool grass + +## New ctsm\_pylib conda environment + +If you have a ctsm\_pylib conda environment installed from before ctsm5.3.040, you may want to keep that under a different name. We suggest the following command for doing this in a local copy of ctsm5.3.040 or later: + +```shell +./py_env_create -r ctsm_pylib_old +``` + +This first renames your existing ctsm\_pylib to ctsm\_pylib\_old and then installs the Python 3.13.2 version as ctsm\_pylib. If you are unsure whether you already have ctsm\_pylib installed, use the same command regardless, as it will skip the renaming step if necessary. + +Information about additional py\_env\_create options — including how to install a fresh copy of the old conda environment — is available as follows: + +```shell +./py_env_create --help +``` + +## Potentially time-evolving \`leafcn\_target\` replaces time-constant \`leafcn\` + +The former is calculated as a function of the latter and can be time-evolving depending on new paramfile parameter \`leafcn\_co2\_slope\` https://github.com/ESCOMP/ctsm/pull/1654. The time-evolving effect defaults to off with \`leafcn\_co2\_slope\` \= 0 on the parameter file. + +# Simulations supporting this release by providing initial conditions + +* f19 \`Clm60BgcCruJra\` 16pft: https://github.com/NCAR/LMWG_dev/issues/125 +* f09 with \`Clm60BgcCropCruJra\`: https://github.com/NCAR/LMWG_dev/issues/124 +* ne30 with \`Clm60BgcCropCruJra\`: https://github.com/NCAR/LMWG_dev/issues/123 (123\_HIST\_popDens) +* ne30 SP https://github.com/NCAR/LMWG_dev/issues/126 +* f09 SP https://github.com/NCAR/LMWG_dev/issues/127 diff --git a/doc/build_docs b/doc/build_docs index 89434622a6..99415e15c4 100755 --- a/doc/build_docs +++ b/doc/build_docs @@ -6,10 +6,24 @@ if [ ! -f doc-builder/build_docs ]; then ${script_dir}/../bin/git-fleximod update doc-builder fi -echo "Running: make fetch-images" -make fetch-images +# Check if --verbose or -V was passed +verbose=false +for arg in "$@"; do + case "$arg" in + --verbose|-V) verbose=true; break ;; + esac +done -echo "Running: ./doc-builder/build_docs $@" +if $verbose; then + echo "Running: make fetch-images" + make fetch-images +else + make fetch-images > /dev/null 2>&1 +fi + +if $verbose; then + echo "Running: ./doc-builder/build_docs $@" +fi ./doc-builder/build_docs "$@" -exit 0 \ No newline at end of file +exit 0 diff --git a/doc/build_docs_to_publish b/doc/build_docs_to_publish index 6804311c64..bc4075c964 100755 --- a/doc/build_docs_to_publish +++ b/doc/build_docs_to_publish @@ -6,13 +6,27 @@ if [ ! -f doc-builder/build_docs_to_publish ]; then "${script_dir}"/../bin/git-fleximod update doc-builder fi +# Check if --verbose or -V was passed +verbose=false +for arg in "$@"; do + case "$arg" in + --verbose|-V) verbose=true; break ;; + esac +done + cd "${script_dir}" -echo "Running: make fetch-images" -make fetch-images +if $verbose; then + echo "Running: make fetch-images" + make fetch-images +else + make fetch-images > /dev/null 2>&1 +fi -echo "Running: ./doc-builder/build_docs_to_publish $@" -pwd +if $verbose; then + echo "Running: ./doc-builder/build_docs_to_publish $@" + pwd +fi ./doc-builder/build_docs_to_publish "$@" -exit 0 \ No newline at end of file +exit 0 diff --git a/doc/ctsm-docs_container/Dockerfile b/doc/ctsm-docs_container/Dockerfile index 3a24e1d4a4..c38a384f80 100644 --- a/doc/ctsm-docs_container/Dockerfile +++ b/doc/ctsm-docs_container/Dockerfile @@ -29,4 +29,4 @@ CMD ["/bin/bash", "-l"] LABEL org.opencontainers.image.title="Container for building CTSM documentation" LABEL org.opencontainers.image.source=https://github.com/ESCOMP/CTSM -LABEL org.opencontainers.image.version="v1.0.2e" +LABEL org.opencontainers.image.version="v2.0.1a" diff --git a/doc/ctsm-docs_container/README.md b/doc/ctsm-docs_container/README.md index bff10aada2..2c8110275d 100644 --- a/doc/ctsm-docs_container/README.md +++ b/doc/ctsm-docs_container/README.md @@ -33,21 +33,22 @@ Here's where you need to specify the version number in the Dockerfile: ```docker LABEL org.opencontainers.image.version="vX.Y.Z" ``` -The string there can technically be anything as long as (a) it starts with a lowercase `v` and (b) it hasn't yet been used on a published version of the container. +The string there can technically be anything as long as (a) it starts with a lowercase `v` and (b) it hasn't yet been used on a published version of the container. You may need to "bump" the version string in order for various tests to pass; if so, just add a lowercase letter at the end. You can check the results of the automatic publication on the [container's GitHub page](https://github.com/ESCOMP/CTSM/pkgs/container/ctsm%2Fctsm-docs). ### Updating doc-builder After the new version of the container is published, you will probably want to tell [doc-builder](https://github.com/ESMCI/doc-builder) to use the new one. Open a PR where you change the tag (the part after the colon) in the definition of `DEFAULT_IMAGE` in `doc_builder/build_commands.py`. Remember, **use the version number**, not "latest". -## Publishing manually (NOT recommended) +## Publishing manually -It's vastly preferable to let GitHub build and publish the new repo using the `docker-image-build-publish.yml` workflow as described above. However, if you need to publish manually for some reason, here's how. +It's vastly preferable to let GitHub build and publish the new repo using the `docker-image-build-publish.yml` workflow as described above. However, you may need to publish manually if, for instance, you introduce a change that breaks `doc-builder`. You could work around that by first merging a CTSM `master` PR that updates the container, then updating `doc-builder` to use it, then updating CTSM to use the new `doc-builder`. That's not always practical, though, so here's how to publish the container manually. ### Building the multi-architecture version When publishing our container, we need to make sure it can run on either arm64 or amd64 processor architecture. This requires a special build process: ```shell +podman manifest rm ctsm-docs-manifest 2>/dev/null podman manifest create ctsm-docs-manifest podman build --platform linux/amd64,linux/arm64 --manifest ctsm-docs-manifest . ``` @@ -66,16 +67,17 @@ export HISTCONTROL=ignoreboth ``` ### Tagging -You'll next need to tag the image. Lots of container instructions tell you to use the `latest` tag, and Podman may actually add that for you. However, `latest` can lead to support headaches as users think they have the right version but actually don't. Instead, you'll make a new version number incremented from the [previous one](https://github.com/ESCOMP/CTSM/pkgs/container/ctsm%2Fctsm-docs/versions), in the `vX.Y.Z` format. +You'll next need to tag the image. Lots of container instructions tell you to use the `latest` tag, and Podman may actually add that for you. However, using `latest` in `doc-builder` can lead to support headaches as users think they have the right version but actually don't. So in addition to `latest`, you'll make a new version number incremented from the [previous one](https://github.com/ESCOMP/CTSM/pkgs/container/ctsm%2Fctsm-docs/versions), in the `vX.Y.Z` format. -Copy the relevant image ID (see `podman images` instructions above) and tag it with your version number like so: +Tag the manifest with your version number like so: ```shell -podman tag 6464f26339bc ghcr.io/escomp/ctsm/ctsm-docs:vX.Y.Z +podman tag ctsm-docs-manifest ghcr.io/escomp/ctsm/ctsm-docs:v2.0.1 ``` Push to the repo: ```shell podman manifest push --all ctsm-docs-manifest ghcr.io/escomp/ctsm/ctsm-docs:vX.Y.Z +podman manifest push --all ctsm-docs-manifest ghcr.io/escomp/ctsm/ctsm-docs:latest ``` Then browse to the [container's GitHub page](https://github.com/ESCOMP/CTSM/pkgs/container/ctsm%2Fctsm-docs) to make sure this all worked and the image is public. diff --git a/doc/ctsm-docs_container/requirements.txt b/doc/ctsm-docs_container/requirements.txt index 178f356b13..19872cb9c0 100644 --- a/doc/ctsm-docs_container/requirements.txt +++ b/doc/ctsm-docs_container/requirements.txt @@ -2,5 +2,5 @@ rst2pdf == 0.103.1 sphinx == 8.2.3 sphinxcontrib_programoutput == 0.18 -sphinx-mdinclude == 0.6.2 +myst-parser == 5.0.0 sphinx_rtd_theme == 3.0.2 diff --git a/doc/doc-builder b/doc/doc-builder index 3ab6d06971..15e171dfcf 160000 --- a/doc/doc-builder +++ b/doc/doc-builder @@ -1 +1 @@ -Subproject commit 3ab6d06971e508f2886f0079db37156ab93c2b07 +Subproject commit 15e171dfcf77ca2bd85415a99a50ad3994c608c4 diff --git a/doc/source/lilac/obtaining-building-and-running/notes-on-running-ctsm.rst b/doc/source/lilac/obtaining-building-and-running/notes-on-running-ctsm.rst index 1e3d36cdf7..6689b37161 100644 --- a/doc/source/lilac/obtaining-building-and-running/notes-on-running-ctsm.rst +++ b/doc/source/lilac/obtaining-building-and-running/notes-on-running-ctsm.rst @@ -11,16 +11,16 @@ Environment variables that may need to be set at runtime ======================================================== -With the MPT MPI library (which is the default MPI library on NCAR's cheyenne machine), it is important to set the environment variable ``MPI_TYPE_DEPTH`` to 16 when running CTSM (this setting is required by the Parallel IO library). Typically you should set this variable in your job submission script, using either: +Currently none. This is only a placeholder. Typically you should set this variable in your job submission script, using either: .. code-block:: Bash - export MPI_TYPE_DEPTH=16 + export = or: .. code-block:: Tcsh - setenv MPI_TYPE_DEPTH 16 + setenv prior to running the model. diff --git a/doc/source/lilac/obtaining-building-and-running/obtaining-and-building-ctsm.rst b/doc/source/lilac/obtaining-building-and-running/obtaining-and-building-ctsm.rst index fcd8235b62..8f0261b0ed 100644 --- a/doc/source/lilac/obtaining-building-and-running/obtaining-and-building-ctsm.rst +++ b/doc/source/lilac/obtaining-building-and-running/obtaining-and-building-ctsm.rst @@ -127,7 +127,7 @@ if you are using a machine that has been ported to CIME_; the second works if yo using a machine that has *not* been ported to CIME_. Both workflows are described below. If you are using a machine that has not been ported to CIME, it is possible to do a complete CIME port and then use the first workflow (by following the `CIME porting guide -`_), but +`_), but unless you need to do so for other reasons (such as running CESM, or running CTSM in a land-only configuration forced by a data atmosphere, using the CIME_ scripting infrastructure), it is generally simpler to use the second workflow below: A full CIME diff --git a/doc/source/lilac/obtaining-building-and-running/setting-ctsm-runtime-options.rst b/doc/source/lilac/obtaining-building-and-running/setting-ctsm-runtime-options.rst index acb1cad9be..6391352bad 100644 --- a/doc/source/lilac/obtaining-building-and-running/setting-ctsm-runtime-options.rst +++ b/doc/source/lilac/obtaining-building-and-running/setting-ctsm-runtime-options.rst @@ -105,8 +105,7 @@ in this file. The first set of options in this file specifies key file names: - ``lnd_domain_file`` must be specified. This file specifies CTSM's grid and land - mask. The general process for creating this file is described in section - :numref:`creating-domain-files`. + mask. - ``fsurdat`` also must be specified. This file specifies a variety of spatially-varying properties. This file is grid-specific, but can be created from grid-independent files diff --git a/doc/source/lilac/specific-atm-models/wrf-tools.rst b/doc/source/lilac/specific-atm-models/wrf-tools.rst index 1222a16f10..ab9ef318b2 100644 --- a/doc/source/lilac/specific-atm-models/wrf-tools.rst +++ b/doc/source/lilac/specific-atm-models/wrf-tools.rst @@ -16,61 +16,21 @@ Before this step, make sure you have successfully created geo_em* files for your specific WRF domain using WPS. Instructions on how to run ``geogrid.exe`` is described in here. -1. Create SCRIP grid file from WRF ``geo_em*`` files, using the following ncl - script:: +1. Create ESMF mesh file from WRF ``geo_em*`` files, using the make_mesh tool. Details in section :numref:`how-to-make-mesh`. - ncl create_scrip_file.ncl +2. Create surface datasets in ``tools/mksurfdata_esmf``. Details in section :numref:`creating-surface-datasets`. - This creates two files that are complements of each other only in the mask field - -2. Create mapping files by using ``mkmapdata`` code under - ``CTSM/tools/mkmapdata/``. - - Using environment variables set the following environment varibales needed - by ``mkunitymap.ncl`` code:: - - setenv GRIDFILE1 wrf2clm_ocean_noneg.nc - setenv GRIDFILE2 wrf2clm_land_noneg.nc - setenv MAPFILE wrf2clm_mapping_noneg.nc - setenv PRINT TRUE - - ncl mkunitymap.ncl - -.. warning:: - - This will throw some git errors if not run in a repository. - -3. Create ESMF mapping files by running ``regridbatch.sh``:: - - qsub regridbatch.sh - -4. In your ctsm repository directory, build:: - - ../../../configure --macros-format Makefile --mpilib mpi-serial - -.. todo:: - Update the below, as domain files aren't needed with nuopc. - -5. Generate CTSM domain files using ``get_domain`` tool:: - - ./gen_domain -m /glade/work/$USER/ctsm/nldas_grid/scrip/wrf2clm_mapping_noneg.nc -o wrf2clm_ocn_noneg -l wrf2clm_lnd_noneg - -.. todo:: - Update the below, as ``mksurfdata.pl`` no longer exists. - -6. Create surface datasets in ``tools/mksurfdata_esmf``:: - - ./mksurfdata.pl -res usrspec -usr_gname "nldas" -usr_gdate "190124" -usr_mapdir "/glade/work/$USER/ctsm/nldas_grid/map" -y 2000 -exedir "/glade/u/home/$USER/src/ctsm/ctsm_surfdata/tools/mksurfdata_esmf" -no-crop Merge WRF initial conditions into an existing CTSM initial condition file -------------------------------------------------------------------------- -The following procedure is if you'd wish to merget WRF inital conditions from +The following procedure is if you'd wish to merge WRF inital conditions from ``wrfinput`` file into CTSM initial condition file :: + module load ncl ncl transfer_wrfinput_to_ctsm_with_snow.ncl 'finidat="the_existing_finidat_file.nc"' 'wrfinput="your_wrfinput_file"' 'merged="the_merged_finidat_file.nc"' .. todo:: - Sam, can you please make the above ncl script available. + Versions of the transfer_wrfinput ncl script are available in /glade/work/slevis/git_wrf/ctsm_init/. diff --git a/doc/source/lilac/specific-atm-models/wrf.rst b/doc/source/lilac/specific-atm-models/wrf.rst index ad85fee777..c0d157f0b5 100644 --- a/doc/source/lilac/specific-atm-models/wrf.rst +++ b/doc/source/lilac/specific-atm-models/wrf.rst @@ -25,9 +25,9 @@ and :numref:`wrf-set-ctsm-runtime-options`. This section assumes use of a machine that has been ported to CIME. If CIME is not ported to your machine, please see `instructions on porting CIME - `_. + `_. - In this example we assume NCAR's ``Cheyenne`` HPC system in particular. + In this example we assume NCAR's ``derecho`` HPC system in particular. .. _clone-WRF-CTSM-repositories: @@ -56,9 +56,9 @@ instructions from section :numref:`obtaining-and-building-ctsm`:: ./lilac/build_ctsm /PATH/TO/CTSM/BUILD --machine MACHINE --compiler COMPILER -For example on ``Cheyenne`` and for ``Intel`` compiler:: +For example on ``derecho`` and for ``Intel`` compiler:: - ./lilac/build_ctsm ctsm_build_dir --compiler intel --machine cheyenne + ./lilac/build_ctsm ctsm_build_dir --compiler intel --machine derecho .. warning:: @@ -171,7 +171,7 @@ skip to section :numref:`wrf-set-ctsm-runtime-options`. Get WPS from this website:: - https://www2.mmm.ucar.edu/wrf/users/download/wrf-regist_or_download.php + https://www2.mmm.ucar.edu/wrf/users/download/get_source.html New users must complete a registration form in this step. @@ -352,32 +352,31 @@ the following files to your WRF run directory:: cp /glade/scratch/negins/wrf_ctsm_files/wrfinput_d01 . cp /glade/scratch/negins/wrf_ctsm_files/wrfbdy_d01 . -Now run WRF-CTSM. On Cheyenne this means submitting a batch job to PBS (Pro workload management system). -Please check NCAR CISL's `instructions on running a batch job on Cheyenne. -`__ +Now run WRF-CTSM. On derecho this means submitting a batch job to PBS (Pro workload management system). +Please check NCAR CISL's `instructions on running a batch job on derecho. +`__ -A simple PBS script to run WRF-CTSM on ``Cheyenne`` looks like this: +A simple PBS script to run WRF-CTSM on ``derecho`` looks like this: .. code-block:: Tcsh - #!/bin/tcsh + #!/bin/bash #PBS -N your_job_name #PBS -A your_project_code #PBS -l walltime=01:00:00 - #PBS -q queue_name + #PBS -q main + #PBS -r n + #PBS -S /bin/bash #PBS -j oe #PBS -k eod #PBS -m abe #PBS -M your_email_address - #PBS -l select=2:ncpus=36:mpiprocs=36 + #PBS -l select=1:ncpus=128:mpiprocs=128 ### Run the executable - setenv MPI_TYPE_DEPTH 16 - mpiexec_mpt ./wrf.exe + mpibind ./wrf.exe -(See :numref:`runtime-environment-variables` for a description of the need to set ``MPI_TYPE_DEPTH`` on ``Cheyenne``.) - -To submit a batch job to the ``Cheyenne`` queues, use ``qsub`` command followed +To submit a batch job to the ``derecho`` queues, use ``qsub`` command followed by the PBS script name. For example, if you named this script ``run_wrf_ctsm.csh``, submit the job like this:: diff --git a/doc/source/tech_note/BVOCs/CLM50_Tech_Note_BVOCs.rst b/doc/source/tech_note/BVOCs/CLM50_Tech_Note_BVOCs.rst index 5d34fdce64..f4bca6df04 100644 --- a/doc/source/tech_note/BVOCs/CLM50_Tech_Note_BVOCs.rst +++ b/doc/source/tech_note/BVOCs/CLM50_Tech_Note_BVOCs.rst @@ -3,24 +3,63 @@ Biogenic Volatile Organic Compounds (BVOCs) =============================================== -This chapter briefly describes the biogenic volatile organic compound (BVOC) emissions model implemented in CLM. The CLM3 version (Levis et al. 2003; Oleson et al. 2004) was based on Guenther et al. (1995). Heald et al. (2008) updated this scheme in CLM4 based on Guenther et al (2006). The current version was implemented in CLM4.5 and is based on MEGAN2.1 discussed in detail in Guenther et al. (2012). This update of MEGAN incorporates four main features: 1) expansion to 147 chemical compounds, 2) the treatment of the light-dependent fraction (LDF) for each compound, 3) inclusion of the inhibition of isoprene emission by atmospheric CO\ :sub:`2` and 4) emission factors mapped to the specific PFTs of the CLM. +This section briefly describes the biogenic volatile organic compound (BVOC) emissions model implemented in CLM. The CLM3 version (:ref:`Levis et al. 2003 `; :ref:`Oleson et al. 2004 `) was based on :ref:`Guenther et al. (1995) `. :ref:`Heald et al. (2008) ` updated this scheme in CLM4 based on :ref:`Guenther et al (2006) `. The current version was first implemented in CLM4.5 and is currently based on MEGAN2.1 discussed in detail in :ref:`Guenther et al. (2012) `. As of CLM5, CLM-MEGAN has included these features: 1) expansion to 147 chemical compounds, 2) the treatment of the light-dependent fraction (LDF) for each compound, 3) inclusion of the inhibition of isoprene emission by atmospheric CO\ :sub:`2`, 4) emission factors mapped to the specific PFTs of the CLM. As of CLM6, CLM-MEGAN includes two new features: 5) the impact of drought, and 6) high-latitude specific isoprene emissions. -MEGAN2.1 now describes the emissions of speciated monoterpenes, sesquiterpenes, oxygenated VOCs as well as isoprene. A flexible scheme has been implemented in the CLM to specify a subset of emissions. This allows for additional flexibility in grouping chemical compounds to form the lumped species frequently used in atmospheric chemistry. The mapping or grouping is therefore defined through a namelist parameter in drv\_flds\_in, e.g. megan\_specifier = 'ISOP = isoprene', 'BIGALK pentane + hexane + heptane + tricyclene'. +MEGAN2.1 describes the emissions of speciated monoterpenes, sesquiterpenes, oxygenated VOCs as well as isoprene. A flexible scheme has been implemented in the CLM to specify a subset of emissions. This allows for additional flexibility in grouping chemical compounds to form the lumped species frequently used in atmospheric chemistry. The mapping or grouping is therefore defined through a namelist parameter in drv\_flds\_in, e.g. megan\_specifier = 'ISOP = isoprene', 'BIGALK pentane + hexane + heptane + tricyclene'. Terrestrial BVOC emissions from plants to the atmosphere are expressed as a flux, :math:`F_{i}` (:math:`\mu` \ g C m\ :sup:`-2` ground area h\ :sup:`-1`), for emission of chemical compound :math:`i` .. math:: - :label: ZEqnNum964222 + :label: flux equation F_{i} =\gamma _{i} \rho \sum _{j}\varepsilon _{i,j} \left(wt\right)_{j} -where :math:`\gamma _{i}` is the emission activity factor accounting for responses to meteorological and phenological conditions, :math:`\rho` is the canopy loss and production factor also known as escape efficiency (set to 1), and :math:`\varepsilon _{i,\, j}` (:math:`\mu` \ g C m\ :sup:`-2` ground area h\ :sup:`-1`) is the emission factor at standard conditions of light, temperature, and leaf area for plant functional type *j* with fractional coverage :math:`\left(wt\right)_{j}` (Guenther et al. 2012). The emission activity factor :math:`\gamma _{i}` depends on plant functional type, temperature, LAI, leaf age, and soil moisture (Guenther et al. 2012) For isoprene only, the effect of CO\ :sub:`2` inhibition is now included as described by Heald et al. (2009). Previously, only isoprene was treated as a light-dependent emission. In MEGAN2.1, each chemical compound is assigned a LDF (ranging from 1.0 for isoprene to 0.2 for some monoterpenes, VOCs and acetone). The activity factor for the light response of emissions is therefore estimated as: +where :math:`\gamma _{i}` is the emission activity factor accounting for responses to meteorological and phenological conditions, :math:`\rho` is the canopy loss and production factor also known as escape efficiency (set to 1), and :math:`\varepsilon _{i,\, j}` (:math:`\mu` \ g C m\ :sup:`-2` ground area h\ :sup:`-1`) is the emission factor at standard conditions of light, temperature, and leaf area for plant functional type *j* with fractional coverage :math:`\left(wt\right)_{j}` (Guenther et al. 2012). The emission activity factor :math:`\gamma _{i}` depends on plant functional type, temperature, LAI, leaf age, and soil moisture (Guenther et al. 2012) For isoprene only, the effect of CO\ :sub:`2` inhibition is now included as described by :ref:`Heald et al. (2009) `. Previously, only isoprene was treated as a light-dependent emission. In MEGAN2.1, each chemical compound is assigned a LDF (ranging from 1.0 for isoprene to 0.2 for some monoterpenes, VOCs and acetone). The activity factor for the light response of emissions is therefore estimated as: .. math:: - :label: 28.2) + :label: light-dependent activity factor \gamma _{P,\, i} =\left(1-LDF_{i} \right)+\gamma _{P\_ LDF} LDF_{i} where the LDF activity factor (:math:`\gamma _{P\_ LDF}` ) is specified as a function of PAR as in previous versions of MEGAN. -The values for each emission factor :math:`\epsilon _{i,\, j}` are now available for each of the plant functional types in the CLM and each chemical compound. This information is distributed through an external file, allowing for more frequent and easier updates. +The values for each emission factor :math:`\epsilon _{i,\, j}` are now available for each of the plant functional types in the CLM and each chemical compound. This information is provided in an external file, allowing for more frequent and easier updates. + +The impact of drought on isoprene emissions is based on the theory proposed by :ref:`Potosnak et al. (2014) `. Specifically, isoprene emissions are expected to increase under mild to moderate drought because drought raises leaf temperature, which stimulates isoprene emissions. Under severe drought, however, isoprene emissions are inhibited because substrate supply becomes constrained. Because the effect of leaf temperature is already represented by the leaf temperature activity factor :math:`\gamma _{T}` and its influence on isoprene emissions, only the inhibitory effect of severe drought (substrate supply impact, :math:`\gamma _{sub}` ) is parameterized as: + +.. math:: + :label: drought factor + + \gamma _{sub} =\frac{1}{1+b_{1} e^{a1 (\beta -0.2)}} + +where :math:`a_1=-7.4463` and :math:`b_1=3.2552` are empirical parameters (described in :ref:`Wang et al., 2022 `). + +Compared with Guenther et al. (2012), updates have been made to represent isoprene emissions from high-latitude plants, specifically boreal broadleaf deciduous shrubs (BBDS) and C3 Arctic grass (C3AG), in order to account for acclimation processes. These updates are based on leaf-enclosure and in situ measurements conducted at Toolik Field Station in Alaska, USA (:ref:`Wang et al., 2024a, 2024b `). +For BBDS, the isoprene emission factor is adjusted according to the mean temperature of the previous day as: + +.. math:: + :label: boreal shrub adjustment factor + + \text{For BBDS:} E_{opt} = 7.9 e^{0.217 (T_{24}-297.15)} + +where :math:`T_{24}` denotes the mean air temperature of the preceding day (Wang et al., 2024a). +For C3AG, the isoprene emission factor responds over a longer timescale of 10 days (Wang et al., 2024b) and is parameterized as a function of the mean air temperature over the preceding 10 days (:math:`T_{240}`): + +.. math:: + :label: C3 arctic grass adjustment factor + + \text{For C3AG:} E_{opt\_g} = e^{0.12 (T_{240}-288.15)} + +In addition, a dynamic temperature response curve for C3AG depends on recent temperature history as: + +.. math:: + :label: C3 arctic grass leaf temperature factor + + \text{For C3AG:} \gamma_{T\_g} = E_{opt\_g} e^{(C_{g} (1/303.15 - 1/T_{leaf}) / R)} + +where :math:`T_{leaf}` denotes the leaf temperature, :math:`R` is the gas constant (ct3 in code, 0.00831 kJ/mol) and :math:`C_{g}` is the parameter controlling the isoprene temperature response of C3AG and changes varies with :math:`T_{240}` as: + +.. math:: + :label: C3 arctic grass parameter + + C_{g} = 95 + 9.49 e^{0.53 (288.15-T_{240})} diff --git a/doc/source/tech_note/CN_Allocation/CLM50_Tech_Note_CN_Allocation.rst b/doc/source/tech_note/CN_Allocation/CLM50_Tech_Note_CN_Allocation.rst index c3eeee1946..2aa64219c7 100644 --- a/doc/source/tech_note/CN_Allocation/CLM50_Tech_Note_CN_Allocation.rst +++ b/doc/source/tech_note/CN_Allocation/CLM50_Tech_Note_CN_Allocation.rst @@ -6,14 +6,14 @@ Carbon and Nitrogen Allocation Introduction ----------------- -The carbon and nitrogen allocation routines in CLM determine the fate of newly assimilated carbon, coming from the calculation of photosynthesis, and available mineral nitrogen, coming from plant uptake of mineral nitrogen in the soil or being drawn out of plant reserves. A significant change to CLM5 relative to prior versions is that allocation of carbon and nitrogen proceed independently rather than in a sequential manner. +The carbon and nitrogen allocation routines in CLM determine the fate of newly assimilated carbon, coming from the calculation of photosynthesis, and available mineral nitrogen, coming from plant uptake of mineral nitrogen in the soil or being drawn out of plant reserves. CLM6 follows the allocation approach applied in CLM5. Carbon Allocation for Maintenance Respiration Costs -------------------------------------------------------- -Allocation of available carbon on each time step is prioritized, with first priority given to the demand for carbon to support maintenance respiration of live tissues (section 13.7). Second priority is to replenish the internal plant carbon pool that supports maintenance respiration during times when maintenance respiration exceeds photosynthesis (e.g. at night, during winter for perennial vegetation, or during periods of drought stress) (Sprugel et al., 1995). Third priority is to support growth of new tissues, including allocation to storage pools from which new growth will be displayed in subsequent time steps. +Allocation of available carbon on each time step is prioritized, with first priority given to the demand for carbon to support maintenance respiration of live tissues (Chapter :numref:`rst_Plant Respiration`). Second priority is to replenish the internal plant carbon pool that supports maintenance respiration during times when maintenance respiration exceeds photosynthesis (e.g. at night, during winter for perennial vegetation, or during periods of drought stress) (:ref:`Sprugel et al. (1995) `). Third priority is to support growth of new tissues, including allocation to storage pools from which new growth will be displayed in subsequent time steps. -The total maintenance respiration demand (:math:`CF_{mr}`, gC m\ :sup:`-2` s\ :sup:`-1`) is calculated as a function of tissue mass and nitrogen concentration, and temperature (section 13.7) The carbon supply to support this demand is composed of fluxes allocated from carbon assimilated in the current timestep (:math:`CF_{GPP,mr}`, gC m\ :sup:`-2` s\ :sup:`-1` and from a storage pool that is drawn down when total demand exceeds photosynthesis ( :math:`CF_{xs,mr}`, gC m\ :sup:`-2` s\ :sup:`-1`): +The total maintenance respiration demand (:math:`CF_{mr}`, gC m\ :sup:`-2` s\ :sup:`-1`) is calculated as a function of tissue mass and nitrogen concentration, and temperature (Chapter :numref:`rst_Plant Respiration`). The carbon supply to support this demand is composed of fluxes allocated from carbon assimilated in the current timestep (:math:`CF_{GPP,mr}`, gC m\ :sup:`-2` s\ :sup:`-1`) and from a storage pool that is drawn down when total demand exceeds photosynthesis (:math:`CF_{xs,mr}`, gC m\ :sup:`-2` s\ :sup:`-1`): .. math:: :label: 19.1 @@ -42,14 +42,14 @@ The storage pool that supplies carbon for maintenance respiration in excess of c CF_{GPP,xs} =\left\{\begin{array}{l} {CF_{GPP,xs,pot} \qquad \qquad \qquad {\rm for\; }CF_{GPP,xs,pot} \le CF_{GPP} -CF_{GPP,mr} } \\ {\max (CF_{GPP} -CF_{GPP,mr} ,0)\qquad {\rm for\; }CF_{GPP,xs,pot} >CF_{GPP} -CF_{GPP,mr} } \end{array}\right. -where :math:`\tau_{xs}` is the time constant (currently set to 30 days) controlling the rate of replenishment of :math:`CS_{xs}`. +where :math:`\tau_{xs}` is the time constant (currently set to 30 days) controlling the rate of replenishment of :math:`CS_{xs}`. The factor :math:`86400` (s day\ :sup:`-1`) converts :math:`\tau_{xs}` from days to seconds so that the flux is consistent with the per-second units used elsewhere. Note that these two top-priority carbon allocation fluxes (:math:`CF_{GPP,mr}` and :math:`CF_{GPP,xs}`) are not stoichiometrically associated with any nitrogen fluxes. Carbon and Nitrogen Stoichiometry of New Growth ---------------------------------------------------- -After accounting for the carbon cost of maintenance respiration, the remaining carbon flux from photosynthesis which can be allocated to new growth (:math:`CF_{avail}`, gC m\ :sup:`-2` s\ :sup:`-1`) is +After accounting for the carbon cost of maintenance respiration, the remaining carbon flux from photosynthesis which can be allocated to new growth (:math:`CF_{avail\_alloc}`, gC m\ :sup:`-2` s\ :sup:`-1`) is .. math:: :label: 19.6 @@ -61,92 +61,106 @@ Potential allocation to new growth is calculated for all of the plant carbon and .. math:: :label: 19.7 - \begin{array}{l} {a_{1} ={\rm \; ratio\; of\; new\; fine\; root\; :\; new\; leaf\; carbon\; allocation}} \\ {a_{2} ={\rm \; ratio\; of\; new\; coarse\; root\; :\; new\; stem\; carbon\; allocation}} \\ {a_{3} ={\rm \; ratio\; of\; new\; stem\; :\; new\; leaf\; carbon\; allocation}} \\ {a_{4} ={\rm \; ratio\; new\; live\; wood\; :\; new\; total\; wood\; allocation}} \\ {g_{1} ={\rm ratio\; of\; growth\; respiration\; carbon\; :\; new\; growth\; carbon.\; }} \end{array} + \begin{aligned} + a_{1} &= \text{ratio of new fine root : new leaf carbon allocation} \\ + a_{2} &= \text{ratio of new coarse root : new stem carbon allocation} \\ + a_{3} &= \text{ratio of new stem : new leaf carbon allocation} \\ + a_{4} &= \text{ratio of new live wood : new total wood allocation} \\ + g_{1} &= \text{ratio of growth respiration carbon : new growth carbon} + \end{aligned} -Parameters :math:`a_{1}`, :math:`a_{2}`, and :math:`a_{4}` are defined as constants for a given PFT (Table 13.1), while :math:`g_{l }` = 0.3 (unitless) is prescribed as a constant for all PFTs, based on construction costs for a range of woody and non-woody tissues (Larcher, 1995). +Parameters :math:`a_{1}`, :math:`a_{2}`, and :math:`a_{4}` are defined as constants for a given PFT (:numref:`Table Allocation and CN ratio parameters`). The growth respiration coefficient :math:`g_{1}` = 0.3 (unitless) is prescribed as a constant for all PFTs, based on construction costs for a range of woody and non-woody tissues (:ref:`Larcher (1995) `). The model includes a dynamic allocation scheme for woody vegetation (parameter :math:`a_{3}` = -1, :numref:`Table Allocation and CN ratio parameters`), in which case the ratio for carbon allocation between new stem and new leaf increases with increasing net primary production (NPP), as .. math:: :label: 19.8 - a_{3} =\frac{2.7}{1+e^{-0.004NPP_{ann} -300} } -0.4 + a_{3} = \frac{2.7}{1 + e^{-0.004 (NPP_{ann} - 300)}} - 0.4 -where :math:`NPP_{ann}` is the annual sum of NPP from the previous year. This mechanism has the effect of increasing woody allocation in favorable growth environments (Allen et al., 2005; Vanninen and Makela, 2005) and during the phase of stand growth prior to canopy closure (Axelsson and Axelsson, 1986). +where :math:`NPP_{ann}` is the annual sum of NPP from the previous year. This mechanism has the effect of increasing woody allocation in favorable growth environments (:ref:`Allen et al. (2005) `; :ref:`Vanninen and Makela (2005) `) and during the phase of stand growth prior to canopy closure (:ref:`Axelsson and Axelsson (1986) `). .. _Table Allocation and CN ratio parameters: -.. table:: Allocation and target carbon\:nitrogen ratio parameters +.. table:: Allocation and target carbon:nitrogen ratio parameters +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | Plant functional type | :math:`a_{1}` | :math:`a_{2}` | :math:`a_{3}` | :math:`a_{4}` | :math:`Target CN_{leaf}` | :math:`Target CN_{fr}` | :math:`Target CN_{lw}` | :math:`Target CN_{dw}` | + | Plant functional type | :math:`a_{1}` | :math:`a_{2}` | :math:`a_{3}` | :math:`a_{4}` | Target :math:`CN_{leaf}` | Target :math:`CN_{fr}` | Target :math:`CN_{lw}` | Target :math:`CN_{dw}` | +==================================+=======================+=======================+=======================+=======================+===========================+=========================+=========================+=========================+ - | NET Temperate | 1 | 0.3 | -1 | 0.1 | 35 | 42 | 50 | 500 | + | NET Temperate | 1.50 | 0.3 | -1 | 0.1 | 58.00 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | NET Boreal | 1 | 0.3 | -1 | 0.1 | 40 | 42 | 50 | 500 | + | NET Boreal | 1.45 | 0.3 | -1 | 0.1 | 60.24 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | NDT Boreal | 1 | 0.3 | -1 | 0.1 | 25 | 42 | 50 | 500 | + | NDT Boreal | 0.73 | 0.3 | -1 | 0.1 | 28.92 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | BET Tropical | 1 | 0.3 | -1 | 0.1 | 30 | 42 | 50 | 500 | + | BET Tropical | 1.47 | 0.3 | -1 | 0.1 | 36.03 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | BET temperate | 1 | 0.3 | -1 | 0.1 | 30 | 42 | 50 | 500 | + | BET temperate | 1.63 | 0.3 | -1 | 0.1 | 34.59 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | BDT tropical | 1 | 0.3 | -1 | 0.1 | 25 | 42 | 50 | 500 | + | BDT tropical | 1.28 | 0.3 | -1 | 0.1 | 18.63 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | BDT temperate | 1 | 0.3 | -1 | 0.1 | 25 | 42 | 50 | 500 | + | BDT temperate | 1.39 | 0.3 | -1 | 0.1 | 21.64 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | BDT boreal | 1 | 0.3 | -1 | 0.1 | 25 | 42 | 50 | 500 | + | BDT boreal | 0.60 | 0.3 | -1 | 0.1 | 17.09 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | BES temperate | 1 | 0.3 | 0.2 | 0.5 | 30 | 42 | 50 | 500 | + | BES temperate | 1.50 | 0.3 | 1.40 | 0.5 | 36.42 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | BDS temperate | 1 | 0.3 | 0.2 | 0.5 | 25 | 42 | 50 | 500 | + | BDS temperate | 1.50 | 0.3 | 0.24 | 0.5 | 23.26 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | BDS boreal | 1 | 0.3 | 0.2 | 0.1 | 25 | 42 | 50 | 500 | - | C\ :sub:`3` arctic grass | 1 | 0 | 0 | 0 | 25 | 42 | 0 | 0 | + | BDS boreal | 1.20 | 0.3 | 0.24 | 0.1 | 21.40 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | C\ :sub:`3` grass | 2 | 0 | 0 | 0 | 25 | 42 | 0 | 0 | + | C\ :sub:`3` arctic grass | 1.20 | 0 | 0 | 0 | 20.70 | 42 | 0 | 0 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | C\ :sub:`4` grass | 2 | 0 | 0 | 0 | 25 | 42 | 0 | 0 | + | C\ :sub:`3` grass | 1.57 | 0 | 0 | 0 | 29.39 | 42 | 0 | 0 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | Crop R | 2 | 0 | 0 | 0 | 25 | 42 | 0 | 0 | + | C\ :sub:`4` grass | 1.50 | 0 | 0 | 0 | 35.36 | 42 | 0 | 0 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | Crop I | 2 | 0 | 0 | 0 | 25 | 42 | 0 | 0 | + | Crop R | 1 | 0 | 0 | 0 | 25 | 42 | 0 | 0 | + +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ + | Crop I | 1 | 0 | 0 | 0 | 25 | 42 | 0 | 0 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ | Corn R | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ | Corn I | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | Temp Cereal R | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + | Temp Cereal R | 2 | 0 | 0 | 1 | 20 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | Temp Cereal I | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + | Temp Cereal I | 2 | 0 | 0 | 1 | 20 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | Winter Cereal R | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + | Winter Cereal R | 2 | 0 | 0 | 1 | 20 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | Winter Cereal I | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + | Winter Cereal I | 2 | 0 | 0 | 1 | 20 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | Soybean R | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + | Soybean R | 2 | 0 | 0 | 1 | 20 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | Soybean I | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + | Soybean I | 2 | 0 | 0 | 1 | 20 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | Miscanthus R | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + | Miscanthus R | 2 | 0 | 0 | 1 | 20 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | Miscanthus I | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + | Miscanthus I | 2 | 0 | 0 | 1 | 20 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | Switchgrass R | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + | Switchgrass R | 2 | 0 | 0 | 1 | 20 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ - | Switchgrass I | 2 | 0 | 0 | 1 | 25 | 42 | 50 | 500 | + | Switchgrass I | 2 | 0 | 0 | 1 | 20 | 42 | 50 | 500 | +----------------------------------+-----------------------+-----------------------+-----------------------+-----------------------+---------------------------+-------------------------+-------------------------+-------------------------+ +PFT name abbreviations: NET = Needleleaf Evergreen Tree, NDT = Needleleaf Deciduous Tree, BET = Broadleaf Evergreen Tree, BDT = Broadleaf Deciduous Tree, BES = Broadleaf Evergreen Shrub, BDS = Broadleaf Deciduous Shrub. The "R" and "I" suffixes on crop PFT names denote rainfed and irrigated management, respectively. + Carbon to nitrogen ratios are defined for different tissue types as follows: .. math:: :label: 19.9 - \begin{array}{l} {CN_{leaf} = {\rm \; C:N\; for\; leaf}} \\ {CN_{fr} = {\rm \; C:N\; for\; fine\; root}} \\ {CN_{lw} = {\rm \; C:N\; for\; live\; wood\; (in\; stem\; and\; coarse\; root)}} \\ {CN_{dw} = {\rm \; C:N\; for\; dead\; wood\; (in\; stem\; and\; coarse\; root)}} \end{array} + \begin{aligned} + CN_{leaf} &= \text{C:N for leaf} \\ + CN_{fr} &= \text{C:N for fine root} \\ + CN_{lw} &= \text{C:N for live wood (in stem and coarse root)} \\ + CN_{dw} &= \text{C:N for dead wood (in stem and coarse root)} + \end{aligned} where all C:N parameters are defined as constants for a given PFT (:numref:`Table Allocation and CN ratio parameters`). -Given values for the parameters in and, total carbon and nitrogen allocation to new growth ( :math:`CF_{alloc}`, gC m\ :sup:`-2` s\ :sup:`-1`, and :math:`NF_{alloc}`, gN m\ :sup:`-2` s\ :sup:`-1`, respectively) can be expressed as functions of new leaf carbon allocation (:math:`CF_{GPP,leaf}`, gC m\ :sup:`-2` s\ :sup:`-1`): +Given values for the parameters in :eq:`19.7` and :eq:`19.9`, total carbon and nitrogen allocation to new growth (:math:`CF_{alloc}`, gC m\ :sup:`-2` s\ :sup:`-1`, and :math:`NF_{alloc}`, gN m\ :sup:`-2` s\ :sup:`-1`, respectively) can be expressed as functions of new leaf carbon allocation (:math:`CF_{GPP,leaf}`, gC m\ :sup:`-2` s\ :sup:`-1`): .. math:: :label: 19.10 @@ -165,7 +179,7 @@ where N_{allom} =\left\{\begin{array}{l} {\frac{1}{CN_{leaf} } +\frac{a_{1} }{CN_{fr} } +\frac{a_{3} a_{4} \left(1+a_{2} \right)}{CN_{lw} } +} \\ {\qquad \frac{a_{3} \left(1-a_{4} \right)\left(1+a_{2} \right)}{CN_{dw} } \qquad {\rm for\; woody\; PFT}} \\ {\frac{1}{CN_{leaf} } +\frac{a_{1} }{CN_{fr} } \qquad \qquad \qquad {\rm for\; non-woody\; PFT.}} \end{array}\right. -Since the C:N stoichiometry for new growth allocation is defined, from Eq., as :math:`C_{allom}`/ :math:`N_{allom}`, the total carbon available for new growth allocation (:math:`CF_{avail\_alloc}`) can be used to calculate the total plant nitrogen demand for new growth ( :math:`NF_{plant\_demand}`, gN m\ :sup:`-2` s\ :sup:`-1`) as: +Since the C:N stoichiometry for new growth allocation is defined, from :eq:`19.10` together with :eq:`19.11` and :eq:`19.12`, as :math:`C_{allom} / N_{allom}`, the total carbon available for new growth allocation (:math:`CF_{avail\_alloc}`) can be used to calculate the total plant nitrogen demand for new growth (:math:`NF_{plant\_demand}`, gN m\ :sup:`-2` s\ :sup:`-1`) as: .. math:: :label: 19.13 @@ -239,7 +253,7 @@ There are two carbon pools associated with each plant tissue – one which repre CF_{alloc,deadcroot\_ stor} =CF_{alloc,leaf\_ tot} a_{2} a_{3} \left(1-a_{4} \right)\left(1-f_{cur} \right). -Nitrogen allocation +Nitrogen Allocation ----------------------------------------- The total flux of nitrogen to be allocated is given by the FUN model (Chapter :numref:`rst_FUN`). This gives a total N to be allocated within a given timestep, :math:`N_{supply}`. The total N allocated for a given tissue :math:`i` is the minimum between the supply and the demand: @@ -247,7 +261,7 @@ The total flux of nitrogen to be allocated is given by the FUN model (Chapter :n .. math:: :label: 19.26 - NF_{alloc,i} = min \left( NF_{demand, i}, NF_{supply, i} \right) + NF_{alloc,i} = \min \left( NF_{demand,i},\, NF_{supply,i} \right) The demand for each tissue, calculated for the tissue to remain on stoichiometry during growth, is: @@ -309,7 +323,7 @@ The demand for each tissue, calculated for the tissue to remain on stoichiometry .. math:: :label: 19.38 - NF_{demand,deadcroot\_ stor} =\frac{CF_{alloc,leaf} a_{2} a_{3} \left(1-a_{4} \right)}{CN_{dw} } \left(1-f_{cur} \right). + NF_{demand,deadcroot\_ stor} =\frac{CF_{alloc,leaf\_ tot} a_{2} a_{3} \left(1-a_{4} \right)}{CN_{dw} } \left(1-f_{cur} \right). After each pool's demand is calculated, the total plant N demand is then the sum of each individual pool :math:`i` corresponding to each tissue: @@ -323,4 +337,4 @@ and the total supply for each tissue :math:`i` is the product of the fractional .. math:: :label: 19.40 - NF_{alloc,i} = N_{uptake} NF_{demand,i} / NF_{demand,tot} + NF_{supply,i} = N_{uptake} \, \frac{NF_{demand,i}}{NF_{demand,tot}} diff --git a/doc/source/tech_note/CN_Pools/CLM50_Tech_Note_CN_Pools.rst b/doc/source/tech_note/CN_Pools/CLM50_Tech_Note_CN_Pools.rst index ebff41577a..7bc6d03ba6 100644 --- a/doc/source/tech_note/CN_Pools/CLM50_Tech_Note_CN_Pools.rst +++ b/doc/source/tech_note/CN_Pools/CLM50_Tech_Note_CN_Pools.rst @@ -23,61 +23,17 @@ In addition to the vegetation pools, CLM includes a series of decomposing carbon Tissue Stoichiometry ----------------------- -As of CLM5, vegetation tissues have a flexible stoichiometry, as described in :ref:`Ghimire et al. (2016) `. Each tissue has a target C\:N ratio, with the target leaf C\:N varying by plant functional type (see :numref:`Table Plant functional type (PFT) target CN parameters`), and nitrogen is allocated at each timestep in order to allow the plant to best match the target stoichiometry. Nitrogen downregulation of productivity acts by increasing the C\:N ratio of leaves when insufficient nitrogen is available to meet stoichiometric demands of leaf growth, thereby reducing the N available for photosynthesis and reducing the :math:`V_{\text{c,max25}}` and :math:`J_{\text{max25}}` terms, as described in Chapter :numref:`rst_Photosynthetic Capacity`. Details of the flexible tissue stoichiometry are described in Chapter :numref:`rst_CN Allocation`. +As of CLM5, vegetation tissues have a flexible stoichiometry, as described in :ref:`Ghimire et al. (2016) `. Each tissue has a target C\:N ratio, with the target leaf C\:N, :math:`CN_{\text{target}}^\text{pft}`, varying by plant functional type (PFT) (:numref:`Table Allocation and CN ratio parameters`). Nitrogen is allocated at each timestep to allow the plant to best match the target stoichiometry. Nitrogen downregulation of productivity acts by increasing the actual C\:N ratio of leaves when insufficient nitrogen is available to meet stoichiometric demands of leaf growth, thereby reducing the N available for photosynthesis and reducing the :math:`V_{\text{c,max25}}` and :math:`J_{\text{max25}}` terms, as described in Chapter :numref:`rst_Photosynthetic Capacity`. Details of the flexible tissue stoichiometry are described in Chapter :numref:`rst_CN Allocation`. -.. _Table Plant functional type (PFT) target CN parameters: +As of CLM5.4, the target leaf C\:N may be time-evolving, :math:`CN_{\text{target}}^{\text{pft,CO2}}`, as a logarithmic function of atmospheric CO\ :sub:`2` that we denote :math:`CN_{\text{perturb}}^{\text{CO2}}`: -.. table:: Plant functional type (PFT) target C:N parameters. +.. math:: + :label: time-evolv target leaf CN - +----------------------------------+-------------------+ - | PFT | target leaf C:N | - +==================================+===================+ - | NET Temperate | 58.00 | - +----------------------------------+-------------------+ - | NET Boreal | 58.00 | - +----------------------------------+-------------------+ - | NDT Boreal | 25.81 | - +----------------------------------+-------------------+ - | BET Tropical | 29.60 | - +----------------------------------+-------------------+ - | BET temperate | 29.60 | - +----------------------------------+-------------------+ - | BDT tropical | 23.45 | - +----------------------------------+-------------------+ - | BDT temperate | 23.45 | - +----------------------------------+-------------------+ - | BDT boreal | 23.45 | - +----------------------------------+-------------------+ - | BES temperate | 36.42 | - +----------------------------------+-------------------+ - | BDS temperate | 23.26 | - +----------------------------------+-------------------+ - | BDS boreal | 23.26 | - +----------------------------------+-------------------+ - | C\ :sub:`3` arctic grass | 28.03 | - +----------------------------------+-------------------+ - | C\ :sub:`3` grass | 28.03 | - +----------------------------------+-------------------+ - | C\ :sub:`4` grass | 35.36 | - +----------------------------------+-------------------+ - | Temperate Corn | 25.00 | - +----------------------------------+-------------------+ - | Spring Wheat | 20.00 | - +----------------------------------+-------------------+ - | Temperate Soybean | 20.00 | - +----------------------------------+-------------------+ - | Cotton | 20.00 | - +----------------------------------+-------------------+ - | Rice | 20.00 | - +----------------------------------+-------------------+ - | Sugarcane | 25.00 | - +----------------------------------+-------------------+ - | Tropical Corn | 25.00 | - +----------------------------------+-------------------+ - | Tropical Soybean | 20.00 | - +----------------------------------+-------------------+ - | Miscanthus | 25.00 | - +----------------------------------+-------------------+ - | Switchgrass | 25.00 | - +----------------------------------+-------------------+ + \begin{split} + CN_{\text{perturb}}^{\text{CO2}} &= CN_{\text{slope}}^{\text{CO2}} \cdot \ln\left(\frac{\text{CO2}_{\text{atm}}}{\text{CO2}_{\text{atm}}^{\text{ref}}}\right), \text{where } CN_{\text{perturb}}^{\text{CO2}} &\ge 0 \\ + CN_{\text{target}}^{\text{pft,CO2}} &= CN_{\text{target}}^\text{pft} + CN_{\text{perturb}}^{\text{CO2}} + \end{split} + +where :math:`CN_{\text{target}}^\text{pft}` is the time-invarying target leaf C\:N at reference CO\ :sub:`2` that depends on PFT, :math:`CN_{\text{slope}}^{\text{CO2}}` (unitless) is the slope of the function, :math:`\text{CO2}_{\text{atm}}` is atmospheric CO\ :sub:`2` in parts per million by volume (ppmv), and :math:`\text{CO2}_{\text{atm}}^{\text{ref}}` is the reference CO\ :sub:`2` (ppmv) above which atmospheric CO\ :sub:`2` begins to scale the target leaf C\:N. The optional time-evolving target leaf C\:N was documented in :ref:`Hauser et al. (2023) `, and its current default is off by setting :math:`CN_{\text{slope}}^{\text{CO2}} = 0`. diff --git a/doc/source/tech_note/Decomposition/CLM50_Tech_Note_Decomposition.rst b/doc/source/tech_note/Decomposition/CLM50_Tech_Note_Decomposition.rst index bf6d52ee45..bc66464cc1 100644 --- a/doc/source/tech_note/Decomposition/CLM50_Tech_Note_Decomposition.rst +++ b/doc/source/tech_note/Decomposition/CLM50_Tech_Note_Decomposition.rst @@ -189,7 +189,7 @@ where :math:`{\Psi}_{j}` is the soil water potential in layer *j*, :math:`{\Psi} \psi \left(T\right)=-\frac{L_{f} \left(T-T_{f} \right)}{10^{3} T} -An additional frozen decomposition limitation can be specified using a ‘frozen Q\ :sub:`10`' following :ref:`Koven et al. (2011) `, however the default value of this is the same as the unfrozen Q\ :sub:`10` value, and therefore the basic hypothesis is that frozen respiration is limited by liquid water availability, and can be modeled following the same approach as thawed but dry soils. +An additional frozen decomposition limitation can be specified using a 'frozen Q\ :sub:`10`' following :ref:`Koven et al. (2011) `, however the default value of this is the same as the unfrozen Q\ :sub:`10` value, and therefore the basic hypothesis is that frozen respiration is limited by liquid water availability, and can be modeled following the same approach as thawed but dry soils. An additional rate scalar, :math:`{r}_{oxygen}` is enabled when the CH\ :sub:`4` submodel is used (set equal to 1 for the single layer model or when the CH\ :sub:`4` submodel is disabled). This limits decomposition when there is insufficient molecular oxygen to satisfy stoichiometric demand (1 mol O\ :sub:`2` consumed per mol CO\ :sub:`2` produced) from heterotrophic decomposers, and supply from diffusion through soil layers (unsaturated and saturated) or aerenchyma (Chapter 19). A minimum value of :math:`{r}_{oxygen}` is set at 0.2, with the assumption that oxygen within organic tissues can supply the necessary stoichiometric demand at this rate. This value lies between estimates of 0.025–0.1 (Frolking et al. 2001), and 0.35 (Wania et al. 2009); the large range of these estimates poses a large unresolved uncertainty. diff --git a/doc/source/tech_note/Dust/CLM50_Tech_Note_Dust.rst b/doc/source/tech_note/Dust/CLM50_Tech_Note_Dust.rst index ad593b6060..55f0c2e204 100644 --- a/doc/source/tech_note/Dust/CLM50_Tech_Note_Dust.rst +++ b/doc/source/tech_note/Dust/CLM50_Tech_Note_Dust.rst @@ -1,124 +1,326 @@ .. _rst_Dust Model: -Dust Model +Dust Emission ============== -Atmospheric dust is mobilized from the land by wind in the CLM. The most important factors determining soil erodibility and dust emission include the wind friction speed, the vegetation cover, and the soil moisture The CLM dust mobilization scheme (:ref:`Mahowald et al. 2006` accounts for these factors based on the DEAD (Dust Entrainment and Deposition model of :ref:`Zender et al. (2003)`. Please refer to the :ref:`Zender et al. (2003)` article for additional information regarding the equations presented in this section. +Atmospheric dust is mobilized from the land by wind in the CLM. The most important factors determining soil erodibility and dust emission include the wind friction velocity, the vegetation cover, and the soil moisture. The latest CTSM allows users to choose between two dust emission schemes: One is Leung_2023 (:ref:`Leung et al. 2023`; :ref:`Leung et al. 2024`) which is the current default for the CLM6 physics or later, and the other is Zender_2003 (:ref:`Mahowald et al. 2006`) based on the DEAD (Dust Entrainment and Deposition model) scheme by :ref:`Zender et al. (2003)`, which is the default for the CLM5 or older physics. -The total vertical mass flux of dust, :math:`F_{j}` (kg m\ :sup:`-2` s\ :sup:`-1`), from the ground into transport bin :math:`j` is given by +We here describe the Leung_2023 scheme based on :ref:`Leung et al. 2023` and :ref:`Leung et al. (2024)` and document some differences in tuning in the latest CTSM. CTSM users can look for the previous documentation for CLM5 physics for a description of the Zender_2003 scheme. + + +.. _Dust Emission Thresholds: + +Dust Emission Thresholds +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. _Fluid Threshold: + +Fluid Threshold +--------------------- + +Dust emission modeling is a threshold parameterization of an aeolian (wind-driven) process for both Leung_2023 and Zender_2003. For Leung_2023, in any given timestep the soil surface wind velocity :math:`u_{*s}` has to be greater than the fluid threshold friction velocity :math:`u_{*ft}` to generate saltation and dust emission: + +.. math:: + :label: wet_fluid_threshold + + u_{\ast ft} = u_{\ast ft0}(D_{p},\rho_{atm}) f_{m}(w) + +where :math:`u_{\ast ft0}(D_{p},\rho_{a})` is the dry fluid threshold without the soil moisture effect :math:`f_{m}`, as a function of median soil diameter :math:`D_{p}` and air density :math:`\rho_{atm}`. In CTSM for Leung_2023, :math:`D_{p}` is a globally uniform number of 130 :math:`\mu` m. :math:`u_{\ast ft0}(D_{p},\rho_{atm})` is given by :ref:`Shao and Lu (2000)`: + +.. math:: + :label: dry_fluid_threshold + + u_{\ast ft0}(D_{p},\rho_{atm}) = \sqrt{\frac{A(\rho_{p} g D_{p} + \gamma / D_{p}) }{\rho_{atm}} } + + +where *g* is the acceleration of gravity (:numref:`Table Physical Constants`), :math:`\rho_{p} = 2650` kg m\ :sup:`-3` is typical soil particle density, and :math:`A = 0.0123` and :math:`\gamma = 1.65 \times 10^{-4}` kg s\ :sup:`-2` are empirical constants. + +.. _Impact of Soil Moisture: + +Impact of Soil Moisture +------------------------- + +The soil moisture effect :math:`f_{m}(w)` is a function of gravimetric soil moisture :math:`w` (kg water / kg soil) at the topmost soil layer. + +:math:`w` is converted from the CLM volumetric soil moisture :math:`\theta` and porosity (saturation moisture :math:`\theta_{sat}`) at the topmost soil layer: + +.. math:: + :label: volumetric_moisture_to_gravimetric_moisture + + w=\theta\frac{ \rho _{liq} }{\rho_{bulk} } + +Note that :math:`w` or :math:`\theta` in CTSM is conventionally (:ref:`Mahowald et al. 2006`) treated as a sum of both liquid and ice/frozen soil moisture at the topmost soil layer, i.e., :math:`w_{1} = w_{liq,1} + w_{ice,1}`. We skip :math:`w_{1}` and use :math:`w` for simplicity. :math:`\theta` is the volumetric soil moisture (water+ice) in the topmost soil layer (m\ :sup:`-3`\ water \ m\ :sup:`-3` soil) (section :numref:`Soil Water`), :math:`\rho _{liq}` is the density of liquid water (kg m\ :sup:`-3`) (:numref:`Table Physical constants`), and :math:`\rho _{bulk}` is the bulk density of soil in the top soil layer (kg m\ :sup:`-3`) defined as in section :numref:`Soil and Snow Thermal Properties` rather than as in :ref:`Zender et al. (2003)`. :math:`\rho_{bulk}` is given by + +.. math:: + :label: soil_bulk_density + + \rho_{bulk} = (1 - \theta_{sat} ) \rho_{p} + +Then, the soil moisture effect :math:`f_{m}(w)` on increasing the fluid threshold is given by :ref:`Fecan et al. (1999)`: + +.. math:: + :label: moisture_factor_on_fluid_threshold + + f_{m}(w) =\left\{\begin{array}{l} {1{\rm \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; for\; }w\le w_{t} } \\ {\sqrt{1+1.21\left[100\left(w-w_{t} \right)\right]^{0.68} } {\rm \; \; for\; }w>w_{t} } \end{array}\right. + + +where :math:`w_{t}` is the minimum gravimetric moisture threshold required to increase the interparticle force and :math:`u_{*ft}`. :math:`w_{t}` increases with clay fraction :math:`f_{clay}`: + +.. math:: + :label: minimum_moisture + + w_{t} =0.01a\left(17f_{clay} +14f_{clay}^{2} \right){\rm \; \; \; \; \; \; 0}\le f_{clay} =\% clay\times 0.01\le 1 + + +where :math:`a=f_{clay}^{-1}` for tuning purposes. Note that this is different from the paper (:ref:`Leung et al. 2023`; :ref:`Leung et al. 2024`) in which :math:`a=1` was chosen. The coefficient 0.01 is used for converting :math:`w_{t}` from % to fraction (kg water / kg soil). :math:`f_{clay}` is the mass fraction of clay particles in the topmost soil layer and %clay comes from the surface dataset (section :numref:`Surface Data`). + +.. _Impact Threshold: + +Impact Threshold +---------------------- + +Another essential dust emission threshold is the impact/dynamic threshold :math:`u_{*it}`, which is the lowest friction velocity or wind stress to matintain saltation: + +.. math:: + :label: impact_threshold + + u_{\ast it} = B_{\ast it} u_{\ast ft0} + +where :math:`B_{\ast it} = 0.81` is a constant on Earth following :ref:`Kok et al. (2012)`. In Leung_2023, :math:`u_{\ast it}` does not depend on and increase with soil moisture. The above equations imply that :math:`u_{\ast it} \, < \, u_{\ast ft0} \le \, u_{\ast ft}`. This means that the winds need a bigger momentum to initiate saltation and dust emission but can reduce below :math:`u_{\ast ft}` and still maintain a weak dust emission flux. The emission flux goes to zero when :math:`u_{\ast s}` drops below :math:`u_{\ast it}`. + +.. _Dust Emission Flux: + +Dust Emission Flux +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The total vertical mass emission flux of dust, :math:`F_{d}` (kg m\ :sup:`-2` s\ :sup:`-1`), from the ground into a transport mode/bin :math:`j` of aerosol is based on :ref:`Kok et al. (2014a)`: + +.. math:: + :label: dust_emiss_flux + + F_{d} = \eta C_{tune} C_{d} f_{bare} f_{clay'} \frac{ \rho_{atm} (u^2_{\ast s} - u^2_{\ast it} ) }{ u^2_{\ast it} } \left( \frac{ u_{\ast s} }{u_{\ast it} } \right) ^\kappa + +where :math:`C_{tune} = 0.05` is a constant, :math:`\eta` is the intermittency factor (we will derive it in section :numref:`Emission Intermittency Due To Turbulent Wind Fluctuations`), and :math:`F_{d}` is the total emission flux summed across modes/bins following a revised form of :ref:`Kok et al. (2014b)`. The dust emission flux goes to zero when :math:`u_{\ast s} \, < \, u_{\ast it}`. :math:`\rho_{atm}` is surface air density from CAM (the atm model). +:math:`f_{clay'}` is a modified clay fraction term appeared earlier in :ref:`Zender et al. (2003)`. In Zender_2003 it is used to indicate the sandblasting efficiency. Zender limited this term to be capped at 0.2: + +.. math:: + :label: clay_sandblast_fact_zender + + f_{clay'} = \textnormal{max}(f_{clay}, 0.2) + +:math:`f_{clay'}` is later adopted by :ref:`Kok et al. (2014a)` to indicate the amount of fine dust particles for sandblasting. The same :math:`f_{clay'}` is used in :ref:`Leung et al. (2024)`. But we later further limit :math:`f_{clay'}` to be within 0.1 and 0.2 to further reduce the impact of how the abundance of fine dust particles can scale the total dust emission flux, as part of the CESM tuning: + +.. math:: + :label: clay_sandblast_fact_leung + + f_{clay'} = \textnormal{max}(0.1+0.5f_{clay}, 0.2) + +Then, :math:`\kappa` is the fragmentation exponent, and :math:`C_{d}` is the dust emission coefficient (or the soil erodibility coefficient): + +.. math:: + :label: dust_emiss_coefficient + + C_{d} = C_{d0} \exp{ (-C_{e} \frac{ u_{\ast st} - u_{\ast st0} }{ u_{\ast st0} } ) } .. math:: - :label: 29.1 + :label: fragment_exponent + + \kappa = C_{\kappa} \frac{ u_{\ast st} - u_{\ast st0} }{ u_{\ast st0} } - F_{j} =TSf_{m} \alpha Q_{s} \sum _{i=1}^{I}M_{i,j} +where :math:`C_{\kappa} = 2.7`, :math:`u_{\ast st0} = 0.16` m s :sup:`-3`, :math:`C_{d0} = 4.4 \times 10^{-5}`, and :math:`C_{e} = 2.0`. :math:`F_{d}` thus roughly scales with :math:`u^{2+\kappa}_{*s}`, where :math:`\kappa \sim 1` over major deserts and :math:`\sim 3` or higher over semiarid and nonarid regions. Since :ref:`Kok et al. (2014a)` has not measured :math:`\kappa > 3` in their measurements, we cap :math:`\kappa` at a maximum value (currently set as 2.5). :math:`u_{\ast st}` is the standardized wet fluid threshold at a typical atmospheric surface air density (Kok et al., 2014): + +.. math:: + :label: standard_fluid_threshold -where :math:`T` is a global factor that compensates for the DEAD model's sensitivity to horizontal and temporal resolution and equals 5 x 10\ :sup:`-4` in the CLM instead of 7 x 10\ :sup:`-4` in :ref:`Zender et al. (2003)`. :math:`S` is the source erodibility factor set to 1 in the CLM and serves as a place holder at this time. + u_{\ast st} = u_{\ast ft} \sqrt{ \rho_{atm} / \rho_{0atm}} -The grid cell fraction of exposed bare soil suitable for dust mobilization :math:`f_{m}` is given by +where :math:`\rho_{0atm} = 1.225` kg m\ :sup:`-3`. As can be seen, :math:`u_{\ast st}` scales with :math:`u_{\ast ft}` and thus soil moisture :math:`w`. Therefore, moisture :math:`w` decreases soil erodibility :math:`C_{d}` but increases dust emission sensitivity :math:`\kappa` to the winds. + +:ref:`Kok et al. (2014a)` is different from many other dust emission parameterizations in the way that the soil erodibility :math:`C_{d}` is not a time-invariant input data but is a transient function, with erodibility increasing with reducing :math:`u^2_{*ft}` (and thus implicitly soil moisture). Similarly, the fragmentation exponent :math:`\kappa` is also transient and increases with enhancing soil moisture. + +The grid cell fraction of exposed bare soil suitable for dust mobilization :math:`f_{bare}` is given by .. math:: - :label: 29.2 + :label: grid_bare_land_frac - f_{m} =\left(1-f_{lake} \right)\left(1-f_{sno} \right)\left(1-f_{v} \right)\frac{w_{liq,1} }{w_{liq,1} +w_{ice,1} } + f_{bare} =\left(1-f_{lake} \right)\left(1-f_{sno} \right)\left(1-f_{v} \right)\frac{w_{liq,1} }{w_{liq,1} +w_{ice,1} } -where :math:`f_{lake}` and :math:`f_{sno}` are the CLM grid cell fractions of lake (section :numref:`Surface Data`) and snow cover (section :numref:`Snow Covered Area Fraction`), all ranging from zero to one. Not mentioned by :ref:`Zender et al. (2003)`, :math:`w_{liq,\, 1}` and :math:`{}_{w_{ice,\, 1} }` are the CLM top soil layer liquid water and ice contents (mm) entered as a ratio expressing the decreasing ability of dust to mobilize from increasingly frozen soil. The grid cell fraction of vegetation cover,\ :math:`{}_{f_{v} }`, is defined as +where :math:`f_{lake}` and :math:`f_{sno}` are the CLM grid cell fractions of lake (section :numref:`Surface Data`) and snow cover (section :numref:`Snow Covered Area Fraction`), all ranging from zero to one. Not mentioned by :ref:`Zender et al. (2003)`, :math:`w_{liq,\, 1}` and :math:`w_{ice,\, 1}` are the CLM top soil layer liquid water and ice contents (mm) entered as a ratio expressing the decreasing ability of dust to mobilize from increasingly frozen soil. The grid cell fraction of vegetation cover, \ :math:`f_{v}`, is defined as .. math:: - :label: 29.3 + :label: grid_vegetated_frac + + 0\le f_{v} =\frac{\mathrm{VAI}}{\mathrm{VAI_{thr}} } \le 1{\rm \; \; \; \; where\; } \mathrm{VAI_{thr}} =0.6{\rm \; m}^{2} {\rm m}^{-2} - 0\le f_{v} =\frac{L+S}{\left(L+S\right)_{t} } \le 1{\rm \; \; \; \; where\; }\left(L+S\right)_{t} =0.3{\rm \; m}^{2} {\rm m}^{-2} +where :math:`\mathrm{VAI}=\mathrm{LAI}+\mathrm{SAI}` is the vegetation area index as a sum of the CLM leaf and stem area index values (m :sup:`2` leaf m\ :sup:`-2` grid) averaged at the land unit level so as to include all the pfts and the bare ground present in a vegetated land unit. Currently, Leung_2023 in CTSM sets the areas with :math:`\mathrm{VAI_{thr}}` smaller than or equal to 0.6 m :sup:`2` m\ :sup:`-2` to be dust-emitting grids, different from the :ref:`Leung et al. (2024)` paper that set :math:`\mathrm{VAI_{thr}}` to be 1 m :sup:`2` m\ :sup:`-2`. :math:`\mathrm{LAI}` and :math:`\mathrm{SAI}` may be prescribed from the CLM input data (section :numref:`Phenology and vegetation burial by snow`) or simulated by the CLM biogeochemistry model (section :numref:`rst_Vegetation Phenology and Turnover`). + +.. _Drag Partition Effect On Reducing Wind Stress: + +Drag Partition Effect On Reducing Wind Stress +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +On top of :ref:`Kok et al. (2014a)`, Leung_2023 introduced the soil surface friction velocity :math:`u_{*s}` as the friction velocity :math:`u_{*}` from CLM corrected by the surface roughness due to the presented rocks and vegetation on the soil surface, encapsulated by the so-called drag partition factor :math:`F_{eff}`. + +.. math:: + :label: soil_surface_ustar + + u_{\ast s} = u_{*} F_{eff} + +The :ref:`Leung et al. (2023)` paper uses an area-weighted averaging method to determine the mean drag partitioning for a grid cell: :math:`F_{eff}^3 = A_{rock} f_{rock}^3 + A_{veg} f_{veg}^3`. :math:`A_{rock}` and :math:`A_{veg}` are fractional area cover (in fraction) from the CLM-prescribed land use from the Land Use Harmonization 2 (LUH2; section :numref:`rst_Transient Landcover Change`). :math:`F_{eff}` is thus a weighted mean of the rock drag partitioning and the vegetation drag partitioning in :ref:`Leung et al. (2023)`. However, since CTSM has the privilege of supporting sub-grid patch-level simulations of dust emissions, we simply separate the calculations of dust emissions into the areas of bare soils and areas of the short vegetation. For a bare soil patch/PFT we use: + +.. math:: + :label: rock_drag_partition + + F_{eff} = f_{rock} + +And for a patch/PFT with short vegetation (shrub, grass, crop) we use: + +.. math:: + :label: veg_drag_partition -where equation :eq:`29.3` applies only for dust mobilization and is not related to the plant functional type fractions prescribed from the CLM input data or simulated by the CLM dynamic vegetation model (Chapter 22). :math:`L` and :math:`S` are the CLM leaf and stem area index values (m :sup:`2` m\ :sup:`-2`) averaged at the land unit level so as to include all the pfts and the bare ground present in a vegetated land unit. :math:`L` and :math:`S` may be prescribed from the CLM input data (section :numref:`Phenology and vegetation burial by snow`) or simulated by the CLM biogeochemistry model (Chapter :numref:`rst_Vegetation Phenology and Turnover`). + F_{eff} = f_{veg} -The sandblasting mass efficiency :math:`\alpha` (m :sup:`-1`) is calculated as +The rock drag partition factor scales with the surface roughness density of rocks, captured by the aeolian roughness length :math:`z_{0a}` from the satellite-derived dataset from :ref:`Prigent et al. (2005)`. The expression was first developed by :ref:`Marticorena and Bergametti (1995)`, which is more valid for the low-roughness surfaces: .. math:: - :label: 29.4 + :label: rock_drag_partition_fact - \alpha =100e^{\left(13.4M_{clay} -6.0\right)\ln 10} {\rm \; \; }\left\{\begin{array}{l} {M_{clay} =\% clay\times 0.01{\rm \; \; \; 0}\le \% clay\le 20} \\ {M_{clay} =20\times 0.01{\rm \; \; \; \; \; \; \; \; 20<\% }clay\le 100} \end{array}\right. + f_{rock} = 1 - \frac{\ln(\frac{z_{0a}}{z_{0s}})}{\ln[b_{1}(\frac{X}{z_{0s}})^{b_{2}}]} -where :math:`M_{clay}` is the mass fraction of clay particles in the soil and %clay is determined from the surface dataset (section :numref:`Surface Data`). :math:`M_{clay} =0` corresponds to sand and :math:`M_{clay} =0.2` to sandy loam. +where :math:`X = 10` m is the distance downstream the point of discontinuity in surface obstacle, :math:`b_{1} = 0.7` and :math:`b_{2} = 0.8` are coefficients (:ref:`Darmenova et al., 2009`), :math:`z_{0s}` is the soil roughness length. :math:`z_{0a}` is from :ref:`Prigent et al. (2005)` and should not be confused with the aerodynamic roughness length :math:`Z_{0}` from the model. This equation only applies for gridcells with VAI smaller than the VAI threshold for dust emission. -:math:`Q_{s}` is the total horizontally saltating mass flux (kg m\ :sup:`-1` s\ :sup:`-1`) of "large" particles (:numref:`Table Dust Mass fraction`), also referred to as the vertically integrated streamwise mass flux +The vegetation drag partition factor scales with vegetation density as captured by VAI following :ref:`Okin (2008)` and :ref:`Pierre et al. (2014)`: .. math:: - :label: 29.5 + :label: veg_drag_partition_effect - Q_{s} = \left\{ - \begin{array}{lr} - \frac{c_{s} \rho _{atm} u_{*s}^{3} }{g} \left(1-\frac{u_{*t} }{u_{*s} } \right)\left(1+\frac{u_{*t} }{u_{*s} } \right)^{2} {\rm \; } & \qquad {\rm for\; }u_{*t} `, in which a statistical substepping method was proposed to account for the temporary shutoff of dust emission fluxes. + +The fraction of time :math:`\eta` is parameterized using the surface winds and thresholds at the saltation height. Therefore, the friction velocities are translated using the log law of the wall to the saltation height, which was defined as :math:`z_{sal}` = 0.1 m by :ref:`Comola et al. (2019)`: .. math:: - :label: 29.6 + :label: mean_wind_sal_height - u_{*t} =f_{z} \left[Re_{*t}^{f} \rho _{osp} gD_{osp} \left(1+\frac{6\times 10^{-7} }{\rho _{osp} gD_{osp}^{2.5} } \right)\right]^{\frac{1}{2} } \rho _{atm} ^{-\frac{1}{2} } f_{w} + u_{s} = \frac{u_{\ast s}}{k} \ln(z_{sal}/z_{0a}) -where :math:`f_{z}` is a factor dependent on surface roughness but set to 1 as a place holder for now, :math:`\rho _{osp}` and :math:`D_{osp}` are the density (2650 kg m\ :sup:`-3`) and diameter (75 x 10\ :math:`{}^{-6}` m) of optimal saltation particles, and :math:`f_{w}` is a factor dependent on soil moisture: +.. math:: + :label: fluid_threshold_sal_height + + u_{ft} = \frac{u_{\ast ft}}{k} \ln(z_{sal}/z_{0a}) .. math:: - :label: 29.7 + :label: imapct_threshold_sal_height - f_{w} =\left\{\begin{array}{l} {1{\rm \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; for\; }w\le w_{t} } \\ {\sqrt{1+1.21\left[100\left(w-w_{t} \right)\right]^{0.68} } {\rm \; \; for\; }w>w_{t} } \end{array}\right. + u_{it} = \frac{u_{\ast it}}{k} \ln(z_{sal}/z_{0a}) -where +where *k* is the von Karman constant (:numref:`Table Physical Constants`), and :math:`z_{0a}`, the aeolian roughness length, is set to be 10:sup:`-4` m here for simplicity. With saltation-height variables defined, the instantaneous wind :math:`\tilde{u}_s` is assumed by Comola to follow a Gaussian distribution with a mean equal to the mean wind speed and the spread :math:`\sigma_{u_{s}}` parameterized by the Similarity Theory (:ref:`Panofsky et al., 1977`): .. math:: - :label: 29.8 + :label: instant_wind_sal_height - w_{t} =a\left(0.17M_{clay} +0.14M_{clay}^{2} \right){\rm \; \; \; \; \; \; 0}\le M_{clay} =\% clay\times 0.01\le 1 + \tilde{u}_s \sim N(u_s, \sigma_{u_s}) -and +And the fluctuation strength is parameterized by the similarity theory: .. math:: - :label: 29.9 + :label: fluctuation_sal_height + + \sigma_{u_s} = u_{\ast s} \left( 12 - 0.5 \frac{z_i}{L} \right)^{1/3} + \quad \text{for } 12 - 0.5 \frac{z_i}{L} \ge 0 + +where :math:`z_i = 1000` m is the planetary boundary-layer height set as a constant for now, and :math:`L` is the Obukhov length scale. This means the instantaneous wind's fluctuation comes from both a shear contribution and a buoyancy contribution. - w=\frac{\theta _{1} \rho _{liq} }{\rho _{d,1} } -where :math:`a=M_{clay}^{-1}` for tuning purposes, :math:`\theta _{1}` is the volumetric soil moisture in the top soil layer (m :math:`{}^{3 }`\ m\ :sup:`-3`) (section :numref:`Soil Water`), :math:`\rho _{liq}` is the density of liquid water (kg m\ :sup:`-3`) (:numref:`Table Physical constants`), and :math:`\rho _{d,\, 1}` is the bulk density of soil in the top soil layer (kg m\ :sup:`-3`) defined as in section :numref:`Soil and Snow Thermal Properties` rather than as in :ref:`Zender et al. (2003)`. :math:`Re_{*t}^{f}` from equation :eq:`29.6` is the threshold friction Reynolds factor +Then, the total fraction of time :math:`\eta` when saltation is active within a model timestep is then formulated as .. math:: - :label: 29.10 + :label: intermittency_fact - Re_{*t}^{f} =\left\{\begin{array}{l} {\frac{0.1291^{2} }{-1+1.928Re_{*t} } {\rm \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; for\; 0.03}\le Re_{*t} \le 10} \\ {0.12^{2} \left(1-0.0858e^{-0.0617(Re_{*t} -10)} \right)^{2} {\rm \; for\; }Re_{*t} >10} \end{array}\right. + \eta = 1 - P_{ft} + \alpha \left( P_{ft} - P_{it} \right) -and :math:`Re_{*t}` is the threshold friction Reynolds number approximation for optimally sized particles +where :math:`P_{it}` is the cumulative probability that the instantaneous wind :math:`\tilde{u}_s` does not exceed the impact threshold :math:`u_{it}`, and :math:`P_{ft}` is the cumulative probability that :math:`\tilde{u}_s` does not exceed the fluid threshold :math:`u_{ft}`. The fluid threshold crossing fraction :math:`\alpha` is defined as the rate of :math:`\tilde{u}_s` sweeping across :math:`u_{ft}` divided by the rate of sweeping across :math:`u_{it}` and :math:`u_{ft}` summed up. The detailed physical interpretation of this formula is in :ref:`Leung et al. (2023)`. Here we just document the equations for each term: + +.. For instance, if :math:`\tilde{u}_s` sweeps across :math:`u_{ft}` often and does not sweep across :math:`u_{it}` much, it means that :math:`\tilde{u}_s` (and thus the timestep-mean :math:`u_s`) should be closer to :math:`u_{ft}` and generally higher than :math:`u_{it}`. Then, :math:`\alpha` is close to 1, and the fraction of time :math:`\eta` (with active emission within a timestep) should also be close to 1. :math:`\alpha` can be represented as .. math:: - :label: 29.11 + :label: threshold_crossing_fraction - Re_{*t} =0.38+1331\left(100D_{osp} \right)^{1.56} + \alpha \approx \left\{ \exp\left[ + \frac{u_{ft}^2 - u_{it}^2 - 2u_s(u_{ft}-u_{it})}{2 \sigma^2_{u_s} } + \right] + 1 \right\}^{-1} -In :eq:`29.5`, :math:`u_{*s}` is defined as the wind friction speed (m s\ :sup:`-1`) accounting for the Owen effect (:ref:`Owen 1964`) +Then, the fraction of time in :math:`\Delta t` when :math:`\tilde{u}_s` is above :math:`u_{ft}` is given by :math:`1 - P_{ft}`, where .. math:: - :label: 29.12 + :label: probability_cross_fluid_threshold + + P_{ft} = \frac{1}{2} \left[ 1 + \operatorname{erf} + \left( \frac{u_{ft} - u_s}{\sqrt{2} \sigma_{u_s}} \right) \right] - u_{*s} = \left\{ - \begin{array}{lr} - u_{*} & \quad {\rm \; for \;} U_{10} ` but here for 10 m above the ground, and :math:`U_{10,\, t}` is the threshold wind speed at 10 m (m s\ :sup:`-1`) + P_{it} = \frac{1}{2} \left[ 1 + \operatorname{erf} + \left( \frac{u_{it} - u_s}{\sqrt{2} \sigma_{u_s}} \right) \right] + +And so the fraction of time :math:`\eta` within :math:`\Delta t` with active emission is determined for :eq:`dust_emiss_flux`. + +.. _Emitted Dust Size Distribution And Dust Transport In Atmosphere: + +Emitted Dust Size Distribution And Dust Transport In Atmosphere +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The total vertical mass emission flux of dust, :math:`F_{d}` (kg m\ :sup:`-2` s\ :sup:`-1`) is then computed with all the above equations and terms. The emission flux is then passed through the coupler to the atmospheric model (CAM) to simulate dust aerosol transport and deposition. The default aerosol model supported in the CAM6 and CAM7 physics is the Modal Aerosol Model (MAM). CAM7 uses the 5-mode MAM (MAM5), in which three modes (Aitken, accumulation, and coarse modes) by default contain dust. + +.. _Brittle Fragmentation Theory For Modal Aerosol Model: + +Brittle Fragmentation Theory For Modal Aerosol Model +----------------------------------------------------- + +The total mass emission flux per grid is partitioned into the three modes following the Brittle Fragmentation Theory (BFT) in :ref:`Kok et al. (2014b)` and later modified by :ref:`Meng et al. (2022)`. In the current model version, the fractions of dust emission flux partitioned in the three modes are 1.65 :math:`\times` 10:sup:`-5`, 0.021, and 0.979 for the Aitken (0.01–0.1 um), accumulation (0.1–1 um), and coarse (1–10 um) modes, respectively, following :ref:`Meng et al. (2022)`. These values are prescribed in the MAM code inside CAM. + +.. _Conventional Bin Partition: + +Conventional Bin Partition +------------------------------ + +In the early CESM versions, CAM employed the Bulk Aerosol Model (BAM) as the default aerosol model. Thus, the emission fluxes in CTSM is by default partitioned into 4 bins before passing to the coupler: .. math:: - :label: 29.13 + :label: bin_partition_convention - U_{10,t} =u_{*t} \frac{U_{10} }{u_{*} } + F_{j} = F_d \sum _{i=1}^{I}M_{i,j} -In equation :eq:`29.1` we sum :math:`M_{i,\, j}` over :math:`I=3` source modes :math:`i` where :math:`M_{i,\, j}` is the mass fraction of each source mode :math:`i` carried in each of *:math:`J=4`* transport bins :math:`j` +where :math:`F_{j}` is the mass emission flux from the :math:`j` th aerosol bin. The current way of paritioning the emission fluxes before passing to the coupler is still being used, but the partition into the different bins is only required by BAM, not the current default MAM in CAM6 and CAM7. Therefore, for MAM, the four :math:`F_{j}` are summed up to become one total flux :math:`F_d` again inside MAM. It is then redistributed inside MAM to different individual MAM modes following the BFT. So, the following details are inherited from previous versions of the code and still works fine, but we may clean up the code in the future. + +Equation :eq:`bin_partition_convention` comes from :ref:`Zender et al. (2003)` and used by :ref:`Mahowald et al. (2006)`. It sums :math:`M_{i,\, j}` over :math:`I=3` source modes :math:`i` where :math:`M_{i,\, j}` is the mass fraction of each source mode :math:`i` carried in each of :math:`J=4` transport bins :math:`j` .. math:: - :label: 29.14 + :label: bin_partition_fraction M_{i,j} =\frac{m_{i} }{2} \left[{\rm erf}\left(\frac{\ln {\textstyle\frac{D_{j,\max } }{\tilde{D}_{v,i} }} }{\sqrt{2} \ln \sigma _{g,i} } \right)-{\rm erf}\left(\frac{\ln {\textstyle\frac{D_{j,\min } }{\tilde{D}_{v,i} }} }{\sqrt{2} \ln \sigma _{g,i} } \right)\right] where :math:`m_{i}`, :math:`\tilde{D}_{v,\, i}`, and :math:`\sigma _{g,\, i}` are the mass fraction, mass median diameter, and geometric standard deviation assigned to each particle source mode :math:`i` (:numref:`Table Dust Mass fraction`), while :math:`D_{j,\, \min }` and :math:`D_{j,\, \max }` are the minimum and maximum diameters (m) in each transport bin :math:`j` (:numref:`Table Dust Minimum and maximum particle diameters`). +Note that in CAM, dust emission flux will be scaled by another global dust tuning factor for matching the observed atmospheric dust constraints. The CAM dust emission scaling factor is supposed to use 1/3.2 for B (land–atm–ocean coupled) cases, and 1/4 for F (land–atm coupled) cases. This means that CTSM-simulated dust emissions will be scaled to ~25–30 % of its original before simulating dust transport. After scaling, global annual total dust emission using Leung_2023 should be roughly ~3000 Tg/yr. + + .. _Table Dust Mass fraction: .. table:: Mass fraction :math:`m_{i}` , mass median diameter :math:`\tilde{D}_{v,\, i}` , and geometric standard deviation :math:`\sigma _{g,\, i}` , per dust source mode :math:`i` diff --git a/doc/source/tech_note/Ecosystem/CLM50_Tech_Note_Ecosystem.rst b/doc/source/tech_note/Ecosystem/CLM50_Tech_Note_Ecosystem.rst index 446ddec529..c755200ad6 100644 --- a/doc/source/tech_note/Ecosystem/CLM50_Tech_Note_Ecosystem.rst +++ b/doc/source/tech_note/Ecosystem/CLM50_Tech_Note_Ecosystem.rst @@ -45,7 +45,7 @@ Vegetated surfaces are comprised of up to 15 possible plant functional types (PF +-----+--------------------------------------------------------------+-------------------+ | IVT | Plant functional type | Acronym | +=====+==============================================================+===================+ - | 0 | Bare Ground | NET Temperate | + | 0 | Bare Ground | - | +-----+--------------------------------------------------------------+-------------------+ | 1 | Needleleaf evergreen tree – temperate | NET Temperate | +-----+--------------------------------------------------------------+-------------------+ @@ -92,7 +92,7 @@ Vegetated surfaces are comprised of up to 15 possible plant functional types (PF Vegetation Structure ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Vegetation structure is defined by leaf and stem area indices (:math:`L,\, S`) and canopy top and bottom heights (:math:`z_{top}`,\ :math:`z_{bot}` ). Separate leaf and stem area indices and canopy heights are prescribed or calculated for each PFT. Daily leaf and stem area indices are obtained from griddeddatasets of monthly values (section :numref:`Surface Data`). Canopy top and bottom heights for trees are from ICESat (:ref:`Simard et al. (2011) `). Canopy top and bottom heights for short vegetation are obtained from gridded datasets but are invariant in space and time and were obtained from PFT-specific values (:ref:`Bonan et al. (2002a) `) (:numref:`Table Plant functional type canopy top and bottom heights`). When the biogeochemistry model is active, vegetation state (LAI, SAI, canopy top and bottom heights) are calculated prognostically (see Chapter :numref:`rst_Vegetation Phenology and Turnover`). +Vegetation structure is defined by leaf and stem area indices (:math:`L,\, S`) and canopy top and bottom heights (:math:`z_{top}`,\ :math:`z_{bot}` ). Separate leaf and stem area indices and canopy heights are prescribed or calculated for each PFT. Daily leaf and stem area indices are obtained from gridded datasets of monthly values (section :numref:`Surface Data`). Canopy top and bottom heights for trees are from ICESat (:ref:`Simard et al. (2011) `). Canopy top and bottom heights for short vegetation are obtained from gridded datasets but are invariant in space and time and were obtained from PFT-specific values (:ref:`Bonan et al. (2002a) `) (:numref:`Table Plant functional type canopy top and bottom heights`). When the biogeochemistry model is active, vegetation state (LAI, SAI, canopy top and bottom heights) are calculated prognostically (see Chapter :numref:`rst_Vegetation Phenology and Turnover`). .. _Table Plant functional type canopy top and bottom heights: @@ -127,7 +127,7 @@ Vegetation structure is defined by leaf and stem area indices (:math:`L,\, S`) a Phenology and vegetation burial by snow ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -When the biogeochemistry model is inactive, leaf and stem area indices (m\ :sup:`2` leaf area m\ :sup:`-2` ground area) are updated daily by linearly interpolating between monthly values. Monthly PFT leaf area index values are developed from the 1-km MODIS-derived monthly grid cell average leaf area index of :ref:`Myneni et al. (2002) `, as described in :ref:`Lawrence and Chase (2007) `. Stem area ndex is calculated from the monthly PFT leaf area index using the methods of :ref:`Zeng et al. (2002) `. The leaf and stem area indices are adjusted for vertical burying by snow (:ref:`Wang and Zeng 2009 `) as +When the biogeochemistry model is inactive, leaf and stem area indices (m\ :sup:`2` leaf area m\ :sup:`-2` ground area) are updated daily by linearly interpolating between monthly values. Monthly PFT leaf area index values are developed from the 1-km MODIS-derived monthly grid cell average leaf area index of :ref:`Myneni et al. (2002) `, as described in :ref:`Lawrence and Chase (2007) `. Stem area index is calculated from the monthly PFT leaf area index using the methods of :ref:`Zeng et al. (2002) `. The leaf and stem area indices are adjusted for vertical burying by snow (:ref:`Wang and Zeng 2009 `) as .. math:: :label: 2.1 @@ -293,9 +293,8 @@ The current state of the atmosphere (:numref:`Table Atmospheric input to land mo :sup:`3`\ There are 14 aerosol deposition rates required depending on species and affinity for bonding with water; 8 of these are dust deposition rates (dry and wet rates for 4 dust size bins, :math:`D_{dst,\, dry1},\, D_{dst,\, dry2},\, D_{dst,\, dry3},\, D_{dst,\, dry4}`, :math:`D_{dst,\, \, wet1},D_{dst,\, wet2},\, D_{dst,wet3},\, D_{dst,\, wet4}` ), 3 are black carbon deposition rates (dry and wet hydrophilic and dry hydrophobic rates, :math:`D_{bc,\, dryhphil},\, D_{bc,\, wethphil},\, D_{bc,\, dryhphob}` ), and 3 are organic carbon deposition rates (dry and wet hydrophilic and dry hydrophobic rates, :math:`D_{oc,\, dryhphil},\, D_{oc,\, wethphil},\, D_{oc,\, dryhphob}` ). These fluxes are computed interactively by the atmospheric model (when prognostic aerosol representation is active) or are prescribed from a time-varying (annual cycle or transient), globally-gridded deposition file defined in the namelist (see the CLM4.5 User's Guide). Aerosol deposition rates were calculated in a transient 1850-2009 CAM simulation (at a resolution of 1.9x2.5x26L) with interactive chemistry (troposphere and stratosphere) driven by CCSM3 20\ :sup:`th` century sea-surface temperatures and emissions (:ref:`Lamarque et al. 2010`) for short-lived gases and aerosols; observed concentrations were specified for methane, N\ :sub:`2`\ O, the ozone-depleting substances (CFCs),and CO\ :sub:`2`. The fluxes are used by the snow-related parameterizations (Chapters :numref:`rst_Surface Albedos` and :numref:`rst_Snow Hydrology`). :sup:`4`\ The nitrogen deposition rate is required by the biogeochemistry model when active and represents the total deposition of mineral nitrogen onto the land surface, combining deposition of NO\ :sub:`y` and NH\ :sub:`x`. The rate is supplied either as a time-varying spatially-varying monthly mean rate fixed for a particular year for control simulations or advancing yearly for transient simulation. This is for the case when CTSM reads it's own datasets, but when coupled to CAM it can also use the Nitrogen deposition calculated or read in by CAM. For the datasets that CTSM uses, Nitrogen deposition rates were calculated from the same CAM chemistry simulation that generated the aerosol deposition rates. -.. _rst_Surface Characterization, Vertical Discretization, and Model Input Requirements: -:sup:`5`\ Climatological 3-hourly lightning frequency at :math:`\sim`\ 1.8° resolution is provided, which was calculated via bilinear interpolation from 1995-2011 NASA LIS/OTD grid product v2.2 (http://ghrc.msfc.nasa.gov) 2-hourly, 2.5° lightning frequency data. In future versions of the model, lightning data may be obtained directly from the atmosphere model. +:sup:`5`\ Climatological 3-hourly lightning frequency at :math:`\sim`\ 1.8° resolution is provided, which was calculated via bilinear interpolation from 1995-2011 NASA LIS/OTD grid product v2.2 (https://cmr.earthdata.nasa.gov/search/concepts/C1995863244-GHRC_DAAC.html) 2-hourly, 2.5° lightning frequency data. In future versions of the model, lightning data may be obtained directly from the atmosphere model. Density of air (:math:`\rho _{atm}` ) (kg m\ :sup:`-3`) is also required but is calculated directly from :math:`\rho _{atm} =\frac{P_{atm} -0.378e_{atm} }{R_{da} T_{atm} }` where :math:`P_{atm}` is atmospheric pressure (Pa), :math:`e_{atm}` is atmospheric vapor pressure (Pa), :math:`R_{da}` is the gas constant for dry air (J kg\ :sup:`-1` K\ :sup:`-1`) (:numref:`Table Physical constants`), and :math:`T_{atm}` is the atmospheric temperature (K). The atmospheric vapor pressure :math:`e_{atm}` is derived from atmospheric specific humidity :math:`q_{atm}` (kg kg\ :sup:`-1`) as :math:`e_{atm} =\frac{q_{atm} P_{atm} }{0.622+0.378q_{atm} }`. @@ -360,7 +359,7 @@ Initialization Initialization of the land model (i.e., providing the model with initial temperature and moisture states) depends on the type of run (startup or restart) (see the CLM4.5 User's Guide). A startup run starts the model from either initial conditions that are set internally in the Fortran code (referred to as arbitrary initial conditions) or from an initial conditions dataset that enables the model to start from a spun up state (i.e., where the land is in equilibrium with the simulated climate). In restart runs, the model is continued from a previous simulation and initialized from a restart file that ensures that the output is bit-for-bit the same as if the previous simulation had not stopped. The fields that are required from the restart or initial conditions files can be obtained by examining the code. Arbitrary initial conditions are specified as follows. -Soil points are initialized with surface ground temperature :math:`T_{g}` and soil layer temperature :math:`T_{i}`, for :math:`i=1,\ldots,N_{levgrnd}`, of 274 K, vegetation temperature :math:`T_{v}` of 283 K, no snow or canopy water (:math:`W_{sno} =0`, :math:`W_{can} =0`), and volumetric soil water content :math:`\theta _{i} =0.15` mm\ :sup:`3` mm\ :sup:`-3` for layers :math:`i=1,\ldots,N_{levsoi}` and :math:`\theta _{i} =0.0` mm\ :sup:`3` mm\ :sup:`-3` for layers :math:`i=N_{levsoi} +1,\ldots,N_{levgrnd}`. placeLake temperatures (:math:`T_{g}` and :math:`T_{i}` ) are initialized at 277 K and :math:`W_{sno} =0`. +Soil points are initialized with surface ground temperature :math:`T_{g}` and soil layer temperature :math:`T_{i}`, for :math:`i=1,\ldots,N_{levgrnd}`, of 274 K, vegetation temperature :math:`T_{v}` of 283 K, no snow or canopy water (:math:`W_{sno} =0`, :math:`W_{can} =0`), and volumetric soil water content :math:`\theta _{i} =0.15` mm\ :sup:`3` mm\ :sup:`-3` for layers :math:`i=1,\ldots,N_{levsoi}` and :math:`\theta _{i} =0.0` mm\ :sup:`3` mm\ :sup:`-3` for layers :math:`i=N_{levsoi} +1,\ldots,N_{levgrnd}`. Lake temperatures (:math:`T_{g}` and :math:`T_{i}` ) are initialized at 277 K and :math:`W_{sno} =0`. Glacier temperatures (:math:`T_{g} =T_{snl+1}` and :math:`T_{i}` for :math:`i=snl+1,\ldots,N_{levgrnd}` where :math:`snl` is the negative of the number of snow layers, i.e., :math:`snl` ranges from –5 to 0) are initialized to 250 K with a snow water equivalent :math:`W_{sno} =1000` mm, snow depth :math:`z_{sno} =\frac{W_{sno} }{\rho _{sno} }` (m) where :math:`\rho _{sno} =250` kg m\ :sup:`-3` is an initial estimate for the bulk density of snow, and :math:`\theta _{i}` \ =1.0 for :math:`i=1,\ldots,N_{levgrnd}`. The snow layer structure (e.g., number of snow layers :math:`snl` and layer thickness) is initialized based on the snow depth (section 6.1). The snow liquid water and ice contents (kg m\ :sup:`-2`) are initialized as :math:`w_{liq,\, i} =0` and :math:`w_{ice,\, i} =\Delta z_{i} \rho _{sno}`, respectively, where :math:`i=snl+1,\ldots,0` are the snow layers, and :math:`\Delta z_{i}` is the thickness of snow layer :math:`i` (m). The soil liquid water and ice contents are initialized as :math:`w_{liq,\, i} =0` and :math:`w_{ice,\, i} =\Delta z_{i} \rho _{ice} \theta _{i}` for :math:`T_{i} \le T_{f}`, and :math:`w_{liq,\, i} =\Delta z_{i} \rho _{liq} \theta _{i}` and :math:`w_{ice,\, i} =0` for :math:`T_{i} >T_{f}`, where :math:`\rho _{ice}` and :math:`\rho _{liq}` are the densities of ice and liquid water (kg m\ :sup:`-3`) (:numref:`Table Physical constants`), and :math:`T_{f}` is the freezing temperature of water (K) (:numref:`Table Physical constants`). All vegetated and glacier land units are initialized with water stored in the unconfined aquifer and unsaturated soil :math:`W_{a} =4000` mm and water table depth :math:`z_{\nabla }` at five meters below the soil column. @@ -479,7 +478,7 @@ Values of certain adjustable parameters inherent in the biogeophysical or biogeo "Latent heat of sublimation", :math:`\lambda _{sub}`, :math:`\lambda _{vap} +L_{f}`, J kg :sup:`-1` :sup:`1` "Thermal conductivity of water", :math:`\lambda _{liq}`, 0.57, W m :sup:`-1` K :sup:`-1` :sup:`1` "Thermal conductivity of ice", :math:`\lambda _{ice}`, 2.29, W m :sup:`-1` K :sup:`-1` - :sup:`1` "Thermal conductivity of air", :math:`\lambda _{air}`, 0.023 W m :sup:`-1` K :sup:`-1` + :sup:`1` "Thermal conductivity of air", :math:`\lambda _{air}`, 0.023, W m :sup:`-1` K :sup:`-1` "Radius of the earth", :math:`R_{e}`, 6.37122, :math:`\times 10^{6}` m :sup:`1`\ Not shared by other components of the coupled modeling system. diff --git a/doc/source/tech_note/External_Nitrogen_Cycle/CLM50_Tech_Note_External_Nitrogen_Cycle.rst b/doc/source/tech_note/External_Nitrogen_Cycle/CLM50_Tech_Note_External_Nitrogen_Cycle.rst index d1c476099d..345693c40c 100644 --- a/doc/source/tech_note/External_Nitrogen_Cycle/CLM50_Tech_Note_External_Nitrogen_Cycle.rst +++ b/doc/source/tech_note/External_Nitrogen_Cycle/CLM50_Tech_Note_External_Nitrogen_Cycle.rst @@ -3,63 +3,40 @@ External Nitrogen Cycle =========================== -.. _Summary of CLM5.0 updates relative to CLM4.5: - -Summary of CLM5.0 updates relative to CLM4.5 ------------------------------------------------------ - -We describe external inputs to the nitrogen cycle in CLM5.0.  Much of the following information appeared in the CLM4.5 Technical Note (:ref:`Oleson et al. 2013 `) as well as :ref:`Koven et al. (2013) `. - -CLM5.0 includes the following changes to terrestrial nitrogen inputs: - -- Time varrying deposition of reactive nitrogen. In off-line runs this changes monthly. In coupled simulations N deposition is passed at the coupling timestep (e.g., half-hourly). - -- Asymbiotic (or free living) N fixation is a function of evapotranspiration and is added to the inorganic nitrogen (NH\ :sub:`4`\ :sup:`+`) pool (described below). - -- Symbiotic N fixation is handled by the FUN model (chapter :numref:`rst_FUN`) and is passed straight to the plant, not the mineral nitrogen pool. Overview ----------------------------------------------------- In addition to the relatively rapid cycling of nitrogen within the plant – litter – soil organic matter system, CLM also represents several processes which couple the internal nitrogen cycle to external sources and sinks. Inputs of new mineral nitrogen are from atmospheric deposition and biological nitrogen fixation. Losses of mineral nitrogen are due to nitrification, denitrification, leaching, and losses in fire. While the short-term dynamics of nitrogen limitation depend on the behavior of the internal nitrogen cycle, establishment of total ecosystem nitrogen stocks depends on the balance between sources and sinks in the external nitrogen cycle (:ref:`Thomas et al. 2015 `). -As with CLM4.5, CLM5.0 represents inorganic N transformations based on the Century N-gas model; this includes separate NH\ :sub:`4`\ :sup:`+` and NO\ :sub:`3`\ :sup:`-` pools, as well as environmentally controlled nitrification and denitrification rates that is described below. +CLM represents inorganic N transformations based on the Century N-gas model; this includes separate NH\ :sub:`4`\ :sup:`+` and NO\ :sub:`3`\ :sup:`-` pools, as well as environmentally controlled nitrification and denitrification rates that is described below. Atmospheric Nitrogen Deposition ------------------------------------ -CLM uses a single variable to represent the total deposition of mineral nitrogen onto the land surface, combining wet and dry deposition of NO\ :sub:`y` and NH\ :sub:`x` as a single flux (:math:`{NF}_{ndep\_sminn}`, gN m\ :sup:`-2` s\ :sup:`-1`). This flux is intended to represent total reactive nitrogen deposited to the land surface which originates from the following natural and anthropogenic sources (Galloway et al. 2004): formation of NO\ :sub:`x` during lightning, NO\ :math:`{}_{x }`\ and NH\ :sub:`3` emission from wildfire, NO\ :sub:`x` emission from natural soils, NH\ :sub:`3` emission from natural soils, vegetation, and wild animals, NO\ :sub:`x` and NH\ :sub:`3` emission during fossil fuel combustion (both thermal and fuel NO\ :sub:`x` production), NO\ :sub:`x` and NH\ :sub:`3` emission from other industrial processes, NO\ :sub:`x` and NH\ :sub:`3` emission from fire associated with deforestation, NO\ :sub:`x` and NH\ :sub:`3` emission from agricultural burning, NO\ :sub:`x` emission from agricultural soils, NH\ :sub:`3` emission from agricultural crops, NH\ :sub:`3` emission from agricultural animal waste, and NH\ :sub:`3` emission from human waste and waste water. The deposition flux is provided as a spatially and (potentially) temporally varying dataset (see section :numref:`Atmospheric Coupling` for a description of the default input dataset). +CLM uses a single variable to represent the total deposition of mineral nitrogen onto the land surface, combining wet and dry deposition of NO\ :sub:`y` and NH\ :sub:`x` as a single flux (:math:`{NF}_{ndep\_sminn}`, gN m\ :sup:`-2` s\ :sup:`-1`). This flux is intended to represent total reactive nitrogen deposited to the land surface which originates from the following natural and anthropogenic sources (Galloway et al. 2004): formation of NO\ :sub:`x` during lightning, NO\ :sub:`x`\ and NH\ :sub:`3` emission from wildfire, NO\ :sub:`x` emission from natural soils, NH\ :sub:`3` emission from natural soils, vegetation, and wild animals, NO\ :sub:`x` and NH\ :sub:`3` emission during fossil fuel combustion (both thermal and fuel NO\ :sub:`x` production), NO\ :sub:`x` and NH\ :sub:`3` emission from other industrial processes, NO\ :sub:`x` and NH\ :sub:`3` emission from fire associated with deforestation, NO\ :sub:`x` and NH\ :sub:`3` emission from agricultural burning, NO\ :sub:`x` emission from agricultural soils, NH\ :sub:`3` emission from agricultural crops, NH\ :sub:`3` emission from agricultural animal waste, and NH\ :sub:`3` emission from human waste and waste water. The deposition flux is provided as a spatially and temporally varying dataset (see section :numref:`Atmospheric Coupling` for a description of the default input dataset). -The nitrogen deposition flux is assumed to enter the NH\ :sub:`4`\ :sup:`+` pool, and is vertically distributed throughout the soil profile. Although N deposition inputs include both oxidized and reduced forms, CLM5 only reads in total N deposition. This approach is held over from CLM4.0, which only represented a single mineral nitrogen pool, however, real pathways for wet and dry nitrogen deposition can be more complex than currently represented in the CLM5.0, including release from melting snowpack and direct foliar uptake of deposited NO\ :sub:`y` (:ref:`Tye et al. 2005 `; :ref:`Vallano and Sparks, 2007 `). +The nitrogen deposition flux is assumed to enter the NH\ :sub:`4`\ :sup:`+` pool, and is vertically distributed throughout the soil profile. Although N deposition inputs include both oxidized and reduced forms, CLM5.0 and CLM6.0 only read in total N deposition. This approach is held over from CLM4.0, which only represented a single mineral nitrogen pool, however, real pathways for wet and dry nitrogen deposition can be more complex than currently represented in CLM, including release from melting snowpack and direct foliar uptake of deposited NO\ :sub:`y` (:ref:`Tye et al. 2005 `; :ref:`Vallano and Sparks, 2007 `). -In offline (uncoupled) CLM5.0 simulations monthly estimates of N deposition are provided, as opposed to decadal files supplied with previous versions of the model. In coupled simulations, N depositions fluxes are passed to the land model at the frequency of the time step (every half hour) through the coupler. +As of CLM5.0, in off line (uncoupled) simulations monthly estimates of N deposition are provided, In coupled simulations, N depositions fluxes are passed to the land model at the frequency of the time step (every half hour) through the coupler. Biological Nitrogen Fixation --------------------------------- +The fixation of new reactive nitrogen from atmospheric N\ :sub:`2` by soil microorganisms is an important component of both preindustrial and modern-day nitrogen budgets, but a mechanistic understanding of global-scale controls on biological nitrogen fixation (BNF) is still only poorly developed (:ref:`Cleveland et al. 1999 `; :ref:`Galloway et al. 2004 `). CLM5 introduced a new representation of biological nitrogen fixation (BNF) that includes both symbiotic and free-living (asymbiotic) components. The symbiotic component is calculated using the Fixation and Uptake of Nitrogen (FUN) model (chapter :numref:`rst_FUN`) to calculate the carbon cost of nitrogen fixation and the amount of nitrogen acquired through symbiotic fixation. This nitrogen is immediately available to plants. One drawback to this approach is that under elevated CO2, when plant productivity increases, FUN predicts increased rates of symbiotic nitrogen fixation, which may not be realistic (:ref:`Wieder et al. 2019 `; :ref:`Kou-Giesbrecht et al. 2025 `). Future work should address this issue. -The fixation of new reactive nitrogen from atmospheric N\ :sub:`2` by soil microorganisms is an important component of both preindustrial and modern-day nitrogen budgets, but a mechanistic understanding of global-scale controls on biological nitrogen fixation (BNF) is still only poorly developed (:ref:`Cleveland et al. 1999 `; :ref:`Galloway et al. 2004 `). CLM5.0 uses the FUN model (chapter :numref:`rst_FUN`) to calculate the carbon cost and nitrogen acquired through symbotic nitrogen fixation. This nitrogen is immediately available to plants. - -:ref:`Cleveland et al. (1999) ` suggested an empirical relationships that predicts BNF as a function of either evapotranspiration rate or net primary productivity for natural vegetation. CLM5.0 adopts the evapotranspiration approach to calculate asymbiotic, or free-living, N fixation. This function has been modified from the :ref:`Cleveland et al. (1999) ` estimates to provide lower estimate of free-living nitrogen fixation in CLM5.0 (:math:`{CF}_{ann\_ET}`, mm yr\ :sup:`-1`). This moves away from the NPP approach used in CLM4.0 and 4.5 and avoids unrealistically increasing freeliving rates of N fixation under global change scenarios (:ref:`Wieder et al. 2015 ` The expression used is: +The free-living component is calculated using an empirical relationship following :ref:`Cleveland et al. (1999) ` who suggested using either evapotranspiration rate or net primary productivity to predicts rates of BNF for natural vegetation. CLM5.0 adopted the evapotranspiration approach to calculate asymbiotic, or free-living, N fixation. This function has been modified from the :ref:`Cleveland et al. (1999) ` estimates to provide lower estimate of free-living nitrogen fixation in CLM (:math:`{CF}_{ann\_ET}`, mm yr\ :sup:`-1`). This moves away from the NPP approach used in CLM4.0 and 4.5 and avoids unrealistically increasing freeliving rates of N fixation under global change scenarios (:ref:`Wieder et al. 2015 `). The expression used is: .. math:: :label: 22.1) NF_{nfix,sminn} ={0.0006\left(0.0117+CF_{ann\_ ET}\right)\mathord{\left/ {\vphantom {0.0006\left(0.0117+ CF_{ann\_ ET}\right) \left(86400\cdot 365\right)}} \right.} \left(86400\cdot 365\right)} -Where :math:`{NF}_{nfix,sminn}` (gN m\ :sup:`-2` s\ :sup:`-1`) is the rate of free-living nitrogen fixation in :numref:`Figure Biological nitrogen fixation`. - -.. _Figure Biological nitrogen fixation: - -.. figure:: image1.png - - Free-living nitrogen fixation as a function of annual evapotranspiration. Results here show annual N inputs from free-living N fixations, but the model actually calculates inputs on a per second basis. - -As with Atmospheric N deposition, free-living N inputs are added directly to the NH\ :sub:`4`\ :sup:`+` pool. +Where :math:`{NF}_{nfix,sminn}` (gN m\ :sup:`-2` s\ :sup:`-1`) is the rate of free-living nitrogen fixation, calculated on a per second basis. As with atmospheric N deposition, free-living N inputs are added directly to the soil NH\ :sub:`4`\ :sup:`+` pool. Nitrification and Denitrification Losses of Nitrogen --------------------------------------------------------- -Nitrification is an autotrophic process that converts less mobile ammonium ions into nitrate, that can more easily be lost from soil systems by leaching or denitrification. The process catalyzed by ammonia oxidizing archaea and bacteria that convert ammonium (NH\ :sub:`4`\ :sup:`+`) into nitrite, which is subsequently oxidized into nitrate (NO\ :sub:`3`\ :sup:`-`). Conditions favoring nitrification include high NH\ :sub:`4`\ :sup:`+` concentrations, well aerated soils, a neutral pH and warmer temperatures. +Nitrification is an autotrophic process that converts less mobile ammonium ions into nitrate, that can more easily be lost from soil systems by leaching or denitrification. The process catalyzed by ammonia oxidizing archaea and bacteria that convert ammonium (NH\ :sub:`4`\ :sup:`+`) into nitrite, which is subsequently oxidized into nitrate (NO\ :sub:`3`\ :sup:`-`). Conditions favoring nitrification include high NH\ :sub:`4`\ :sup:`+` concentrations, well aerated soils, a neutral pH, and warmer temperatures. Under aerobic conditions in the soil oxygen is the preferred electron acceptor supporting the metabolism of heterotrophs, but anaerobic conditions favor the activity of soil heterotrophs which use nitrate as an electron acceptor (e.g. *Pseudomonas* and *Clostridium*) supporting respiration. This process, known as denitrification, results in the transformation of nitrate to gaseous N\ :sub:`2`, with smaller associated production of NO\ :sub:`x` and N\ :sub:`2`\ O. It is typically assumed that nitrogen fixation and denitrification were approximately balanced in the preindustrial biosphere ( :ref:`Galloway et al. 2004 `). It is likely that denitrification can occur within anaerobic microsites within an otherwise aerobic soil environment, leading to large global denitrification fluxes even when fluxes per unit area are rather low (:ref:`Galloway et al. 2004 `). @@ -70,7 +47,7 @@ CLM includes a detailed representation of nitrification and denitrification base f_{nitr,p} =\left[NH_{4} \right]k_{nitr} f\left(T\right)f\left(H_{2} O\right)f\left(pH\right) -where :math:`{f}_{nitr,p}` is the potential nitrification rate (prior to competition for NH\ :sub:`4`\ :sup:`+` by plant uptake and N immobilization), :math:`{k}_{nitr}` is the maximum nitrification rate (10 % day\ :math:`\mathrm{-}`\ 1, (:ref:`Parton et al. 2001 `), and *f(T)* and *f(H\)*\ :sub:`2`\ O) are rate modifiers for temperature and moisture content. CLM uses the same rate modifiers as are used in the decomposition routine. *f(pH)* is a rate modifier for pH; however, because CLM does not calculate pH, instead a fixed pH value of 6.5 is used in the pH function of :ref:`Parton et al. (1996) `. +where :math:`{f}_{nitr,p}` is the potential nitrification rate (prior to competition for NH\ :sub:`4`\ :sup:`+` by plant uptake and N immobilization), :math:`{k}_{nitr}` is the maximum nitrification rate (10 % day\ :math:`\mathrm{-}`\ 1, (:ref:`Parton et al. 2001 `), and *f(T)* and *f(H\)*\ :sub:`2`\ O) are rate modifiers for temperature and moisture content. CLM uses the same rate modifiers as are used in the decomposition routine. *f(pH)* is a rate modifier for pH. Although new surface datasets in CLM6.0 provide gridded estimates for soil pH, this information is not currently being used in the model. Instead, a fixed pH value of 6.5 is used in the pH function of :ref:`Parton et al. (1996) `. The potential denitrification rate is co-limited by NO\ :sup:`-3` concentration and C consumption rates, and occurs only in the anoxic fraction of soils: @@ -86,7 +63,7 @@ where :math:`{f}_{denitr,p}` is the potential denitrification rate and *f(decomp frac_{anox} =\exp \left(-aR_{\psi }^{-\alpha } V^{-\beta } C^{\gamma } \left[\theta +\chi \varepsilon \right]^{\delta } \right) -where *a*, :math:`\alpha`, :math:`\beta`, :math:`\gamma`, and :math:`\delta` are constants (equal to 1.5x10\ :sup:`-10`, 1.26, 0.6, 0.6, and 0.85, respectively), :math:`{R}_{\psi}` is the radius of a typical pore space at moisture content :math:`\psi`, *V* is the O\ :sub:`2` consumption rate, *C* is the O\ :sub:`2` concentration, :math:`\theta` is the water-filled pore space, :math:`\chi` is the ratio of diffusivity of oxygen in water to that in air, and :math:`\epsilon` is the air-filled pore space (:ref:`Arah and Vinten (1995) `). These parameters are all calculated separately at each layer to define a profile of anoxic porespace fraction in the soil. +where :math:`a` :math:`\alpha`, :math:`\beta`, :math:`\gamma`, and :math:`\delta` are constants (equal to 1.5x10\ :sup:`-10`, 1.26, 0.6, 0.6, and 0.85, respectively), :math:`{R}_{\psi}` is the radius of a typical pore space at moisture content :math:`\psi`, :math:`V` is the O\ :sub:`2` consumption rate, :math:`C` is the O\ :sub:`2` concentration, :math:`\theta` is the water-filled pore space, :math:`\chi` is the ratio of diffusivity of oxygen in water to that in air, and :math:`\epsilon` is the air-filled pore space (:ref:`Arah and Vinten 1995 `). These parameters are all calculated separately at each layer to define a profile of anoxic porespace fraction in the soil. The nitrification/denitrification models used here also predict fluxes of N\ :sub:`2`\ O via a "hole-in-the-pipe" approach (:ref:`Firestone and Davidson, 1989 `). A constant fraction (6 * 10\ :math:`{}^{-4}`, :ref:`Li et al. 2000 `) of the nitrification flux is assumed to be N\ :sub:`2`\ O, while the fraction of denitrification going to N\ :sub:`2`\ O, \ :math:`{P}_{N2:N2O}`, is variable, following the Century (:ref:`del Grosso et al. 2000 `) approach: @@ -136,8 +113,9 @@ where :math:`{WS}_{tot\_soil}` (kgH\ :sub:`2`\ O m\ :sup:`-2`) is the total mass Alternative way of evaluating the Leaching Losses of Nitrogen -------------------------------------------------------------- -The previous leaching mechanism is not designed for describing the vertical transport of :math:`{NO}_{3}^{-}` in soil, an alternative way to evaluate the vertical convective, diffusive, and dispersive of dissolved :math:`{NO}_{3}^{-}` in soil is provided in (:ref:`Luo et al. 2025 `). -To obtain the vertical profile of soil mineral N after vertical movement of each timestep, the vertical transport equation is summarized in :eq:`22.20`. +Leaching losses of :math:`{NO}_{3}^{-}` are notably low in CLM because of low rates of nitrification and high plant N uptake (:ref:`Houlton et al. 2015 `, :ref:`Nevison et al. 2022 `). Future work should address these biases. + +Towards this end, the previous leaching mechanism is not designed for describing the vertical transport of :math:`{NO}_{3}^{-}` in soil, an alternative way to evaluate the vertical convective, diffusive, and dispersive of dissolved :math:`{NO}_{3}^{-}` in soil is provided in (:ref:`Luo et al. 2025 `). This is option is not active by default in CLM6.0, but can be activated by the user. To obtain the vertical profile of soil mineral N after vertical movement of each timestep, the vertical transport equation is summarized in :eq:`22.20`. .. math:: :label: 22.20 diff --git a/doc/source/tech_note/External_Nitrogen_Cycle/image1.png b/doc/source/tech_note/External_Nitrogen_Cycle/image1.png deleted file mode 100755 index b28b5d1894..0000000000 --- a/doc/source/tech_note/External_Nitrogen_Cycle/image1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f3acfbbb90ad0c44ff7179a257c44f59d4b0b5a0da348825b02aa5034bee1640 -size 29009 diff --git a/doc/source/tech_note/FUN/CLM50_Tech_Note_FUN.rst b/doc/source/tech_note/FUN/CLM50_Tech_Note_FUN.rst index 1c4a43deb6..fb69877849 100644 --- a/doc/source/tech_note/FUN/CLM50_Tech_Note_FUN.rst +++ b/doc/source/tech_note/FUN/CLM50_Tech_Note_FUN.rst @@ -6,7 +6,7 @@ Fixation and Uptake of Nitrogen (FUN) Introduction ----------------- -The Fixation and Uptake of Nitrogen model is based on work by :ref:`Fisher et al. (2010)`, :ref:`Brzostek et al. (2014)`, and :ref:`Shi et al. (2016)`. The concept of FUN is that in most cases, Nitrogen uptake requires the expenditure of energy in the form of carbon, and further, that there are numerous potential sources of Nitrogen in the environment which a plant may exchange for carbon. The ratio of carbon expended to Nitrogen acquired is referred to here as the cost, or exchange rate, of N acquisition (:math:`E_{nacq}`, gC/gN)). There are eight pathways for N uptake: +The Fixation and Uptake of Nitrogen model (FUN) is based on work by :ref:`Fisher et al. (2010)`, :ref:`Brzostek et al. (2014)`, and :ref:`Shi et al. (2016)`, as described in :ref:`Fisher et al. (2019)`.The concept of FUN is that in most cases, nitrogen (N) uptake requires the expenditure of energy in the form of carbon (C), and further, that there are numerous potential sources of N in the environment which a plant may exchange for C. The ratio of carbon expended to nitrogen acquired is referred to here as the cost, or exchange rate, of N acquisition (:math:`E_{nacq}`, gC/gN)). There are eight pathways for N uptake: 1. Fixation by symbiotic bacteria in root nodules (for N fixing plants) (:math:`_{fix}`) 2. Retranslocation of N from senescing tissues (:math:`_{ret}`) @@ -17,12 +17,14 @@ The Fixation and Uptake of Nitrogen model is based on work by :ref:`Fisher et al 7. Nonmycorrhizal uptake of NH4 (:math:`_{nonmyc,nh4}`) 8. Nonmycorrhizal uptake of NO3 (:math:`_{nonmyc,no3}`) -The notation suffix for each pathway is given in parentheses here. At each timestep, each of these pathways is associated with a cost term (:math:`N_{cost,x}`), a payment in carbon (:math:`C_{nuptake,x}`), and an influx of Nitrogen (:math:`N_{uptake,x}`) where :math:`x` is one of the eight uptake streams listed above. +The notation suffix for each pathway is given in parentheses here. At each timestep, each of these pathways is associated with a cost term (:math:`N_{cost,x}`), a payment in carbon (:math:`C_{nuptake,x}`), and an influx of nitrogen (:math:`N_{uptake,x}`) where :math:`x` is one of the eight uptake streams listed above. -For each PFT, we define a fraction of the total C acquisition that can be used for N fixation (:math:`f_{fixers}`), which is broadly equivalent to the fraction of a given PFT that is capable of fixing Nitrogen, and thus represents an upper limit on the amount to which fixation can be increased in low n conditions. For each PFT, the cost calculation is conducted twice. Once where fixation is possible and once where it is not. (:math:`f_{fixers}`) +For each PFT, we define a fraction of the total C acquisition that can be used for N fixation (:math:`f_{fixers}`), which is broadly equivalent to the fraction of a given PFT that is capable of fixing Nitrogen, and thus represents an upper limit on the amount to which fixation can be increased in low N conditions. For each PFT, the cost calculation is conducted twice. Once where fixation is possible and once where it is not (:math:`f_{fixers}`). For all of the active uptake pathways, whose cost depends on varying concentrations of N through the soil profile, the costs and fluxes are also determined by soil layer :math:`j`. +Notable changes to FUN in CLM6 include: (1) Updated the emperical function describing the temperature sensitivity of nitrogen fixation (:ref:`Bytnerowicz et al. 2022`). (2) Corrected an error in the parameter values for nonmycorrhizal uptake of inorganic N that was published in :ref:`Brzostek et al. (2014)`. And (3) introduced an empirical function that adjusts target leaf C:N ratios with atmospheric concentrations of CO\ :sub:`2` (:ref:`Hauser et al 2023`, this is documented in section :numref:`rst_CN Pools` and is turned off by default in CLM6). We also acknowledge that previously identified limitations of the implementation of FUN in CLM remain. These include a reduction in interannual variability of net ecosystem productivity (:ref:`Wieder et al. 2021`) and strong increases in rates of symbiotic nitrogen fixation under elevated CO\ :sub:`2` (:ref:`Wieder et al. 2019 `; :ref:`Kou-Giesbrecht et al. 2025 `). Future work should address these issues. + Boundary conditions of FUN -------------------------------------------------------- @@ -30,23 +32,54 @@ Available Carbon ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The carbon available for FUN, :math:`C_{avail}` (gC m\ :sup:`-2`) is the total canopy photosynthetic uptake (GPP), minus the maintenance respiration fluxes (:math:`m_r`) and multiplied by the time step in seconds (:math:`\delta t`). Thus, the remainder of this chapter considers fluxes per timestep, and integrates these fluxes as they are calculated. - .. math:: +.. math:: + :label: C_avail_1 C_{avail} = (GPP - m_r) \delta t Growth respiration is thus only calculated on the part of the carbon uptake that remains after expenditure of C by the FUN module. -Available Soil Nitrogen -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Cost of Nitrogen Fixation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The cost of fixation is derived from :ref:`Houlton et al. (2008)`. - .. math:: +Nitrogen fixation rates are temperature dependent. In CLM6 the carbon cost of nitrogen fixation was derived from an empirical function fit to data from a greenhouse experiment measuring nitrogen fixation by woody plants from :ref:`Bytnerowicz et al. (2022)`. CLM5 used a different empirical function to describe the temperature dependence of nitrogenase activity from :ref:`Houlton et al. (2008)`. + +This Bytnerowicz formulation (:math:`F_B`) defines a temperature dependent N fixation rate function as: + +.. math:: + :label: F_B + + F_{B} = \left(\frac{T_{max} - T_{soil}}{T_{max} - T_{opt}}\right) \left(\frac{T_{soil} - T_{min}}{T_{opt} - T_{min}}\right)^{\frac{T_{opt}-T_{min}}{T_{max}-T_{opt}}} + +where :math:`T_{soil}` is soil temperature (°C), and :math:`T_{min}`, :math:`T_{opt}` , and :math:`T_{max}` define the lower bound, optimum, and upper bound of the biome-specific temperature response. The function is unitless and bounded between 0 and 1. The function is calculated separately for each soil layer and weighted by the fraction of roots present in that layer. The rate function is interpreted as a conductance like term for N acquisition, and its inverse is used to represent a temperature-limited carbon cost of nitrogen fixation (:math:`N_{cost,fix}`) to give a temperature limited cost in terms of C to N ratios: + +.. math:: + :label: N_cost_fix_1 + + N_{cost,fix} = \frac{S_{fix}}{F_{B}} + +The minimum cost of N fixation, :math:`S_{fix}`, occurs at :math:`T_{opt}` and is set as 6 gC :math:`\mathrm{gN}^{-1}`. When soil temperature falls outside the range of :math:`T_{min}` and :math:`T_{max}`, the cost of fixation is set to an arbitrarily large value (10\ :sup:`9`) to effectively suppress N fixation. Parameters for :math:`T_{min}`, :math:`T_{opt}`, :math:`T_{max}` differ between tropical and extra tropical plant functional types (PFTs), following the biome specific estimates reported by :ref:`Bytnerowicz et al. (2022)`. Parameter values for tropical and extra-tropical PFTs are as follows: + +\ Tropical: :math:`T_{min}` =7.04, :math:`T_{opt}` =33.22, and :math:`T_{max}` =45.35. + +\ Extra-tropical: :math:`T_{min}` =−2.04, :math:`T_{opt}` =32.10, and :math:`T_{max}` =43.98. + + +The Houlton function used in CLM5 the cost of fixation (:math:`N_{cost,fix}`) calculated as: + +.. math:: + :label: N_cost_fix_2 + + N_{cost,fix} = -S_{fix}/(1.25 e^{a_{fix} + b_{fix} . T_{soil} (1 - 0.5 T_{soil}/ c_{fix}) }) + +Herein, :math:`a_{fix}`, :math:`b_{fix}` and :math:`c_{fix}` are all parameters of the temperature response function of fixation reported by Houlton et al. (2008) (:math:`exp[a+bT_{soil}(1-0.5T_{soil}/c)]`). :math:`T_{soil}` is the soil temperature in C. The values of these parameters are fitted to empirical data as a=-3.62 :math:`\pm` 0.52, b=0.27 :math:`\pm` 0.04 and c=25.15 :math:`\pm` 0.66. The hardwired coefficient 1.25 converts from the temperature response function to a 0-1 limitation factor (as specifically employed by Houlton et al.). This function is a 'rate' of uptake for a given temperature. Here we assimilated the rate of fixation into the cost term by assuming that the rate is analogous to a conductance for N, and inverting the term to produce a cost/resistance analogue. We then multiply this temperature term by the minimum cost at optimal temperature (:math:`S_{fix}`) to give a temperature limited cost in terms of C to N ratios. + +.. _Figure Carbon costs of N fixation as a function of soil temperature: + +.. figure:: image1.png + + Figure Carbon costs of N fixation as a function of soil temperature. Bytnerowicz et al(2022) function for tropical and extra-tropical PFTs (red and blue lines, respectively) that are used in CLM6; and the Houlton et al (2008) function (black line) that was used in CLM5. - N_{cost,fix} = -s_{fix}/(1.25 e^{a_{fix} + b_{fix} . t_{soil} (1 - 0.5 t_{soil}/ c_{fix}) }) -Herein, :math:`a_{fix}`, :math:`b_{fix}` and :math:`c_{fix}` are all parameters of the temperature response function of fixation reported by Houlton et al. (2008) (:math:`exp[a+bT_s(1-0.5T_s/c)`). t_{soil} is the soil temperature in C. The values of these parameters are fitted to empirical data as a=-3.62 :math:`\pm` 0.52, b=0.27:math:`\pm` 0.04 and c=25.15 :math:`\pm` 0.66. 1.25 converts from the temperature response function to a 0-1 limitation factor (as specifically employed by Houlton et al.). This function is a 'rate' of uptake for a given temperature. Here we assimilated the rate of fixation into the cost term by assuming that the rate is analagous to a conductance for N, and inverting the term to produce a cost/resistance analagoue. We then multiply this temperature term by the minimum cost at optimal temperature (:math:`s_{fix}`) to give a temperature limited cost in terms of C to N ratios. Cost of Active Uptake ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -55,20 +88,22 @@ The cost of N uptake from soil, for each layer :math:`j`, is controlled by two u For non-mycorrhizal uptake: - .. math:: +.. math:: + :label: N_cost,nonmyc,j N_{cost,nonmyc,j} = \frac{k_{n,nonmyc}}{N_{smin,j}} + \frac{k_{c,nonmyc}}{c_{root,j}} and for active uptake: - .. math:: +.. math:: + :label: N_cost,active,j N_{cost,active,j} = \frac{k_{n,active}}{N_{smin,j}} + \frac{k_{c,active}}{c_{root,j}} where :math:`k_{n,active}` varies according to whether we are considering ecto or arbuscular mycorrhizal uptake. - .. math:: - :label: 18.2 +.. math:: + :label: k_n,active k_{n,active} = \left\{\begin{array}{lr} @@ -76,39 +111,48 @@ where :math:`k_{n,active}` varies according to whether we are considering ecto o k_{n,Aactive}& e = 0 \end{array}\right\} -where m=1 pertains to the fraction of the PFT that is ecotmycorrhizal, as opposed to arbuscular mycorrhizal. +where e = 1 pertains to the fraction of the PFT that is ectomycorrhizal, as opposed to arbuscular mycorrhizal. + +CLM6 corrects an error in the calculation of non-mycorrhizal uptake in CLM5, which had swapped parameter values for :math:`k_{c,nonmyc}` and :math:`k_{n,nonmyc}` that were inherited from the original publication of :ref:`Brzostek et al. (2014)`. Resolving N cost across simultaneous uptake streams -------------------------------------------------------- -The total cost of N uptake is calculated based on the assumption that carbon is partitioned to each stream in proportion to the inverse of the cost of uptake. So, more expensive pathways receive less carbon. Earlier versions of FUN :ref:`(Fisher et al., 2010)`) utilized a scheme whereby plants only took up N from the cheapest pathway. :ref:`Brzostek et al. (2014)` introduced a scheme for the simultaneous uptake from different pathways. Here we calcualate a 'conductance' to N uptake (analagous to the inverse of the cost function conceptualized as a resistance term) :math:`N_{conductance}` ( gN/gC) as: +The total cost of N uptake is calculated based on the assumption that carbon is partitioned to each stream in proportion to the inverse of the cost of uptake. So, more expensive pathways receive less carbon. Earlier versions of FUN :ref:`(Fisher et al. 2010`) utilized a scheme whereby plants only took up N from the cheapest pathway. :ref:`Brzostek et al. (2014)` introduced a scheme for the simultaneous uptake from different pathways. Here we calculate a 'conductance' to N uptake (analogous to the inverse of the cost function conceptualized as a resistance term) :math:`N_{conductance}` (gN/gC) as: - .. math:: +.. math:: + :label: N_conductance - N_{conductance,f}= \sum{(1/N_{cost,x})} + N_{conductance}= \sum{(1/N_{cost,x})} From this, we then calculate the fraction of the carbon allocated to each pathway as - .. math:: +.. math:: + :label: C_frac,x C_{frac,x} = \frac{1/N_{cost,x}}{N_{conductance}} These fractions are used later, to calculate the carbon expended on different uptake pathways. Next, the N acquired from each uptake stream per unit C spent (:math:`N_{exch,x}`, gN/gC) is determined as - .. math:: +.. math:: + :label: N_exch,x N_{exch,x} = \frac{C_{frac,x}}{N_{cost,x}} We then determine the total amount of N uptake per unit C spent (:math:`N_{exch,tot}`, gN/gC) as the sum of all the uptake streams. - .. math:: +.. math:: + :label: N_exch,tot + N_{exch,tot} = \sum{N_{exch,x}} and thus the subsequent overall N cost is - .. math:: +.. math:: + :label: N_cost,tot + N_{cost,tot} = 1/{N_{exch,tot}} - Retranslocation is determined via a different set of mechanisms, once the :math:`N_{cost,tot}` is known. +Retranslocation is determined via a different set of mechanisms, once the :math:`N_{cost,tot}` is known. Nitrogen Retranslocation -------------------------------------------------------- @@ -116,37 +160,42 @@ The retranslocation uses an iterative algorithm to remove Nitrogen from each pie At each timestep, the pool of carbon in falling leaves (:math:`C_{fallingleaf}`, g m\ :sup:`-2`) is generated from the quantity of litterfall on that day (see Phenology chapter for details). The amount of N in the litter pool (:math:`N_{fallingleaf}`, g m\ :sup:`-2`) is calculated as the total leaf N multiplied by the fraction of the leaf pool passed to litter that timestep. - .. math:: +.. math:: + :label: N_fallingleaf_1 - N_{fallingleaf} = N_{leaf}.C_{fallingleaf}/C_{leaf} + N_{fallingleaf} = N_{leaf}.C_{fallingleaf}/C_{leaf} The carbon available at the beginning of the iterative retranslocation calculation is equal to the :math:`C_{avail}` input into FUN. - .. math:: +.. math:: + :label: C_avail,retrans,0 - C_{avail,retrans,0} = C_{avail} + C_{avail,retrans,0} = C_{avail} Free Retranslocation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Some part of the leaf Nitrogen pool is removed without the need for an C expenditure. This 'free' N uptake amount, (:math:`N_{retrans,free}`, gN m\ :sup:`-2`) is calculated as - .. math:: +.. math:: + :label: N_retrans,free - N_{retrans,free} = max(N_{fallingleaf} - (C_{fallingleaf}/CN_{litter,min} ),0.0) + N_{retrans,free} = max(N_{fallingleaf} - (C_{fallingleaf}/CN_{litter,min} ),0.0) where :math:`CN_{litter,min}` is the minimum C:N ratio of the falling litter (currently set to 1.5 x the target C:N ratio). The new :math:`N_{fallingleaf}` (gN m\ :sup:`-2`) is then determined as - .. math:: +.. math:: + :label: N_fallingleaf_2 - N_{fallingleaf} = N_{fallingleaf} - N_{retrans,free} + N_{fallingleaf} = N_{fallingleaf} - N_{retrans,free} and the new litter C:N ratio as - .. math:: +.. math:: + :label: CN_fallingleaf - CN_{fallingleaf}=C_{fallingleaf}/N_{fallingleaf} + CN_{fallingleaf}=C_{fallingleaf}/N_{fallingleaf} Paid-for Retranslocation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -158,139 +207,166 @@ The remaining calculations conduct an iterative calculation to determine the deg First we calculate the cost of extraction (:math:`cost_{retrans}`, gC/gN) for the current leaf C:N ratio as - .. math:: +.. math:: + :label: cost_retrans + + cost_{retrans}= k_{retrans} / (1/CN_{fallingleaf})^{1.3} - cost_{retrans}= k_{retrans} / (1/CN_{fallingleaf})^{1.3} +where :math:`k_{retrans}` is a parameter controlling the overall cost of resorption, which also increases exponentially as the C:N ratio increases. -where :math:`k_{retrans}` is a parameter controlling the overall cost of resorption, which also increases exponentially as the C:N ratio increases +Next, we calculate the amount of C needed to be spent to increase the falling leaf C:N ratio by 1.0 in this iteration +:math:`i` (:math:`C_{retrans,spent,i}`, gC m\ :sup:`-2`) as: -Next, we calculate the amount of C needed to be spent to increase the falling leaf C:N ratio by 1.0 in this iteration :math:`i` (:math:`C_{retrans_spent,i}`, gC m\ :sup:`-2`) as: - .. math:: +.. math:: + :label: C_retrans,spent,i_1 - C_{retrans,spent,i} = cost_{retrans}.(N_{fallingleaf} - C_{fallingleaf}/ + C_{retrans,spent,i} = cost_{retrans}.(N_{fallingleaf} - C_{fallingleaf}/ (CN_{fallingleaf} + 1.0)) (wherein the retranslocation cost is assumed to not change over the increment of 1.0 in C:N ratio). Next, we calculate whether this is larger than the remaining C available to spend. - .. math:: +.. math:: + :label: C_retrans,spent,i_2 - C_{retrans,spent,i} = min(C_{retrans,spent,i}, C_{avail,retrans,i}) + C_{retrans,spent,i} = min(C_{retrans,spent,i}, C_{avail,retrans,i}) -The amount of N retranslocated from the leaf in this iteration (:math:`N_{retrans_paid,i}`, gN m\ :sup:`-2`) is calculated, checking that it does not fall below zero: +The amount of N retranslocated from the leaf in this iteration (:math:`N_{retrans,paid,i}`, gN m\ :sup:`-2`) is calculated, checking that it does not fall below zero: - .. math:: +.. math:: + :label: N_retrans,paid,i - N_{retrans,paid,i} = min(N_{fallingleaf},C_{retrans,spent,i} / cost_{retrans}) + N_{retrans,paid,i} = min(N_{fallingleaf},C_{retrans,spent,i} / cost_{retrans}) The next step calculates the growth C which is accounted for by this amount of N extraction in this iteration (:math:`C_{retrans,accounted,i}`). This is calculated using the current plant C:N ratio, and also for the additional C which will need to be spent on growth respiration to build this amount of new tissue. - .. math:: +.. math:: + :label: C_retrans,accouned,i - C_{retrans,accounted,i} = N_{retrans,paid,i} . CN_{plant} . (1.0 + gr_{frac}) + C_{retrans,accounted,i} = N_{retrans,paid,i} . CN_{plant} . (1.0 + gr_{frac}) Then the falling leaf N is updated: - .. math:: +.. math:: + :label: N_fallingleaf_3 - N_{fallingleaf} = N_{fallingleaf} - N_{ret,i} + N_{fallingleaf} = N_{fallingleaf} - N_{ret,i} -and the :math:`CN_{fallingleaf}` and cost_{retrans} are updated. The amount of available carbon that is either unspent on N acquisition nor accounted for by N uptake is updated: +and the :math:`CN_{fallingleaf}` and :math:`cost_{retrans}` are updated. The amount of available carbon that is either unspent on N acquisition nor accounted for by N uptake is updated: - .. math:: +.. math:: + :label: C_avail,retrans,i+1 - C_{avail,retrans,i+1} = C_{avail,retrans,i} - C_{retrans,spent,i} - C_{retrans,accounted,i} + C_{avail,retrans,i+1} = C_{avail,retrans,i} - C_{retrans,spent,i} - C_{retrans,accounted,i} Outputs of Retranslocation algorithm. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The final output of the retranslocation calculation are the retranslocated N (:math:`N_{retrans}`, gN m\ :sup:`-2`), C spent on retranslocation (:math:`C_{retrans_paid}`, gC m\ :sup:`-2`), and C accounted for by retranslocation (:math:`C_{retrans_accounted}`, gC m\ :sup:`-2`). +The final output of the retranslocation calculation are the retranslocated N (:math:`N_{retrans}`, gN m\ :sup:`-2`), C spent on retranslocation (:math:`C_{retrans,paid}`, gC m\ :sup:`-2`), and C accounted for by retranslocation (:math:`C_{retrans,accounted}`, gC m\ :sup:`-2`). -For paid-for uptake, we accumulate the total carbon spent on retranslocation (:math:`C_{spent_retrans}`), +For paid-for uptake, we accumulate the total carbon spent on retranslocation (:math:`C_{spent,retrans}`), - .. math:: +.. math:: + :label: C_retrans,spent - C_{retrans,spent} = \sum{C_{retrans,i}} + C_{retrans,spent} = \sum{C_{retrans,i}} The total N acquired from retranslocation is - .. math:: +.. math:: + :label: N_retrans - N_{retrans} = N_{retrans,paid}+N_{retrans,free} + N_{retrans} = N_{retrans,paid}+N_{retrans,free} where N acquired by paid-for retranslocation is - .. math:: +.. math:: + :label: N_retrans,paid - N_{retrans,paid} = \sum{N_{retrans,paid,i}} + N_{retrans,paid} = \sum{N_{retrans,paid,i}} -The total carbon accounted for by retranslocation is the sum of the C accounted for by paid-for N uptake (:math:`N_{retrans_paid}`) and by free N uptake (:math:`N_{retrans_free}`). +The total carbon accounted for by retranslocation is the sum of the C accounted for by paid-for N uptake (:math:`N_{retrans,paid}`) and by free N uptake (:math:`N_{retrans,free}`). - .. math:: +.. math:: + :label: C_retrans,accounted - C_{retrans,accounted} = \sum{C_{retrans,accounted,i}}+N_{retrans,free}.CN_{plant} . (1.0 + gr_{frac}) + C_{retrans,accounted} = \sum{C_{retrans,accounted,i}}+N_{retrans,free}.CN_{plant} . (1.0 + gr_{frac}) The total available carbon in FUN to spend on fixation and active uptake (:math:`C_{tospend}`, gC m\ :sup:`-2`) is calculated as the carbon available minus that account for by retranslocation: - .. math:: +.. math:: + :label: C_tospend - C_{tospend} = C_{avail} - C_{retrans,accounted} + C_{tospend} = C_{avail} - C_{retrans,accounted} Carbon expenditure on fixation and active uptake. -------------------------------------------------------- At each model timestep, the overall cost of N uptake is calculated (see below) in terms of C:N ratios. The available carbon (:math:`C_{avail}`, g m\ :sup:`-2` s\ :sup:`-1`) is then allocated to two alternative outcomes, payment for N uptake, or conservation for growth. For each carbon conserved for growth, a corresponding quantity of N must be made available. In the case where the plant target C:N ratio is fixed, the partitioning between carbon for growth (:math:`C_{growth}`) and carbon for N uptake (:math:`C_{nuptake}`) is calculated by solving a system of simultaneous equations. First, the carbon available must equal the carbon spent on N uptake plus that saved for growth. - .. math:: +.. math:: + :label: C_avail_2 C_{growth}+C_{nuptake}=C_{avail} Second, the nitrogen acquired from expenditure of N (left hand side of term below) must equal the N that is required to match the growth carbon (right hand side of term below). - .. math:: +.. math:: + :label: C_nuptake_over_N_cost C_{nuptake}/N_{cost} =C_{growth}/CN_{target} The solution to these two equated terms can be used to estimate the ideal :math:`C_{nuptake}` as follows, - .. math:: +.. math:: + :label: C_nuptake_1 + C_{nuptake} =C_{tospend}/ ( (1.0+f_{gr}*(CN_{target} / N_{cost}) + 1) . and the other C and N fluxes can be determined following the logic above. Modifications to allow variation in C:N ratios -------------------------------------------------------- -The original FUN model as developed by :ref:`Fisher et al. (2010)` and :ref:`Brzostek et al. (2014)` assumes a fixed plant tissue C:N ratio. This means that in the case where N is especially limiting, all excess carbon will be utilized in an attempt to take up more Nitrogen. It has been repeatedly observed, however, that in these circumstances in real life, plants have some flexibility in the C:N stoichiometry of their tissues, and therefore, this assumption may not be realistic. However, the degree to which the C:N ratio varies with N availability is poorly documented, and existing global nitrogen models use a variety of heuristic methods by which to incorporate changing C:N ratios (Zaehle and Friend 2010; Ghimire et al. 2016). This algorithm exists as a placeholder to allow variable C:N ratios to occur, and to allow exploration of how much the parameters controlling their flexibility has on model outcomes. Incorporation of emerging understanding of the controls on tissue stoichiometry should ultimately replace this scheme. +The original FUN model as developed by :ref:`Fisher et al. (2010)` and :ref:`Brzostek et al. (2014)` assumes a fixed plant tissue C:N ratio. This means that in the case where N is especially limiting, all excess carbon will be utilized in an attempt to take up more nitrogen. It has been repeatedly observed, however, that in these circumstances in real life, plants have some flexibility in the C:N stoichiometry of their tissues, and therefore, this assumption may not be realistic. However, the degree to which the C:N ratio varies with N availability is poorly documented, and existing global nitrogen models use a variety of heuristic methods by which to incorporate changing C:N ratios (:ref:`Zaehle and Friend 2010`; :ref:`Ghimire et al. 2016`). This algorithm exists as a placeholder to allow variable C:N ratios to occur, and to allow exploration of how much the parameters controlling their flexibility has on model outcomes. Incorporation of emerging understanding of the controls on tissue stoichiometry should ultimately replace this scheme. -Thus, in CLM5, we introduce the capacity for tissue C:N ratios to be prognostic, rather than static. Overall N and C availability (:math:`N_{uptake}` and :math:`C_{growth}`) and hence tissue C:N ratios, are both determined by FUN. Allocation to individual tissues is discussed in the allocation chapter +Thus, in CLM5, we introduce the capacity for tissue C:N ratios to be prognostic, rather than static. Overall N and C availability (:math:`N_{uptake}` and :math:`C_{growth}`) and hence tissue C:N ratios, are both determined by FUN. Allocation to individual tissues is discussed in the allocation chapter. CLM5 introduced an algorithm which adjusts the C expenditure on uptake to allow varying tissue C:N ratios. Increasing C spent on uptake will directly reduce the C:N ratio, and reducing C spent on uptake (retaining more for tissue growth) will increase it. C spent on uptake is impacted by both the N cost in the environment, and the existing tissue C:N ratio of the plant. The output of this algorithm is :math:`\gamma_{FUN}`, the fraction of the ideal :math:`C_{nuptake}` calculated from the FUN equation above -Here we introduce an algorithm which adjusts the C expenditure on uptake to allow varying tissue C:N ratios. Increasing C spent on uptake will directly reduce the C:N ratio, and reducing C spent on uptake (retaining more for tissue growth) will increase it. C spent on uptake is impacted by both the N cost in the environment, and the existing tissue C:N ratio of the plant. The output of this algorithm is :math:`\gamma_{FUN}`, the fraction of the ideal :math:`C_{nuptake}` calculated from the FUN equation above +.. math:: + :label: C_nuptake_2 - .. math:: C_{nuptake} = C_{nuptake}.\gamma_{FUN} +Subsequent sensitivity tests found relatively low flexibility in the target C:N ratios resulting from this approach (:ref:`Fisher et al. 2019`). Thus, :ref:`Hauser et al. (2023)` introduced an additional function to force time evolving foliar C:N ratios to vary with atmospheric CO\ :sub:`2` concentrations as shown in Eq. :eq:`time-evolv target leaf CN` (section :numref:`rst_CN Pools`). + Response of C expenditure to Nitrogen uptake cost ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The environmental cost of Nitrogen (:math:`N_{cost,tot}`) is used to determine :math:`\gamma_{FUN}`. - .. math:: +.. math:: + :label: gamma_FUN_1 + \gamma_{FUN} = max(0.0,1.0 - (N_{cost,tot}-a_{cnflex})/b_{cnflex}) where :math:`a_{cnflex}` and :math:`b_{cnflex}` are parameters fitted to give flexible C:N ranges over the operating range of N costs of the model. Calibration of these parameters should be subject to future testing in idealized experimental settings; they are here intended as a placeholder to allow some flexible stoichiometry, in the absence of adequate understanding of this process. Here :math:`a_{cnflex}` operates as the :math:`N_{cost,tot}` above which there is a modification in the C expenditure (to allow higher C:N ratios), and :math:`b_{cnflex}` is the scalar which determines how much the C expenditure is modified for a given discrepancy between :math:`a_{cnflex}` and the actual cost of uptake. Response of C expenditure to plant C:N ratios ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -We first calculate a :math:`\delta_{CN}`, which is the difference between the target C:N (:math:`target_{CN}`) a model parameter, and the existing C:N ratio (:math:`CN_{plant}`) +We first calculate a :math:`\delta_{CN}`, which is the difference between the target C:N (:math:`CN_{target}`) a model parameter (:numref:`Table Allocation and CN ratio parameters`), and the existing C:N ratio (:math:`CN_{plant}`) - .. math:: +.. math:: + :label: CN_plant - CN_{plant} = \frac{C_{leaf} + C_{leaf,storage}}{N_{leaf} + N_{leaf,storage})} + CN_{plant} = \frac{C_{leaf} + C_{leaf,storage}}{N_{leaf} + N_{leaf,storage})} and - .. math:: - \delta_{CN} = CN_{plant} - target_{CN} + +.. math:: + :label: delta_CN + + \delta_{CN} = CN_{plant} - CN_{target} We then increase :math:`\gamma_{FUN}` to account for situations where (even if N is expensive) plant C:N ratios have increased too far from the target. Where :math:`\delta_{CN}` is negative, we reduce C spent on N uptake and retain more C for growth - .. math:: +.. math:: + :label: gamma_FUN_2 \gamma_{FUN} = \left\{\begin{array}{lr} @@ -300,7 +376,9 @@ We then increase :math:`\gamma_{FUN}` to account for situations where (even if We then restrict the degree to which C expenditure can be reduced (to prevent unrealistically high C:N ratios) as - .. math:: +.. math:: + :label: gamma_FUN_3 + \gamma_{FUN} = max(min(1.0,\gamma_{FUN}),0.5) Calculation of N uptake streams from active uptake and fixation @@ -308,58 +386,68 @@ Calculation of N uptake streams from active uptake and fixation Once the final :math:`C_{nuptake}` is known, the fluxes of C to the individual pools can be derived as - .. math:: +.. math:: + :label: C_nuptake,x C_{nuptake,x} = C_{frac,x}.C_{nuptake} - .. math:: +.. math:: + :label: N_nuptake,x N_{uptake,x} = \frac{C_{nuptake}}{N_{cost}} Following this, we determine whether the extraction estimates exceed the pool size for each source of N. Where :math:`N_{active,no3} + N_{nonmyc,no3} > N_{avail,no3}`, we calculate the unmet uptake, :math:`N_{unmet,no3}` - .. math:: +.. math:: + :label: N_unmet,no3 N_{unmet,no3} = N_{active,no3} + N_{nonmyc,no3} - N_{avail,no3} then modify both fluxes to account - .. math:: +.. math:: + :label: N_active,no3 N_{active,no3} = N_{active,no3} + N_{unmet,no3}.\frac{N_{active,no3}}{N_{active,no3}+N_{nonmyc,no3}} - .. math:: +.. math:: + :label: N_nonmyc,no3 N_{nonmyc,no3} = N_{nonmyc,no3} + N_{unmet,no3}.\frac{N_{nonmyc,no3}}{N_{active,no3}+N_{nonmyc,no3}} and similarly, for NH4, where :math:`N_{active,nh4} + N_{nonmyc,nh4} > N_{avail,nh4}`, we calculate the unmet uptake, :math:`N_{unmet,no3}` - .. math:: +.. math:: + :label: N_unmet,nh4 N_{unmet,nh4} = N_{active,nh4} + N_{nonmyc,nh4} - N_{avail,nh4} then modify both fluxes to account - .. math:: +.. math:: + :label: N_active,nh4 N_{active,nh4} = N_{active,nh4} + N_{unmet,nh4}.\frac{N_{active,nh4}}{N_{active,nh4}+N_{nonmyc,nh4}} - .. math:: +.. math:: + :label: N_nonmyc,nh4 N_{nonmyc,nh4} = N_{nonmyc,nh4} + N_{unmet,nh4}.\frac{N_{nonmyc,nh4}}{N_{active,nh4}+N_{nonmyc,nh4}} and then update the C spent to account for hte new lower N acquisition in that layer/pool. - .. math:: +.. math:: + :label: C_active_and_nonmyc C_{active,nh4} = N_{active,nh4}.N_{cost,active,nh4}\\ C_{active,no3} = N_{active,no3}.N_{cost,active,no3}\\ - C_{nonmyc,no3} = N_{nonmyc,no3}.N_{cost,nonmyc,no3}\\ + C_{nonmyc,nh4} = N_{nonmyc,nh4}.N_{cost,nonmyc,nh4}\\ C_{nonmyc,no3} = N_{nonmyc,no3}.N_{cost,nonmyc,no3}\\ Following this, we determine how much carbon is accounted for for each soil layer. - .. math:: +.. math:: + :label: C_accounted,x,j C_{accounted,x,j} = C_{spent,j,x} - (N_{acquired,j,x}.CN_{plant}.(1.0+ gr_{frac})) diff --git a/doc/source/tech_note/FUN/image1.png b/doc/source/tech_note/FUN/image1.png new file mode 100644 index 0000000000..7851a7a0a8 --- /dev/null +++ b/doc/source/tech_note/FUN/image1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:824fd908c8bdc9cd99ee4a2510d3ccb05d70280c7bad4728dd0eee5e43365fc3 +size 247878 diff --git a/doc/source/tech_note/Fire/CLM50_Tech_Note_Fire.rst b/doc/source/tech_note/Fire/CLM50_Tech_Note_Fire.rst index 0483567ff5..7ee974fc35 100644 --- a/doc/source/tech_note/Fire/CLM50_Tech_Note_Fire.rst +++ b/doc/source/tech_note/Fire/CLM50_Tech_Note_Fire.rst @@ -3,7 +3,7 @@ Fire ======== -The fire parameterization in CLM contains four components: non-peat fires outside cropland and tropical closed forests, agricultural fires in cropland, deforestation fires in the tropical closed forests, and peat fires (see :ref:`Li et al. 2012a `, :ref:`Li et al. 2012b `, :ref:`Li et al. 2013 `, :ref:`Li and Lawrence 2017 ` for details). In this fire parameterization, burned area is affected by climate and weather conditions, vegetation composition and structure, and human activities. After burned area is calculated, we estimate the fire impact, including biomass and peat burning, fire-induced vegetation mortality, adjustment of the carbon and nitrogen (C/N) pools, and fire emissions. +The fire parameterization in CLM contains four components: non-peat fires outside cropland and tropical closed forests, agricultural fires in cropland, deforestation fires in the tropical closed forests, and peat fires (see :ref:`Li et al. 2012a `, :ref:`Li et al. 2012b `, :ref:`Li et al. 2013 `, :ref:`Li and Lawrence 2017 `, :ref:`Li et al. 2024b ` for details). In this fire parameterization, burned area is affected by climate and weather conditions, vegetation composition and structure, and human activities. After burned area is calculated, we estimate the fire impact, including biomass and peat burning, fire-induced vegetation mortality, adjustment of the carbon and nitrogen (C/N) pools, and fire emissions. .. _Non-peat fires outside cropland and tropical closed forest: @@ -29,9 +29,9 @@ Fire counts :math:`N_{f}` is taken as .. math:: :label: 23.2 - N_{f} = N_{i} f_{b} f_{m} f_{se,o} + N_{f} = N_{i} f_{b} f_{m} f_{se,o} f_{topo} -where :math:`N_{i}` ( count s\ :sup:`-1`) is the number of ignition sources due to natural causes and human activities; :math:`f_{b}` and :math:`f_{m}` (fractions) represent the availability and combustibility of fuel, respectively; :math:`f_{se,o}` is the fraction of anthropogenic and natural fires unsuppressed by humans and related to the socioeconomic conditions. +where :math:`N_{i}` ( count s\ :sup:`-1`) is the number of ignition sources due to natural causes and human activities; :math:`f_{b}` and :math:`f_{m}` (fractions) represent the availability and combustibility of fuel, respectively; :math:`f_{se,o}` is the fraction of anthropogenic and natural fires unsuppressed by humans and related to the socioeconomic conditions; :math:`f_{topo}` represents the influence of topography on fires. :math:`N_{i}` (count s\ :sup:`-1`) is given as @@ -66,7 +66,7 @@ Fuel availability :math:`f_{b}` is given as \begin{array}{cc} {} & {} \end{array}\begin{array}{c} {B_{ag} B_{up} } \end{array}\right\} \ , -where :math:`B_{ag}` (g C m\ :sup:`-2`) is the biomass of combined leaf, stem, litter, and woody debris pools; :math:`B_{low}` = 105 g C m :sup:`-2` is the lower fuel threshold below which fire does not occur; :math:`B_{up}` = 1050 g C m\ :sup:`-2` is the upper fuel threshold above which fire occurrence is not limited by fuel availability. +where :math:`B_{ag}` (g C m\ :sup:`-2`) is the biomass of combined leaf, stem, litter, and woody debris pools; :math:`B_{low}` = 75 g C m :sup:`-2` is the lower fuel threshold below which fire does not occur; :math:`B_{up}` = 825 g C m\ :sup:`-2` is the upper fuel threshold above which fire occurrence is not limited by fuel availability. Fuel combustibility :math:`f_{m}` is estimated by @@ -75,24 +75,24 @@ Fuel combustibility :math:`f_{m}` is estimated by f_{m} = {f_{RH} f_{\beta}}, \qquad T_{17cm} > T_{f} -where :math:`f_{RH}` and :math:`f_{\beta }` represent the dependence of fuel combustibility on relative humidity :math:`RH` (%) and root-zone soil moisture limitation :math:`\beta` (fraction); :math:`T_{17cm}` is the temperature of the top 17 cm of soil (K) and :math:`T_{f}` is the freezing temperature. :math:`f_{RH}` is a weighted average of real time :math:`RH` (:math:`RH_{0}`) and 30-day running mean :math:`RH` (:math:`RH_{30d}`): +where :math:`f_{RH}` and :math:`f_{\beta }` represent the dependence of fuel combustibility on relative humidity :math:`RH` (%) and root-zone soil wetness :math:`\beta` (fraction); :math:`T_{17cm}` is the temperature of the top 17 cm of soil (K) and :math:`T_{f}` is the freezing temperature. :math:`f_{RH}` is a weighted average of real time :math:`RH` (:math:`RH_{0}`) and 30-day running mean :math:`RH` (:math:`RH_{30d}`): .. math:: :label: 23.8 - f_{RH} = (1-w) l_{RH_{0}} + wl_{RH_{30d}} + f_{RH} = [(1-w) l_{RH_{0}} + wl_{RH_{30d}}]^{0.75} -where weight :math:`w=\max [0,\min (1,\frac{B_{ag}-2500}{2500})]`, :math:`l_{{RH}_{0}}=1-\max [0,\min (1,\frac{RH_{0}-30}{80-30})]`, and :math:`l_{{RH}_{30d}}=1-\max [0.75,\min (1,\frac{RH_{30d}}{90})]`. :math:`f_{\beta}` is given by +where weight :math:`w=\max [0,\min (1,\frac{B_{ag}-2500}{2500})]`, :math:`l_{{RH}_{0}}=1-\max [0,\min (1,\frac{RH_{0}-30}{85-30})]`, and :math:`l_{{RH}_{30d}}=1-\max [0.6,\min (1,\frac{RH_{30d}}{95})]`. :math:`f_{\beta}` is given by .. math:: :label: 23.9 f_{\beta } =\left\{\begin{array}{cccc} - {1} & {} & {} & {\beta\le \beta_{low} } \\ {\frac{\beta_{up} -\beta}{\beta_{up} -\beta_{low} } } & {} & {} & {\beta_{low} <\beta<\beta_{up} } \\ + {1} & {} & {} & {\beta\le \beta_{low} } \\ ({\frac{\beta_{up} -\beta}{\beta_{up} -\beta_{low} } })^{0.25} & {} & {} & {\beta_{low} <\beta<\beta_{up} } \\ {0} & {} & {} & {\beta\ge \beta_{up} } - \end{array}\right\} \ , + \end{array}\right. -where :math:`\beta _{low}` \ =0.85 and :math:`\beta _{up}` \ =0.98 are the lower and upper thresholds, respectively. +where :math:`\beta _{low}` \ and :math:`\beta _{up}` \ are the PFT-dependent lower and upper thresholds (:numref:`Table PFT-specific fire parameters`). For scarcely populated regions (:math:`D_{p} \le 0.1` person km :sup:`-2`), we assume that anthropogenic suppression on fire occurrence is negligible, i.e., :math:`f_{se,o} =1.0`. In regions of :math:`D_{p} >0.1` person km\ :sup:`-2`, we parameterize the fraction of anthropogenic and natural fires unsuppressed by human activities as @@ -128,26 +128,29 @@ which captures 73% of the observed MODIS fire counts with variable GDP in region to reproduce the relationship between MODIS fire counts and GDP. -.. _Average spread area of a fire: - -Average spread area of a fire -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Fire fighting capacity depends on socioeconomic conditions and affects fire spread area. Due to a lack of observations, we consider the socioeconomic impact on the average burned area rather than separately on fire spread rate and fire duration: +The influence of topography on fires: .. math:: :label: 23.14 - a=a^{*} F_{se} + f_{topo} =\left\{\begin{array}{cc} + {0.004} & {elevation>2500m} \\ + {1} & {else} + \end{array}\right. -where :math:`a^{*}` is the average burned area of a fire without anthropogenic suppression and :math:`F_{se}` is the socioeconomic effect on fire spread area. +This indicates reduced burnability above 2500 m. It can be removed if CLM accounts in the future for the intense light exposure of Arctic C\ :sub:`3` grasses on plateaus, leading to greater carbon allocation to fine roots than to leaves and to reduced infiltration. + +.. _Average spread area of a fire: + +Average spread area of a fire +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Average burned area of a fire without anthropogenic suppression is assumed elliptical in shape with the wind direction along the major axis and the point of ignition at one of the foci. According to the area formula for an ellipse, average burned area of a fire can be represented as: +Average burned area of a fire is assumed elliptical in shape with the wind direction along the major axis and the point of ignition at one of the foci. According to the area formula for an ellipse, average burned area of a fire can be represented as: .. math:: :label: 23.15 - a^{*} =\pi \frac{l}{2} \frac{w}{2} \times 10^{-6} =\frac{\pi u_{p}^{2} \tau ^{2} }{4L_{B} } (1+\frac{1}{H_{B} } )^{2} \times 10^{-6} + a =\pi \frac{l}{2} \frac{w}{2} \times 10^{-6} =\frac{\pi u_{p}^{2} \tau ^{2} }{4L_{B} } (1+\frac{1}{H_{B} } )^{2} \times 10^{-6} where :math:`u_{p}` (m s\ :sup:`-1`) is the fire spread rate in the downwind direction; :math:`\tau` (s) is average fire duration; :math:`L_{B}` and :math:`H_{B}` are length-to-breadth ratio and head-to-back ratio of the ellipse; 10 :sup:`-6` converts m :sup:`2` to km :sup:`2`. @@ -172,7 +175,7 @@ The fire spread rate in the downwind direction is represented as u_{p} =u_{\max } C_{m} g(W) -(:ref:`Arora and Boer, 2005`), where :math:`u_{\max }` (m s\ :sup:`-1`) is the PFT-dependent average maximum fire spread rate in natural vegetation regions; :math:`C_{m} =\sqrt{f_{m}}` and :math:`g(W)` represent the dependence of :math:`u_{p}` on fuel wetness and wind speed :math:`W`, respectively. :math:`u_{\max }` is set to 0.33 m s :sup:`-1`\ for grass PFTs, 0.28 m s :sup:`-1` for shrub PFTs, 0.26 m s\ :sup:`-1` for needleleaf tree PFTs, and 0.25 m s\ :sup:`-1` for other tree PFTs. :math:`g(W)` is derived from the mathematical properties of the ellipse and equation :eq:`23.16` and :eq:`23.17`. +(:ref:`Arora and Boer, 2005`), where :math:`u_{\max }` (m s\ :sup:`-1`) is the PFT-dependent average maximum fire spread rate in natural vegetation regions (:numref:`Table PFT-specific fire parameters`); :math:`C_{m} =\sqrt{f_{m}}` and :math:`g(W)` represent the dependence of :math:`u_{p}` on fuel wetness and wind speed :math:`W`, respectively. :math:`g(W)` is derived from the mathematical properties of the ellipse and equation :eq:`23.16` and :eq:`23.17` .. math:: :label: 23.19 @@ -186,16 +189,24 @@ Since g(\ *W*)=1.0, and \ :math:`L_{B}` and :math:`H_{B}` are at their maxima \ g(0)=\frac{1+\frac{1}{H_{B} ^{\max } } }{2L_{B} ^{\max } } =0.05. -In the absence of globally gridded data on barriers to fire (e.g. rivers, lakes, roads, firebreaks) and human fire-fighting efforts, average fire duration is simply assumed equal to 1 which is the observed 2001–2004 mean persistence of most fires in the world (:ref:`Giglio et al. 2006 `). +Fire duration is affected by fire fighting capacity which depends on socioeconomic condition and by the natural vegetation fuel continuity: -As with the socioeconomic influence on fire occurrence, we assume that the socioeconomic influence on fire spreading is negligible in regions of :math:`D_{p} \le 0.1` person km\ :sup:`-2`, i.e., :math:`F_{se} = 1.0`. In regions of :math:`D_{p} >0.1` person km\ :sup:`-2`, we parameterize such socioeconomic influence as: + +.. math:: + :label: 23.201 + + \tau=\tau*F_{se}F_{c} + +where :math:`\tau*` represents the fire duration under conditions without anthropogenic suppression and landscape fragmentation, setting to 5 days for all natural vegetation PFTs; :math:`F_{se}` is the socioeconomic effect on fire spread area; :math:`F_{c}` is the fuel continuity factor. + +As with the socioeconomic influence on fire occurrence, we assume that the socioeconomic influence on fire duration is negligible in regions of :math:`D_{p} \le 0.1` person km\ :sup:`-2`, i.e., :math:`F_{se} = 1.0`. In regions of :math:`D_{p} >0.1` person km\ :sup:`-2`, we parameterize such socioeconomic influence as: .. math:: :label: 23.21 F_{se} =F_{d} F_{e} -where :math:`{F}_{d}` and :math:`{F}_{e}` are effects of the demographic and economic conditions on the average spread area of a fire, and are identified by maximizing the explained variability of the GFED3 burned area fraction with both socioeconomic indices in grid cells with various dominant vegetation types. For shrub and grass PFTs, the demographic impact factor is +where :math:`{F}_{d}` and :math:`{F}_{e}` are effects of the demographic and economic conditions. For shrub and grass PFTs, the demographic impact factor is .. math:: :label: 23.22 @@ -228,6 +239,16 @@ and Equations :eq:`23.22` - :eq:`23.25` reflect that more developed and more densely populated regions have a higher fire fighting capability. +The continuity factor is the fractional coverage (0 to 1) of natural vegetation (not including bare soil) in the grid cell (:math:`f_{natveg}`) + +.. math:: + :label: 23.251 + + F_{c} =f_{natveg} =1 - f_{urban} - f_{lake} - f_{cropland} - f_{baresoil} + +where :math:`f_{urban}`, :math:`f_{lake}`, :math:`f_{cropland}`, and :math:`f_{baresoil}` are factional coverage of urban, lake, cropland, and bare soil. + + .. _Fire impact: Fire impact @@ -240,7 +261,7 @@ In post-fire regions, we calculate PFT-level fire carbon emissions from biomass \phi _{j} =A_{b,j} \mathbf{C}_{j} \bullet \mathbf{CC}_{j} -where :math:`A_{b,j}` (km\ :sup:`2` \s\ :sup:`-1`) is burned area for the :math:`j`\ th PFT; **C**\ :sub:`j` =(:math:`C_{leaf}`, :math:`C_{stem}`, :math:`C_{root}`, :math:`C_{ts}`) is a vector with carbon density (g C km :sup:`-2`) for leaf, stem (live and dead stem), root (fine, live coarse and dead coarse root), and transfer and storage carbon pools as elements; :math:`\mathbf{CC}_{j}` = (:math:`\mathbf{CC}_{leaf}`, :math:`\mathbf{CC}_{stem}`, :math:`\mathbf{CC}_{root}`, :math:`\mathbf{CC}_{ts}`) is the corresponding combustion completeness factor vector (:numref:`Table PFT-specific combustion completeness and fire mortality factors`). Moreover, we assume that 50% and 28% of column-level litter and coarse woody debris are burned and the corresponding carbon is transferred to atmosphere. +where :math:`A_{b,j}` (km\ :sup:`2` \s\ :sup:`-1`) is burned area for the :math:`j`\ th PFT; **C**\ :sub:`j` =(:math:`C_{leaf}`, :math:`C_{stem}`, :math:`C_{root}`, :math:`C_{ts}`) is a vector with carbon density (g C km :sup:`-2`) for leaf, stem (live and dead stem), root (fine, live coarse and dead coarse root), and transfer and storage carbon pools as elements; :math:`\mathbf{CC}_{j}` = (:math:`\mathbf{CC}_{leaf}`, :math:`\mathbf{CC}_{stem}`, :math:`\mathbf{CC}_{root}`, :math:`\mathbf{CC}_{ts}`) is the corresponding combustion completeness factor vector (:numref:`Table PFT-specific fire parameters`). Moreover, we assume that 50% and 28% of column-level litter and coarse woody debris are burned and the corresponding carbon is transferred to atmosphere. Tissue mortality due to fire leads to carbon transfers in two ways. First, carbon from uncombusted leaf, live stem, dead stem, root, and transfer and storage pools :math:`\mathbf{C^{'} _{j1}} ={(C_{{leaf}} (1-CC_{{leaf}} ),C_{{livestem}} (1-CC_{{stem}} ),C_{{deadstem}} (1-CC_{{stem}} ),C_{{root}} (1-CC_{{root}} ),C_{{ts}} (1-CC_{{ts}} ))}_{j}` (g C km\ :sup:`-2`) is transferred to litter as @@ -249,14 +270,14 @@ Tissue mortality due to fire leads to carbon transfers in two ways. First, carbo \Psi _{j1} =\frac{A_{b,j} }{f_{j} A_{g} } \mathbf{C^{'} _{j1}} \bullet M_{j1} -where :math:`M_{j1} =(M_{{leaf}},M_{{livestem,1}},M_{{deadstem}},M_{{root}},M_{{ts}} )_{j}` is the corresponding mortality factor vector (:numref:`Table PFT-specific combustion completeness and fire mortality factors`). Second, carbon from uncombusted live stems is transferred to dead stems as: +where :math:`M_{j1} =(M_{{leaf}},M_{{livestem,1}},M_{{deadstem}},M_{{root}},M_{{ts}} )_{j}` is the corresponding mortality factor vector (:numref:`Table PFT-specific fire parameters`). Second, carbon from uncombusted live stems is transferred to dead stems as: .. math:: :label: 23.28 \Psi _{j2} =\frac{A_{b,j} }{f_{j} A_{g} } C_{livestem} (1-CC_{stem} )M_{livestem,2} -where :math:`M_{livestem,2}` is the corresponding mortality factor (:numref:`Table PFT-specific combustion completeness and fire mortality factors`). +where :math:`M_{livestem,2}` is the corresponding mortality factor (:numref:`Table PFT-specific fire parameters`). Fire nitrogen emissions and nitrogen transfers due to fire-induced mortality are calculated the same way as for carbon, using the same values for combustion completeness and mortality factors. With CLM's dynamic vegetation option enabled, the number of tree PFT individuals killed by fire per km\ :sup:`2` (individual km\ :sup:`-2` s\ :sup:`-1`) is given by @@ -265,7 +286,7 @@ Fire nitrogen emissions and nitrogen transfers due to fire-induced mortality are P_{disturb,j} =\frac{A_{b,j} }{f_{j} A_{g} } P_{j} \xi _{j} -where :math:`P_{j}` (individual km\ :sup:`-2`) is the population density for the :math:`j` th tree PFT and :math:`\xi _{j}` is the whole-plant mortality factor (:numref:`Table PFT-specific combustion completeness and fire mortality factors`). +where :math:`P_{j}` (individual km\ :sup:`-2`) is the population density for the :math:`j` th tree PFT and :math:`\xi _{j}` is the whole-plant mortality factor (:numref:`Table PFT-specific fire parameters`). .. _Agricultural fires: @@ -279,7 +300,7 @@ The burned area of cropland (km\ :sup:`2` s\ :sup:`-1`) is taken as :math:`{A}_{ A_{b} =a_{1} f_{se} f_{t} f_{crop} A_{g} -where :math:`a_{1}` (s\ :sup:`-1`) is a constant; :math:`f_{se}` represents the socioeconomic effect on fires; :math:`f_{t}` determines the seasonality of agricultural fires; :math:`f_{crop}` is the fractional coverage of cropland. :math:`a_{1}` \ = 1.6x10\ :sup:`-4` \hr\ :sup:`-1`\ is estimated using an inverse method, by matching 1997-2004 simulations to the analysis of :ref:`van der Werf et al. (2010) ` that shows the 2001-2009 average contribution of cropland fires is 4.7% of the total global burned area. +where :math:`a_{1}` (s\ :sup:`-1`) is a constant; :math:`f_{se}` represents the socioeconomic effect on fires; :math:`f_{t}` determines the seasonality of agricultural fires; :math:`f_{crop}` is the fractional coverage of cropland. :math:`a_{1}` \ = 0.34 \hr\ :sup:`-1`\ is estimated using an inverse method, by matching simulated global agricultural burned area to the GFED5 (:ref:`Chen et al. 2023 `) cropland burned area of 82 Mha yr\ :sup:`-1` for 2002−2020. The socioeconomic factor :math:`f_{se}` is given as follows: @@ -293,18 +314,18 @@ Here .. math:: :label: 23.32 - f_{d} =0.04+0.96\times \exp [-\pi (\frac{D_{p} }{350} )^{0.5} ] + f_{d} =0.2+0.8\times \exp (-\pi \frac{D_{p} }{400} ) and .. math:: :label: 23.33 - f_{e} =0.01+0.99\times \exp (-\pi \frac{GDP}{10} ) + f_{e} =0.05+0.95\times \exp (-\pi \frac{GDP}{20} ) -are the effects of population density and GDP on burned area, derived in a similar way to equation :eq:`23.32` and :eq:`23.33`. :math:`f_{t}` is set to 1 at the first time step during the climatological peak month for agricultural fires (:ref:`van der Werf et al. 2010 `); :math:`{f}_{t}` is set to 0 otherwise. Peak month in this dataset correlates with the month after harvesting or the month before planting. In CLM we use this dataset the same way whether the CROP option is active or not, without regard to the CROP option's simulated planting and harvesting dates. +are the effects of population density and GDP on burned area, derived in a similar way to equation :eq:`23.32` and :eq:`23.33`. :math:`f_{t}` is set to 1 at the first time step of the climatological peak month for GFED5 agricultural burned area and during the post-harvest and pre-planting period. -In the post-fire region, fire impact is parameterized similar to section :numref:`Fire impact` but with combustion completeness factors and tissue mortality factors for crop PFTs (:numref:`Table PFT-specific combustion completeness and fire mortality factors`). +In the post-fire region, fire impact is parameterized similar to section :numref:`Fire impact` but with combustion completeness factors and tissue mortality factors for crop PFTs (:numref:`Table PFT-specific fire parameters`). .. _Deforestation fires: @@ -320,12 +341,12 @@ CLM focuses on deforestation fires in tropical closed forests. Tropical closed f where :math:`b` (s\ :sup:`-1`) is a global constant; :math:`f_{lu}` (fraction) represents the effect of decreasing fractional coverage of tree PFTs derived from land use data; :math:`f_{cli,d}` (fraction) represents the effect of climate conditions on the burned area. -Constants :math:`b` and :math:`{f}_{lu}` are calibrated based on observations and reanalysis datasets in the Amazon rainforest (tropical closed forests within 15.5 °S :math:`\text{-}` 10.5 °N, 30.5 ° W :math:`\text{-}` 91 ° W). :math:`b` = 0.033 d\ :sup:`-1` and :math:`f_{lu}` is defined as +Constants :math:`b` and :math:`{f}_{lu}` are calibrated based on observations and reanalysis datasets in the Amazon rainforest (tropical closed forests within 15.5 °S :math:`\text{-}` 10.5 °N, 30.5 ° W :math:`\text{-}` 91 ° W). :math:`b` = 0.03 d\ :sup:`-1` and :math:`f_{lu}` is defined as .. math:: :label: 23.35 - f_{lu} = \max (0.0005,0.19D-0.001) + f_{lu} = 0.67 \min (0.01,D) + 0.001 where :math:`D` (yr\ :sup:`-1`) is the annual loss of tree cover based on CLM land use and land cover change data. @@ -334,13 +355,9 @@ The effect of climate on deforestation fires is parameterized as: .. math:: :label: 23.36 - \begin{array}{ll} - f_{cli,d} \quad = & \quad \max \left[0,\min (1,\frac{b_{2} -P_{60d} }{b_{2} } )\right]^{0.5} \times \\ - & \quad \max \left[0,\min (1,\frac{b_{3} -P_{10d} }{b_{3} } )\right]^{0.5} \times \\ - & \quad \max \left[0,\min (1,\frac{0.25-P}{0.25} )\right] - \end{array} + f_{cli,d} = \max [0,\min (1,1- \frac{P_{30d} }{b_{1} })] \max [0,\min (1,1- \frac{P}{0.25 } )] -where :math:`P` (mm d :sup:`-1`) is instantaneous precipitation, while :math:`P_{60d}` (mm d\ :sup:`-1`) and :math:`P_{10d}` (mm d :sup:`-1`) are 60-day and 10-day running means of precipitation, respectively; :math:`b_{2}` (mm d :sup:`-1`) and :math:`b_{3}` (mm d :sup:`-1`) are the grid-cell dependent thresholds of :math:`P_{60d}` and :math:`P_{10d}`; 0.25 mm d :sup:`-1` is the maximum precipitation rate for drizzle. :ref:`Le Page et al. (2010) ` analyzed the relationship between large-scale deforestation fire counts and precipitation during 2003 :math:`\text{-}`\ 2006 in southern Amazonia where tropical evergreen trees (BET Tropical) are dominant. Figure 2 in :ref:`Le Page et al. (2010) ` showed that fires generally occurred if both :math:`P_{60d}` and :math:`P_{10d}` were less than about 4.0 mm d :sup:`-1`, and fires occurred more frequently in a drier environment. Based on the 30-yr (1985 to 2004) precipitation data in :ref:`Qian et al. (2006) `. The climatological precipitation of dry months (P < 4.0 mm d :sup:`-1`) in a year over tropical deciduous tree (BDT Tropical) dominated regions is 46% of that over BET Tropical dominated regions, so we set the PFT-dependent thresholds of :math:`P_{60d}` and :math:`P_{10d}` as 4.0 mm d :sup:`-1` for BET Tropical and 1.8 mm d :sup:`-1` (= 4.0 mm d :sup:`-1` :math:`\times` 46%) for BDT Tropical, and :math:`b`\ :sub:`2` and :math:`b`\ :sub:`3` are the average of thresholds of BET Tropical and BDT Tropical weighted bytheir coverage. +where :math:`P` (mm d :sup:`-1`) is instantaneous precipitation, while :math:`P_{30d}` (mm d\ :sup:`-1`) is 30-day running means of precipitation; :math:`b_{1}` is grid-cell dependent thresholds of :math:`P_{30d}`; 0.25 mm d :sup:`-1` is the maximum precipitation rate for drizzle. :math:`b_{1}` is the average of thresholds of BET Tropical (0.5 mm d :sup:`-1`) and BDT Tropical ( 3.0 mm d :sup:`-1`) by their fractional coverage, where thresholds are derived based on GFED5 burned area and dry-season CRUJRA climatological precipitation for BET to BDT dominant regions in the Amazon rainforests. The post-fire area due to deforestation is not limited to land-type conversion regions. In the tree-reduced region, the maximum fire carbon emissions are assumed to be 80% of the total conversion flux. According to the fraction of conversion flux for tropical trees in the tree-reduced region (60%) assigned by CLM4-CN, to reach the maximum fire carbon emissions in a conversion region requires burning this region about twice when we set PFT-dependent combustion completeness factors to about 0.3 for stem [the mean of 0.2\ :math:`{-}`\ 0.4 used in :ref:`van der Werf et al. (2010) `. Therefore, when the burned area calculated from equation :eq:`23.36` is no more than twice the tree-reduced area, we assume no escaped fires outside the land-type conversion region, and the fire-related fraction of the total conversion flux is estimated as :math:`\frac{A_{b} /A_{g} }{2D}`. Otherwise, 80% of the total conversion flux is assumed to be fire carbon emissions, and the biomass combustion and vegetation mortality outside the tree-reduced regions with an area fraction of :math:`\frac{A_{b} }{A_{g} } -2D` are set as in section :numref:`Fire impact`. @@ -356,14 +373,14 @@ The burned area due to peat fires is given as :math:`{A}_{b}`: A_{b} = c \ f_{cli,p} f_{peat} A_{g} -where :math:`c` (s\ :sup:`-1`) is a constant; :math:`f_{cli,p}` represents the effect of climate on the burned area; and :math:`f_{peat}` is the fractional coverage of peatland in the grid cell. :math:`c` = 0.17 :math:`\times` 10 :sup:`-3` hr\ :sup:`-1` for tropical peat fires and :math:`c` = 0.9 :math:`\times` 10 :sup:`-5` hr :sup:`-1` for boreal peat fires are derived using an inverse method, by matching simulations to earlier studies: about 2.4 Mha peatland was burned over Indonesia in 1997 (:ref:`Page et al. 2002 `) and the average burned area of peat fires in Western Canada was 0.2 Mha yr :sup:`-1` for 1980-1999 (:ref:`Turetsky et al. 2004 `). +where :math:`c` (s\ :sup:`-1`) is a constant; :math:`f_{cli,p}` represents the effect of climate on the burned area; and :math:`f_{peat}` is the fractional coverage of peatland in the grid cell. :math:`c` = 0.75 :math:`\times` 10 :sup:`-4` hr\ :sup:`-1` for tropical peat fires and :math:`c` = 0.58 :math:`\times` 10 :sup:`-4` hr :sup:`-1` for boreal peat fires are derived using an inverse method, by matching simulations to earlier studies: about 0.5 Mha yr :sup:`-1` for Indonesia tropical peat fires based on GFED5 for 2002–2014 (:ref:`Chen et al., 2023 `) and the average burned area of peat fires in Western Canada was 0.2 Mha yr :sup:`-1` for 1980-1999 (:ref:`Turetsky et al. 2004 `). -For tropical peat fires, :math:`f_{cli,p}` is set as a function of long-term precipitation :math:`P_{60d}` : +For tropical peat fires, :math:`f_{cli,p}` is set as a function of long-term precipitation :math:`P_{30d}` : .. math:: :label: 23.38 - f_{cli,p} = \ max \left[0,\min \left(1,\frac{4-P_{60d} }{4} \right)\right]^{2} . + f_{cli,p} = \max \left[0,\min \left(1,1- \frac{P_{30d} }{6.5} \right)\right] . For boreal peat fires, :math:`f_{cli,p}` is set to @@ -389,46 +406,44 @@ Emissions for trace gas and aerosol species x and the j-th PFT, :math:`E_{x,j}` E_{x,j} = EF_{x,j}\frac{\phi _{j} }{[C]}. -Here, :math:`EF_{x,j}` (g species (g dm)\ :sup:`-1`) is PFT-dependent emission factor scaled from biome-level values (Li et al., in prep, also used for FireMIP fire emissions data) by Dr. Val Martin and Dr. Li. :math:`[C]` = 0.5 (g C (g dm)\ :sup:`-1`) is a conversion factor from dry matter to carbon. +Here, :math:`EF_{x,j}` (g species (g dm)\ :sup:`-1`) is PFT-dependent emission factor scaled from biome-level values (:ref:`Li et al. 2019 `; :ref:`Li et al. 2024b `) :math:`[C]` = 0.5 (g C (g dm)\ :sup:`-1`) is a conversion factor from dry matter to carbon. Emission height is PFT-dependent: 4.3 km for needleleaf tree PFTs, 3 km for other boreal and temperate tree PFTs, 2.5 km for tropical tree PFTs, 2 km for shrub PFTs, and 1 km for grass and crop PFTs. These values are compiled from earlier studies by Dr. Val Martin. -.. _Table PFT-specific combustion completeness and fire mortality factors: - -.. table:: PFT-specific combustion completeness and fire mortality factors. - - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | PFT | *CC*\ :sub:`leaf` | *CC*\ :sub:`stem` | *CC*\ :sub:`root` | *CC*\ :sub:`ts` | *M*\ :sub:`leaf` | *M*\ :sub:`livestem,1` | *M*\ :sub:`deadstem` | *M*\ :sub:`root` | *M*\ :sub:`ts` | *M*\ :sub:`livestem,2` | :math:`\xi`\ :sub:`j` | - +==================================+===========================+===========================+===========================+=========================+==========================+==============================+==============================+==========================+========================+==============================+=================================+ - | NET Temperate | 0.80 | 0.30 | 0.00 | 0.50 | 0.80 | 0.15 | 0.15 | 0.15 | 0.50 | 0.35 | 0.15 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | NET Boreal | 0.80 | 0.30 | 0.00 | 0.50 | 0.80 | 0.15 | 0.15 | 0.15 | 0.50 | 0.35 | 0.15 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | NDT Boreal | 0.80 | 0.30 | 0.00 | 0.50 | 0.80 | 0.15 | 0.15 | 0.15 | 0.50 | 0.35 | 0.15 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | BET Tropical | 0.80 | 0.27 | 0.00 | 0.45 | 0.80 | 0.13 | 0.13 | 0.13 | 0.45 | 0.32 | 0.13 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | BET Temperate | 0.80 | 0.27 | 0.00 | 0.45 | 0.80 | 0.13 | 0.13 | 0.13 | 0.45 | 0.32 | 0.13 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | BDT Tropical | 0.80 | 0.27 | 0.00 | 0.45 | 0.80 | 0.10 | 0.10 | 0.10 | 0.35 | 0.25 | 0.10 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | BDT Temperate | 0.80 | 0.27 | 0.00 | 0.45 | 0.80 | 0.10 | 0.10 | 0.10 | 0.35 | 0.25 | 0.10 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | BDT Boreal | 0.80 | 0.27 | 0.00 | 0.45 | 0.80 | 0.13 | 0.13 | 0.13 | 0.45 | 0.32 | 0.13 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | BES Temperate | 0.80 | 0.35 | 0.00 | 0.55 | 0.80 | 0.17 | 0.17 | 0.17 | 0.55 | 0.38 | 0.17 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | BDS Temperate | 0.80 | 0.35 | 0.00 | 0.55 | 0.80 | 0.17 | 0.17 | 0.17 | 0.55 | 0.38 | 0.17 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | BDS Boreal | 0.80 | 0.35 | 0.00 | 0.55 | 0.80 | 0.17 | 0.17 | 0.17 | 0.55 | 0.38 | 0.17 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | C\ :sub:`3` Grass Arctic | 0.80 | 0.80 | 0.00 | 0.80 | 0.80 | 0.20 | 0.20 | 0.20 | 0.80 | 0.60 | 0.20 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | C\ :sub:`3` Grass | 0.80 | 0.80 | 0.00 | 0.80 | 0.80 | 0.20 | 0.20 | 0.20 | 0.80 | 0.60 | 0.20 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | C\ :sub:`4` Grass | 0.80 | 0.80 | 0.00 | 0.80 | 0.80 | 0.20 | 0.20 | 0.20 | 0.80 | 0.60 | 0.20 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - | Crop | 0.80 | 0.80 | 0.00 | 0.80 | 0.80 | 0.20 | 0.20 | 0.20 | 0.80 | 0.60 | 0.20 | - +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+ - -Leaves (:math:`CC_{leaf}` ), stems (:math:`CC_{stem}` ), roots (:math:`CC_{root}` ), and transfer and storage carbon (:math:`CC_{ts}` ); mortality factors for leaves (:math:`M_{leaf}` ), live stems (:math:`M_{livestem,1}` ), dead stems (:math:`M_{deadstem}` ), roots (:math:`M_{root}` ), and transfer and storage carbon (:math:`M_{ts}` ) related to the carbon transfers from these pools to litter pool; mortality factors for live stems (:math:`M_{livestem,2}` ) related to the carbon transfer from live stems to dead stems; whole-plant mortality factor (:math:`\xi _{j}` ). +.. _Table PFT-specific fire parameters: + +.. table:: PFT-specific fire parameters. Note that the parameter values listed in this document (PFT-specific and others) are calibrated for default CLM6/CTSM6 land-only simulations forced by CRUJRA meteorology. For cases with the experimental hillslope hydrology mode and for CESM3 coupled simulations with an active atmosphere model, different values are recommended for the lower and upper thresholds of root-zone soil wetness and the maximum fire spread rate to keep the simulated global total burned area within the observational range, because these configurations alter soil moisture states and/or the fire calculation framework. The different values are available in the form of alternate parameter files. + + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | PFT | *CC*\ :sub:`leaf` | *CC*\ :sub:`stem` | *CC*\ :sub:`root` | *CC*\ :sub:`ts` | *M*\ :sub:`leaf` | *M*\ :sub:`livestem,1` | *M*\ :sub:`deadstem` | *M*\ :sub:`root` | *M*\ :sub:`ts` | *M*\ :sub:`livestem,2` | :math:`\xi`\ :sub:`j` | :math:`u`\ :sub:`max` | :math:`\beta`\ :sub:`low` | :math:`\beta`\ :sub:`up` | + +==================================+===========================+===========================+===========================+=========================+==========================+==============================+==============================+==========================+========================+==============================+=================================+====================================+====================================+====================================+ + | NET Temperate | 0.80 | 0.30 | 0.00 | 0.50 | 0.80 | 0.15 | 0.15 | 0.15 | 0.50 | 0.35 | 0.15 | 0.020 | 0.25 | 0.55 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | NET Boreal | 0.80 | 0.30 | 0.00 | 0.50 | 0.80 | 0.15 | 0.15 | 0.15 | 0.50 | 0.35 | 0.15 | 0.023 | 0.35 | 0.7 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | NDT Boreal | 0.80 | 0.30 | 0.00 | 0.50 | 0.80 | 0.15 | 0.15 | 0.15 | 0.50 | 0.35 | 0.15 | 0.023 | 0.35 | 0.7 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | BET Tropical | 0.80 | 0.27 | 0.00 | 0.45 | 0.80 | 0.13 | 0.13 | 0.13 | 0.45 | 0.32 | 0.13 | 0.053 | 0.35 | 0.75 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | BET Temperate | 0.80 | 0.27 | 0.00 | 0.45 | 0.80 | 0.13 | 0.13 | 0.13 | 0.45 | 0.32 | 0.13 | 0.020 | 0.3 | 0.7 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | BDT Tropical | 0.80 | 0.27 | 0.00 | 0.45 | 0.80 | 0.10 | 0.10 | 0.10 | 0.35 | 0.25 | 0.10 | 0.033 | 0.3 | 0.7 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | BDT Temperate | 0.80 | 0.27 | 0.00 | 0.45 | 0.80 | 0.13 | 0.13 | 0.13 | 0.45 | 0.32 | 0.13 | 0.020 | 0.3 | 0.7 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | BDT Boreal | 0.80 | 0.27 | 0.00 | 0.45 | 0.80 | 0.13 | 0.13 | 0.13 | 0.45 | 0.32 | 0.13 | 0.020 | 0.3 | 0.7 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | BES Temperate | 0.80 | 0.35 | 0.00 | 0.55 | 0.80 | 0.17 | 0.17 | 0.17 | 0.55 | 0.38 | 0.17 | 0.020 | 0.3 | 0.55 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | BDS Temperate | 0.80 | 0.35 | 0.00 | 0.55 | 0.80 | 0.17 | 0.17 | 0.17 | 0.55 | 0.38 | 0.17 | 0.020 | 0.3 | 0.55 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | BDS Boreal | 0.80 | 0.35 | 0.00 | 0.55 | 0.80 | 0.17 | 0.17 | 0.17 | 0.55 | 0.38 | 0.17 | 0.023 | 0.35 | 0.7 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | C\ :sub:`3` Grass Arctic | 0.80 | 0.80 | 0.00 | 0.80 | 0.80 | 0.20 | 0.20 | 0.20 | 0.80 | 0.60 | 0.20 | 0.023 | 0.35 | 0.7 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | C\ :sub:`3` Grass | 0.80 | 0.80 | 0.00 | 0.80 | 0.80 | 0.20 | 0.20 | 0.20 | 0.80 | 0.60 | 0.20 | 0.048 | 0.3 | 0.7 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + | C\ :sub:`4` Grass | 0.80 | 0.80 | 0.00 | 0.80 | 0.80 | 0.20 | 0.20 | 0.20 | 0.80 | 0.60 | 0.20 | 0.062 | 0.4 | 0.7 | + +----------------------------------+---------------------------+---------------------------+---------------------------+-------------------------+--------------------------+------------------------------+------------------------------+--------------------------+------------------------+------------------------------+---------------------------------+------------------------------------+------------------------------------+------------------------------------+ + +Combustion completeness factors for leaf (:math:`CC_{leaf}` ), stem (:math:`CC_{stem}` ), root (:math:`CC_{root}` ), and transfer and storage carbon (:math:`CC_{ts}` ); mortality factors for leaf (:math:`M_{leaf}` ), live stem (:math:`M_{livestem,1}` ), dead stem (:math:`M_{deadstem}` ), root (:math:`M_{root}` ), and transfer and storage carbon (:math:`M_{ts}` ) related to the carbon transfers from these pools to the litter pool; mortality factor for live stem (:math:`M_{livestem,2}` ) related to the carbon transfer from the live stem pool to the dead stem pool; whole-plant mortality factor (:math:`\xi _{j}` ); maximum fire spread rate (:math:`u_{max}`); lower and upper thresholds for root-zone soil wetness (:math:`\beta _{low}` and :math:`\beta _{up}`). diff --git a/doc/source/tech_note/Fluxes/CLM50_Tech_Note_Fluxes.rst b/doc/source/tech_note/Fluxes/CLM50_Tech_Note_Fluxes.rst index 0fe347d2b3..84da23626e 100644 --- a/doc/source/tech_note/Fluxes/CLM50_Tech_Note_Fluxes.rst +++ b/doc/source/tech_note/Fluxes/CLM50_Tech_Note_Fluxes.rst @@ -730,24 +730,29 @@ In the case of a vegetated surface, the sensible heat :math:`H` and water vapor Theory ^^^^^^^^^^^^ -The air within the canopy is assumed to have negligible capacity to store heat so that the sensible heat flux :math:`H` between the surface at height :math:`z_{0h} +d` and the atmosphere at height :math:`z_{atm,\, h}` must be balanced by the sum of the sensible heat from the vegetation :math:`H_{v}` and the ground :math:`H_{g}` +The air within the canopy is assumed to have negligible capacity to store heat so that the sensible heat flux :math:`H` between the surface at height :math:`z_{0h} +d` and the atmosphere at height :math:`z_{atm,\, h}` must be balanced by the sum of the sensible heat from the vegetation (:math:`H_{leaf}` and :math:`H_{stem}`) and the ground (:math:`H_{g}`) .. math:: :label: 5.86 - H=H_{v} +H_{g} + H=H_{leaf}+H_{stem}+H_{g} where, with reference to :numref:`Figure Schematic diagram of sensible heat fluxes`, .. math:: :label: 5.87 - H=-\rho _{atm} C_{p} \frac{\left(\theta _{atm} -T_{s} \right)}{r_{ah} } + H=-\rho _{atm} C_{p} \frac{\left(\theta _{atm}-T_{s} \right)}{r_{ah} } .. math:: :label: 5.88 - H_{v} =-\rho _{atm} C_{p} \left(T_{s} -T_{v} \right)\frac{\left(L+S\right)}{r_{b} } + H_{leaf} =-\rho _{atm} C_{p} \frac{\left(T_{s}-T_{leaf} \right)}{r_{leaf} } + +.. math:: + :label: 5.88b + + H_{stem} =-\rho _{atm} C_{p} \frac{\left(T_{s}-T_{stem} \right)}{r_{stem} } .. math:: :label: 5.89 @@ -759,12 +764,12 @@ where .. math:: :label: 5.90 - H_{soil} =-\rho _{atm} C_{p} \frac{\left(T_{s} -T_{1} \right)}{r_{ah} ^{{'} } } + H_{soil} =-\rho _{atm} C_{p} \frac{\left(T_{s}-T_{1} \right)}{r_{ah} ^{{'} } } .. math:: :label: 5.91 - H_{sno} =-\rho _{atm} C_{p} \frac{\left(T_{s} -T_{snl+1} \right)}{r_{ah} ^{{'} } } + H_{sno} =-\rho _{atm} C_{p} \frac{\left(T_{s}-T_{snl+1} \right)}{r_{ah} ^{{'} } } .. math:: :label: 5.92 @@ -773,28 +778,55 @@ where where :math:`\rho _{atm}` is the density of atmospheric air (kg m\ :sup:`-3`), :math:`C_{p}` is the specific heat capacity of air (J kg\ :sup:`-1` K\ :sup:`-1`) (:numref:`Table Physical constants`), :math:`\theta _{atm}` is the atmospheric potential temperature (K), and :math:`r_{ah}` is the aerodynamic resistance to sensible heat transfer (s m\ :sup:`-1`). -Here, :math:`T_{s}` is the surface temperature at height :math:`z_{0h} +d`, also referred to as the canopy air temperature. :math:`L` and :math:`S` are the exposed leaf and stem area indices (section :numref:`Phenology and vegetation burial by snow`), :math:`r_{b}` is the leaf boundary layer resistance (s m\ :sup:`-1`), and :math:`r_{ah} ^{{'} }` is the aerodynamic resistance (s m\ :sup:`-1`) to heat transfer between the ground at height :math:`z_{0h} ^{{'} }` and the canopy air at height :math:`z_{0h} +d`. +Here, :math:`T_{s}` is the surface temperature at height :math:`z_{0h} +d`, also referred to as the canopy air temperature. :math:`T_{leaf}` and :math:`T_{stem}` are the leaf and stem temperatures, :math:`r_{leaf}` and :math:`r_{stem}` are the resistances to sensible heat transfer (s m\ :sup:`-1`), and :math:`r_{ah} ^{{'} }` is the aerodynamic resistance (s m\ :sup:`-1`) to heat transfer between the ground at height :math:`z_{0h} ^{{'} }` and the canopy air at height :math:`z_{0h} +d`. + +The leaf resistance is + +.. math:: + :label: 5.92b + + r_{leaf} =\frac{r_{b}}{A_{leaf} } + +where :math:`r_{b}` is the leaf boundary layer resistance (s m\ :sup:`-1`), :math:`A_{leaf} = 2 L` is the (two-sided) surface area of leaves per unit ground area and :math:`L` is the exposed leaf area index (section :numref:`Phenology and vegetation burial by snow`). + +The stem resistance is + +.. math:: + :label: 5.92c + + r_{stem} =\frac{\left(r_{b} + r_{bole}\right)}{A_{stem} } + +where :math:`r_{bole}` is the resistance to heat transfer between the interior of the tree and the tree surface (s m\ :sup:`-1`), and :math:`A_{stem}` is the surface area of stems per unit ground area. + +The stem surface area is + +.. math:: + :label: 5.92d + + A_{stem} =N_{tree} k_{A} \left(\pi D_{bh}\right) h_{tree} + +where :math:`N_{tree}` is the number of trees per m\ :sup:`2`, :math:`k_{A}` is an adjustable parameter to account for the departure of tree area from a cylinder, :math:`D_{bh}` is the mean tree breast-height diameter (m), and :math:`h_{tree}` is the mean tree height (m). + +For plant functional types other than trees or shrubs, or if :math:`D_{bh} < 0.05`, :math:`A_{leaf} = 2 L + S` and :math:`A_{stem} = 0`. Furthermore, for trees and shrubs, if :math:`L < 0.1`, :math:`A_{leaf} = 2 L + S`, where :math:`S` is the exposed stem area index (section :numref:`Phenology and vegetation burial by snow`). This is intended to avoid small :math:`A_{leaf}` which leads to small leaf conductance and high leaf temperature which can trigger an error in the RRTMGP component of the atmospheric model. .. _Figure Schematic diagram of sensible heat fluxes: .. figure:: image1.png - Figure Schematic diagram of sensible heat fluxes for (a) - non-vegetated surfaces and (b) vegetated surfaces. + Schematic diagram of sensible heat fluxes for (a) non-vegetated surfaces and (b) vegetated surfaces. .. _Figure Schematic diagram of latent heat fluxes: .. figure:: image2.png - Figure Schematic diagram of water vapor fluxes for (a) - non-vegetated surfaces and (b) vegetated surfaces. + Schematic diagram of water vapor fluxes for (a) non-vegetated surfaces and (b) vegetated surfaces. Equations :eq:`5.86` - :eq:`5.89` can be solved for the canopy air temperature :math:`T_{s}` .. math:: :label: 5.93 - T_{s} =\frac{c_{a}^{h} \theta _{atm} +c_{g}^{h} T_{g} +c_{v}^{h} T_{v} }{c_{a}^{h} +c_{g}^{h} +c_{v}^{h} } + T_{s} =\frac{c_{a}^{h} \theta _{atm} +c_{g}^{h} T_{g} +c_{leaf}^{h} T_{leaf} +c_{stem}^{h} T_{stem} }{c_{a}^{h} +c_{g}^{h} +c_{leaf}^{h} +c_{stem}^{h} } where @@ -811,24 +843,36 @@ where .. math:: :label: 5.96 - c_{v}^{h} =\frac{\left(L+S\right)}{r_{b} } + c_{leaf}^{h} =\frac{1}{r_{leaf} } + +.. math:: + :label: 5.96b + + c_{stem}^{h} =\frac{1}{r_{stem} } -are the sensible heat conductances from the canopy air to the atmosphere, the ground to canopy air, and leaf surface to canopy air, respectively (m s\ :sup:`-1`). +are the sensible heat conductances from the canopy air to the atmosphere, the ground to canopy air, the leaf surface to canopy air, and the stem surface to canopy air, respectively (m s\ :sup:`-1`). -When the expression for :math:`T_{s}` is substituted into equation :eq:`5.88`, the sensible heat flux from vegetation :math:`H_{v}` is a function of :math:`\theta _{atm}`, :math:`T_{g}`, and :math:`T_{v}` +When the expression for :math:`T_{s}` is substituted into equation :eq:`5.88`, the sensible heat flux from leaves :math:`H_{leaf}` is a function of :math:`\theta _{atm}`, :math:`T_{g}`, :math:`T_{leaf}`, and :math:`T_{stem}` .. math:: :label: 5.97 - H_{v} = -\rho _{atm} C_{p} \left[c_{a}^{h} \theta _{atm} +c_{g}^{h} T_{g} -\left(c_{a}^{h} +c_{g}^{h} \right)T_{v} \right]\frac{c_{v}^{h} }{c_{a}^{h} +c_{v}^{h} +c_{g}^{h} } . + H_{leaf} = -\rho _{atm} C_{p} \left[c_{a}^{h} \theta _{atm} +c_{g}^{h} T_{g} +c_{stem}^{h} T_{stem} -\left(c_{a}^{h} +c_{g}^{h} +c_{stem}^{h} \right)T_{leaf} \right]\frac{c_{leaf}^{h} }{c_{a}^{h} +c_{leaf}^{h} +c_{stem}^{h} +c_{g}^{h} } . -Similarly, the expression for :math:`T_{s}` can be substituted into equations :eq:`5.89`, :eq:`5.90`, :eq:`5.91`, and :eq:`5.92` to obtain the sensible heat flux from ground :math:`H_{g}` +Similarly, :math:`T_{s}` can be substituted into equation :eq:`5.88b` to obtain the sensible heat flux from stems :math:`H_{stem}` .. math:: - :label: 5.98 + :label: 5.97b + + H_{stem} = -\rho _{atm} C_{p} \left[c_{a}^{h} \theta _{atm} +c_{g}^{h} T_{g} +c_{leaf}^{h} T_{leaf} -\left(c_{a}^{h} +c_{g}^{h} +c_{leaf}^{h} \right)T_{stem} \right]\frac{c_{stem}^{h} }{c_{a}^{h} +c_{leaf}^{h} +c_{stem}^{h} +c_{g}^{h} } , - H_{g} = -\rho _{atm} C_{p} \left[c_{a}^{h} \theta _{atm} +c_{v}^{h} T_{v} -\left(c_{a}^{h} +c_{v}^{h} \right)T_{g} \right]\frac{c_{g}^{h} }{c_{a}^{h} +c_{v}^{h} +c_{g}^{h} } . +and :math:`T_{s}` can be substituted into equations :eq:`5.89`, :eq:`5.90`, :eq:`5.91`, and :eq:`5.92` to obtain the sensible heat flux from ground :math:`H_{g}` + +.. math:: + :label: 5.98 + H_{g} = -\rho _{atm} C_{p} \left[c_{a}^{h} \theta _{atm} +c_{leaf}^{h} T_{leaf} +c_{stem}^{h} T_{stem}-\left(c_{a}^{h} +c_{leaf}^{h} +c_{stem}^{h} \right)T_{g} \right]\frac{c_{g}^{h} }{c_{a}^{h} +c_{leaf}^{h} +c_{stem}^{h} +c_{g}^{h} } . + The air within the canopy is assumed to have negligible capacity to store water vapor so that the water vapor flux :math:`E` between the surface at height :math:`z_{0w} +d` and the atmosphere at height :math:`z_{atm,\, w}` must be balanced by the sum of the water vapor flux from the vegetation :math:`E_{v}` and the ground :math:`E_{g}` .. math:: @@ -987,6 +1031,20 @@ The bare soil turbulent transfer coefficient is where the kinematic viscosity of air :math:`\upsilon =1.5\times 10^{-5}` m\ :sup:`2` s\ :sup:`-1` and :math:`a=0.13`. +When biomass heat storage is active, an empirical under-canopy wind speed is used in the calculation of the aerodynamic resistances to heat and moisture + +.. math:: + :label: eq_rah_raw + + r_{ah} ^{{'} } =r_{aw} ^{{'} } =\frac{1}{C_{s} U_{uc} } + +where + +.. math:: + :label: eq_under_canopy_wind_speed + + U_{uc} =\min \left(0.4, \frac{0.3 \ V_{a}}{u_{*}} \right) \ . + The leaf boundary layer resistance :math:`r_{b}` is .. math:: @@ -1033,7 +1091,7 @@ The ratio of wind speed at canopy height to friction velocity, :math:`\frac{U_{h .. math:: :label: 5.125b - \frac{U_{h}} {u_{*} } =(C_{S} + \lambda C_{R})^{0.5} \exp(\frac{\min \left(\lambda, \lambda_{\max}\right) c U_{h}} {2 u_{*}}) + \frac{U_{h}} {u_{*} } =(C_{S} + \lambda C_{R})^{0.5} \exp(\frac{\min \left(\lambda, \lambda_{\max}\right) c U_{h}} {2 u_{*} }) where :math:`C_{S}` represents the drag coefficient of the ground in the absence of vegetation, :math:`C_{R}` is the drag coefficient of an isolated roughness element (plant), and :math:`c` is an empirical constant. These three are pft-dependent parameters (:numref:`Table Plant functional type aerodynamic parameters`). :math:`\lambda_{max}` is the maximum :math:`\lambda` above which :math:`\frac{U_{h}} {u_{*}}` becomes constant. :math:`\lambda_{max}` is set to the value of :math:`\lambda` for which :eq:`5.125b`, in the absence of :math:`\lambda_{max}`, would have its minimum. :math:`\lambda_{max}` is also a pft-dependent parameter (:numref:`Table Plant functional type aerodynamic parameters`). :eq:`5.125b` can be written as @@ -1150,57 +1208,141 @@ where :math:`c_{d1} =7.5`. Numerical Implementation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Canopy energy conservation gives +Canopy energy conservation gives the temperature change of the leaves within the canopy .. math:: :label: 5.128 - -\overrightarrow{S}_{v} +\overrightarrow{L}_{v} \left(T_{v} \right)+H_{v} \left(T_{v} \right)+\lambda E_{v} \left(T_{v} \right)=0 + \overrightarrow{S}_{leaf} + \overrightarrow{L}_{leaf} \left(T_{leaf} \right) + - H_{leaf} \left(T_{leaf} \right) - \lambda E_{leaf} + \left(T_{leaf} \right) = C_{leaf} \frac{dT_{leaf}}{dt} -where :math:`\overrightarrow{S}_{v}` is the solar radiation absorbed by the vegetation (section :numref:`Solar Fluxes`), :math:`\overrightarrow{L}_{v}` is the net longwave radiation absorbed by vegetation (section :numref:`Longwave Fluxes`), and :math:`H_{v}` and :math:`\lambda E_{v}` are the sensible and latent heat fluxes from vegetation, respectively. The term :math:`\lambda` is taken to be the latent heat of vaporization :math:`\lambda _{vap}` (:numref:`Table Physical constants`). +where :math:`\overrightarrow{S}_{leaf}` is the solar radiation absorbed by the leaves (section :numref:`Solar Fluxes`), :math:`\overrightarrow{L}_{leaf}` is the net longwave radiation absorbed by the leaves (section :numref:`Longwave Fluxes`), and :math:`H_{leaf}` and :math:`\lambda E_{leaf}` are the sensible and latent heat fluxes from the leaves, respectively. :math:`C_{leaf}` is the areametric heat capacity of the leaves, and :math:`\lambda` is the latent heat of vaporization :math:`\lambda _{vap}` (:numref:`Table Physical constants`). -:math:`\overrightarrow{L}_{v}`, :math:`H_{v}`, and :math:`\lambda E_{v}` depend on the vegetation temperature :math:`T_{v}`. The Newton-Raphson method for finding roots of non-linear systems of equations can be applied to iteratively solve for :math:`T_{v}` as +:math:`C_{leaf}` (J m\ :sup:`-2` K\ :sup:`-1`) is the sum of the heat capacities of the dry leaves and of the water contained in the leaves multiplied by the dry leaf mass per area .. math:: - :label: 5.129 + :label: 5.128b + + C_{leaf} = \left(c_{dry} + \frac{f_{w}}{1-f_{w}} c_{water}\right) M_{leaf} + +where :math:`M_{leaf} = M_{a} \ L` and :math:`M_{a}` (kg m\ :sup:`-2`) is the leaf mass per leaf area. + +The stem energy balance is described by + +.. math:: + :label: 5.128c + + \begin{array}{lr} + \overrightarrow{S}_{stem} + \overrightarrow{L}_{stem} \left(T_{stem} \right) + - H_{stem} \left(T_{stem} \right) + = C_{stem} \frac{dT_{stem}}{dt} + \end{array} + +where :math:`\overrightarrow{S}_{stem}` is the solar radiation absorbed by the stems, :math:`\overrightarrow{L}_{stem}` is the net longwave radiation absorbed by the stems, :math:`H_{stem}` is the sensible flux from the stems to the canopy air space, and :math:`C_{stem}` is the areametric heat capacity of the stems. + +:math:`C_{stem}` (J m\ :sup:`-2` K\ :sup:`-1`) is the sum of the heat capacities of the dry wood and of the water contained in the stems multiplied by the mass of biomass per area + +.. math:: + :label: 5.128d + + C_{stem} = \left(c_{dry} + \frac{f_{w}}{1-f_{w}} c_{water}\right) M_{tree} + +where :math:`c_{dry}` (J kg\ :sup:`-1` K\ :sup:`-1`) is the heat capacity of the dry wood, :math:`c_{water}` (J kg\ :sup:`-1` K\ :sup:`-1`) is the heat capacity of water, and :math:`f_{w}` is the assumed fraction of fresh biomass that is water. The tree dry mass per area is calculated as + +.. math:: + :label: 5.128e + + M_{tree} = N_{tree} \ \rho_{wood} \ V_{tree} + +where :math:`\rho_{wood}` (kg m\ :sup:`-3`) is the density of dry wood, :math:`N_{tree}` (m\ :sup:`-2`) is the number of trees per square meter, and :math:`V_{tree}` (m\ :sup:`3`), the individual tree volume, is calculated by assuming that trees are cylindrical + +.. math:: + :label: 5.128f + + V_{tree} = k_{V} \ \pi \left( \frac{D_{bh}}{2} \right)^{2} h_{tree} + +where :math:`D_{bh}` is the mean breast-height diameter and :math:`h_{tree}` is the mean tree height. :math:`k_{V}` is an adjustable parameter to account for the departure of tree volume from a cylinder. + +The radiation absorbed by leaves and stems is assumed to be a constant fraction of the radiation absorbed by the canopy + +.. math:: + :label: 5.128g + + \begin{array}{lr} + \overrightarrow{S}_{leaf} & = & f_{leaf} \ \overrightarrow{S}_{canopy} \\ + \overrightarrow{L}_{leaf} & = & f_{leaf} \ \overrightarrow{L}_{canopy} \\ + \overrightarrow{S}_{stem} & = & f_{stem} \ \overrightarrow{S}_{canopy} \\ + \overrightarrow{L}_{stem} & = & f_{stem} \ \overrightarrow{L}_{canopy} , + \end{array} + +where the stem fraction is + +.. math:: + :label: 5.128h + + f_{stem} = k_{vert} \frac{S}{L + S} , + +where :math:`k_{vert}` is an adjustable parameter to account for the vertical distribution of stem area through the canopy. The leaf fraction is :math:`f_{leaf} = 1 - f_{stem}`. - \Delta T_{v} =\frac{\overrightarrow{S}_{v} -\overrightarrow{L}_{v} -H_{v} -\lambda E_{v} }{\frac{\partial \overrightarrow{L}_{v} }{\partial T_{v} } +\frac{\partial H_{v} }{\partial T_{v} } +\frac{\partial \lambda E_{v} }{\partial T_{v} } } -where :math:`\Delta T_{v} =T_{v}^{k+1} -T_{v}^{k}` and the subscript "k" indicates the iteration. +:math:`\overrightarrow{L}_{leaf}`, :math:`H_{leaf}`, and :math:`\lambda E_{leaf}` depend on the vegetation temperature :math:`T_{leaf}`. The Newton-Raphson method for finding roots of non-linear systems of equations can be applied to iteratively solve for :math:`T_{leaf}` as + +.. math:: + :label: 5.129 + + \Delta T_{leaf} =\frac{\overrightarrow{S}_{leaf} -\overrightarrow{L}_{leaf} -H_{leaf} -\lambda E_{leaf} - \frac{C_{leaf}}{dt} (T_{leaf}^{n} - T_{leaf}^{0}) }{\frac{\partial \overrightarrow{L}_{leaf} }{\partial T_{leaf} } +\frac{\partial H_{leaf} }{\partial T_{leaf} } +\frac{\partial \lambda E_{leaf} }{\partial T_{leaf} } +\frac{C_{leaf}}{dt}} + +where :math:`\Delta T_{leaf} =T_{leaf}^{n+1} -T_{leaf}^{n}` and the subscript "n" indicates the iteration. The partial derivatives are .. math:: :label: 5.130 - \frac{\partial \overrightarrow{L}_{v} }{\partial T_{v} } =4\varepsilon _{v} \sigma \left[2-\varepsilon _{v} \left(1-\varepsilon _{g} \right)\right]T_{v}^{3} + \frac{\partial \overrightarrow{L}_{leaf} }{\partial T_{leaf} } =4\varepsilon _{leaf} \sigma \left[2-\varepsilon _{leaf} \left(1-\varepsilon _{g} \right)\right]T_{leaf}^{3} .. math:: :label: 5.131 - \frac{\partial H_{v} }{\partial T_{v} } =\rho _{atm} C_{p} \left(c_{a}^{h} +c_{g}^{h} \right)\frac{c_{v}^{h} }{c_{a}^{h} +c_{v}^{h} +c_{g}^{h} } + \frac{\partial H_{leaf} }{\partial T_{leaf} } =\rho _{atm} C_{p} \left(c_{a}^{h} +c_{stem}^{h} +c_{g}^{h} \right)\frac{c_{leaf}^{h} }{c_{a}^{h} +c_{leaf}^{h} +c_{stem}^{h} +c_{g}^{h} } .. math:: :label: 5.132 - \frac{\partial \lambda E_{v} }{\partial T_{v} } =\lambda \rho _{atm} \left(c_{a}^{w} +c_{g}^{w} \right)\frac{c_{v}^{w} }{c_{a}^{w} +c_{v}^{w} +c_{g}^{w} } \frac{dq_{sat}^{T_{v} } }{dT_{v} } . + \frac{\partial \lambda E_{leaf} }{\partial T_{leaf} } =\lambda \rho _{atm} \left(c_{a}^{w} +c_{g}^{w} \right)\frac{c_{leaf}^{w} }{c_{a}^{w} +c_{leaf}^{w} +c_{g}^{w} } \frac{dq_{sat}^{T_{leaf} } }{dT_{leaf} } . -The partial derivatives :math:`\frac{\partial r_{ah} }{\partial T_{v} }` and :math:`\frac{\partial r_{aw} }{\partial T_{v} }`, which cannot be determined analytically, are ignored for :math:`\frac{\partial H_{v} }{\partial T_{v} }` and :math:`\frac{\partial \lambda E_{v} }{\partial T_{v} }`. However, if :math:`\zeta` changes sign more than four times during the temperature iteration, :math:`\zeta =-0.01`. This helps prevent "flip-flopping" between stable and unstable conditions. The total water vapor flux :math:`E_{v}`, transpiration flux :math:`E_{v}^{t}`, and sensible heat flux :math:`H_{v}` are updated for changes in leaf temperature as +The partial derivatives :math:`\frac{\partial r_{ah} }{\partial T_{leaf} }` and :math:`\frac{\partial r_{aw} }{\partial T_{leaf} }`, which cannot be determined analytically, are ignored for :math:`\frac{\partial H_{leaf} }{\partial T_{leaf} }` and :math:`\frac{\partial \lambda E_{leaf} }{\partial T_{leaf} }`. However, if :math:`\zeta` changes sign more than four times during the temperature iteration, :math:`\zeta =-0.01`. This helps prevent "flip-flopping" between stable and unstable conditions. The total water vapor flux :math:`E_{leaf}`, transpiration flux :math:`E_{leaf}^{t}`, and sensible heat flux :math:`H_{leaf}` are updated for changes in leaf temperature as .. math:: :label: 5.133 - E_{v} =-\rho _{atm} \left[c_{a}^{w} q_{atm} +c_{g}^{w} q_{g} -\left(c_{a}^{w} +c_{g}^{w} \right)\left(q_{sat}^{T_{v} } +\frac{dq_{sat}^{T_{v} } }{dT_{v} } \Delta T_{v} \right)\right]\frac{c_{v}^{w} }{c_{a}^{w} +c_{v}^{w} +c_{g}^{w} } + E_{leaf} =-\rho _{atm} \left[c_{a}^{w} q_{atm} +c_{g}^{w} q_{g} -\left(c_{a}^{w} +c_{g}^{w} \right)\left(q_{sat}^{T_{leaf} } +\frac{dq_{sat}^{T_{leaf} } }{dT_{leaf} } \Delta T_{leaf} \right)\right]\frac{c_{leaf}^{w} }{c_{a}^{w} +c_{leaf}^{w} +c_{g}^{w} } .. math:: :label: 5.134 - E_{v}^{t} =-r_{dry} ^{{'} {'} } \rho _{atm} \left[c_{a}^{w} q_{atm} +c_{g}^{w} q_{g} -\left(c_{a}^{w} +c_{g}^{w} \right)\left(q_{sat}^{T_{v} } +\frac{dq_{sat}^{T_{v} } }{dT_{v} } \Delta T_{v} \right)\right]\frac{c_{v}^{h} }{c_{a}^{w} +c_{v}^{w} +c_{g}^{w} } + E_{leaf}^{t} =-r_{dry} ^{{'} {'} } \rho _{atm} \left[c_{a}^{w} q_{atm} +c_{g}^{w} q_{g} -\left(c_{a}^{w} +c_{g}^{w} \right)\left(q_{sat}^{T_{leaf} } +\frac{dq_{sat}^{T_{leaf} } }{dT_{leaf} } \Delta T_{leaf} \right)\right]\frac{c_{leaf}^{h} }{c_{a}^{w} +c_{leaf}^{w} +c_{g}^{w} } .. math:: :label: 5.135 - H_{v} =-\rho _{atm} C_{p} \left[c_{a}^{h} \theta _{atm} +c_{g}^{h} T_{g} -\left(c_{a}^{h} +c_{g}^{h} \right)\left(T_{v} +\Delta T_{v} \right)\right]\frac{c_{v}^{h} }{c_{a}^{h} +c_{v}^{h} +c_{g}^{h} } . + H_{leaf} =-\rho _{atm} C_{p} \left[c_{a}^{h} \theta _{atm} +c_{g}^{h} T_{g} -\left(c_{a}^{h} +c_{g}^{h} \right)\left(T_{leaf} +\Delta T_{leaf} \right)\right]\frac{c_{leaf}^{h} }{c_{a}^{h} +c_{leaf}^{h} +c_{g}^{h} } . + +Stem temperature is updated using + +.. math:: + :label: 5.135b + + \Delta T_{stem} =\frac{\overrightarrow{S}_{stem} -\overrightarrow{L}_{stem} -H_{stem} }{\frac{\partial \overrightarrow{L}_{stem} }{\partial T_{stem} } +\frac{C_{stem}}{dt}} . + +The change in biomass heat storage from leaves and stems is + +.. math:: + :label: 5.135c + + H_{canopy} = \frac{C_{leaf} \Delta T_{leaf} + C_{stem} \Delta T_{stem}}{dt} . + The numerical solution for vegetation temperature and the fluxes of momentum, sensible heat, and water vapor flux from vegetated surfaces proceeds as follows: @@ -1255,7 +1397,7 @@ The numerical solution for vegetation temperature and the fluxes of momentum, se \Delta _{2} =\overrightarrow{S}_{v} -\overrightarrow{L}_{v} -\frac{\partial \overrightarrow{L}_{v} }{\partial T_{v} } \Delta T_{v} -H_{v} -\frac{\partial H_{v} }{\partial T_{v} } \Delta T_{v} -\lambda E_{v} -\frac{\partial \lambda E_{v} }{\partial T_{v} } \Delta T_{v} -where :math:`\Delta T_{v} =1{\rm \; or\; }-1`. The error :math:`\Delta _{2}` is added to the sensible heat flux later. + where :math:`\Delta T_{v} =1{\rm \; or\; }-1`. The error :math:`\Delta _{2}` is added to the sensible heat flux later. #. Water vapor flux :math:`E_{v}` (:eq:`5.133` ) @@ -1268,7 +1410,7 @@ where :math:`\Delta T_{v} =1{\rm \; or\; }-1`. The error :math:`\Delta _{2}` is \Delta _{3} =\max \left(0,\, E_{v} -E_{v}^{t} -\frac{W_{can} }{\Delta t} \right). -The error :math:`\lambda \Delta _{3}` is added to the sensible heat flux later. + The error :math:`\lambda \Delta _{3}` is added to the sensible heat flux later. #. Sensible heat flux :math:`H_{v}` (:eq:`5.135` ). The three energy error terms, :math:`\Delta _{1}`, :math:`\Delta _{2}`, and :math:`\lambda \Delta _{3}` are also added to the sensible heat flux. @@ -1282,7 +1424,11 @@ The error :math:`\lambda \Delta _{3}` is added to the sensible heat flux later. #. Specific humidity difference :math:`q_{atm} -q_{s}` -#. Potential temperature scale :math:`\theta _{*} =\frac{\theta _{*} }{\theta _{atm} -\theta _{s} } \left(\theta _{atm} -\theta _{s} \right)` where :math:`\frac{\theta _{*} }{\theta _{atm} -\theta _{s} }` was calculated earlier in the iteration #. Humidity scale :math:`q_{*} =\frac{q_{*} }{q_{atm} -q_{s} } \left(q_{atm} -q_{s} \right)` where :math:`\frac{q_{*} }{q_{atm} -q_{s} }` was calculated earlier in the iteration #. Virtual potential temperature scale :math:`\theta _{v*}` (:eq:`5.17` ) +#. Potential temperature scale :math:`\theta _{*} =\frac{\theta _{*} }{\theta _{atm} -\theta _{s} } \left(\theta _{atm} -\theta _{s} \right)` where :math:`\frac{\theta _{*} }{\theta _{atm} -\theta _{s} }` was calculated earlier in the iteration + +#. Humidity scale :math:`q_{*} =\frac{q_{*} }{q_{atm} -q_{s} } \left(q_{atm} -q_{s} \right)` where :math:`\frac{q_{*} }{q_{atm} -q_{s} }` was calculated earlier in the iteration + +#. Virtual potential temperature scale :math:`\theta _{v*}` (:eq:`5.17` ) #. Wind speed including the convective velocity, :math:`V_{a}` (:eq:`5.24` ) diff --git a/doc/source/tech_note/Fluxes/image1.png b/doc/source/tech_note/Fluxes/image1.png old mode 100755 new mode 100644 index b74d0a0c92..1e3db6a291 --- a/doc/source/tech_note/Fluxes/image1.png +++ b/doc/source/tech_note/Fluxes/image1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e1c868e187fac803a6b051b0148936909d3994bc2e89de2d58bf2c96bcfaef7 -size 9847 +oid sha256:517b729ffa486194b48d5250e4070e04abe255a22d39da6d41cfe71f121042a9 +size 28285 diff --git a/doc/source/tech_note/Fluxes/image1_no_bhs.png b/doc/source/tech_note/Fluxes/image1_no_bhs.png new file mode 100755 index 0000000000..b74d0a0c92 --- /dev/null +++ b/doc/source/tech_note/Fluxes/image1_no_bhs.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e1c868e187fac803a6b051b0148936909d3994bc2e89de2d58bf2c96bcfaef7 +size 9847 diff --git a/doc/source/tech_note/Glacier/CLM50_Tech_Note_Glacier.rst b/doc/source/tech_note/Glacier/CLM50_Tech_Note_Glacier.rst index 4c15ebbf56..e8a4b81298 100644 --- a/doc/source/tech_note/Glacier/CLM50_Tech_Note_Glacier.rst +++ b/doc/source/tech_note/Glacier/CLM50_Tech_Note_Glacier.rst @@ -3,7 +3,7 @@ Glaciers ======== -This chapter describes features of CLM that are specific to coupling to an ice sheet model (in the CESM context, this is the CISM model; :ref:`Lipscomb and Sacks (2012)` provide documentation and user's guide for CISM). General information about glacier land units can be found elsewhere in this document (see Chapter :numref:`rst_Surface Characterization, Vertical Discretization, and Model Input Requirements` for an overview). +This chapter describes features of CLM that are specific to coupling to an ice sheet model (in the CESM context, this is the CISM model; see the `CISM documentation and user's guide _` for more information). General information about glacier land units can be found elsewhere in this document (see Chapter :numref:`rst_Surface Characterization, Vertical Discretization, and Model Input Requirements` for an overview). .. _Glaciers summary of CLM5.0 updates relative to CLM4.5: @@ -113,7 +113,7 @@ The default behaviors for the world's glacier and ice sheet regions are describe Multiple elevation class scheme ------------------------------- -The glacier land unit contains multiple columns based on surface elevation. These are known as elevation classes, and the land unit is referred to as *glacier\_mec*. (As described in section :numref:`Glacier regions`, some regions have only a single elevation class, but they are still referred to as *glacier\_mec* land units.) The default is to have 10 elevation classes whose lower limits are 0, 200, 400, 700, 1000, 1300, 1600, 2000, 2500, and 3000 m. Each column is characterized by a fractional area and surface elevation that are read in during model initialization, and then possibly overridden by CISM as the run progresses. Each *glacier\_mec* column within a grid cell has distinct ice and snow temperatures, snow water content, surface fluxes, and SMB. +The glacier land unit contains multiple columns based on surface elevation. These are known as elevation classes, and the land unit is referred to as *glacier\_mec*. (As described in section :numref:`Glacier regions`, some regions have only a single elevation class, but they are still referred to as *glacier\_mec* land units.) The default is to have 10 elevation classes whose lower limits are 0, 200, 400, 700, 1000, 1300, 1600, 2000, 2500, and 3000 m. Each column is characterized by a fractional area and surface elevation that are read in during model initialization, and then possibly overridden by CISM as the run progresses. Each *glacier\_mec* column within a grid cell has distinct ice and snow temperatures, snow water content, surface fluxes, and SMB. In CLM6 users can optionally specify using :ref:`Sturm et al. (1997)` or :ref:`Jordan (1991)` parameterizations for snow thermal conductivity over glacier land units (see Chapter :numref:`rst_Soil and Snow Temperatures`), with Sturm (1997) set as the default. The atmospheric surface temperature, potential temperature, specific humidity, density, and pressure are downscaled from the atmosphere's mean grid cell elevation to the *glacier\_mec* column elevation using a specified lapse rate (typically 6.0 deg/km) and an assumption of uniform relative humidity. Longwave radiation is downscaled by assuming a linear decrease in downwelling longwave radiation with increasing elevation (0.032 W m\ :sup:`-2` m\ :sup:`-1`, limited to 0.5 - 1.5 times the gridcell mean value, then normalized to conserve gridcell total energy) :ref:`(Van Tricht et al., 2016)`. Total precipitation is partitioned into rain vs. snow as described in Chapter :numref:`rst_Surface Characterization, Vertical Discretization, and Model Input Requirements`. The partitioning of precipitation is based on the downscaled temperature, allowing rain to fall at lower elevations while snow falls at higher elevations. diff --git a/doc/source/tech_note/Hillslope_Hydrology/CLM50_Tech_Note_Hillslope_Hydrology.rst b/doc/source/tech_note/Hillslope_Hydrology/CLM50_Tech_Note_Hillslope_Hydrology.rst new file mode 100644 index 0000000000..848e19aa79 --- /dev/null +++ b/doc/source/tech_note/Hillslope_Hydrology/CLM50_Tech_Note_Hillslope_Hydrology.rst @@ -0,0 +1,58 @@ +.. _rst_Hillslope_Hydrology: + +Hillslope Hydrology +===================== + +CLM is typically operated using a single column to represent the hydrologic state of the vegetated land unit. The CLM 'Hillslope Hydrology' configuration extends the standard configuration by instantiating multiple columns per gridcell, each performing the standard vertical model physics (:ref:`Swenson et al. 2019b`). A set of connected columns in a gridcell is referred to as a hillslope, and lateral runoff fluxes can be passed between hillslope columns. In addition to calculating lateral moisture fluxes, meteorological downscaling is enabled in the hillslope configuration (:numref:`Figure Hillslope Hydrology Schematic`). These processes require a description of the columns' topographic characteristics, which are described by specifying six geomorphic parameters: the column area :math:`A`, the mean column height :math:`h`, the width of the column at its downslope interface :math:`w`, the mean distance of the column from the channel :math:`d`, the mean slope of the column :math:`\alpha`, and the column's aspect (defined with respect to North) :math:`\beta` (:numref:`Figure Hillslope Hydrology Geomorphic Parameters`). A method for estimating the geomorphic parameters from a digital elevation model (DEM) is described by :ref:`Swenson and Lawrence 2025`. + +.. _Figure Hillslope Hydrology Schematic: + +.. Figure:: image1.png + :align: center + + Processes enabled in Hillslope Hydrology: lateral subsurface flow passed between columns, slope/aspect based insolation, elevation-based downscaling. + +.. _Figure Hillslope Hydrology Geomorphic Parameters: + +.. Figure:: image2.png + :align: center + + Hillslope geomorphic parameters specified for each column via input data file. + +Saturated subsurface flow along the hillslope profile is described by Darcy's law + +.. math:: + :label: hh.eqn.1 + + q = - K_{s} \frac{d\Psi}{dx} , + +where :math:`q` is the moisture flux (m\ :sup:`3` m\ :sup:`-2` s\ :sup:`-1`), :math:`K_{s}` is the saturated hydraulic conductivity (m/s), :math:`\Psi` is the hydraulic head (m), and :math:`x` is the distance from the base of the hillslope (m). In unconfined saturated flow, the hydraulic head is the absolute water table height. To calculate the hydraulic head gradient, each column's water table depth :math:`z_{\nabla}` is subtracted from the relative hillslope elevation :math:`h`. + +Each hillslope has a stream channel, whose state variable is described by the volume of water in the channel :math:`V_{stream}`. The stream channel is defined by the bankfull width :math:`W_{channel}` (m) and depth :math:`D_{channel}` (m), which are given by + +.. math:: + :label: hh.eqn.2 + + \begin{array}{l} + W_{channel} = c_{w} A_{hill}^{b_{w}} \\ + D_{channel} = c_{d} A_{hill}^{b_{d}} , + \end{array} + +where :math:`c_{w}` and :math:`c_{d}` are scaling parameters, :math:`A_{hill}` (m\ :sup:`2`) is the total hillslope area, and :math:`b_{w}=0.6` and :math:`b_{d}=0.4` are power law exponents. Channel flow is described by the Manning equation (:ref:`Dingman 2002`). When :math:`V_{stream}` is greater than the bankfull volume, a floodplain described by a constant slope is assumed. + +Downscaling of incoming solar radiation uses topographic slope :math:`\alpha` and aspect :math:`\beta` to redistribute insolation between the gridcell's hillslope columns, while conserving the total energy flux. Incoming direct solar radiation, :math:`S_{gridcell}`, is divided by the gridcell cosine of the solar zenith angle, :math:`cosz_{gridcell}`, then multiplied by the column's cosine of the solar zenith angle, :math:`cosz_{column}`, which is calculated using the column's topographic slope and aspect + +.. math:: + :label: hh.eqn.3 + + S_{column} = S_{gridcell} \frac{cosz_{column}}{cosz_{gridcell}} , + +Other meteorological inputs, e.g. temperature and precipitation, can be adjusted using elevation‐based downscaling. For such variables, the gridcell-level value is modified by an anomaly defined by the lapse rate :math:`\lambda` + +.. math:: + :label: hh.eqn.4 + + X_{column} = X_{gridcell} + \lambda \ \Delta Z_{column} + +where :math:`X` represents a meteorological variable and :math:`\Delta Z_{column}` represents the column elevation anomaly with respect to the gridcell mean elevation. + diff --git a/doc/source/tech_note/Hillslope_Hydrology/image1.png b/doc/source/tech_note/Hillslope_Hydrology/image1.png new file mode 100644 index 0000000000..633d1cbded --- /dev/null +++ b/doc/source/tech_note/Hillslope_Hydrology/image1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53880cbc2c33c4699b500d84671026159e46901b70b97cec0822d663395e7ada +size 44239 diff --git a/doc/source/tech_note/Hillslope_Hydrology/image2.png b/doc/source/tech_note/Hillslope_Hydrology/image2.png new file mode 100644 index 0000000000..88e224e2c0 --- /dev/null +++ b/doc/source/tech_note/Hillslope_Hydrology/image2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92f6ed79efac07cb130c9a830ab7c8eda8dd23df8337c17cf1965fbe428665d5 +size 44198 diff --git a/doc/source/tech_note/Introduction/CLM50_Tech_Note_Introduction.rst b/doc/source/tech_note/Introduction/CLM50_Tech_Note_Introduction.rst index b931dc8fed..1f77e8c038 100644 --- a/doc/source/tech_note/Introduction/CLM50_Tech_Note_Introduction.rst +++ b/doc/source/tech_note/Introduction/CLM50_Tech_Note_Introduction.rst @@ -21,126 +21,6 @@ The National Center for Atmospheric Research (NCAR) is operated by the nonprofit National Center for Atmospheric Research P. O. Box 3000, Boulder, Colorado 80307-300 -**LIST OF FIGURES** - -- :numref:`Figure Land processes` Land biogeophysical, biogeochemical, and landscape processes simulated by CLM (adapted from :ref:`Lawrence et al. (2011)` for CLM5.0). - -- :numref:`Figure CLM subgrid hierarchy` Configuration of the CLM subgrid hierarchy. - -- :numref:`Figure Radiation Schematic` Schematic diagram of (a) direct beam radiation, (b) diffuse solar radiation, and (c) longwave radiation absorbed, transmitted, and reflected by vegetation and ground. - -- :numref:`Figure Schematic diagram of sensible heat fluxes` Schematic diagram of sensible heat fluxes for (a) non-vegetated surfaces and (b) vegetated surfaces. - -- :numref:`Figure Schematic diagram of latent heat fluxes` Schematic diagram of water vapor fluxes for (a) non-vegetated surfaces and (b) vegetated surfaces. - -- :numref:`Figure Soil Temperature Schematic`. Schematic diagram of numerical scheme used to solve for soil temperature. - -- :numref:`Figure Hydrologic processes` Hydrologic processes represented in CLM. - -- :numref:`Figure Water flux schematic` Schematic diagram of numerical scheme used to solve for soil water fluxes. - -- :numref:`Figure three layer snow pack` Example of three layer snow pack (snl=-3). - -- :numref:`Figure MOSART conceptual diagram` MOSART conceptual diagram. - -- :numref:`Figure Schematic representation of the urban landunit` Schematic representation of the urban land unit. - -- :numref:`Figure Schematic of urban and atmospheric model coupling` Schematic of urban and atmospheric model coupling. - -- :numref:`Figure Schematic of THESIS urban properties tool` Schematic of THESIS urban properties tool. - -- :numref:`Figure Vegetation fluxes and pools` Vegetation fluxes and pools. - -- :numref:`Figure annual phenology cycle` Example of annual phenology cycle for seasonal deciduous. - -- :numref:`Figure Schematic of decomposition model in CLM` Schematic of decomposition model in CLM. - -- :numref:`Figure Pool structure` Pool structure, transitions, respired fractions, and turnover times for the 2 alternate soil decomposition models included in CLM. - -- :numref:`Figure Biological nitrogen fixation` Biological nitrogen fixation as a function of annual net primary production. - -- :numref:`Figure Methane Schematic` Schematic representation of biological and physical processes integrated in CLM that affect the net CH4 surface flux. - -- :numref:`Figure Schematic of land cover change` Schematic of land cover change impacts on CLM carbon pools and fluxes. - -- :numref:`Figure Schematic of translation of annual LUH2 land units` Schematic of translation of annual UNH land units to CLM plant functional types. - -**LIST OF TABLES** - -- :numref:`Table Plant functional types` Plant functional types - -- :numref:`Table Plant functional type canopy top and bottom heights` Plant functional type canopy top and bottom heights - -- :numref:`Table Soil layer structure` Soil layer structure - -- :numref:`Table Atmospheric input to land model` Atmospheric input to land model - -- :numref:`Table Land model output to atmospheric model` Land model output to atmospheric model - -- :numref:`Table Surface data required for CLM and their base spatial resolution` Surface data required for CLM and their base spatial resolution - -- :numref:`Table Physical constants` Physical constants - -- :numref:`Table Plant functional type optical properties` Plant functional type optical properties - -- :numref:`Table Intercepted snow optical properties` Intercepted snow optical properties - -- :numref:`Table Dry and saturated soil albedos` Dry and saturated soil albedos - -- :numref:`Table Spectral bands and weights used for snow radiative transfer` Spectral bands and weights used for snow radiative transfer - -- :numref:`Table Single-scatter albedo values used for snowpack impurities and ice` Single-scatter albedo values used for snowpack impurities and ice - -- :numref:`Table Mass extinction values` Mass extinction values (m2 kg-1) used for snowpack impurities and ice. - -- :numref:`Table Asymmetry scattering parameters used for snowpack impurities and ice` Asymmetry scattering parameters used for snowpack impurities and ice. - -- :numref:`Table Orbital parameters` Orbital parameters - -- :numref:`Table Plant functional type aerodynamic parameters` Plant functional type aerodynamic parameters - -- :numref:`Table Coefficients for saturation vapor pressure` Coefficients for e\ :sub:`sat`\ :sup:`T` - -- :numref:`Table Coefficients for derivative of esat` Coefficients for the derivative of e\ :sub:`sat`\ :sup:`T` - -- :numref:`Table Meltwater scavenging` Meltwater scavenging efficiency for particles within snow - -- :numref:`Table snow layer thickness` Minimum and maximum thickness of snow layers (m) - -- :numref:`Table Plant functional type (PFT) stomatal conductance parameters` Plant functional type (PFT) stomatal conductance parameters. - -- :numref:`Table Temperature dependence parameters for C3 photosynthesis` Temperature dependence parameters for C3 photosynthesis. - -- :numref:`Table Plant functional type root distribution parameters` Plant functional type root distribution parameters. - -- :numref:`Table MOSART Parameters` List of parameters in the global hydrography dataset. - -- :numref:`Table Allocation and CN ratio parameters` Allocation and carbon:nitrogen ratio parameters - -- :numref:`Table Decomposition rate constants` Decomposition rate constants for litter and SOM pools, C:N ratios, and acceleration parameters for the CLM-CN decomposition pool structure. - -- :numref:`Table Respiration fractions for litter and SOM pools` Respiration fractions for litter and SOM pools - -- :numref:`Table Turnover times` Turnover times, C:N ratios, and acceleration parameters for the Century-based decomposition cascade. - -- :numref:`Table Respiration fractions for Century-based structure` Respiration fractions for litter and SOM pools for Century-based structure - -- :numref:`Table PFT-specific combustion completeness and fire mortality factors` PFT-specific combustion completeness and fire mortality factors. - -- :numref:`Table Methane Parameter descriptions` Parameter descriptions and sensitivity analysis ranges applied in the methane model. - -- :numref:`Table Temperature dependence of aqueous and gaseous diffusion` Temperature dependence of aqueous and gaseous diffusion coefficients for CH4 and O2. - -- :numref:`Table Crop plant functional types` Crop plant functional types (PFTs). - -- :numref:`Table Crop phenology parameters` Crop phenology and morphology parameters. - -- :numref:`Table Crop allocation parameters` Crop allocation parameters. - -- :numref:`Table Dust Mass fraction` Mass fraction m\ :sub:`i` , mass median diameter :sub:`v, i` , and geometric standard deviation :sub:`g, i` , per dust source mode i - -- :numref:`Table Dust Minimum and maximum particle diameters` Minimum and maximum particle diameters in each dust transport bin j - **ACKNOWLEDGEMENTS** The authors would like to acknowledge the substantial contributions of the following members of the Land Model and Biogeochemistry Working Groups to the development of the Community Land Model since its inception in 1996: Benjamin Andre, Ian Baker, Michael Barlage, Mike Bosilovich, Marcia Branstetter, Tony Craig, Aiguo Dai, Yongjiu Dai, Mark Decker, Scott Denning, Robert Dickinson, Paul Dirmeyer, Jared Entin, Jay Famiglietti, Johannes Feddema, Mark Flanner, Jon Foley, Andrew Fox, Inez Fung, David Gochis, Alex Guenther, Tim Hoar, Forrest Hoffman, Paul Houser, Trish Jackson, Brian Kauffman, Silvia Kloster, Natalie Mahowald, Jiafu Mao, Lei Meng, Sheri Michelson, Guo-Yue Niu, Adam Phillips, Taotao Qian, Jon Radakovich, James Randerson, Nan Rosenbloom, Steve Running, Koichi Sakaguchi, Adam Schlosser, Andrew Slater, Reto Stöckli, Ying Sun, Quinn Thomas, Peter Thornton, Mariana Vertenstein, Nicholas Viovy, Aihui Wang, Guiling Wang, Zong-Liang Yang, Charlie Zender, Xiaodong Zeng, and Xubin Zeng. diff --git a/doc/source/tech_note/Lake/CLM50_Tech_Note_Lake.rst b/doc/source/tech_note/Lake/CLM50_Tech_Note_Lake.rst index 88cb77d737..e99fed4c3c 100644 --- a/doc/source/tech_note/Lake/CLM50_Tech_Note_Lake.rst +++ b/doc/source/tech_note/Lake/CLM50_Tech_Note_Lake.rst @@ -3,14 +3,14 @@ Lake Model ============= -The lake model, denoted the *Lake, Ice, Snow, and Sediment Simulator* (LISSS), is from :ref:`Subin et al. (2012a) `. It includes extensive modifications to the lake code of :ref:`Zeng et al. (2002) ` used in CLM versions 2 through 4, which utilized concepts from the lake models of :ref:`Bonan (1996) `, :ref:`Henderson-Sellers (1985) `, :ref:`Henderson-Sellers (1986) `, :ref:`Hostetler and Bartlein (1990) `, and the coupled lake-atmosphere model of :ref:`Hostetler et al. (1993) `, :ref:`Hostetler et al. (1993) `. Lakes have spatially variable depth prescribed in the surface data (section :ref:`External Data Lake`); the surface data optionally includes lake optical extinction coeffient and horizontal fetch, currently only used for site simulations. Lake physics includes freezing and thawing in the lake body, resolved snow layers, and "soil" and bedrock layers below the lake body. Temperatures and ice fractions are simulated for :math:`N_{levlak} =10` layers (for global simulations) or :math:`N_{levlak} =25` (for site simulations) with discretization described in section :numref:`Vertical Discretization Lake`. Lake albedo is described in section :numref:`Surface Albedo Lake`. Lake surface fluxes (section :numref:`Surface Fluxes and Surface Temperature Lake`) generally follow the formulations for non-vegetated surfaces, including the calculations of aerodynamic resistances (section :numref:`Sensible and Latent Heat Fluxes for Non-Vegetated Surfaces`); however, the lake surface temperature :math:`T_{g}` (representing an infinitesimal interface layer between the top resolved lake layer and the atmosphere) is solved for simultaneously with the surface fluxes. After surface fluxes are evaluated, temperatures are solved simultaneously in the resolved snow layers (if present), the lake body, and the soil and bedrock, using the ground heat flux *G* as a top boundary condition. Snow, soil, and bedrock models generally follow the formulations for non-vegetated surfaces (Chapter :numref:`rst_Soil and Snow Temperatures`), with modifications described below. +The lake model, denoted the *Lake, Ice, Snow, and Sediment Simulator* (LISSS), is from :ref:`Subin et al. (2012a) `. It includes extensive modifications to the lake code of :ref:`Zeng et al. (2002) ` used in CLM versions 2 through 4, which utilized concepts from the lake models of :ref:`Bonan (1996) `, :ref:`Henderson-Sellers (1985) `, :ref:`Henderson-Sellers (1986) `, :ref:`Hostetler and Bartlein (1990) `, and the coupled lake-atmosphere model of :ref:`Hostetler et al. (1993) `. Lakes have spatially varying depth prescribed in the surface data (section :ref:`External Data Lake`); the surface data optionally includes lake optical extinction coeffient and horizontal fetch, currently only used for site simulations. Lake physics includes freezing and thawing in the lake body, resolved snow layers, and "soil" and bedrock layers below the lake body. Temperatures and ice fractions are simulated for :math:`N_{levlak} =10` layers (for global simulations) or :math:`N_{levlak} =25` (for site simulations) with discretization described in section :numref:`Vertical Discretization Lake`. Lake albedo is described in section :numref:`Ground Albedos`. Lake surface fluxes (section :numref:`Surface Fluxes and Surface Temperature Lake`) generally follow the formulations for non-vegetated surfaces, including the calculations of aerodynamic resistances (section :numref:`Sensible and Latent Heat Fluxes for Non-Vegetated Surfaces`); however, the lake surface temperature :math:`T_{g}` (representing an infinitesimal interface layer between the top resolved lake layer and the atmosphere) is solved for simultaneously with the surface fluxes. After surface fluxes are evaluated, temperatures are solved simultaneously in the resolved snow layers (if present), the lake body, and the soil and bedrock, using the ground heat flux *G* as a top boundary condition. Snow, soil, and bedrock models generally follow the formulations for non-vegetated surfaces (Chapter :numref:`rst_Soil and Snow Temperatures`), with modifications described below. .. _Vertical Discretization Lake: Vertical Discretization --------------------------- -Currently, there is one lake modeled in each grid cell (with prescribed or assumed depth *d*, extinction coefficient :math:`\eta`, and fetch *f*), although this could be modified with changes to the CLM subgrid decomposition algorithm in future model versions. As currently implemented, the lake consists of 0-5 snow layers; water and ice layers (10 for global simulations and 25 for site simulations) comprising the "lake body;" 10 "soil" layers; and 5 bedrock layers. Each lake body layer has a fixed water mass (set by the nominal layer thickness and the liquid density), with frozen mass-fraction *I* a state variable. Resolved snow layers are present if the snow thickness :math:`z_{sno} \ge s_{\min }`, where *s*\ :sub:`min` = 4 cm by default, and is adjusted for model timesteps other than 1800 s in order to maintain numerical stability (section :numref:`Modifications to Snow Layer Logic Lake`). For global simulations with 10 body layers, the default (50 m lake) body layer thicknesses are given by: :math:`\Delta z_{i}` of 0.1, 1, 2, 3, 4, 5, 7, 7, 10.45, and 10.45 m, with node depths :math:`z_{i}` located at the center of each layer (i.e., 0.05, 0.6, 2.1, 4.6, 8.1, 12.6, 18.6, 25.6, 34.325, 44.775 m). For site simulations with 25 layers, the default thicknesses are (m): 0.1 for layer 1; 0.25 for layers 2-5; 0.5 for layers 6-9; 0.75 for layers 10-13; 2 for layers 14-15; 2.5 for layers 16-17; 3.5 for layers 18-21; and 5.225 for layers 22-25. For lakes with depth *d* :math:`\neq` 50 m and *d* :math:`\ge` 1 m, the top layer is kept at 10 cm and the other 9 layer thicknesses are adjusted to maintain fixed proportions. For lakes with *d* :math:`<` 1 m, all layers have equal thickness. Thicknesses of snow, soil, and bedrock layers follow the scheme used over non-vegetated surfaces (Chapter :numref:`rst_Soil and Snow Temperatures`), with modifications to the snow layer thickness rules to keep snow layers at least as thick as *s*\ :sub:`min` (section :numref:`Modifications to Snow Layer Logic Lake`). +Currently, there is one lake modeled in each grid cell (with prescribed or default depth *d*, extinction coefficient :math:`\eta`, and fetch *f*), although this could be modified with changes to the CLM subgrid decomposition algorithm in future model versions. As currently implemented, the lake consists of 0-5 snow layers; water and ice layers (10 for global simulations and 25 for site simulations) comprising the "lake body;" 10 "soil" layers; and 5 bedrock layers. Each lake body layer has a fixed water mass (set by the nominal layer thickness and the liquid density), with frozen mass-fraction *I* a state variable. Resolved snow layers are present if the snow thickness :math:`z_{sno} \ge s_{\min }`, where *s*\ :sub:`min` = 4 cm by default, and is adjusted for model timesteps other than 1800 s in order to maintain numerical stability (section :numref:`Modifications to Snow Layer Logic Lake`). For global simulations with 10 body layers, the default (50 m lake) body layer thicknesses are given by: :math:`\Delta z_{i}` of 0.1, 1, 2, 3, 4, 5, 7, 7, 10.45, and 10.45 m, with node depths :math:`z_{i}` located at the center of each layer (i.e., 0.05, 0.6, 2.1, 4.6, 8.1, 12.6, 18.6, 25.6, 34.325, 44.775 m). For site simulations with 25 layers, the default thicknesses are (m): 0.1 for layer 1; 0.25 for layers 2-5; 0.5 for layers 6-9; 0.75 for layers 10-13; 2 for layers 14-15; 2.5 for layers 16-17; 3.5 for layers 18-21; and 5.225 for layers 22-25. For lakes with depth *d* :math:`\neq` 50 m and *d* :math:`\ge` 1 m, the top layer is kept at 10 cm and the other 9 layer thicknesses are adjusted to maintain fixed proportions. For lakes with *d* :math:`<` 1 m, all layers have equal thickness. Thicknesses of snow, soil, and bedrock layers follow the scheme used over non-vegetated surfaces (Chapter :numref:`rst_Soil and Snow Temperatures`), with modifications to the snow layer thickness rules to keep snow layers at least as thick as *s*\ :sub:`min` (section :numref:`Modifications to Snow Layer Logic Lake`). .. _External Data Lake: @@ -19,31 +19,6 @@ External Data As discussed in :ref:`Subin et al. (2012a, b) `, the Global Lake and Wetland Database (:ref:`Lehner and Doll 2004`) is currently used to prescribe lake fraction in each land model grid cell, for a total of 2.3 million km\ :sup:`-2`. As in :ref:`Subin et al. (2012a, b) `, the :ref:`Kourzeneva et al. (2012)` global gridded dataset is currently used to estimate a mean lake depth in each grid cell, based on interpolated compilations of geographic information. -.. _Surface Albedo Lake: - -Surface Albedo ------------------- - -For direct radiation, the albedo *a* for lakes with ground temperature :math:`{T}_{g}` (K) above freezing is given by (:ref:`Pivovarov, 1972`) - -.. math:: - :label: 12.1 - - a=\frac{0.5}{\cos z+0.15} - -where *z* is the zenith angle. For diffuse radiation, the expression in eq. is integrated over the full sky to yield *a* = 0.10. - -For frozen lakes without resolved snow layers, the albedo at cold temperatures *a*\ :sub:`0` is 0.60 for visible and 0.40 for near infrared radiation. As the temperature at the ice surface, :math:`{T}_{g}`, approaches freezing [ :math:`{T}_{f}` (K) (:numref:`Table Physical Constants`)], the albedo is relaxed towards 0.10 based on :ref:`Mironov et al. (2010)`: - -.. math:: - :label: 12.2 - - a=a_{0} \left(1-x\right)+0.10x,x=\exp \left(-95\frac{T_{f} -T_{g} }{T_{f} } \right) - -where *a* is restricted to be no less than that given in :eq:`12.1`. - -For frozen lakes with resolved snow layers, the reflectance of the ice surface is fixed at *a*\ :sub:`0`, and the snow reflectance is calculated as over non-vegetated surfaces (Chapter :numref:`rst_Surface Albedos`). These two reflectances are combined to obtain the snow-fraction-weighted albedo as in over non-vegetated surfaces (Chapter :numref:`rst_Surface Albedos`). - .. _Surface Fluxes and Surface Temperature Lake: Surface Fluxes and Surface Temperature @@ -56,7 +31,7 @@ Surface Properties The fraction of shortwave radiation absorbed at the surface, :math:`\beta`, depends on the lake state. If resolved snow layers are present, then :math:`\beta` is set equal to the absorption fraction predicted by the snow-optics submodel (Chapter :numref:`rst_Surface Albedos`) for the top snow layer. Otherwise, :math:`\beta` is set equal to the near infrared fraction of the shortwave radiation reaching the surface simulated by the atmospheric model or atmospheric data model used for offline simulations (Chapter :numref:`rst_Land-only Mode`). The remainder of the shortwave radiation fraction (1 :math:`{-}` :math:`\beta`) is absorbed in the lake body or soil as described in section :numref:`Radiation Penetration`. -The surface roughnesses are functions of the lake state and atmospheric forcing. +The surface roughnesses are functions of the lake state and atmospheric forcing. For unfrozen lakes (:math:`T_{g} > T_{f}`), :math:`z_{0m}` is given by (:ref:`Subin et al. (2012a) `) @@ -68,7 +43,7 @@ For unfrozen lakes (:math:`T_{g} > T_{f}`), :math:`z_{0m}` is given by (:ref:`Su where :math:`\alpha` = 0.1, :math:`\nu` is the kinematic viscosity of air given below, *C* is the effective Charnock coefficient given below, :math:`u_{*}` is the friction velocity (m/s), and *g* is the acceleration of gravity (:numref:`Table Physical Constants`). The kinematic viscosity is given by .. math:: - :label: 12.4 + :label: 12.4 \nu =\nu _{0} \left(\frac{T_{g} }{T_{0} } \right)^{1.5} \frac{P_{0} }{P_{ref} } @@ -79,7 +54,7 @@ where :math:`P_{ref}` is the pressure at the atmospheric reference height. The Charnock coefficient *C* is a function of the lake fetch *F* (m), given in the surface data or set to 25 times the lake depth *d* by default: .. math:: - :label: 12.5 + :label: 12.5 \begin{array}{l} {C=C_{\min } +(C_{\max } -C_{\min } )\exp \left\{-\min \left(A,B\right)\right\}} \\ {A={\left(\frac{Fg}{u_{*} ^{2} } \right)^{{1\mathord{\left/ {\vphantom {1 3}} \right.} 3} } \mathord{\left/ {\vphantom {\left(\frac{Fg}{u_{*} ^{2} } \right)^{{1\mathord{\left/ {\vphantom {1 3}} \right.} 3} } f_{c} }} \right.} f_{c} } } \\ {B=\varepsilon \frac{\sqrt{dg} }{u} } \end{array} @@ -104,7 +79,7 @@ For frozen lakes ( :math:`T_{g} \le T_{f}` ) without resolved snow layers ( :math:`snl = 0` ), :math:`z_{0m} =z_{0m_{ice}} =2.3\times 10^{-3} {\rm m}` (:ref:`Meier et al. (2022) `). For frozen lakes with resolved -snow layers ( :math:`snl > 0` ), the momentum roughness length is evaluated based on accumulated snow melt :math:`M_{a} {\rm }` (:ref:`Meier et al. (2022) `). +snow layers ( :math:`snl > 0` ), the momentum roughness length is evaluated based on accumulated snow melt :math:`M_{a} {\rm }` (:ref:`Meier et al. (2022) `). For :math:`M_{a} >=1\times 10^{-5}` .. math:: @@ -123,7 +98,7 @@ For :math:`M_{a} <1\times 10^{-5}` Accumulated snow melt :math:`M_{a}` at the current time step :math:`t` is defined as .. math:: - :label: 12.5d + :label: 12.5d M ^{t}_{a} = M ^{t-1}_{a} - (q ^{t}_{sno} \Delta t + q ^{t}_{snowmelt} \Delta t)\times 10^{-3} @@ -169,7 +144,7 @@ where :math:`\vec{S}_{g}` \ is the absorbed solar radiation in the lake, .. math:: :label: 12.8 - \lambda =\left\{\begin{array}{l} {\lambda _{sub} \qquad T_{g} \le T_{f} } \\ {\lambda _{vap} \qquad T_{g} >T_{f} } \end{array}\right\}. + \lambda =\Bigg\{\begin{array}{l} {\lambda _{sub} \qquad T_{g} \le T_{f} } \\ {\lambda _{vap} \qquad T_{g} >T_{f} } \end{array} The sensible heat flux (W m\ :sup:`-2`) is @@ -226,7 +201,7 @@ The absorbed solar radiation :math:`\vec{S}_{g}` is \vec{S}_{g} =\sum _{\Lambda }S_{atm} \, \downarrow _{\Lambda }^{\mu } \left(1-\alpha _{g,\, \Lambda }^{\mu } \right) +S_{atm} \, \downarrow _{\Lambda } \left(1-\alpha _{g,\, \Lambda } \right) -where :math:`S_{atm} \, \downarrow _{\Lambda }^{\mu }` and :math:`S_{atm} \, \downarrow _{\Lambda }` are the incident direct beam and diffuse solar fluxes (W m\ :sup:`-2`) and :math:`\Lambda` denotes the visible (:math:`<` 0.7\ :math:`\mu {\rm m}`) and near-infrared (:math:`\ge` 0.7\ :math:`\mu {\rm m}`) wavebands (section :numref:`Atmospheric Coupling`), and :math:`\alpha _{g,\, \Lambda }^{\mu }` and :math:`\alpha _{g,\, \mu }` are the direct beam and diffuse lake albedos (section :numref:`Surface Albedo Lake`). +where :math:`S_{atm} \, \downarrow _{\Lambda }^{\mu }` and :math:`S_{atm} \, \downarrow _{\Lambda }` are the incident direct beam and diffuse solar fluxes (W m\ :sup:`-2`) and :math:`\Lambda` denotes the visible (:math:`<` 0.7\ :math:`\mu {\rm m}`) and near-infrared (:math:`\ge` 0.7\ :math:`\mu {\rm m}`) wavebands (section :numref:`Atmospheric Coupling`), and :math:`\alpha _{g,\, \Lambda }^{\mu }` and :math:`\alpha _{g,\, \mu }` are the direct beam and diffuse lake albedos (section :numref:`Ground Albedos`). The net emitted longwave radiation is @@ -241,7 +216,7 @@ where :math:`L_{g} \, \uparrow` is the upward longwave radiation from the surfac .. math:: :label: 12.16 - L\, \uparrow =\left(1-\varepsilon _{g} \right)L_{atm} \, \downarrow +\varepsilon _{g} \sigma \left(T_{g}^{n} \right)^{4} +4\varepsilon _{g} \sigma \left(T_{g}^{n} \right)^{3} \left(T_{g}^{n+1} -T_{g}^{n} \right) + \vec{L}_{g}\, \uparrow =\left(1-\varepsilon _{g} \right)L_{atm} \, \downarrow +\varepsilon _{g} \sigma \left(T_{g}^{n} \right)^{4} +4\varepsilon _{g} \sigma \left(T_{g}^{n} \right)^{3} \left(T_{g}^{n+1} -T_{g}^{n} \right) where :math:`\varepsilon _{g} =0.97` is the lake surface emissivity, :math:`\sigma` is the Stefan-Boltzmann constant (W m\ :sup:`-2` K\ :sup:`-4`) (:numref:`Table Physical Constants`), and @@ -285,29 +260,29 @@ where the partial derivatives are The fluxes of momentum, sensible heat, and water vapor are solved for simultaneously with lake surface temperature as follows. To begin, :math:`z_{0m}` and the scalar roughness lengths are set as described in section :numref:`Surface Properties Lake`. -#. An initial guess for the wind speed :math:`V_{a}` including the convective velocity :math:`U_{c}` is obtained from :eq:`5.24` assuming an initial convective velocity :math:`U_{c} =0` m s\ :sup:`-1` for stable conditions (:math:`\theta _{v,\, atm} -\theta _{v,\, s} \ge 0` as evaluated from :eq:`5.50`) and :math:`U_{c} =0.5` for unstable conditions (:math:`\theta _{v,\, atm} -\theta _{v,\, s} <0`). +#. An initial guess for the wind speed :math:`V_{a}` including the convective velocity :math:`U_{c}` is obtained from equation :eq:`5.24` assuming an initial convective velocity :math:`U_{c} =0` m s\ :sup:`-1` for stable conditions (:math:`\theta _{v,\, atm} -\theta _{v,\, s} \ge 0` as evaluated from equation :eq:`5.50`) and :math:`U_{c} =0.5` for unstable conditions (:math:`\theta _{v,\, atm} -\theta _{v,\, s} <0`). -#. An initial guess for the Monin-Obukhov length :math:`L` is obtained from the bulk Richardson number using :eq:`5.46` and :eq:`5.48`. +#. An initial guess for the Monin-Obukhov length :math:`L` is obtained from the bulk Richardson number using equations :eq:`5.46` and :eq:`5.48`. #. The following system of equations is iterated four times: -#. Heat of vaporization / sublimation :math:`\lambda` \ (:eq:`12.8`) +#. Heat of vaporization / sublimation :math:`\lambda` \ (equation :eq:`12.8`) -#. Thermal conductivity :math:`\lambda _{T}` \ (above) +#. Thermal conductivity :math:`\lambda _{T}` \ (described above after equation :eq:`12.13`) -#. Friction velocity :math:`u_{*}` (:eq:`5.32`, :eq:`5.33`, :eq:`5.34`, :eq:`5.35`) +#. Friction velocity :math:`u_{*}` (equations :eq:`5.32`, :eq:`5.33`, :eq:`5.34`, :eq:`5.35`) -#. Potential temperature scale :math:`\theta _{*}` (:eq:`5.37`, :eq:`5.38`, :eq:`5.39`, :eq:`5.40`) +#. Potential temperature scale :math:`\theta _{*}` (equations :eq:`5.37`, :eq:`5.38`, :eq:`5.39`, :eq:`5.40`) -#. Humidity scale :math:`q_{*}` (:eq:`5.41`, :eq:`5.42`, :eq:`5.43`, :eq:`5.44`) +#. Humidity scale :math:`q_{*}` (equations :eq:`5.41`, :eq:`5.42`, :eq:`5.43`, :eq:`5.44`) -#. Aerodynamic resistances :math:`r_{am}`, :math:`r_{ah}`, and :math:`r_{aw}` (:eq:`5.55`, :eq:`5.56`, :eq:`5.57`) +#. Aerodynamic resistances :math:`r_{am}`, :math:`r_{ah}`, and :math:`r_{aw}` (equations :eq:`5.55`, :eq:`5.56`, :eq:`5.57`) -#. Lake surface temperature :math:`T_{g}^{n+1}` (:eq:`12.18`) +#. Lake surface temperature :math:`T_{g}^{n+1}` (equation :eq:`12.18`) -#. Heat of vaporization / sublimation :math:`\lambda` (:eq:`12.8`) +#. Heat of vaporization / sublimation :math:`\lambda` (equation :eq:`12.8`) -#. Sensible heat flux :math:`H_{g}` is updated for :math:`T_{g}^{n+1}` (:eq:`12.9`) +#. Sensible heat flux :math:`H_{g}` is updated for :math:`T_{g}^{n+1}` (equation :eq:`12.9`) #. Water vapor flux :math:`E_{g}` is updated for :math:`T_{g}^{n+1}` as @@ -318,13 +293,13 @@ The fluxes of momentum, sensible heat, and water vapor are solved for simultaneo where the last term on the right side of equation :eq:`12.23` is the change in saturated specific humidity due to the change in :math:`T_{g}` between iterations. -#. Saturated specific humidity :math:`q_{sat}^{T_{g} }` and its derivative :math:`\frac{dq_{sat}^{T_{g} } }{dT_{g} }` are updated for :math:`T_{g}^{n+1}` (section :numref:`Monin-Obukhov Similarity Theory`). +14. Saturated specific humidity :math:`q_{sat}^{T_{g} }` and its derivative :math:`\frac{dq_{sat}^{T_{g} } }{dT_{g} }` are updated for :math:`T_{g}^{n+1}` (section :numref:`Monin-Obukhov Similarity Theory`). -#. Virtual potential temperature scale :math:`\theta _{v*}` (:eq:`5.17`) +#. Virtual potential temperature scale :math:`\theta _{v*}` (equation :eq:`5.17`) -#. Wind speed including the convective velocity, :math:`V_{a}` (:eq:`5.24`) +#. Wind speed including the convective velocity, :math:`V_{a}` (equation :eq:`5.24`) -#. Monin-Obukhov length :math:`L` (:eq:`5.49`) +#. Monin-Obukhov length :math:`L` (equation :eq:`5.49`) #. Roughness lengths (section :numref:`Surface Properties Lake`). @@ -375,28 +350,21 @@ where :math:`\tilde{c}_{v}` is the volumetric heat capacity (J m\ :sup:`-3` K\ : \frac{d}{dt} \sum _{j=1}^{N}\left[\tilde{c}_{v,j} (t)\left(T_{j} -T_{f} \right)+L_{j} (t)\right] \Delta z_{j} =G+\left(1-\beta \right)\vec{S}_{g} -where :math:`\tilde{c}_{v,j} (t)`\ is the volumetric heat capacity of the *j*\ th layer (section :numref:`Radiation Penetration`), :math:`L_{j} (t)`\ is the latent heat of fusion per unit volume of the *j*\ th layer (proportional to the mass of liquid water present), and the right-hand side represents the net influx of energy to the lake system. Note that :math:`\tilde{c}_{v,j} (t)` can only change due to phase change (except for changing snow layer mass, which, apart from energy required to melt snow, represents an untracked energy flux in the land model, along with advected energy associated with water flows in general), and this is restricted to occur at :math:`T_{j} =T_{f}` \ in the snow-lake-soil system, allowing eq. to be precisely enforced and justifying the exclusion of :math:`c_{v,j}` from the time derivative in eq.. - -.. _Overview of Changes from CLM4 2: - -Overview of Changes from CLM4 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Thermal conductivities include additional eddy diffusivity, beyond the :ref:`Hostetler and Bartlein (1990)` formulation, due to unresolved processes (:ref:`Fang and Stefan 1996`; :ref:`Subin et al. (2012a) `). Lake water is now allowed to freeze by an arbitrary fraction for each layer, which releases latent heat and changes thermal properties. Convective mixing occurs for all lakes, even if frozen. Soil and bedrock are included beneath the lake. The full snow model is used if the snow thickness exceeds a threshold; if there are resolved snow layers, radiation transfer is predicted by the snow-optics submodel (Chapter :numref:`rst_Surface Albedos`), and the remaining radiation penetrating the bottom snow layer is absorbed in the top layer of lake ice; conversely, if there are no snow layers, the solar radiation penetrating the bottom lake layer is absorbed in the top soil layer. The lakes have variable depth, and all physics is assumed valid for arbitrary depth, except for a depth-dependent enhanced mixing (section :numref:`Eddy Diffusivity and Thermal Conductivities`). Finally, a previous sign error in the calculation of eddy diffusivity (specifically, the Brunt-Väisälä frequency term; eq. ) was corrected. +where :math:`\tilde{c}_{v,j} (t)`\ is the volumetric heat capacity of the *j*\ th layer (section :numref:`Heat Capacities Lake`), :math:`L_{j} (t)`\ is the latent heat of fusion per unit volume of the *j*\ th layer (proportional to the mass of liquid water present), and the right-hand side represents the net influx of energy to the lake system. Note that :math:`\tilde{c}_{v,j} (t)` can only change due to phase change (except for changing snow layer mass, which, apart from energy required to melt snow, represents an untracked energy flux in the land model, along with advected energy associated with water flows in general), and this is restricted to occur at :math:`T_{j} =T_{f}` \ in the snow-lake-soil system, allowing equation :eq:`12.27` to be precisely enforced and justifying the exclusion of :math:`c_{v,j}` from the time derivative in equation :eq:`12.27`. .. _Boundary Conditions Lake: Boundary Conditions ^^^^^^^^^^^^^^^^^^^^^^^^^ -The top boundary condition, imposed at the top modeled layer :math:`i=j_{top}`, where :math:`j_{top} =-n_{sno} +1`, is the downwards surface flux *G* defined by the energy flux residual during the surface temperature solution (section :numref:`Boundary Conditions Lake`). The bottom boundary condition, imposed at :math:`i=N_{levlak} +N_{levgrnd}`, is zero flux. The 2-m windspeed :math:`u_{2}` \ (m s\ :sup:`-1`) is used in the calculation of eddy diffusivity: +The top boundary condition, imposed at the top modeled layer :math:`i=j_{top}`, where :math:`j_{top} =-n_{sno} +1`, is the downwards surface flux *G* defined by the energy flux residual during the surface temperature solution (section :numref:`Surface Flux Solution Lake`). The bottom boundary condition, imposed at :math:`i=N_{levlak} +N_{levgrnd}`, is zero flux. The 2-m windspeed :math:`u_{2}` \ (m s\ :sup:`-1`) is used in the calculation of eddy diffusivity: .. math:: :label: 12.28 u_{2} =\frac{u_{*} }{k} \ln \left(\frac{2}{z_{0m} } \right)\ge 0.1. -where :math:`u_{*}` \ is the friction velocity calculated in section :numref:`Boundary Conditions Lake` and +where :math:`u_{*}` \ is the friction velocity calculated in section :numref:`Monin-Obukhov Similarity Theory` and *k* is the von Karman constant (:numref:`Table Physical Constants`). .. _Eddy Diffusivity and Thermal Conductivities: @@ -419,7 +387,7 @@ where :math:`\kappa _{e}` is due to wind-driven eddies (:ref:`Hostetler and Bart .. math:: :label: 12.30 - m_{d} =\left\{\begin{array}{l} {1,\qquad d<25{\rm m}} \\ {10,\qquad d\ge 25{\rm m}} \end{array}\right\} + m_{d} =\Bigg\{\begin{array}{rr} {1,\qquad d<25{\rm m}} \\ {10,\qquad d\ge 25{\rm m}} \end{array} where *d* is the lake depth. @@ -428,9 +396,9 @@ The wind-driven eddy diffusion coefficient :math:`\kappa _{e,\, i}` (m\ :sup:`2` .. math:: :label: 12.31 - \kappa _{e,\, i} =\left\{\begin{array}{l} {\frac{kw^{*} z_{i} }{P_{0} \left(1+37Ri^{2} \right)} \exp \left(-k^{*} z_{i} \right)\qquad T_{g} >T_{f} } \\ {0\qquad T_{g} \le T_{f} } \end{array}\right\} + \kappa _{e,\, i} =\Bigg\{\begin{array}{rr} {\frac{kw^{*} z_{i} }{P_{0} \left(1+37Ri^{2} \right)} \exp \left(-k^{*} z_{i} \right)\qquad T_{g} >T_{f} } \\ {0\qquad T_{g} \le T_{f} } \end{array} -where :math:`P_{0} =1` is the neutral value of the turbulent Prandtl number, :math:`z_{i}` is the node depth (m), the surface friction velocity (m s\ :sup:`-1`) is :math:`w^{*} =0.0012u_{2}`, and :math:`k^{*}` varies with latitude :math:`\phi` as :math:`k^{*} =6.6u_{2}^{-1.84} \sqrt{\left|\sin \phi \right|}`. For the bottom layer, :math:`\kappa _{e,\, N_{levlak} } =\kappa _{e,N_{levlak} -1\, }`. As in :ref:`Hostetler and Bartlein (1990)`, the 2-m wind speed :math:`u_{2}` (m s\ :sup:`-1`) (eq. ) is used to evaluate :math:`w^{*}` and :math:`k^{*}` rather than the 10-m wind used by :ref:`Henderson-Sellers (1985) `. +where :math:`P_{0} =1` is the neutral value of the turbulent Prandtl number, :math:`z_{i}` is the node depth (m), the surface friction velocity (m s\ :sup:`-1`) is :math:`w^{*} =0.0012u_{2}`, and :math:`k^{*}` varies with latitude :math:`\phi` as :math:`k^{*} =6.6u_{2}^{-1.84} \sqrt{\left|\sin \phi \right|}`. For the bottom layer, :math:`\kappa _{e,\, N_{levlak} } =\kappa _{e,N_{levlak} -1\, }`. As in :ref:`Hostetler and Bartlein (1990)`, the 2-m wind speed :math:`u_{2}` (m s\ :sup:`-1`) (equation :eq:`12.28`) is used to evaluate :math:`w^{*}` and :math:`k^{*}` rather than the 10-m wind used by :ref:`Henderson-Sellers (1985) `. The Richardson number is @@ -446,7 +414,7 @@ where N^{2} =\frac{g}{\rho _{i} } \frac{\partial \rho }{\partial z} -and :math:`g` is the acceleration due to gravity (m s\ :sup:`-2`) (:numref:`Table Physical Constants`), :math:`\rho _{i}` is the density of water (kg m\ :sup:`-3`), and :math:`\frac{\partial \rho }{\partial z}` is approximated as :math:`\frac{\rho _{i+1} -\rho _{i} }{z_{i+1} -z_{i} }`. Note that because here, *z* is increasing downwards (unlike in :ref:`Hostetler and Bartlein (1990)`), eq. contains no negative sign; this is a correction from CLM4. The density of water is (:ref:`Hostetler and Bartlein (1990)`) +and :math:`g` is the acceleration due to gravity (m s\ :sup:`-2`) (:numref:`Table Physical Constants`), :math:`\rho _{i}` is the density of water (kg m\ :sup:`-3`), and :math:`\frac{\partial \rho }{\partial z}` is approximated as :math:`\frac{\rho _{i+1} -\rho _{i} }{z_{i+1} -z_{i} }`. Note that because here, *z* is increasing downwards (unlike in :ref:`Hostetler and Bartlein (1990)`), equation :eq:`12.33` contains no negative sign; this is a correction from CLM4. The density of water is (:ref:`Hostetler and Bartlein (1990)`) .. math:: :label: 12.34 @@ -460,7 +428,7 @@ The enhanced diffusivity :math:`K_{ed}` is given by (:ref:`Fang and Stefan 1996< K_{ed} =1.04\times 10^{-8} \left(N^{2} \right)^{-0.43} ,N^{2} \ge 7.5\times 10^{-5} {\rm s}^{2} -where :math:`N^{2}` \ is calculated as in eq. except for the minimum value imposed in. +where :math:`N^{2}` \ is calculated as in equation :eq:`12.33` except for the minimum value imposed by equation :eq:`12.35`. The thermal conductivity for the liquid water portion of lake body layer *i*, :math:`\tau _{liq,i}` (W m\ :sup:`-1` K\ :sup:`-1`) is given by @@ -485,14 +453,14 @@ The overall thermal conductivity :math:`\tau _{i}` for layer *i* with ice mass-f \tau _{i} =\frac{\tau _{ice,eff} \tau _{liq,i} }{\tau _{liq,i} I_{i} +\tau _{ice} \left(1-I_{i} \right)} . -The thermal conductivity of snow, soil, and bedrock layers above and below the lake, respectively, are computed identically to those for vegetated land units (Chapter :numref:`rst_Soil and Snow Temperatures`), except for the adjustment of thermal conductivity for frost heave or excess ice (:ref:`Subin et al., 2012a, Supporting Information`). +The thermal conductivity of snow, soil, and bedrock layers above and below the lake, respectively, are computed identically to those for vegetated land units (Chapter :numref:`rst_Soil and Snow Temperatures`), except for the adjustment of thermal conductivity for frost heave or excess ice (:ref:`Subin et al., 2012a, Supporting Information`). In CLM6 users can optionally specify using :ref:`Sturm et al. (1997)` or :ref:`Jordan (1991)` parameterizations for snow thermal conductivity over lakes (see Chapter :numref:`rst_Soil and Snow Temperatures`), with :ref:`Sturm et al. (1997)` set as the default. .. _Radiation Penetration: Radiation Penetration ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If there are no resolved snow layers, the surface absorption fraction :math:`\beta` is set according to the near-infrared fraction simulated by the atmospheric model. This is apportioned to the surface energy budget (section :numref:`Surface Properties Lake`), and thus no additional radiation is absorbed in the top :math:`z_{a}` (currently 0.6 m) of unfrozen lakes, for which the light extinction coefficient :math:`\eta` (m\ :sup:`-1`) varies between lake columns (eq. ). For frozen lakes (:math:`T_{g} \le T_{f}` ), the remaining :math:`\left(1-\beta \right)\vec{S}_{g}` fraction of surface absorbed radiation that is not apportioned to the surface energy budget is absorbed in the top lake body layer. This is a simplification, as lake ice is partially transparent. If there are resolved snow layers, then the snow optics submodel (Chapter :numref:`rst_Surface Albedos`) is used to calculate the snow layer absorption (except for the absorption predicted for the top layer by the snow optics submodel, which is assigned to the surface energy budget), with the remainder penetrating snow layers absorbed in the top lake body ice layer. +If there are no resolved snow layers, the surface absorption fraction :math:`\beta` is set according to the near-infrared fraction simulated by the atmospheric model. This is apportioned to the surface energy budget (section :numref:`Surface Properties Lake`), and thus no additional radiation is absorbed in the top :math:`z_{a}` (currently 0.6 m) of unfrozen lakes, for which the light extinction coefficient :math:`\eta` (m\ :sup:`-1`) varies between lake columns (equation :eq:`12.41`). For frozen lakes (:math:`T_{g} \le T_{f}` ), the remaining :math:`\left(1-\beta \right)\vec{S}_{g}` fraction of surface absorbed radiation that is not apportioned to the surface energy budget is absorbed in the top lake body layer. This is a simplification, as lake ice is partially transparent. If there are resolved snow layers, then the snow optics submodel (Chapter :numref:`rst_Surface Albedos`) is used to calculate the snow layer absorption (except for the absorption predicted for the top layer by the snow optics submodel, which is assigned to the surface energy budget), with the remainder penetrating snow layers absorbed in the top lake body ice layer. For unfrozen lakes, the solar radiation remaining at depth :math:`z>z_{a}` in the lake body is given by @@ -559,7 +527,7 @@ where superscripts *n* + 1 and *n* denote values at the end and beginning of the :math:`F_{i}` (W m\ :sup:`-2`) is the downward heat flux at the bottom of layer *i*, and :math:`\phi _{i}` is the solar radiation absorbed in layer *i*. -Eq. is solved using the semi-implicit Crank-Nicholson Method, resulting in a tridiagonal system of equations: +Equation :eq:`12.44` is solved using the semi-implicit Crank-Nicholson Method, resulting in a tridiagonal system of equations: .. math:: :label: 12.45 @@ -612,14 +580,14 @@ Finally, the mass of ice in the layer :math:`M_{ice}` is adjusted downwards by : where :math:`c'_{v,i} =c_{v,i} +M\left(c_{liq} -c_{ice} \right)`. -If freezing occurs, :math:`Q_{avail}` is again given by but will be negative. The melt :math:`M`, also negative, is given by +If freezing occurs, :math:`Q_{avail}` is again given by equation :eq:`12.47`, but will be negative. The melt :math:`M`, also negative, is given by .. math:: :label: 12.51 M=\max \left\{-M_{liq} ,\frac{Q_{avail} }{H_{fus} } \right\} -where :math:`M_{liq}` is the mass of water in the layer: :math:`\left(1-I_{i} \right)\rho _{liq} \Delta z_{i}` for a lake body layer, or the soil / snow water content state variable (:math:`w_{liq}` ). The heat remainder :math:`Q_{rem}` is given by eq. and will be negative or zero. Finally, :math:`M_{liq}` is adjusted downwards by :math:`-M` and the temperature is reset according to eq.. +where :math:`M_{liq}` is the mass of water in the layer: :math:`\left(1-I_{i} \right)\rho _{liq} \Delta z_{i}` for a lake body layer, or the soil / snow water content state variable (:math:`w_{liq}` ). The heat remainder :math:`Q_{rem}` is given by equation :eq:`12.49` and will be negative or zero. Finally, :math:`M_{liq}` is adjusted downwards by :math:`-M` and the temperature is reset according to equation :eq:`12.50` In the presence of nonzero snow water :math:`W_{sno}` without resolved snow layers over an unfrozen top lake layer, the available energy in the top lake layer :math:`\left(T_{1} -T_{f} \right)c_{v,1}` is used to melt the snow. Similar to above, :math:`W_{sno}` is either completely melted and the remainder of heat returned to the top lake layer, or the available heat is exhausted and the top lake layer is set to freezing. The snow thickness is adjusted downwards in proportion to the amount of melt, maintaining constant density. @@ -704,7 +672,7 @@ Lake Hydrology Overview ^^^^^^^^^^^^^^ -Hydrology is done similarly to other impervious non-vegetated columns (e.g., glaciers) where snow layers may be resolved but infiltration into the permanent ground is not allowed. The water mass of lake columns is currently maintained constant, aside from overlying snow. The water budget is balanced with :math:`q_{rgwl}` (eq.; kg m\ :sup:`-2` s\ :sup:`-1`), a generalized runoff term for impervious land units that may be negative. +Hydrology is done similarly to other impervious non-vegetated columns (e.g., glaciers) where snow layers may be resolved but infiltration into the permanent ground is not allowed. The water mass of lake columns is currently maintained constant, aside from overlying snow. The water budget is balanced with :math:`q_{rgwl}` (kg m\ :sup:`-2` s\ :sup:`-1`), a generalized runoff term for impervious land units that may be negative (see section :numref:`rst_Hydrology` for more information about :math:`q_{rgwl}`). There are some modifications to the soil and snow parameterizations as compared with the soil in vegetated land units, or the snow overlying other impervious columns. The soil can freeze or thaw, with the allowance for frost heave (or the initialization of excess ice) (sections :numref:`Eddy Diffusivity and Thermal Conductivities` and :numref:`Phase Change Lake`), but no air-filled pore space is allowed in the soil. To preserve numerical stability in the lake model (which uses a slightly different surface flux algorithm than over other non-vegetated land units), two changes are made to the snow model. First, dew or frost is not allowed to be absorbed by a top snow layer which has become completely melted during the timestep. Second, because occasional instabilities occurred during model testing when the Courant–Friedrichs–Lewy (CFL) condition was violated, due to the explicit time-stepping integration of the surface flux solution, resolved snow layers must be a minimum of :math:`s_{\min }` = 4 cm thick rather than 1 cm when the default timestep of 1800 s is used. diff --git a/doc/source/tech_note/MOSART/CLM50_Tech_Note_MOSART.rst b/doc/source/tech_note/MOSART/CLM50_Tech_Note_MOSART.rst index 674e4cc0b3..36bf94bdb8 100644 --- a/doc/source/tech_note/MOSART/CLM50_Tech_Note_MOSART.rst +++ b/doc/source/tech_note/MOSART/CLM50_Tech_Note_MOSART.rst @@ -32,7 +32,7 @@ In MOSART, the travel velocities of water across hillslopes, sub-network and mai .. math:: :label: 14.1 - V = \frac{R^{\frac{2}{3}} S_{f}}{n} + V = \frac{R^{\frac{2}{3}} S_{f}^{\frac{1}{2}}}{n} where :math:`V` is the travel velocity (m s :sup:`-1` ), :math:`R` is the hydraulic radius (m). :math:`S_{f}` is the friction slope that accounts for the effects of gravity, friction, inertia and other forces on the water. If the channel slope is steep enough, the gravity force dominates over the others so one can approximate :math:`S_{f}` by the channel bed slope :math:`S`, which is the key assumption underpinning the kinematic wave method. :math:`n` is the Manning's roughness coefficient, which is mainly controlled by surface roughness and sinuosity of the flow path. @@ -41,7 +41,7 @@ If the water surface is sufficiently large or the water depth :math:`h` is suffi .. math:: :label: 14.2 - R_{h} = h_{h} + R_{h} = h_{h} \\ R_{t} = h_{t} Here :math:`R_{h}` (m) and :math:`R_{t}` (m) are hydraulic radius for hillslope and sub-network channel routing respectively, and :math:`h_{h}` (m) and :math:`h_{t}` (m) are water depth during hillslope and sub-network channel routing respectively. @@ -60,9 +60,9 @@ For hillslopes, sub-network and main channels, a common continuity equation can .. math:: :label: 14.4 - \frac{dS}{dt} = Q_{in} - Q_{out} + R + \frac{dS}{dt} = Q_{in} - Q_{out} + R - I -where :math:`Q_{in}` (m :sup:`3` s :sup:`-1` ) is the main channel flow from the upstream grid(s) into the main channel of the current grid, which is zero for hillslope and sub-network routing. :math:`Q_{out}` (m :sup:`3` s :sup:`-1` ) is the outflow rate from hillslope into the sub-network, from the sub-network into the main channel, or from the current main channel to the main channel of its downstream grid (if not the outlet grid) or ocean (if the current grid is the basin outlet). :math:`R` (m :sup:`3` s :sup:`-1` ) is a source term, which could be the surface runoff generation rate for hillslopes, or lateral inflow (from hillslopes) into sub-network channel or water-atmosphere exchange fluxes such as precipitation and evaporation. It is assumed that surface runoff is generated uniformly across all the hillslopes. Currently, MOSART does not exchange water with the atmosphere or return water to the land model so its function is strictly to transport water from runoff generation through the hillslope, tributaries, and main channels to the basin outlets. +where :math:`Q_{in}` (m :sup:`3` s :sup:`-1` ) is the main channel flow from the upstream grid(s) into the main channel of the current grid, which is zero for hillslope and sub-network routing. :math:`Q_{out}` (m :sup:`3` s :sup:`-1` ) is the outflow rate from hillslope into the sub-network, from the sub-network into the main channel, or from the current main channel to the main channel of its downstream grid (if not the outlet grid) or ocean (if the current grid is the basin outlet). :math:`R` (m :sup:`3` s :sup:`-1` ) is a source term, which could be the surface runoff generation rate for hillslopes, or lateral inflow (from hillslopes) into sub-network channel or water-atmosphere exchange fluxes such as precipitation and evaporation. It is assumed that surface runoff is generated uniformly across all the hillslopes. :math:`I` is water abstraction via irrigation demand only from main channel (i.e., :math:`I` = 0 for hillslope and sub-network). Currently, MOSART does not exchange water with the atmosphere, but returns water from a main channel to the land model based on irrigation demand if irrigation opition is actived in the land model. .. _Numerical Solution MOSART: @@ -112,14 +112,3 @@ MOSART is supported by a comprehensive, global hydrography dataset at 0.5 ° res | :math:`n_{h}` | \- | Manning's roughness coefficient for overland flow routing | +-------------------------+---------------+------------------------------------------------------------------------------------------------------------------------------------+ -Difference between CLM5.0 and CLM4.5 -------------------------------------- - -1. Routing methods: RTM, a linear reservoir method, is used in CLM4.5 for river routing, whilst in CLM5.0, MOSART is an added option for river routing based on the more physically-based kinematic wave method. - -2. Runoff treatment: In RTM runoff is routed regardless of its sign so negative streamflow can be simulated at times. MOSART routes only non-negative runoff and always produces positive streamflow, which is important for future extensions to model riverine heat and biogeochemical fluxes. - -3. Input parameters: RTM in CLM4.5 only requires one layer of a spatially varying variable of channel velocity, whilst MOSART in CLM5.0 requires 13 parameters that are all available globally at 0.5 ° resolution. - -4. Outputs: RTM only produces streamflow simulation, whilst MOSART additionally simulates the time-varying channel velocities, channel water depth, and channel surface water variations. - diff --git a/doc/source/tech_note/Methane/CLM50_Tech_Note_Methane.rst b/doc/source/tech_note/Methane/CLM50_Tech_Note_Methane.rst index ac45114a28..f489dce3be 100644 --- a/doc/source/tech_note/Methane/CLM50_Tech_Note_Methane.rst +++ b/doc/source/tech_note/Methane/CLM50_Tech_Note_Methane.rst @@ -12,7 +12,9 @@ Mechanistically modeling net surface CH\ :sub:`4` emissions requires representin Methane Model Structure and Flow ------------------------------------- -The driver routine for the methane biogeochemistry calculations (ch4, in ch4Mod.F) controls the initialization of boundary conditions, inundation, and impact of redox conditions; calls to routines to calculate CH\ :sub:`4` production, oxidation, transport through aerenchyma, ebullition, and the overall mass balance (for unsaturated and saturated soils and, if desired, lakes); resolves changes to CH\ :sub:`4` calculations associated with a changing inundated fraction; performs a mass balance check; and calculates the average gridcell CH\ :sub:`4` production, oxidation, and exchanges with the atmosphere. +The driver routine for the methane biogeochemistry calculations controls the initialization of boundary conditions, inundation, and impact of redox conditions; calls to routines to calculate CH\ :sub:`4` production, oxidation, transport through aerenchyma, ebullition, and the overall mass balance (for unsaturated and saturated soils and, if desired, lakes); resolves changes to CH\ :sub:`4` calculations associated with a changing inundated fraction; performs a mass balance check; and calculates the average column CH\ :sub:`4` production, oxidation, and exchanges with the atmosphere. + +Default history includes a short list of methane-related fields. One can set namelist parameter ``hist_wrtch4diag = .true.`` to obtain a list of methane-related fields that is longer by about 20. Alternatively one may use namelist fincl statements to add individual fields of interest to history. .. _Governing Mass-Balance Relationship: @@ -30,22 +32,21 @@ Here *z* (m) represents the vertical dimension, *t* (s) is time, and *R* account An analogous version of equation :eq:`24.1` is concurrently solved for O\ :sub:`2`, but with the following differences relative to CH\ :sub:`4`: *P* = *E* = 0 (i.e., no production or ebullition), and the oxidation sink includes the O\ :sub:`2` demanded by methanotrophs, heterotroph decomposers, nitrifiers, and autotrophic root respiration. -As currently implemented, each gridcell contains an inundated and a non-inundated fraction. Therefore, equation :eq:`24.1` is solved four times for each gridcell and time step: in the inundated and non-inundated fractions, and for CH\ :sub:`4` and O\ :sub:`2`. If desired, the CH\ :sub:`4` and O\ :sub:`2` mass balance equation is solved again for lakes (Chapter 9). For non-inundated areas, the water table interface is defined at the deepest transition from greater than 95% saturated to less than 95% saturated that occurs above frozen soil layers. The inundated fraction is allowed to change at each time step, and the total soil CH\ :sub:`4` quantity is conserved by evolving CH\ :sub:`4` to the atmosphere when the inundated fraction decreases, and averaging a portion of the non-inundated concentration into the inundated concentration when the inundated fraction increases. +As currently implemented, each column contains an inundated and a non-inundated fraction. Therefore, equation :eq:`24.1` is solved four times for each column and time step: in the inundated and non-inundated fractions, and for CH\ :sub:`4` and O\ :sub:`2`. If desired, the CH\ :sub:`4` and O\ :sub:`2` mass balance equation is solved again for lakes (Chapter 9). For non-inundated areas, the water table interface is defined at the deepest transition from greater than 95% saturated to less than 95% saturated that occurs above frozen soil layers. The inundated fraction is allowed to change at each time step, and the total soil CH\ :sub:`4` quantity is conserved by adjusting the non-inundated concentration and the inundated concentration when the inundated fraction changes. .. _Figure Methane Schematic: -.. figure:: image1.png - - Schematic representation of biological and physical processes integrated in CLM that affect the net CH\ :sub:`4` - surface flux (:ref:`Riley et al. 2011a`). (left) - Fully inundated portion of a CLM gridcell and (right) variably saturated portion of a gridcell. +.. Figure:: image1.png + :align: center + + Schematic representation of biological and physical processes integrated in CLM that affect the net CH\ :sub:`4` surface flux (:ref:`Riley et al. 2011a`). (left) Fully inundated portion of a CLM column and (right) variably saturated portion of a column. .. _CH4 Production: CH\ :sub:`4` Production ---------------------------------- -Because CLM does not currently specifically represent wetland plant functional types or soil biogeochemical processes, we used gridcell-averaged decomposition rates as proxies. Thus, the upland (default) heterotrophic respiration is used to estimate the wetland decomposition rate after first dividing off the O\ :sub:`2` limitation. The O\ :sub:`2` consumption associated with anaerobic decomposition is then set to the unlimited version so that it will be reduced appropriately during O\ :sub:`2` competition. CH\ :sub:`4` production at each soil level in the anaerobic portion (i.e., below the water table) of the column is related to the gridcell estimate of heterotrophic respiration from soil and litter (R\ :sub:`H`; mol C m\ :sup:`-2` s\ :sub:`-1`) corrected for its soil temperature (:math:`{T}_{s}`) dependence, soil temperature through a :math:`{A}_{10}` factor (:math:`f_{T}`), pH (:math:`f_{pH}`), redox potential (:math:`f_{pE}`), and a factor accounting for the seasonal inundation fraction (*S*, described below): +Because CLM does not currently specifically represent wetland plant functional types or soil biogeochemical processes, we used column-averaged decomposition rates as proxies. Thus, the upland (default) heterotrophic respiration is used to estimate the wetland decomposition rate after first dividing off the O\ :sub:`2` limitation. The O\ :sub:`2` consumption associated with anaerobic decomposition is then set to the unlimited version so that it will be reduced appropriately during O\ :sub:`2` competition. CH\ :sub:`4` production at each soil level in the anaerobic portion (i.e., below the water table) of the column is related to the column estimate of heterotrophic respiration from soil and litter (R\ :sub:`H`; mol C m\ :sup:`-2` s\ :sub:`-1`) corrected for its soil temperature (:math:`{T}_{s}`) dependence, soil temperature through a :math:`{Q}_{10}` factor (:math:`f_{T}`), pH (:math:`f_{pH}`), redox potential (:math:`f_{pE}`), and a factor accounting for the seasonal inundation fraction (*S*, described below): .. math:: :label: 24.2 @@ -54,9 +55,7 @@ Because CLM does not currently specifically represent wetland plant functional t Here, :math:`f_{CH_{4} }` is the baseline ratio between CO\ :sub:`2` and CH\ :sub:`4` production (all parameters values are given in :numref:`Table Methane Parameter descriptions`). Currently, :math:`f_{CH_{4} }` is modified to account for our assumptions that methanogens may have a higher Q\ :math:`{}_{10}` than aerobic decomposers; are not N limited; and do not have a low-moisture limitation. -When the single BGC soil level is used in CLM (Chapter :numref:`rst_Decomposition`), the temperature factor, :math:`f_{T}`, is set to 0 for temperatures equal to or below freezing, even though CLM allows heterotrophic respiration below freezing. However, if the vertically resolved BGC soil column is used, CH\ :sub:`4` production continues below freezing because liquid water stress limits decomposition. The base temperature for the :math:`{Q}_{10}` factor, :math:`{T}_{B}`, is 22°C and effectively modified the base :math:`f_{CH_{4}}` value. - -For the single-layer BGC version, :math:`{R}_{H}` is distributed among soil levels by assuming that 50% is associated with the roots (using the CLM PFT-specific rooting distribution) and the rest is evenly divided among the top 0.28 m of soil (to be consistent with CLM's soil decomposition algorithm). For the vertically resolved BGC version, the prognosed distribution of :math:`{R}_{H}` is used to estimate CH\ :sub:`4` production. +The prognosed :math:`{R}_{H}` is used to estimate the vertical distribution of CH\ :sub:`4` production. CLM allows heterotrophic respiration below freezing, so :math:`f_{T}` may be nonzero and CH\ :sub:`4` production continues when temperatures are below freezing, although liquid water stress limits decomposition. The base temperature for the :math:`{Q}_{10}` factor, :math:`{T}_{B}`, is 22°C and effectively modified the base :math:`f_{CH_{4}}` value. The factor :math:`f_{pH}` is nominally set to 1, although a static spatial map of *pH* can be used to determine this factor (:ref:`Dunfield et al. 1993`) by applying: @@ -65,7 +64,7 @@ The factor :math:`f_{pH}` is nominally set to 1, although a static spatial map o f_{pH} =10^{-0.2235pH^{2} +2.7727pH-8.6} . -The :math:`f_{pE}` factor assumes that alternative electron acceptors are reduced with an e-folding time of 30 days after inundation. The default version of the model applies this factor to horizontal changes in inundated area but not to vertical changes in the water table depth in the upland fraction of the gridcell. We consider both :math:`f_{pH}` and :math:`f_{pE}` to be poorly constrained in the model and identify these controllers as important areas for model improvement. +The :math:`f_{pE}` factor assumes that alternative electron acceptors are reduced with an e-folding time of 30 days after inundation. The default version of the model applies this factor to horizontal changes in inundated area but not to vertical changes in the water table depth in the upland fraction of the column. We consider both :math:`f_{pH}` and :math:`f_{pE}` to be poorly constrained in the model and identify these controllers as important areas for model improvement. As a non-default option to account for CH\ :sub:`4` production in anoxic microsites above the water table, we apply the Arah and Stephen (1998) estimate of anaerobic fraction: @@ -256,7 +255,8 @@ To simplify the solution, we assumed that gaseous diffusion dominates above the Boundary Conditions ^^^^^^^^^^^^^^^^^^^^^^^^^^ -We assume the CH\ :sub:`4` and O\ :sub:`2` surface fluxes can be calculated from an effective conductance and a gaseous concentration gradient between the atmospheric concentration and either the gaseous concentration in the first soil layer (unsaturated soils) or in equilibrium with the water (saturated soil\ :math:`w\left(C_{1}^{n} -C_{a} \right)` and :math:`w\left(C_{1}^{n+1} -C_{a} \right)` for the fully explicit and fully implicit cases, respectively (however, see :ref:`Tang and Riley (2013)` for a more complete representation of this process). Here, *w* is the surface boundary layer conductance as calculated in the existing CLM surface latent heat calculations. If the top layer is not fully saturated, the :math:`\frac{D_{m1} }{\Delta x_{m1} }` term is replaced with a series combination: :math:`\left[\frac{1}{w} +\frac{\Delta x_{1} }{D_{1} } \right]^{-1}`, and if the top layer is saturated, this term is replaced with :math:`\left[\frac{K_{H} }{w} +\frac{\frac{1}{2} \Delta x_{1} }{D_{1} } \right]^{-1}`, where :math:`{K}_{H}` is the Henry's law equilibrium constant. +We assume the CH\ :sub:`4` and O\ :sub:`2` surface fluxes can be calculated from an effective conductance and a gaseous concentration gradient between the atmospheric concentration and either the gaseous concentration in the surface soil layer (for the non-inundated calculation) or in equilibrium with the surface water (for the inundated calculation). In addition to the resolved soil layers, a surface layer is used in the methane module to account for the presence of surface water in the inundated fraction of the column or unsaturated conditions in the non-inundated fraction of the column. The thickness of the surface layer, :math:`\Delta z_{sfc}`, is given by the surface water thickness :math:`W_{sfc}` (in meters) for the inundated calculation or by :math:`3 \ \sigma _{micro} - W_{sfc}` for the non-inundated calculation, where :math:`\sigma _{micro}` is the standard deviation of microtopography :eq:`7.68`. The inclusion of the surface layer ensures that an unsaturated zone exists in the non-inundated fraction of the column even if the top soil layer is saturated. The surface boundary layer conductance, :math:`w`, is calculated in the existing CLM surface latent heat calculations. If the top layer is not fully saturated, the :math:`\frac{D_{m1} }{\Delta x_{m1} }` term is replaced with a series combination: :math:`\left[\frac{1}{w} +\frac{\Delta x_{1} }{D_{1} } \right]^{-1}`, and if the top layer is saturated, this term is replaced with :math:`\left[\frac{K_{H} }{w} +\frac{\frac{1}{2} \Delta x_{1} }{D_{1} } \right]^{-1}`, where :math:`{K}_{H}` is the Henry's law equilibrium constant. + When snow is present, a resistance is added to account for diffusion through the snow based on the Millington-Quirk expression :eq:`24.13` and CLM's prediction of the liquid water, ice, and air fractions of each snow layer. When the soil is ponded, the diffusivity is assumed to be that of methane in pure water, and the resistance as the ratio of the ponding depth to diffusivity. The overall conductance is taken as the series combination of surface, snow, and ponding resistances. We assume a zero flux gradient at the bottom of the soil column. @@ -321,15 +321,14 @@ and the soil element below the interface: Inundated Fraction Prediction ---------------------------------- - -A simplified dynamic representation of spatial inundation based on recent work by :ref:`Prigent et al. (2007)` is used. :ref:`Prigent et al. (2007)` described a multi-satellite approach to estimate the global monthly inundated fraction (:math:`{F}_{i}`) over an equal area grid (0.25 :math:`\circ` \ :math:`\times`\ 0.25\ :math:`\circ` at the equator) from 1993 - 2000. They suggested that the IGBP estimate for inundation could be used as a measure of sensitivity of their detection approach at low inundation. We therefore used the sum of their satellite-derived :math:`{F}_{i}` and the constant IGBP estimate when it was less than 10% to perform a simple inversion for the inundated fraction for methane production (:math:`{f}_{s}`). The method optimized two parameters (:math:`{fws}_{slope}` and :math:`{fws}_{intercept}`) for each grid cell in a simple model based on simulated total water storage (:math:`{TWS}`): +When surface water (:math:`W_{sfc}`) is nonzero, the fraction of the land surface that is inundated, :math:`f_{h2osfc}`, is given by equation :eq:`7.67`. For cases in which the prognosed inundated fraction is deemed unrealistic, an observationally based inundated area, :math:`{f}_{s}`, based on work by :ref:`Prigent et al. (2007)` can be used. :ref:`Prigent et al. (2007)` described a multi-satellite approach to estimate the global monthly inundated fraction (:math:`{F}_{i}`) over an equal area grid (0.25 :math:`\circ` \ :math:`\times`\ 0.25\ :math:`\circ` at the equator) from 1993 - 2000. They suggested that the IGBP estimate for inundation could be used as a measure of sensitivity of their detection approach at low inundation. We therefore used the sum of their satellite-derived :math:`{F}_{i}` and the constant IGBP estimate when it was less than 10% to perform a simple inversion for the inundated fraction for methane production (:math:`{f}_{s}`). The method optimized two parameters (:math:`{fws}_{slope}` and :math:`{fws}_{intercept}`) for each grid cell in a simple model based on simulated total water storage (:math:`{TWS}`): .. math:: :label: 24.20 f_{s} =fws_{slope} TWS + fws_{intercept} . -These parameters were evaluated at the 0.5° resolution, and aggregated for coarser simulations. Ongoing work in the hydrology submodel of CLM may alleviate the need for this crude simplification of inundated fraction in future model versions. +These parameters were evaluated at the 0.5° resolution, and aggregated for coarser simulations. .. _Seasonal Inundation: diff --git a/doc/source/tech_note/Photosynthesis/CLM50_Tech_Note_Photosynthesis.rst b/doc/source/tech_note/Photosynthesis/CLM50_Tech_Note_Photosynthesis.rst index 8c0899cc17..6410556ac8 100644 --- a/doc/source/tech_note/Photosynthesis/CLM50_Tech_Note_Photosynthesis.rst +++ b/doc/source/tech_note/Photosynthesis/CLM50_Tech_Note_Photosynthesis.rst @@ -3,16 +3,14 @@ Stomatal Resistance and Photosynthesis ========================================= -Summary of CLM5.0 updates relative to the CLM4.5 ------------------------------------------------------ +History +------- -We describe here the complete photosynthesis and stomatal conductance parameterizations that appear in CLM5.0. Corresponding information for CLM4.5 appeared in the CLM4.5 Technical Note (:ref:`Oleson et al. 2013 `). - -CLM5 includes the following new changes to photosynthesis and stomatal conductance: +We describe here the complete photosynthesis and stomatal conductance parameterizations that appear in CLM6.0. In this version relative to CLM5, we have changed numerous parameter values, but have kept the algorithm unchanged. In CLM5 relative to CLM4.5, this section included the following updates: - Default stomatal conductance calculation uses the Medlyn conductance model -- :math:`V_{c,max}` and :math:`J_{max}` at 25 :sup:`\o`\ C: are now prognostic, and predicted via optimality by the LUNA model (Chapter :numref:`rst_Photosynthetic Capacity`) +- :math:`V_{c,max}` and :math:`J_{max}` at 25\ :sup:`\o`\ C: are now prognostic, and predicted via optimality by the LUNA model (Chapter :numref:`rst_Photosynthetic Capacity`) - Leaf N concentration and the fraction of leaf N in Rubisco used to calculate :math:`V_{cmax25}` are determined by the LUNA model (Chapter :numref:`rst_Photosynthetic Capacity`) @@ -28,16 +26,16 @@ Leaf stomatal resistance, which is needed for the water vapor flux (Chapter :num Stomatal resistance ----------------------- -CLM5 calculates stomatal conductance using the Medlyn stomatal conductance model (:ref:`Medlyn et al. 2011`). Previous versions of CLM calculated leaf stomatal resistance using the Ball-Berry conductance model as described by :ref:`Collatz et al. (1991)` and implemented in global climate models (:ref:`Sellers et al. 1996`). The Medlyn model calculates stomatal conductance (i.e., the inverse of resistance) based on net leaf photosynthesis, the leaf-to-air vapor pressure difference, and the CO\ :sub:`2` concentration at the leaf surface. Leaf stomatal resistance is: +Since CLM5 the model has calculated stomatal conductance using the Medlyn stomatal conductance model (:ref:`Medlyn et al. 2011`). Previous versions of CLM calculated leaf stomatal resistance using the Ball-Berry conductance model as described by :ref:`Collatz et al. (1991)` and implemented in global climate models (:ref:`Sellers et al. 1996`). The Medlyn model calculates stomatal conductance (i.e., the inverse of resistance) based on net leaf photosynthesis, the leaf-to-air vapor pressure difference, and the CO\ :sub:`2` concentration at the leaf surface. Leaf stomatal resistance is: .. math:: :label: 9.1 \frac{1}{r_{s} } =g_{s} = g_{o} + 1.6(1 + \frac{g_{1} }{\sqrt{D_{s}}}) \frac{A_{n} }{{c_{s} \mathord{\left/ {\vphantom {c_{s} P_{atm} }} \right.} P_{atm} } } -where :math:`r_{s}` is leaf stomatal resistance (s m\ :sup:`2` :math:`\mu`\ mol\ :sup:`-1`), :math:`g_{o}` is the minimum stomatal conductance (:math:`\mu` mol m :sup:`-2` s\ :sup:`-1`), :math:`A_{n}` is leaf net photosynthesis (:math:`\mu`\ mol CO\ :sub:`2` m\ :sup:`-2` s\ :sup:`-1`), :math:`c_{s}` is the CO\ :sub:`2` partial pressure at the leaf surface (Pa), :math:`P_{atm}` is the atmospheric pressure (Pa), and :math:`D_{s}=(e_{i}-e{_s})/1000` is the leaf-to-air vapor pressure difference at the leaf surface (kPa) where :math:`e_{i}` is the saturation vapor pressure (Pa) evaluated at the leaf temperature :math:`T_{v}`, and :math:`e_{s}` is the vapor pressure at the leaf surface (Pa). :math:`g_{1}` is a plant functional type dependent parameter (:numref:`Table Plant functional type (PFT) stomatal conductance parameters`) and are the same as those used in the CABLE model (:ref:`de Kauwe et al. 2015 `). +where :math:`r_{s}` is leaf stomatal resistance (s m\ :sup:`2` :math:`\mu`\ mol\ :sup:`-1`), :math:`A_{n}` is leaf net photosynthesis (:math:`\mu`\ mol CO\ :sub:`2` m\ :sup:`-2` s\ :sup:`-1`), :math:`c_{s}` is the CO\ :sub:`2` partial pressure at the leaf surface (Pa), :math:`P_{atm}` is the atmospheric pressure (Pa), and :math:`D_{s}=(e_{i}-e{_s})/1000` is the leaf-to-air vapor pressure difference at the leaf surface (kPa) where :math:`e_{i}` is the saturation vapor pressure (Pa) evaluated at the leaf temperature :math:`T_{v}`, and :math:`e_{s}` is the vapor pressure at the leaf surface (Pa). :math:`g_{o}` is plant functional type (pft)-dependent minimum stomatal conductance (:math:`\mu` mol m :sup:`-2` s\ :sup:`-1`) and :math:`g_{1}` is a pft-dependent parameter (:numref:`Table Plant functional type (PFT) stomatal conductance parameters`) with same values originally as in the CABLE model (:ref:`de Kauwe et al. 2015 `) but most values have been replaced in CLM6. -The value for :math:`g_{o}=100` :math:`\mu` mol m :sup:`-2` s\ :sup:`-1` for C\ :sub:`3` and C\ :sub:`4` plants. Photosynthesis is calculated for sunlit (:math:`A^{sun}`) and shaded (:math:`A^{sha}`) leaves to give :math:`r_{s}^{sun}` and :math:`r_{s}^{sha}`. Additionally, soil water influences stomatal resistance through plant hydraulic stress, detailed in the :ref:`rst_Plant Hydraulics` chapter. +Photosynthesis is calculated for sunlit (:math:`A^{sun}`) and shaded (:math:`A^{sha}`) leaves to give :math:`r_{s}^{sun}` and :math:`r_{s}^{sha}`. Additionally, soil water influences stomatal resistance through plant hydraulic stress, detailed in the :ref:`rst_Plant Hydraulics` chapter. Resistance is converted from units of s m\ :sup:`2` :math:`\mu` mol\ :sup:`-1` to s m\ :sup:`-1` as: 1 s m\ :sup:`-1` = :math:`1\times 10^{-9} R_{gas} \frac{\theta _{atm} }{P_{atm} }` :math:`\mu` mol\ :sup:`-1` m\ :sup:`2` s, where :math:`R_{gas}` is the universal gas constant (J K\ :sup:`-1` kmol\ :sup:`-1`) (:numref:`Table Physical constants`) and :math:`\theta _{atm}` is the atmospheric potential temperature (K). @@ -45,57 +43,59 @@ Resistance is converted from units of s m\ :sup:`2` :math:`\mu` mol\ :sup:`-1` t .. table:: Plant functional type (PFT) stomatal conductance parameters. - +----------------------------------+-------------------+ - | PFT | g\ :sub:`1` | - +==================================+===================+ - | NET Temperate | 2.35 | - +----------------------------------+-------------------+ - | NET Boreal | 2.35 | - +----------------------------------+-------------------+ - | NDT Boreal | 2.35 | - +----------------------------------+-------------------+ - | BET Tropical | 4.12 | - +----------------------------------+-------------------+ - | BET temperate | 4.12 | - +----------------------------------+-------------------+ - | BDT tropical | 4.45 | - +----------------------------------+-------------------+ - | BDT temperate | 4.45 | - +----------------------------------+-------------------+ - | BDT boreal | 4.45 | - +----------------------------------+-------------------+ - | BES temperate | 4.70 | - +----------------------------------+-------------------+ - | BDS temperate | 4.70 | - +----------------------------------+-------------------+ - | BDS boreal | 4.70 | - +----------------------------------+-------------------+ - | C\ :sub:`3` arctic grass | 2.22 | - +----------------------------------+-------------------+ - | C\ :sub:`3` grass | 5.25 | - +----------------------------------+-------------------+ - | C\ :sub:`4` grass | 1.62 | - +----------------------------------+-------------------+ - | Temperate Corn | 1.79 | - +----------------------------------+-------------------+ - | Spring Wheat | 5.79 | - +----------------------------------+-------------------+ - | Temperate Soybean | 5.79 | - +----------------------------------+-------------------+ - | Cotton | 5.79 | - +----------------------------------+-------------------+ - | Rice | 5.79 | - +----------------------------------+-------------------+ - | Sugarcane | 1.79 | - +----------------------------------+-------------------+ - | Tropical Corn | 1.79 | - +----------------------------------+-------------------+ - | Tropical Soybean | 5.79 | - +----------------------------------+-------------------+ - | Miscanthus | 1.79 | - +----------------------------------+-------------------+ - | Switchgrass | 1.79 | - +----------------------------------+-------------------+ + +----------------------------------+-------------+------------------+ + | PFT | g\ :sub:`o` | g\ :sub:`1` | + +==================================+=============+==================+ + | NET Temperate | 110.93 | 2.35 | + +----------------------------------+-------------+------------------+ + | NET Boreal | 12500 | 2.57 | + +----------------------------------+-------------+------------------+ + | NDT Boreal | 1.00 | 2.09 | + +----------------------------------+-------------+------------------+ + | BET Tropical | 1733.21 | 3.50 | + +----------------------------------+-------------+------------------+ + | BET temperate | 102.24 | 4.12 | + +----------------------------------+-------------+------------------+ + | BDT tropical | 97.56 | 2.85 | + +----------------------------------+-------------+------------------+ + | BDT temperate | 100.40 | 4.45 | + +----------------------------------+-------------+------------------+ + | BDT boreal | 99.73 | 5.05 | + +----------------------------------+-------------+------------------+ + | BES temperate | 100.00 | 4.38 | + +----------------------------------+-------------+------------------+ + | BDS temperate | 100.00 | 4.70 | + +----------------------------------+-------------+------------------+ + | BDS boreal | 100.00 | 4.70 | + +----------------------------------+-------------+------------------+ + | C\ :sub:`3` arctic grass | 100.00 | 3.78 | + +----------------------------------+-------------+------------------+ + | C\ :sub:`3` grass | 5063.54 | 8.32 | + +----------------------------------+-------------+------------------+ + | C\ :sub:`4` grass | 100.00 | 1.62 | + +----------------------------------+-------------+------------------+ + | C\ :sub:`3` crop | 5063.54 | 9.17 | + +----------------------------------+-------------+------------------+ + | Temperate Corn | 100.00 | 1.79 | + +----------------------------------+-------------+------------------+ + | Spring Wheat | 100.00 | 5.79 | + +----------------------------------+-------------+------------------+ + | Temperate Soybean | 100.00 | 5.79 | + +----------------------------------+-------------+------------------+ + | Cotton | 100.00 | 5.79 | + +----------------------------------+-------------+------------------+ + | Rice | 100.00 | 5.79 | + +----------------------------------+-------------+------------------+ + | Sugarcane | 100.00 | 1.79 | + +----------------------------------+-------------+------------------+ + | Tropical Corn | 100.00 | 1.79 | + +----------------------------------+-------------+------------------+ + | Tropical Soybean | 100.00 | 5.79 | + +----------------------------------+-------------+------------------+ + | Miscanthus | 100.00 | 1.79 | + +----------------------------------+-------------+------------------+ + | Switchgrass | 100.00 | 1.79 | + +----------------------------------+-------------+------------------+ .. _Photosynthesis: @@ -105,18 +105,18 @@ Photosynthesis Photosynthesis in C\ :sub:`3` plants is based on the model of :ref:`Farquhar et al. (1980)`. Photosynthesis in C\ :sub:`4` plants is based on the model of :ref:`Collatz et al. (1992)`. :ref:`Bonan et al. (2011)` describe the implementation, modified here. In its simplest form, leaf net photosynthesis after accounting for respiration (:math:`R_{d}` ) is .. math:: - :label: 9.2 + :label: leaf_net_psn - A_{n} =\min \left(A_{c} ,A_{j} ,A_{p} \right)-R_{d} . + A_{n} =\min \left(A_{c} ,A_{j} ,A_{p} \right)-R_{d} The RuBP carboxylase (Rubisco) limited rate of carboxylation :math:`A_{c}` (:math:`\mu` \ mol CO\ :sub:`2` m\ :sup:`-2` s\ :sup:`-1`) is .. math:: - :label: 9.3 + :label: rubisco_lim_rate_of_carboxylation - A_{c} =\left\{\begin{array}{l} {\frac{V_{c\max } \left(c_{i} -\Gamma _{*} \right)}{c_{i} +K_{c} \left(1+{o_{i} \mathord{\left/ {\vphantom {o_{i} K_{o} }} \right.} K_{o} } \right)} \qquad {\rm for\; C}_{{\rm 3}} {\rm \; plants}} \\ {V_{c\max } \qquad \qquad \qquad {\rm for\; C}_{{\rm 4}} {\rm \; plants}} \end{array}\right\}\qquad \qquad c_{i} -\Gamma _{*} \ge 0. + A_{c} =\left\{\begin{array}{l} {\frac{\beta_{t} V_{c\max } \left(c_{i} -\Gamma _{*} \right)}{c_{i} +K_{c} \left(1+{o_{i} \mathord{\left/ {\vphantom {o_{i} K_{o} }} \right.} K_{o} } \right)} \qquad {\rm for\; C}_{{\rm 3}} {\rm \; plants}} \\ {\beta_{t} V_{c\max } \qquad \qquad \qquad {\rm for\; C}_{{\rm 4}} {\rm \; plants}} \end{array}\right\}\qquad \qquad c_{i} -\Gamma _{*} \ge 0. -The maximum rate of carboxylation allowed by the capacity to regenerate RuBP (i.e., the light-limited rate) :math:`A_{j}` (:math:`\mu` \ mol CO\ :sub:`2` m\ :sup:`-2` s\ :sup:`-1`) is +where :math:`\beta_{t} = \beta_{t,sun}` is the transpiration water stress for sunlit leaves and :math:`\beta_{t} = \beta_{t,sha}` for shaded leaves (Eqs. :eq:`beta_t_sun`, :eq:`beta_t_sha`). The maximum rate of carboxylation allowed by the capacity to regenerate RuBP (i.e., the light-limited rate) :math:`A_{j}` (:math:`\mu` \ mol CO\ :sub:`2` m\ :sup:`-2` s\ :sup:`-1`) is .. math:: :label: 9.4 @@ -128,9 +128,9 @@ The product-limited rate of carboxylation for C\ :sub:`3` plants and the PEP car .. math:: :label: 9.5 - A_{p} =\left\{\begin{array}{l} {3T_{p\qquad } \qquad \qquad {\rm for\; C}_{{\rm 3}} {\rm \; plants}} \\ {k_{p} \frac{c_{i} }{P_{atm} } \qquad \qquad \qquad {\rm for\; C}_{{\rm 4}} {\rm \; plants}} \end{array}\right\}. + A_{p} =\left\{\begin{array}{l} {3T_{p\qquad } \qquad \qquad {\rm for\; C}_{{\rm 3}} {\rm \; plants}} \\ {k_{p} \frac{c_{i} }{P_{atm} } \qquad \qquad \qquad {\rm for\; C}_{{\rm 4}} {\rm \; plants}} \end{array}\right\} -In these equations, :math:`c_{i}` is the internal leaf CO\ :sub:`2` partial pressure (Pa) and :math:`o_{i} =0.20P_{atm}` is the O\ :sub:`2` partial pressure (Pa). :math:`K_{c}` and :math:`K_{o}` are the Michaelis-Menten constants (Pa) for CO\ :sub:`2` and O\ :sub:`2`. :math:`\Gamma _{*}` (Pa) is the CO\ :sub:`2` compensation point. :math:`V_{c\max }` is the maximum rate of carboxylation (µmol m\ :sup:`-2` s\ :sup:`-1`, Chapter :numref:`rst_Photosynthetic Capacity`) and :math:`J_{x}` is the electron transport rate (µmol m\ :sup:`-2` s\ :sup:`-1`). :math:`T_{p}` is the triose phosphate utilization rate (µmol m\ :sup:`-2` s\ :sup:`-1`), taken as :math:`T_{p} =0.167V_{c\max }` so that :math:`A_{p} =0.5V_{c\max }` for C\ :sub:`3` plants (as in :ref:`Collatz et al. 1992 `). For C\ :sub:`4` plants, the light-limited rate :math:`A_{j}` varies with :math:`\phi` in relation to the quantum efficiency (:math:`\alpha =0.05` mol CO\ :sub:`2` mol\ :sup:`-1` photon). :math:`\phi` is the absorbed photosynthetically active radiation (W m\ :sup:`-2`) (section :numref:`Solar Fluxes`), which is converted to photosynthetic photon flux assuming 4.6 :math:`\mu` \ mol photons per joule. :math:`k_{p}` is the initial slope of C\ :sub:`4` CO\ :sub:`2` response curve. +In these equations, :math:`c_{i}` is the internal leaf CO\ :sub:`2` partial pressure (Pa) and :math:`o_{i} =0.209P_{atm}` is the O\ :sub:`2` partial pressure (Pa) (where 0.209 is the value of the atmospheric O\ :sub:`2` molar ratio in mol/mol). :math:`K_{c}` and :math:`K_{o}` are the Michaelis-Menten constants (Pa) for CO\ :sub:`2` and O\ :sub:`2`. :math:`\Gamma _{*}` (Pa) is the CO\ :sub:`2` compensation point. :math:`V_{c\max }` is the maximum rate of carboxylation (µmol m\ :sup:`-2` s\ :sup:`-1`, Chapter :numref:`rst_Photosynthetic Capacity`) and :math:`J_{x}` is the electron transport rate (µmol m\ :sup:`-2` s\ :sup:`-1`). :math:`T_{p}` is the triose phosphate utilization rate (µmol m\ :sup:`-2` s\ :sup:`-1`), taken as :math:`T_{p} =0.167V_{c\max }` so that :math:`A_{p} =0.5V_{c\max }` for C\ :sub:`3` plants (as in :ref:`Collatz et al. 1992 `). For C\ :sub:`4` plants, the light-limited rate :math:`A_{j}` varies with :math:`\phi` in relation to the quantum efficiency (:math:`\alpha =0.05` mol CO\ :sub:`2` mol\ :sup:`-1` photon). :math:`\phi` is the absorbed photosynthetically active radiation (W m\ :sup:`-2`) (section :numref:`Solar Fluxes`), which is converted to photosynthetic photon flux assuming 4.6 :math:`\mu` \ mol photons per joule. :math:`k_{p}` is the initial slope of C\ :sub:`4` CO\ :sub:`2` response curve. For C\ :sub:`3` plants, the electron transport rate depends on the photosynthetically active radiation absorbed by the leaf. A common expression is the smaller of the two roots of the equation @@ -146,37 +146,31 @@ where :math:`J_{\max }` is the maximum potential rate of electron transport (:ma I_{PSII} =0.5\Phi _{PSII} (4.6\phi ) -where :math:`\Phi _{PSII}` is the quantum yield of photosystem II, and the term 0.5 arises because one photon is absorbed by each of the two photosystems to move one electron. Parameter values are :math:`\Theta _{PSII}` \ = 0.7 and :math:`\Phi _{PSII}` \ = 0.85. In calculating :math:`A_{j}` (for both C\ :sub:`3` and C\ :sub:`4` plants), :math:`\phi =\phi ^{sun}` for sunlit leaves and :math:`\phi =\phi ^{sha}` for shaded leaves. +where :math:`\Phi _{PSII}` is the quantum yield of photosystem II, and the term 0.5 arises because one photon is absorbed by each of the two photosystems to move one electron. Parameter values are :math:`\Theta _{PSII}` \ = 0.7 and :math:`\Phi _{PSII} = 1 - f_{nps} = 0.85`, where :math:`f_{nps}` is the fraction of light absorbed by non-photosynthetic pigment. In calculating :math:`A_{j}` (for both C\ :sub:`3` and C\ :sub:`4` plants), :math:`\phi =\phi ^{sun}` for sunlit leaves and :math:`\phi =\phi ^{sha}` for shaded leaves. The model uses co-limitation as described by :ref:`Collatz et al. (1991, 1992) `. The actual gross photosynthesis rate, :math:`A`, is given by the smaller root of the equations .. math:: :label: 9.8 - \begin{array}{rcl} {\Theta _{cj} A_{i}^{2} -\left(A_{c} +A_{j} \right)A_{i} +A_{c} A_{j} } & {=} & {0} \\ {\Theta _{ip} A^{2} -\left(A_{i} +A_{p} \right)A+A_{i} A_{p} } & {=} & {0} \end{array} . - -Values are :math:`\Theta _{cj} =0.98` and :math:`\Theta _{ip} =0.95` for C\ :sub:`3` plants; and :math:`\Theta _{cj} =0.80`\ and :math:`\Theta _{ip} =0.95` for C\ :sub:`4` plants. :math:`A_{i}` is the intermediate co-limited photosynthesis. :math:`A_{n} =A-R_{d}`. + \begin{array}{rcl} {\Theta _{cj} A_{i}^{2} -\left(A_{c} +A_{j} \right)A_{i} +A_{c} A_{j} } & {=} & {0} \\ {\Theta _{ip} A^{2} -\left(A_{i} +A_{p} \right)A+A_{i} A_{p} } & {=} & {0} \end{array} -The parameters :math:`K_{c}`, :math:`K_{o}`, and :math:`\Gamma` depend on temperature. Values at 25 °C are :math:`K_{c25} ={\rm 4}0{\rm 4}.{\rm 9}\times 10^{-6} P_{atm}`, :math:`K_{o25} =278.4\times 10^{-3} P_{atm}`, and :math:`\Gamma _{25} {\rm =42}.75\times 10^{-6} P_{atm}`. :math:`V_{c\max }`, :math:`J_{\max }`, :math:`T_{p}`, :math:`k_{p}`, and :math:`R_{d}` also vary with temperature. +Values are :math:`\Theta _{cj} =0.9393` and :math:`\Theta _{ip} =0.95` for C\ :sub:`3` plants, :math:`\Theta _{cj} =0.80` and :math:`\Theta _{ip} =0.95` for C\ :sub:`4` plants, and :math:`\Theta _{cj} =0.98` for C\ :sub:`3` non-generic crops. :math:`A_{i}` is the intermediate co-limited photosynthesis. -:math:`J_{\max 25}` at 25 :sup:`\o`\ C: is calculated by the LUNA model (Chapter :numref:`rst_Photosynthetic Capacity`) +Now we write Eq. :eq:`leaf_net_psn` as :math:`A_{n} = A - \beta_{t} R_{d}` with :math:`\beta_{t}` as defined in Eq. :eq:`rubisco_lim_rate_of_carboxylation` to account for the effect of water stress on respiration. -Parameter values at 25 :sup:`\o`\ C are calculated from :math:`V_{c\max }` \ at 25 -:sup:`\o`\ C:, including: -:math:`T_{p25} =0.167V_{c\max 25}`, and -:math:`R_{d25} =0.015V_{c\max 25}` (C\ :sub:`3`) and -:math:`R_{d25} =0.025V_{c\max 25}` (C\ :sub:`4`). +The parameters :math:`K_{c}`, :math:`K_{o}`, and :math:`\Gamma _{*}` depend on temperature. Values at 25°C are :math:`K_{c25} ={\rm 4}0{\rm 4}.{\rm 9}\times 10^{-6} P_{atm}`, :math:`K_{o25} =278.4\times 10^{-3} P_{atm}`, and :math:`\Gamma _{*25} {\rm =42}.75\times 10^{-6} P_{atm}`. -For C\ :sub:`4` plants, :math:`k_{p25} =20000\; V_{c\max 25}`. +:math:`V_{c\max }`, :math:`J_{\max }`, :math:`T_{p}`, :math:`k_{p}`, and :math:`R_{d}` also vary with temperature. :math:`J_{\max 25}` at 25\ :sup:`\o`\ C is calculated by the LUNA model (Chapter :numref:`rst_Photosynthetic Capacity`). -However, when the biogeochemistry is active (the default mode), :math:`R_{d25}` is calculated from leaf nitrogen as described in (Chapter :numref:`rst_Plant Respiration`) +Parameter values at 25\ :sup:`\o`\ C are calculated from :math:`V_{c\max }` \ at 25\ :sup:`\o`\ C, including: :math:`T_{p25} =0.167V_{c\max 25}`, :math:`R_{d25} =0.015V_{c\max 25}` (C\ :sub:`3`), and :math:`R_{d25} =0.025V_{c\max 25}` (C\ :sub:`4`). For C\ :sub:`4` plants, :math:`k_{p25} =20000\; V_{c\max 25}`. However, in active biogeochemistry mode (default), :math:`R_{d25}` is calculated from leaf nitrogen (see Chapter :numref:`rst_Plant Respiration`) The parameters :math:`V_{c\max 25}`, :math:`J_{\max 25}`, :math:`T_{p25}`, :math:`k_{p25}`, and :math:`R_{d25}` are scaled over the canopy for sunlit and shaded leaves (section :numref:`Canopy scaling`). In C\ :sub:`3` plants, these are adjusted for leaf temperature, :math:`T_{v}` (K), as: .. math:: :label: 9.9 - \begin{array}{rcl} {V_{c\max } } & {=} & {V_{c\max 25} \; f\left(T_{v} \right)f_{H} \left(T_{v} \right)} \\ {J_{\max } } & {=} & {J_{\max 25} \; f\left(T_{v} \right)f_{H} \left(T_{v} \right)} \\ {T_{p} } & {=} & {T_{p25} \; f\left(T_{v} \right)f_{H} \left(T_{v} \right)} \\ {R_{d} } & {=} & {R_{d25} \; f\left(T_{v} \right)f_{H} \left(T_{v} \right)} \\ {K_{c} } & {=} & {K_{c25} \; f\left(T_{v} \right)} \\ {K_{o} } & {=} & {K_{o25} \; f\left(T_{v} \right)} \\ {\Gamma } & {=} & {\Gamma _{25} \; f\left(T_{v} \right)} \end{array} + \begin{array}{rcl} {V_{c\max } } & {=} & {V_{c\max 25} \; f\left(T_{v} \right)f_{H} \left(T_{v} \right)} \\ {J_{\max } } & {=} & {J_{\max 25} \; f\left(T_{v} \right)f_{H} \left(T_{v} \right)} \\ {T_{p} } & {=} & {T_{p25} \; f\left(T_{v} \right)f_{H} \left(T_{v} \right)} \\ {R_{d} } & {=} & {R_{d25} \; f\left(T_{v} \right)f_{H} \left(T_{v} \right)} \\ {K_{c} } & {=} & {K_{c25} \; f\left(T_{v} \right)} \\ {K_{o} } & {=} & {K_{o25} \; f\left(T_{v} \right)} \\ {\Gamma _{*}} & {=} & {\Gamma _{*25} \; f\left(T_{v} \right)} \end{array} .. math:: :label: 9.10 @@ -188,9 +182,9 @@ and .. math:: :label: 9.11 - f_{H} \left(T_{v} \right)=\frac{1+\exp \left(\frac{298.15\Delta S-\Delta H_{d} }{298.15\times 0.001R_{gas} } \right)}{1+\exp \left(\frac{\Delta ST_{v} -\Delta H_{d} }{0.001R_{gas} T_{v} } \right)} . + f_{H} \left(T_{v} \right)=\frac{1+\exp \left(\frac{298.15\Delta S-\Delta H_{d} }{298.15\times 0.001R_{gas} } \right)}{1+\exp \left(\frac{\Delta ST_{v} -\Delta H_{d} }{0.001R_{gas} T_{v} } \right)} -:numref:`Table Temperature dependence parameters for C3 photosynthesis` lists parameter values for :math:`\Delta H_{a}` and :math:`\Delta H_{d}`. :math:`\Delta S` is calculated separately for :math:`V_{c\max }` and :math:`J_{max }` to allow for temperature acclimation of photosynthesis (see equation :eq:`9.16`), and :math:`\Delta S` is 490 J mol :sup:`-1` K :sup:`-1` for :math:`R_d` (:ref:`Bonan et al. 2011`, :ref:`Lombardozzi et al. 2015`). Because :math:`T_{p}` as implemented here varies with :math:`V_{c\max }`, :math:`T_{p}` uses the same temperature parameters as :math:`V_{c\max}`. For C\ :sub:`4` plants, +:numref:`Table Temperature dependence parameters for C3 photosynthesis` lists parameter values for :math:`\Delta H_{a}` and :math:`\Delta H_{d}`. :math:`\Delta S` (entropy term) is calculated separately for :math:`V_{c\max }` and :math:`J_{max }` to allow for temperature acclimation of photosynthesis (see equation :eq:`9.16`), and :math:`\Delta S` is 490 J mol :sup:`-1` K :sup:`-1` for :math:`R_d` (:ref:`Bonan et al. 2011`, :ref:`Lombardozzi et al. 2015`). Because :math:`T_{p}` as implemented here varies with :math:`V_{c\max }`, :math:`T_{p}` uses the same temperature parameters as :math:`V_{c\max}`. For C\ :sub:`4` plants, .. math:: :label: 9.12 @@ -246,12 +240,12 @@ In the model, acclimation is implemented as in :ref:`Kattge and Knorr (2007) `) based on an optimality hypothesis to nitrogen allocation among light capture, electron transport, carboxylation, respiration and storage. Specifically, the model allocates the nitrogen by maximizing the daily net photosynthetic carbon gain under following two key assumptions: +The photosynthetic capacity is represented by two key parameters: 1) the maximum rate of carboxylation at 25°C, :math:`V_{\text{c,max25}}`; and 2) the maximum rate of electron transport at 25°C, :math:`J_{\text{max25}}`. They are predicted by a mechanistic model of leaf utilization of nitrogen for assimilation (LUNA V1.0) (:ref:`Ali et al. 2016`) based on an optimality hypothesis to nitrogen allocation among light capture, electron transport, carboxylation, respiration and storage. Specifically, the model allocates the nitrogen by maximizing the daily net photosynthetic carbon gain under following two key assumptions: - nitrogen allocated for light capture, electron transport and carboxylation are co-limiting; - respiratory nitrogen is allocated to maintain dark respiration determined by :math:`V_{\text{c,max}}`. -Compared to traditional photosynthetic capacity models, a key advantage of LUNA is that the model is able to predict the potential acclimation of photosynthetic capacities at different environmental conditions as determined by temperature, radiation, CO :sub:`2` concentrations, day length, and humidity. +Compared to traditional photosynthetic capacity models, a key advantage of LUNA is that the model is able to predict the potential acclimation of photosynthetic capacities at different environmental conditions as determined by temperature, radiation, CO\ :sub:`2` concentrations, day length, and humidity. .. _Model inputs and parameter estimations: @@ -17,12 +17,12 @@ Model inputs and parameter estimations ------------------------------------------------------- The LUNA model includes the following four unitless parameters: -- :math:`J_{maxb0}` , which specifies the baseline proportion of nitrogen allocated for electron transport; -- :math:`J_{maxb1}` , which determines response of electron transport rate to light availability; -- :math:`t_{c,j0}` , which defines the baseline ratio of Rubisco-limited rate to light-limited rate; -- :math:`H` , which determines the response of electron transport rate to relative humidity. +- :math:`J_{maxb0}` , which specifies the baseline proportion of nitrogen allocated for electron transport rate; +- :math:`J_{maxb1}` , which determines response of electron transport rate to light availability; +- :math:`t_{c,j0}` , which defines the baseline ratio of Rubisco-limited rate to light-limited rate; +- :math:`H` , which determines the response of electron transport rate to relative humidity. -The above four parameters are estimated by fitting the LUNA model to a global compilation of >800 observations located at different biomes, canopy locations, and time of the year from 1993-2013 (Ali et al. 2015). The model inputs are area-based leaf nitrogen content, leaf mass per unit leaf area and the driving environmental conditions (average of past 10 days) including temperature, CO :sub:`2` concentrations, daily mean and maximum radiation, relative humidity and day length. The estimated values in CLM5 for the listed parameters are 0.0311, 0.17, 0.8054, and 6.0999, respectively. In LUNA V1.0, the estimated parameter values are for C3 natural vegetations. In view that potentially large differences in photosynthetic capacity could exist between crops and natural vegetations due to human selection and genetic modifications, in CLM5, the LUNA model are used only for C3 natural vegetations. The photosynthetic capacity for crops and C4 plants are thus still kept the same as CLM4.5. Namely, it is estimated based on the leaf nitrogen content, fixed RUBISCO allocations for :math:`V_{c\max 25}` and an adjusting factor to account for the impact of day length. In CLM5, the model simulates both sun-lit and shaded leaves; however, because the sun-lit and shaded leaves can changes through the day based on the sun angles, we do not differentiate the photosynthetic capacity difference for sun-lit or shaded leaves. +For CLM5, the above four parameters were estimated by fitting the LUNA model to a global compilation of >800 observations located at different biomes, canopy locations, and time of the year from 1993-2013 (:ref:`Ali et al. 2016`). The model inputs are area-based leaf nitrogen content, leaf mass per unit leaf area and the driving environmental conditions (average of the past 10 days) including temperature, CO\ :sub:`2` concentrations, daily mean and maximum radiation, relative humidity and day length. The estimated values in CLM5 for the listed parameters were 0.0311, 0.17, 0.8054, and 6.0999, respectively. As of CLM6, these values have since been updated during our calibration process. See the latest parameter file for the most up-to-date values. In LUNA V1.0, the estimated parameter values are for C3 natural vegetation. In view that potentially large differences in photosynthetic capacity could exist between crops and natural vegetation due to human selection and genetic modifications, the LUNA model is used only for C3 natural vegetation. The photosynthetic capacity for crops and C4 plants are thus still kept the same as CLM4.5. Namely, it is estimated based on the leaf nitrogen content, fixed rubisco allocations for :math:`V_{c\max 25}` and an adjusting factor to account for the impact of day length. In CLM, the model simulates both sun-lit and shaded leaves; however, because the sun-lit and shaded leaves can changes through the day based on the sun angles, we do not differentiate the photosynthetic capacity difference for sun-lit or shaded leaves. .. _Model structure: @@ -34,32 +34,32 @@ Model structure Plant Nitrogen '''''''''''''''''''''''''' -The structure of the LUNA model is adapted from :ref:`Xu et al. (2012)`, where the plant nitrogen at the leaf level ( :math:`\text{LNC}_{a}`; gN/ m :sup:`2` leaf) is divided into four pools: structural nitrogen( :math:`N_{\text{str}}`; gN/m :sup:`2` leaf), photosynthetic nitrogen ( :math:`N_{\text{psn}}`; gN/m :sup:`2` leaf), storage nitrogen( :math:`N_{\text{store}}`; gN/m :sup:`2` leaf), and respiratory nitrogen ( :math:`N_{\text{resp}}`; gN/m :sup:`2` leaf). Namely, +The structure of the LUNA model is adapted from :ref:`Xu et al. (2012)`, where the plant nitrogen at the leaf level (:math:`\text{LNC}_{a}`; gN/ m\ :sup:`2` leaf) is divided into four pools: structural nitrogen (:math:`N_{\text{str}}`; gN/m\ :sup:`2` leaf), photosynthetic nitrogen (:math:`N_{\text{psn}}`; gN/m\ :sup:`2` leaf), storage nitrogen (:math:`N_{\text{store}}`; gN/m\ :sup:`2` leaf), and respiratory nitrogen (:math:`N_{\text{resp}}`; gN/m\ :sup:`2` leaf). Namely, .. math:: - :label: 10.1) + :label: :lnc_a:) \text{LNC}_{a} = N_{\text{psn}} + N_{\text{str}}+ N_{\text{store}} + N_{\text{resp}}. -The photosynthetic nitrogen, :math:`N_{\text{psn}}`, is further divided into nitrogen for light capture ( :math:`N_{\text{lc}}`; gN/m :sup:`2` leaf), nitrogen for electron transport ( :math:`N_{\text{et}}`; gN/m :sup:`2` leaf), and nitrogen for carboxylation ( :math:`N_{\text{cb}}`; gN/m :sup:`2` leaf). Namely, +The photosynthetic nitrogen, :math:`N_{\text{psn}}`, is further divided into nitrogen for light capture (:math:`N_{\text{lc}}`; gN/m\ :sup:`2` leaf), nitrogen for electron transport (:math:`N_{\text{et}}`; gN/m\ :sup:`2` leaf), and nitrogen for carboxylation (:math:`N_{\text{cb}}`; gN/m\ :sup:`2` leaf). Namely, .. math:: - :label: 10.2) + :label: :N_psn:) N_{\text{psn}} =N_{\text{et}} + N_{\text{cb}} + N_{\text{lc}}. -The structural nitrogen, :math:`N_{\text{str}}`, is calculated as the multiplication of leaf mass per unit area (:math:`\text{LMA}`; g biomass/m :sup:`2` leaf), and the structural nitrogen content (:math:`\text{SNC}`; gN/g biomass). Namely, +The structural nitrogen, :math:`N_{\text{str}}`, is calculated as the multiplication of leaf mass per unit area (:math:`\text{LMA}`; g biomass/m\ :sup:`2` leaf), and the structural nitrogen content (:math:`\text{SNC}`; gN/g biomass). Namely, .. math:: - :label: 10.3) + :label: :N_str:) N_{\text{str}} = \text{SNC} \cdot \text{LMA} -where :math:`\text{SNC}` is set to be fixed at 0.004 (gN/g biomass), based on data on C:N ratio from dead wood (White etal.,2000), and :math:`\text{LMA}` is the inverse of specific leaf area at the canopy top (:math:`SLA_{\text{0}}`), a PFT-level parameter (:numref:`Table Plant functional type (PFT) leaf N parameters`). +where :math:`\text{SNC}` is set to be fixed at 0.004 (gN/g biomass), based on data on C:N ratio from dead wood :ref:`(White et al. 2000`), and :math:`\text{LMA}` is the inverse of specific leaf area at the canopy top (:math:`SLA_{\text{0}}`), a PFT-level parameter (:numref:`Table Plant functional type (PFT) leaf N parameters`). .. _Table Plant functional type (PFT) leaf N parameters: -.. table:: Plant functional type (PFT) leaf N parameters. +.. table:: Plant functional type (PFT) leaf N parameters. Note: These are the original CLM5 values and may not reflect current values. :math:`SLA_{\text{0}}` is the specific leaf area at the canopy top (m\ :sup:`2` leaf/g biomass). +----------------------------------+--------------------------+ | PFT | :math:`SLA_{\text{0}}` | @@ -113,51 +113,50 @@ where :math:`\text{SNC}` is set to be fixed at 0.004 (gN/g biomass), based on da | Switchgrass | 0.03500 | +----------------------------------+--------------------------+ -Notes: :math:`SLA_{\text{0}}` is the specific leaf area at the canopy top (m :sup:`2` leaf/g biomass) -We assume that plants optimize their nitrogen allocations (i.e., :math:`N_{\text{store}}`, :math:`N_{\text{resp}}`, :math:`N_{\text{lc}}`, :math:`N_{\text{et}}`, :math:`N_{\text{cb}}`) to maximize the photosynthetic carbon gain, defined as the gross photosynthesis ( :math:`A` ) minus the maintenance respiration for photosynthetic enzymes ( :math:`R_{\text{psn}}` ), under specific environmental conditions and given plant's strategy of leaf nitrogen use. Namely, the solutions of nitrogen allocations \{ :math:`N_{\text{store}}`, :math:`N_{\text{resp}}`, :math:`N_{\text{lc}}`, :math:`N_{\text{et}}`, :math:`N_{\text{cb}}` \} can be estimated as follows, +We assume that plants optimize their nitrogen allocations (i.e., :math:`N_{\text{store}}`, :math:`N_{\text{resp}}`, :math:`N_{\text{lc}}`, :math:`N_{\text{et}}`, :math:`N_{\text{cb}}`) to maximize the photosynthetic carbon gain, defined as the gross photosynthesis (:math:`A`) minus the maintenance respiration for photosynthetic enzymes (:math:`R_{\text{psn}}`), under specific environmental conditions and given the plant's strategy of leaf nitrogen use. Namely, the solutions of nitrogen allocations \{:math:`N_{\text{store}}`, :math:`N_{\text{resp}}`, :math:`N_{\text{lc}}`, :math:`N_{\text{et}}`, :math:`N_{\text{cb}}`\} can be estimated as follows, .. math:: - :label: 10.4) + :label: :N_allocations:) \left\{\hat{N}_{\text{{store}}}, \hat{N}_{\text{{resp}}}, \hat{\mathrm{N}}_{\text{lc}}, \hat{N}_{\text{et}}, \hat{\mathrm{N}}_{\text{cb}} \right\} = \underset{\mathrm{N}_{\text{store}}\,+\,\mathrm{N}_{\text{resp}}\,+\,\mathrm{N}_{\text{lc}}\,+\,\mathrm{N}_{\text{et}}\,+\,\mathrm{N}_{\text{cb}}\,<\text{FNC}_{\mathrm{a}}}{\text{argmax}} (A-R_{\text{psn}}), -where :math:`\text{FNC}_{a}` is the functional nitrogen content defined as the total leaf nitrogen content ( :math:`\text{LNC}_{a}`) minus the structural nitrogen content ( :math:`N_{\text{str}}` ). +where :math:`\text{FNC}_{a}` is the functional nitrogen content defined as the total leaf nitrogen content (:math:`\text{LNC}_{a}`) minus the structural nitrogen content (:math:`N_{\text{str}}`). -The gross photosynthesis, :math:`A`, was calculated with a coupled leaf gas exchange model based on the :ref:`Farquhar et al. (1980)` model of photosynthesis and Ball--Berry-type stomatal conductance model (Ball et al. 1987). The maintenance respiration for photosynthetic enzymes, :math:`R_{\text{psn}}`, is calculated by the multiplication of total photosynthetic nitrogen ( :math:`N_{\text{psn}}` ) and the maintenance respiration cost for photosynthetic enzymes. +The gross photosynthesis, :math:`A`, was calculated with a coupled leaf gas exchange model based on the :ref:`Farquhar et al. (1980)` model of photosynthesis and Ball-Berry-type stomatal conductance model :ref:`(Ball et al. 1987)`. The maintenance respiration for photosynthetic enzymes, :math:`R_{\text{psn}}`, is calculated by the multiplication of total photosynthetic nitrogen (:math:`N_{\text{psn}}`) and the maintenance respiration cost for photosynthetic enzymes. Maximum electron transport rate ''''''''''''''''''''''''''''''''' -In the LUNA model, the maximum electron transport rate ( :math:`J_{\text{max}}`; :math:`{\mu} mol` electron / m :sup:`2`/s) is simulated to have a baseline allocation of nitrogen and additional nitrogen allocation to change depending on the average daytime photosynthetic active radiation (PAR; :math:`{\mu} mol` electron / m :sup:`2`/s), day length (hours) and air humidity. Specifically, the LUNA model has +In the LUNA model, the maximum electron transport rate (:math:`J_{\text{max}}`; μmol electron/m\ :sup:`2`/s) is simulated to have a baseline allocation of nitrogen and additional nitrogen allocation to change depending on the average daytime photosynthetic active radiation (PAR; μmol electron/ m\ :sup:`2`/s), day length (hours) and air humidity. Specifically, the LUNA model has .. math:: - :label: 10.5) + :label: :J_max:) - J_{\text{{max}}} = J_{\text{max}0} + J_{\text{max}b1} + J_{\text{max}} = J_{\text{max}0} + J_{\text{max}b1} f\left(\text{day length} \right)f\left(\text{humidity} \right)\alpha \text{PAR} The baseline electron transport rate, :math:`J_{\text{max}0}`, is calculated as follows, .. math:: - :label: 10.6) + :label: :J_max0:) - J_{\text{max}0} = J_{\text{max}b0}{\text{FNC}}_{\mathrm{a}}{\text{NUE}}_{J_{\text{{max}}}} + J_{\text{max}0} = J_{\text{max}b0}{\text{FNC}}_{\mathrm{a}}{\text{NUE}}_{J_{\text{max}}} -where :math:`J_{\text{max}b0}` (unitless) is the baseline proportion of nitrogen allocated for electron transport rate. :math:`{\text{NUE}}_{J_{\text{{max}}}}` ( :math:`{\mu} mol` electron /s/g N) is the nitrogen use efficiency of :math:`J_{\text{{max}}}`. :math:`J_{\text{max}b1}` (unitless) is a coefficient determining the response of the electron transport rate to amount of absorbed light (i.e., :math:`\alpha \text{PAR}`). :math:`f\left(\text{day length} \right)` is a function specifies the impact of day length (hours) on :math:`J_{\text{max}}` in view that longer day length has been demonstrated by previous studies to alter :math:`V_{\mathrm{c}\text{max}25}` and :math:`J_{\text{max}25}` (Bauerle et al. 2012; Comstock and Ehleringer 1986) through photoperiod sensing and regulation (e.g., Song et al. 2013). Following Bauerle et al. (2012), :math:`f\left(\text{day length} \right)` is simulated as follows, +where :math:`J_{\text{max}b0}` (unitless) is the baseline proportion of nitrogen allocated for electron transport rate. :math:`{\text{NUE}}_{J_{\text{max}}}` (μmol electron/s/g N) is the nitrogen use efficiency of :math:`J_{\text{max}}`. :math:`J_{\text{max}b1}` (unitless) is a coefficient determining the response of the electron transport rate to amount of absorbed light (i.e., :math:`\alpha \text{PAR}`). :math:`f\left(\text{day length} \right)` is a function specifies the impact of day length (hours) on :math:`J_{\text{max}}` in view that longer day length has been demonstrated by previous studies to alter :math:`V_{\mathrm{c}\text{max}25}` and :math:`J_{\text{max}25}` (:ref:`Bauerle et al. 2012`; :ref:`Comstock and Ehleringer 1986`) through photoperiod sensing and regulation (e.g., :ref:`Song et al. 2013`). Following :ref:`Bauerle et al. (2012)`, :math:`f\left(\text{day length} \right)` is simulated as follows, .. math:: - :label: 10.7) + :label: :day_length:) f\left(\text{day length} \right) = \left(\frac{\text{day length}}{12} \right)^{2}. -:math:`f\left(\text{humidity} \right)` represents the impact of air humidity on :math:`J_{\text{{max}}}`. We assume that higher humidity leads to higher :math:`J_{\text{{max}}}` with less water limitation on stomata opening and that low relative humidity has a stronger impact on nitrogen allocation due to greater water limitation. When relative humidity (RH; unitless) is too low, we assume that plants are physiologically unable to reallocate nitrogen. We therefore assume that there exists a critical value of relative humidity ( :math:`RH_{0} = 0.25`; unitless), below which there is no optimal nitrogen allocation. Based on the above assumptions, we have +:math:`f\left(\text{humidity} \right)` represents the impact of air humidity on :math:`J_{\text{{max}}}`. We assume that higher humidity leads to higher :math:`J_{\text{max}}` with less water limitation on stomata opening and that low relative humidity has a stronger impact on nitrogen allocation due to greater water limitation. When relative humidity (RH; unitless) is too low, we assume that plants are physiologically unable to reallocate nitrogen. We therefore assume that there exists a critical value of relative humidity (:math:`RH_{0} = 0.25`; unitless), below which there is no optimal nitrogen allocation. Based on the above assumptions, we have .. math:: - :label: 10.8) + :label: :humidity:) f\left(\text{humidity} \right) = \left(1-\mathrm{e}^{\left(-H @@ -165,22 +164,22 @@ where :math:`J_{\text{max}b0}` (unitless) is the baseline proportion of nitrogen where :math:`H` (unitless) specifies the impact of relative humidity on electron transport rate. -The efficiency of light energy absorption (unitless), :math:`\alpha`, is calculated depending on the amount of nitrogen allocated for light capture, :math:`\mathrm{N}_{\text{lc}}`. Following Niinemets and Tenhunen (1997), the LUNA model has, +The efficiency of light energy absorption (unitless), :math:`\alpha`, is calculated depending on the amount of nitrogen allocated for light capture, :math:`\mathrm{N}_{\text{lc}}`. Following :ref:`Niinemets and Tenhunen (1997)`, the LUNA model has, .. math:: - :label: 10.9) + :label: :light_energy_absorp_alpha:) \alpha =\frac{0.292}{1+\frac{0.076}{\mathrm{N}_{\text{lc}}C_{b}}} -where 0.292 is the conversion factor from photon to electron. :math:`C_{b}` is the conversion factor (1.78) from nitrogen to chlorophyll. After we estimate :math:`J_{\text{{max}}}`, the actual electron transport rate with the daily maximum radiation ( :math:`J_{x}`) can be calculated using the empirical expression of leaf (1937), +where 0.292 is the conversion factor from photon to electron. :math:`C_{b}` is the conversion factor (set to 1.78) from nitrogen to chlorophyll. After we estimate :math:`J_{\text{max}}`, the actual electron transport rate with the daily maximum radiation (:math:`J_{x}`) can be calculated using the empirical expression of :ref:`Smith (1937)`, .. math:: - :label: 10.10) + :label: :J_x:) J_{x} = \frac{\alpha \text{PAR}_{\text{max}}} {\left(1 + \frac{\alpha^{2}{\text{PAR}}_{\text{{max}}}^{2}}{J_{\text{{max}}}^{2}} \right)^{0.5}} -where :math:`\text{PAR}_{\text{{max}}}` ( :math:`\mu mol`/m :sup:`2`/s) is the maximum photosynthetically active radiation during the day. +where :math:`\text{PAR}_{\text{max}}` (μmol/m\ :sup:`2`/s) is the maximum photosynthetically active radiation during the day. Maximum rate of carboxylation '''''''''''''''''''''''''''''' @@ -188,56 +187,56 @@ Maximum rate of carboxylation The maximum rate of carboxylation at 25°C varies with foliage nitrogen concentration and specific leaf area and is calculated as in :ref:`Thornton and Zimmermann (2007)`. At 25°C, .. math:: - :label: 10.11) + :label: :vcmax25:) V_{c\max 25} = N_{cb} NUE_{V_{c\max 25}} -where :math:`N_{cb}` is nitrogen for carboxylation (g N m\ :sup:`-2` leaf, :numref:`Table Plant functional type (PFT) leaf N parameters`), and :math:`NUE_{V_{c\max 25}}` = 47.3 x 6.25 and is the nitrogen use efficiency for :math:`V_{c\max 25}`. The constant 47.3 is the specific Rubisco activity ( :math:`\mu` mol CO\ :sub:`2` g\ :sup:`-1` Rubisco s\ :sup:`-1`) measured at 25°C, and the constant 6.25 is the nitrogen binding factor for Rubisco (g Rubisco g\ :sup:`-1` N; :ref:`Rogers 2014`). +where :math:`N_{cb}` is nitrogen for carboxylation (g N/m\ :sup:`2` leaf, :numref:`Table Plant functional type (PFT) leaf N parameters`), and :math:`NUE_{V_{c\max 25}}` = 47.3 x 6.25 and is the nitrogen use efficiency for :math:`V_{c\max 25}`. The constant 47.3 is the specific Rubisco activity (μmol CO\ :sub:`2`/g Rubisco/s) measured at 25°C, and the constant 6.25 is the nitrogen binding factor for Rubisco (g Rubisco/g N; :ref:`Rogers 2014`). :math:`V_{c\max 25}` additionally varies with daylength (:math:`DYL`) using the function :math:`f(DYL)`, which introduces seasonal variation to :math:`V_{c\max }` .. math:: - :label: 10.12) + :label: :f_DYL:) f\left(DYL\right)=\frac{\left(DYL\right)^{2} }{\left(DYL_{\max } \right)^{2} } with :math:`0.01\le f\left(DYL\right)\le 1`. Daylength (seconds) is given by .. math:: - :label: 10.13) + :label: :DYL:) DYL=2\times 13750.9871\cos ^{-1} \left[\frac{-\sin \left(lat\right)\sin \left(decl\right)}{\cos \left(lat\right)\cos \left(decl\right)} \right] -where :math:`lat` (latitude) and :math:`decl` (declination angle) are from section :numref:`Solar Zenith Angle`. Maximum daylength (:math:`DYL_{\max }` ) is calculated similarly but using the maximum declination angle for present-day orbital geometry (:math:`\pm`\ 23.4667° [:math:`\pm`\ 0.409571 radians], positive for Northern Hemisphere latitudes and negative for Southern Hemisphere). +where :math:`lat` (latitude) and :math:`decl` (declination angle) are from section :numref:`Solar Zenith Angle`. Maximum daylength (:math:`DYL_{\max }`) is calculated similarly but using the maximum declination angle for present-day orbital geometry (:math:`\pm`\ 23.4667° [:math:`\pm`\ 0.409571 radians], positive for Northern Hemisphere latitudes and negative for Southern Hemisphere). Implementation of Photosynthetic Capacity '''''''''''''''''''''''''''''''''''''''''' -Based on :ref:`Farquhar et al. (1980)` and Wullschleger (1993), we can calculate the electron-limited photosynthetic rate under daily maximum radiation ( :math:`W_{jx}`) and the Rubisco-limited photosynthetic rate ( :math:`W_{\mathrm{c}}`) as follows, +Based on :ref:`Farquhar et al. (1980)` and :ref:`Wullschleger (1993)`, we can calculate the electron-limited photosynthetic rate under daily maximum radiation (:math:`W_{jx}`) and the Rubisco-limited photosynthetic rate (:math:`W_{\mathrm{c}}`) as follows, .. math:: - :label: 10.14) + :label: :W_Jx:) W_{J_{x}} = K_{j}J_{x} , .. math:: - :label: 10.15) + :label: :W_c_1:) W_{\mathrm{c}} = K_{\mathrm{c}} V_{{\mathrm{c}, \text{max}}}, -where :math:`K_{j}` and :math:`K_{\mathrm{c}}` as the conversion factors for :math:`J_{x}` and :math:`V_{{\mathrm{c}, \text{max}}}` ( :math:`V_{{\mathrm{c}, \text{max}}}` to :math:`W_{\mathrm{c}}` and :math:`J_{x}` to :math:`W_{J_{x}}`), respectively. Based on :ref:`Xu et al. (2012)`, Maire et al. (2012) and Walker et al. (2014), we assume that :math:`W_{\mathrm{c}}` is proportional to :math:`W_{J_{x}}`. Specifically, we have +where :math:`K_{j}` and :math:`K_{\mathrm{c}}` as the conversion factors for :math:`J_{x}` and :math:`V_{{\mathrm{c}, \text{max}}}` (:math:`V_{{\mathrm{c}, \text{max}}}` to :math:`W_{\mathrm{c}}` and :math:`J_{x}` to :math:`W_{J_{x}}`), respectively. Based on :ref:`Xu et al. (2012)`, :ref:`Maire et al. (2012)` and :ref:`Walker et al. (2014)`, we assume that :math:`W_{\mathrm{c}}` is proportional to :math:`W_{J_{x}}`. Specifically, we have .. math:: - :label: 10.16) + :label: :W_c_2:) W_{\mathrm{c}}=t_{\alpha}t_{\mathrm{c}, j0}W_{J_{x}} -where :math:`t_{\mathrm{c}, j0}` is the baseline ratio of :math:`W_{\mathrm{c}}` to :math:`W_{J_{x}}`. We recognize that this ratio may change depending on the nitrogen use efficiency of carboxylation and electron transport (Ainsworth and Rogers 2007), therefore the LUNA model has the modification factor, :math:`t_{\alpha}`, to adjust baseline the ratio depending on the nitrogen use efficiency for electron vs carboxylation (:ref:`Ali et al. 2016`). +where :math:`t_{\mathrm{c}, j0}` is the baseline ratio of :math:`W_{\mathrm{c}}` to :math:`W_{J_{x}}`. We recognize that this ratio may change depending on the nitrogen use efficiency of carboxylation and electron transport (:ref:`Ainsworth and Rogers 2007`), therefore the LUNA model has the modification factor, :math:`t_{\alpha}`, to adjust baseline the ratio depending on the nitrogen use efficiency for electron vs carboxylation (:ref:`Ali et al. 2016`). Total Respiration ''''''''''''''''''' -Following :ref:`Collatz et al. (1991)`, the total respiration ( :math:`R_{\mathrm{t}}`) is calculated in proportion to :math:`V_{\text{c,max}}`, +Following :ref:`Collatz et al. (1991)`, the total respiration (:math:`R_{\mathrm{t}}`) is calculated in proportion to :math:`V_{\text{c,max}}`, .. math:: :label: 10.17) @@ -258,4 +257,4 @@ where :math:`D_{\text{day}}` and :math:`D_{\text{night}}` are daytime and nightt Numerical scheme --------------------------------------------------------- -The LUNA model searches for the "optimal" nitrogen allocations for maximum net photosynthetic carbon gain by incrementally increase the nitrogen allocated for light capture (i.e., :math:`N_{\text{lc}}`) (see :ref:`Ali et al. (2016)` for details). We assume that plants only optimize the nitrogen allocation when they can grow (i.e., GPP>0.0). If GPP become zero under stress, then the LUNA model assume a certain amount of enzyme will decay at daily rates of 0.1, in view that the half-life time for photosynthetic enzymes are short (~7 days) (Suzuki et al. 2001). To avoid unrealistic low values of photosynthetic capacity, the decay is only limited to 50 percent of the original enzyme levels. +The LUNA model searches for the "optimal" nitrogen allocations for maximum net photosynthetic carbon gain by incrementally increase the nitrogen allocated for light capture (i.e., :math:`N_{\text{lc}}`) (see :ref:`Ali et al. 2016` for details). We assume that plants only optimize the nitrogen allocation when they can grow (i.e., GPP > 0.0). If GPP becomes zero under stress, then the LUNA model assumes a certain amount of enzymes will decay at daily rates of 0.1, in the view that the half-life time for photosynthetic enzymes is short (~7 days) (:ref:`Suzuki et al. 2001`). To avoid unrealistically low values of photosynthetic capacity, this decay is limited to 50% of the original enzyme levels. diff --git a/doc/source/tech_note/Plant_Hydraulics/CLM50_Tech_Note_Plant_Hydraulics.rst b/doc/source/tech_note/Plant_Hydraulics/CLM50_Tech_Note_Plant_Hydraulics.rst index 18a4fe1fdc..db9cb172fc 100644 --- a/doc/source/tech_note/Plant_Hydraulics/CLM50_Tech_Note_Plant_Hydraulics.rst +++ b/doc/source/tech_note/Plant_Hydraulics/CLM50_Tech_Note_Plant_Hydraulics.rst @@ -353,12 +353,12 @@ Plant water demand depends on stomatal conductance, which is described in sectio E_{shade} = E_{shade,max} \cdot 2^{-\left(\dfrac{\psi_{shadeleaf}}{p50_e}\right)^{c_k}} .. math:: - :label: 11.203 + :label: beta_t_sun \beta_{t,sun} = \dfrac{g_{s,sun}}{g_{s,sun,\beta_t=1}} .. math:: - :label: 11.204 + :label: beta_t_sha \beta_{t,shade} = \dfrac{g_{s,shade}}{g_{s,shade,\beta_t=1}} @@ -382,9 +382,9 @@ Plant water demand depends on stomatal conductance, which is described in sectio :math:`g_{s,shade}` = stomatal conductance of water corresponding to :math:`E_{shade}` -:math:`g_{s,sun,max}` = stomatal conductance of water corresponding to :math:`E_{sun,max}` +:math:`g_{s,sun,\beta_t=1}` = stomatal conductance of water corresponding to :math:`E_{sun,max}` -:math:`g_{s,shade,max}` = stomatal conductance of water corresponding to :math:`E_{shade,max}` +:math:`g_{s,shade,\beta_t=1}` = stomatal conductance of water corresponding to :math:`E_{shade,max}` .. _Vegetation Water Potential: @@ -574,16 +574,14 @@ Now we compute all the entries for :math:`A` and :math:`b` based on the soil moi We iterate until :math:`b\to 0`, signifying water flux balance through the system. The result is a final set of water potentials ( :math:`\psi_{root}`, :math:`\psi_{xylem}`, :math:`\psi_{shadeleaf}`, :math:`\psi_{sunleaf}`) satisfying non-divergent water flux through the system. The magnitude of the water flux is driven by soil matric potential and unstressed ( :math:`\beta_t=1`) transpiration. -We use the transpiration solution (corresponding to the final solution for :math:`\psi`) to compute stomatal conductance. The stomatal conductance is then used to compute :math:`\beta_t`. +We use the transpiration solution (corresponding to the final solution for :math:`\psi`) to compute stomatal conductance. The stomatal conductance is then used to compute :math:`\beta_t` as in Eqs :eq:`beta_t_sun`, :eq:`beta_t_sha` shown again here: -.. math:: - :label: 11.416 +.. SKIP math labels here, as these equations have been numbered elsewhere +.. math:: \beta_{t,sun} = \dfrac{g_{s,sun}}{g_{s,sun,\beta_t=1}} .. math:: - :label: 11.417 - \beta_{t,shade} = \dfrac{g_{s,shade}}{g_{s,shade,\beta_t=1}} The :math:`\beta_t` values are used in the Photosynthesis module (see section :numref:`Photosynthesis`) to apply water stress. The solution for :math:`\psi` is saved as a new variable (vegetation water potential) and is indicative of plant water status. The soil-to-root fluxes :math:`\left( q_{3,1},q_{3,2},\mbox{...},q_{3,n}\right)` are used as the soil transpiration sink in the Richards' equation subsurface flow equations (see section :numref:`Soil Water`). diff --git a/doc/source/tech_note/Plant_Mortality/CLM50_Tech_Note_Plant_Mortality.rst b/doc/source/tech_note/Plant_Mortality/CLM50_Tech_Note_Plant_Mortality.rst index a60b6000b5..507bcc6bdc 100644 --- a/doc/source/tech_note/Plant_Mortality/CLM50_Tech_Note_Plant_Mortality.rst +++ b/doc/source/tech_note/Plant_Mortality/CLM50_Tech_Note_Plant_Mortality.rst @@ -2,460 +2,369 @@ Plant Mortality =================== +What has changed +---------------------------------------------- + +In CLM5, gap-phase mortality in non-FATES vegetation was commonly represented using a prescribed constant mortality rate (2% yr :sup:`-1`) applied uniformly across perennial plant functional types. However, this process should be better constrained given different climate zones (:ref:`Keller et al. 2004`; :ref:`Sollins 1982`), different species mixtures (:ref:`Gomes et al. 2003`), and different size and age classes (:ref:`Busing 2005`; :ref:`Law et al. 2003`). In CLM6, mortality formulations have evolved beyond a single fixed mortality parameter for all PFTs. The annual mortality (*r_mort*) has now become a PFT-dependent variable, with some woody PFTs by default assigned a value other than 0.02 (:numref:`Table Model default annual mortality rate`). + +.. _Table Model default annual mortality rate: + +.. table:: Model default annual mortality rate (*r_mort*) for woody PFTs + + +---------------------------------------------------+--------------------------------------+ + | Plant functional type | Mortality rate (yr :sup:`-1`) | + +===================================================+======================================+ + | NET Temperate | 0.0211945164991821 | + +---------------------------------------------------+--------------------------------------+ + | NET Boreal | 0.0174 | + +---------------------------------------------------+--------------------------------------+ + | NDT Boreal | 0.0198950093389492 | + +---------------------------------------------------+--------------------------------------+ + | BET Tropical | 0.024 | + +---------------------------------------------------+--------------------------------------+ + | BET Temperate | 0.0199981934178915 | + +---------------------------------------------------+--------------------------------------+ + | BDT Tropical | 0.0200001818014196 | + +---------------------------------------------------+--------------------------------------+ + | BDT Temperate | 0.0210684434513937 | + +---------------------------------------------------+--------------------------------------+ + | BDT Boreal | 0.024 | + +---------------------------------------------------+--------------------------------------+ + +PFT name abbreviations: NET = Needleleaf Evergreen Tree, NDT = Needleleaf Deciduous Tree, BET = Broadleaf Evergreen Tree, BDT = Broadleaf Deciduous Tree. Shrubs and grasses all still use the default 2% annual mortality rate. + + + +Conceptual representation +---------------------------------------------- +This section describes plant mortality in the biogeochemistry (BGC) configuration of CLM for non-FATES vegetation. It focuses on the representation of gap-phase mortality, which accounts for the aggregate loss of plant biomass due to processes such as disturbance, competition, age-related decline, and environmental stress. + +In this framework, mortality is represented as a first-order loss process, in which all vegetation carbon and nitrogen pools experience proportional losses over time. The equations presented in this section describe the pool-level mortality fluxes and their routing within the biogeochemical framework. + +This section does not describe mechanistic mortality processes represented in the Functionally Assembled Terrestrial Ecosystem Simulator (FATES), where mortality emerges from explicit demographic, physiological, and disturbance processes (see Chapter :numref:`rst_Dynamic Global Vegetation and FATES`). Readers interested in those formulations should refer to the `FATES documentation`_. Mortality associated with fire and land-use or harvest processes is treated separately in the Fire and Land Use Change sections (see Chapters :numref:`rst_Fire` and :numref:`rst_Transient Landcover Change`, respectively). Legacy dynamic vegetation configurations (CNDV) used related mortality formulations but are no longer actively supported; mechanistic dynamic vegetation and mortality processes in CTSM are now handled through FATES. + +.. _FATES documentation: https://fates-users-guide.readthedocs.io/en/latest/index.html + + +Implementation +---------------------------------------------- + +Vegetation carbon and nitrogen dynamics are implemented using a matrix-based formulation (:ref:`Lu et al. 2020`; :ref:`Liao et al. 2023`), in which the evolution of vegetation pools is governed by a combination of process-specific transfer and turnover operators. Within this framework, mortality is represented as one component of the overall vegetation transfer system, alongside phenological turnover and fire-related processes. -Plant mortality as described here applies to perennial vegetation types, and is intended to represent the death of individuals from a stand of plants due to the aggregate of processes such as wind throw, insect attack, disease, extreme temperatures or drought, and age-related decline in vigor. These processes are referred to in aggregate as "gap-phase" mortality. Mortality due to fire and anthropogenic land cover change are treated separately (see Chapters :numref:`rst_Fire` and :numref:`rst_Transient Landcover Change`, respectively). +The matrix formulation provides a compact representation of vegetation dynamics and organizes the bookkeeping of transfers among pools, but does not alter the underlying conceptual treatment of mortality as a proportional loss from vegetation pools. -Mortality Fluxes Leaving Vegetation Pools + +Mortality fluxes and routing ---------------------------------------------- -Whole-plant mortality is parameterized very simply, assuming a mortality rate of 2% yr\ :sup:`-1` for all vegetation types. This is clearly a gross oversimplification of an important process, and additional work is required to better constrain this process in different climate zones (:ref:`Keller et al. 2004`; :ref:`Sollins 1982`), for different species mixtures (:ref:`Gomes et al. 2003`), and for different size and age classes (:ref:`Busing 2005`; :ref:`Law et al. 2003`). Literature values for forest mortality rates range from at least 0.7% to 3.0% yr\ :sup:`-1`. Taking the annual rate of mortality (*am*, proportion yr\ :sup:`-1`) as 0.02, a mortality rate per second (*m*) is calculated as :math:`m={am\mathord{\left/ {\vphantom {am \left(365\cdot 86400\right)}} \right.} \left(365\cdot 86400\right)}`. All vegetation carbon and nitrogen pools for display, storage, and transfer are affected at rate *m*, with mortality fluxes out of vegetation pools eventually merged to the column level and deposited in litter pools. Mortality (*mort*) fluxes out of displayed vegetation carbon and nitrogen pools are +Carbon and nitrogen removed from vegetation pools are routed according to tissue type: + +- Leaf and fine-root pools are transferred to litter pools (labile, cellulose, and lignin components) + +- Stem and coarse-root pools are transferred to coarse woody debris pools + +- Storage and transfer pools are assumed to represent labile material and are therefore transferred to litter pools + +This formulation provides a simplified, bulk representation of mortality consistent with the structure of non-demographic CLM configurations. A conceptual diagram of vegetation fluxes and pools (:numref:`Figure Vegetation fluxes and pools`) can be found in Chapter :numref:`rst_CN Pools`. + + +Mortality fluxes leaving vegetation pools +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Whole-plant mortality is represented as a first-order process with a prescribed mortality rate. For an annual mortality fraction (:math:`a_m`, yr\ :sup:`-1`), the corresponding rate per unit time (second) :math:`m` is given by: .. math:: :label: 33.1) - CF_{leaf\_ mort} =CS_{leaf} m + m = \frac{a_m}{365 \times 86400} + +Mortality fluxes from vegetation carbon pools are computed as: .. math:: :label: 33.2) - CF_{froot\_ mort} =CS_{froot} m + CF_{i,mort} =CS_{i} m + +and similarly for nitrogen: .. math:: :label: 33.3) - CF_{livestem\_ mort} =CS_{livestem} m + NF_{i,mort} =NS_{i} m + +where :math:`CF_{i}` is carbon flux, :math:`CS_{i}` is carbon state variable (or pool), :math:`NF_{i}` is nitrogen flux, :math:`NS_{i}` is nitrogen state, for each vegetation pool :math:`i`, respectively. + +These fluxes are applied to all vegetation pools, including: + +- displayed pools: *leaf*, *froot*, *livestem*, *deadstem*, *livecroot*, *deadcroot* +- storage pools: *leaf_stor*, *froot_stor*, *livestem_stor*, *deadstem_stor*, *livecroot_stor*, *deadcroot_stor*, *gresp_stor* +- transfer pools: *leaf_xfer*, *froot_xfer*, *livestem_xfer*, *deadstem_xfer*, *livecroot_xfer*, *deadcroot_xfer*, *gresp_xfer* +- retranslocated pools: *retrans* + +where *croot* refers to coarse roots, *froot* refers to fine roots, *gresp* refers to growth respiration, *retrans* refers to retranslocated, *stor* refers to storage, and *xfer* refers to transfer. Note that *gresp* only exists in carbon pools, and *retrans* only exists in nitrogen pools. + + + +Aggregation to column level +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Analogous to the treatment of litterfall fluxes (Chapter :numref:`rst_Vegetation Phenology and Turnover`), mortality fluxes leaving the vegetation pools are first computed at the plant functional type (PFT) level and then aggregated to the column level according to the weighted distribution of PFT :math:`p` on the column (:math:`wcol_{p}` ), and deposited in litter or coarse woody debris pools, which are defined at the column level. + +- Non-woody tissue pools + +Carbon and nitrogen fluxes from mortality of displayed leaf and fine root into litter pools are calculated as .. math:: :label: 33.4) - CF_{deadstem\_ mort} =CS_{deadstem} m + CF_{leaf\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{leaf\_ mort} f_{lab\_ leaf,p} wcol_{p} .. math:: :label: 33.5) - CF_{livecroot\_ mort} =CS_{livecroot} m + CF_{leaf\_ mort,lit2} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{leaf\_ mort} f_{cel\_ leaf,p} wcol_{p} .. math:: :label: 33.6) - CF_{deadcroot\_ mort} =CS_{deadcroot} m + CF_{leaf\_ mort,lit3} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{leaf\_ mort} f_{lig\_ leaf,p} wcol_{p} .. math:: :label: 33.7) - NF_{leaf\_ mort} =NS_{leaf} m + CF_{froot\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{froot\_ mort} f_{lab\_ froot,p} wcol_{p} .. math:: :label: 33.8) - NF_{froot\_ mort} =NS_{froot} m + CF_{froot\_ mort,lit2} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{froot\_ mort} f_{cel\_ froot,p} wcol_{p} .. math:: :label: 33.9) - NF_{livestem\_ mort} =NS_{livestem} m + CF_{froot\_ mort,lit3} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{froot\_ mort} f_{lig\_ froot,p} wcol_{p} + +where :math:`{f}_{lab\_leaf,p}`, :math:`{f}_{cel\_leaf,p}`, and :math:`{f}_{lig\_leaf,p}` are the labile (lit1), cellulose/hemicellulose (lit2), and lignin (lit3) fractions of leaf litter for PFT :math:`p`, +and the same rule applies to the fine root litter fractions. +:math:`{wcol}_{p}` is the fractional contribution of PFT :math:`p` to the column, :math:`p` is an index through the plant functional types occurring on a column, and :math:`n_{\mathrm{pft}}` is the number of PFTs present in the column. + +Nitrogen fluxes to the litter pools are assumed to follow the C:N of the senescent tissue, and so are distributed using the same fractions used for carbon fluxes: .. math:: :label: 33.10) - NF_{deadstem\_ mort} =NS_{deadstem} m + NF_{leaf\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{leaf\_ mort} f_{lab\_ leaf,p} wcol_{p} .. math:: :label: 33.11) - NF_{livecroot\_ mort} =NS_{livecroot} m + NF_{leaf\_ mort,lit2} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{leaf\_ mort} f_{cel\_ leaf,p} wcol_{p} .. math:: :label: 33.12) - NF_{deadcroot\_ mort} =NS_{deadcroot} m + NF_{leaf\_ mort,lit3} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{leaf\_ mort} f_{lig\_ leaf,p} wcol_{p} .. math:: :label: 33.13) - NF_{retrans\_ mort} =NS_{retrans} m. - -where CF are carbon fluxes, CS is carbon storage, NF are nitrogen fluxes, NS is nitrogen storage, *croot* refers to coarse roots, *froot* refers to fine roots, and *retrans* refers to retranslocated. - -Mortality fluxes out of carbon and nitrogen storage (*stor)* pools are + NF_{froot\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{froot\_ mort} f_{lab\_ froot,p} wcol_{p} .. math:: :label: 33.14) - CF_{leaf\_ stor\_ mort} =CS_{leaf\_ stor} m + NF_{froot\_ mort,lit2} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{froot\_ mort} f_{cel\_ froot,p} wcol_{p} .. math:: :label: 33.15) - CF_{froot\_ stor\_ mort} =CS_{froot\_ stor} m + NF_{froot\_ mort,lit3} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{froot\_ mort} f_{lig\_ froot,p} wcol_{p} . + + +- Woody tissue pools + +Carbon and nitrogen mortality fluxes from displayed live and dead stem and coarse root pools are merged to the column level and deposited in the coarse woody debris (*cwd*) pools: .. math:: :label: 33.16) - CF_{livestem\_ stor\_ mort} =CS_{livestem\_ stor} m + CF_{livestem\_ mort,cwd} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{livestem\_ mort} wcol_{p} .. math:: :label: 33.17) - CF_{deadstem\_ stor\_ mort} =CS_{deadstem\_ stor} m + CF_{deadstem\_ mort,cwd} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{deadstem\_ mort} wcol_{p} .. math:: :label: 33.18) - CF_{livecroot\_ stor\_ mort} =CS_{livecroot\_ stor} m + CF_{livecroot\_ mort,cwd} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{livecroot\_ mort} wcol_{p} .. math:: :label: 33.19) - CF_{deadcroot\_ stor\_ mort} =CS_{deadcroot\_ stor} m + CF_{deadcroot\_ mort,cwd} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{deadcroot\_ mort} wcol_{p} .. math:: :label: 33.20) - CF_{gresp\_ stor\_ mort} =CS_{gresp\_ stor} m + NF_{livestem\_ mort,cwd} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{livestem\_ mort} wcol_{p} .. math:: :label: 33.21) - NF_{leaf\_ stor\_ mort} =NS_{leaf\_ stor} m + NF_{deadstem\_ mort,cwd} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{deadstem\_ mort} wcol_{p} .. math:: :label: 33.22) - NF_{froot\_ stor\_ mort} =NS_{froot\_ stor} m + NF_{livecroot\_ mort,cwd} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{livecroot\_ mort} wcol_{p} .. math:: :label: 33.23) - NF_{livestem\_ stor\_ mort} =NS_{livestem\_ stor} m + NF_{deadcroot\_ mort,cwd} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{deadcroot\_ mort} wcol_{p} + +- Storage and transfer pools + +All vegetation storage and transfer pools for carbon and nitrogen are assumed to exist as labile pools within the plant (e.g. as carbohydrate stores, in the case of carbon pools). This assumption applies to storage and transfer pools for both non-woody and woody tissues. The mortality fluxes from these pools are therefore assumed to be deposited in the labile litter pools (:math:`{CS}_{lit1}`, :math:`{NS}_{lit1}`), after being merged to the column level. + +Carbon mortality fluxes out of storage and transfer pools are: .. math:: :label: 33.24) - NF_{deadstem\_ stor\_ mort} =NS_{deadstem\_ stor} m + CF_{leaf\_ stor\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{leaf\_ stor\_ mort} wcol_{p} .. math:: :label: 33.25) - NF_{livecroot\_ stor\_ mort} =NS_{livecroot\_ stor} m + CF_{froot\_ stor\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{froot\_ stor\_ mort} wcol_{p} .. math:: :label: 33.26) - NF_{deadcroot\_ stor\_ mort} =NS_{deadcroot\_ stor} m - -where *gresp* refers to growth respiration. - -Mortality fluxes out of carbon and nitrogen transfer (*xfer)* growth pools are + CF_{livestem\_ stor\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{livestem\_ stor\_ mort} wcol_{p} .. math:: :label: 33.27) - CF_{leaf\_ xfer\_ mort} =CS_{leaf\_ xfer} m + CF_{deadstem\_ stor\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{deadstem\_ stor\_ mort} wcol_{p} .. math:: :label: 33.28) - CF_{froot\_ xfer\_ mort} =CS_{froot\_ xfer} m + CF_{livecroot\_ stor\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{livecroot\_ stor\_ mort} wcol_{p} .. math:: :label: 33.29) - CF_{livestem\_ xfer\_ mort} =CS_{livestem\_ xfer} m + CF_{deadcroot\_ stor\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{deadcroot\_ stor\_ mort} wcol_{p} .. math:: :label: 33.30) - CF_{deadstem\_ xfer\_ mort} =CS_{deadstem\_ xfer} m + CF_{gresp\_ stor\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{gresp\_ stor\_ mort} wcol_{p} .. math:: :label: 33.31) - CF_{livecroot\_ xfer\_ mort} =CS_{livecroot\_ xfer} m + CF_{leaf\_ xfer\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{leaf\_ xfer\_ mort} wcol_{p} .. math:: :label: 33.32) - CF_{deadcroot\_ xfer\_ mort} =CS_{deadcroot\_ xfer} m + CF_{froot\_ xfer\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{froot\_ xfer\_ mort} wcol_{p} .. math:: :label: 33.33) - CF_{gresp\_ xfer\_ mort} =CS_{gresp\_ xfer} m + CF_{livestem\_ xfer\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{livestem\_ xfer\_ mort} wcol_{p} .. math:: :label: 33.34) - NF_{leaf\_ xfer\_ mort} =NS_{leaf\_ xfer} m + CF_{deadstem\_ xfer\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{deadstem\_ xfer\_ mort} wcol_{p} .. math:: :label: 33.35) - NF_{froot\_ xfer\_ mort} =NS_{froot\_ xfer} m + CF_{livecroot\_ xfer\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{livecroot\_ xfer\_ mort} wcol_{p} .. math:: :label: 33.36) - NF_{livestem\_ xfer\_ mort} =NS_{livestem\_ xfer} m + CF_{deadcroot\_ xfer\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{deadcroot\_ xfer\_ mort} wcol_{p} .. math:: :label: 33.37) - NF_{deadstem\_ xfer\_ mort} =NS_{deadstem\_ xfer} m + CF_{gresp\_ xfer\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}CF_{gresp\_ xfer\_ mort} wcol_{p} . + +Nitrogen mortality fluxes out of storage and transfer pools, including the storage pool for retranslocated nitrogen, are calculated as: .. math:: :label: 33.38) - NF_{livecroot\_ xfer\_ mort} =NS_{livecroot\_ xfer} m + NF_{leaf\_ stor\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{leaf\_ stor\_ mort} wcol_{p} .. math:: :label: 33.39) - NF_{deadcroot\_ xfer\_ mort} =NS_{deadcroot\_ xfer} m - -Mortality Fluxes Merged to the Column Level ------------------------------------------------- - -Analogous to the treatment of litterfall fluxes, mortality fluxes leaving the vegetation pools are merged to the column level according to the weighted distribution of PFTs on the column (:math:`wcol_{p}` ), and deposited in litter and coarse woody debris pools, which are defined at the column level. Carbon and nitrogen fluxes from mortality of displayed leaf and fine root into litter pools are calculated as - + NF_{froot\_ stor\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{froot\_ stor\_ mort} wcol_{p} + .. math:: :label: 33.40) - CF_{leaf\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{leaf\_ mort} f_{lab\_ leaf,p} wcol_{p} + NF_{livestem\_ stor\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{livestem\_ stor\_ mort} wcol_{p} .. math:: :label: 33.41) - CF_{leaf\_ mort,lit2} =\sum _{p=0}^{npfts}CF_{leaf\_ mort} f_{cel\_ leaf,p} wcol_{p} + NF_{deadstem\_ stor\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{deadstem\_ stor\_ mort} wcol_{p} .. math:: :label: 33.42) - CF_{leaf\_ mort,lit3} =\sum _{p=0}^{npfts}CF_{leaf\_ mort} f_{lig\_ leaf,p} wcol_{p} + NF_{livecroot\_ stor\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{livecroot\_ stor\_ mort} wcol_{p} .. math:: :label: 33.43) - CF_{froot\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{froot\_ mort} f_{lab\_ froot,p} wcol_{p} + NF_{deadcroot\_ stor\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{deadcroot\_ stor\_ mort} wcol_{p} .. math:: :label: 33.44) - CF_{froot\_ mort,lit2} =\sum _{p=0}^{npfts}CF_{froot\_ mort} f_{cel\_ froot,p} wcol_{p} + NF_{retrans\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{retrans\_ mort} wcol_{p} .. math:: :label: 33.45) - CF_{froot\_ mort,lit3} =\sum _{p=0}^{npfts}CF_{froot\_ mort} f_{lig\_ froot,p} wcol_{p} + NF_{leaf\_ xfer\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{leaf\_ xfer\_ mort} wcol_{p} .. math:: :label: 33.46) - NF_{leaf\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{leaf\_ mort} f_{lab\_ leaf,p} wcol_{p} + NF_{froot\_ xfer\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{froot\_ xfer\_ mort} wcol_{p} .. math:: :label: 33.47) - NF_{leaf\_ mort,lit2} =\sum _{p=0}^{npfts}NF_{leaf\_ mort} f_{cel\_ leaf,p} wcol_{p} + NF_{livestem\_ xfer\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{livestem\_ xfer\_ mort} wcol_{p} .. math:: :label: 33.48) - NF_{leaf\_ mort,lit3} =\sum _{p=0}^{npfts}NF_{leaf\_ mort} f_{lig\_ leaf,p} wcol_{p} + NF_{deadstem\_ xfer\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{deadstem\_ xfer\_ mort} wcol_{p} .. math:: :label: 33.49) - NF_{froot\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{froot\_ mort} f_{lab\_ froot,p} wcol_{p} + NF_{livecroot\_ xfer\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{livecroot\_ xfer\_ mort} wcol_{p} .. math:: :label: 33.50) - NF_{froot\_ mort,lit2} =\sum _{p=0}^{npfts}NF_{froot\_ mort} f_{cel\_ froot,p} wcol_{p} - -.. math:: - :label: 33.51) - - NF_{froot\_ mort,lit3} =\sum _{p=0}^{npfts}NF_{froot\_ mort} f_{lig\_ froot,p} wcol_{p} . - -where *lab* refers to labile, *cel* refers to cellulose, and *lig* refers to lignin. Carbon and nitrogen mortality fluxes from displayed live and dead stem and coarse root pools are merged to the column level and deposited in the coarse woody debris (*cwd*) pools: - -.. math:: - :label: 33.52) - - CF_{livestem\_ mort,cwd} =\sum _{p=0}^{npfts}CF_{livestem\_ mort} wcol_{p} - -.. math:: - :label: 33.53) - - CF_{deadstem\_ mort,cwd} =\sum _{p=0}^{npfts}CF_{deadstem\_ mort} wcol_{p} - -.. math:: - :label: 33.54) - - CF_{livecroot\_ mort,cwd} =\sum _{p=0}^{npfts}CF_{livecroot\_ mort} wcol_{p} - -.. math:: - :label: 33.55) - - CF_{deadcroot\_ mort,cwd} =\sum _{p=0}^{npfts}CF_{deadcroot\_ mort} wcol_{p} - -.. math:: - :label: 33.56) - - NF_{livestem\_ mort,cwd} =\sum _{p=0}^{npfts}NF_{livestem\_ mort} wcol_{p} - -.. math:: - :label: 33.57) - - NF_{deadstem\_ mort,cwd} =\sum _{p=0}^{npfts}NF_{deadstem\_ mort} wcol_{p} - -.. math:: - :label: 33.58) - - NF_{livecroot\_ mort,cwd} =\sum _{p=0}^{npfts}NF_{livecroot\_ mort} wcol_{p} - -.. math:: - :label: 33.59) - - NF_{deadcroot\_ mort,cwd} =\sum _{p=0}^{npfts}NF_{deadcroot\_ mort} wcol_{p} - -All vegetation storage and transfer pools for carbon and nitrogen are assumed to exist as labile pools within the plant (e.g. as carbohydrate stores, in the case of carbon pools). This assumption applies to storage and transfer pools for both non-woody and woody tissues. The mortality fluxes from these pools are therefore assumed to be deposited in the labile litter pools (:math:`{CS}_{lit1}`, :math:`{NS}_{lit1}`), after being merged to the column level. Carbon mortality fluxes out of storage and transfer pools are: - -.. math:: - :label: 33.60) - - CF_{leaf\_ stor\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{leaf\_ stor\_ mort} wcol_{p} - -.. math:: - :label: 33.61) - - CF_{froot\_ stor\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{froot\_ stor\_ mort} wcol_{p} - -.. math:: - :label: 33.62) - - CF_{livestem\_ stor\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{livestem\_ stor\_ mort} wcol_{p} - -.. math:: - :label: 33.63) - - CF_{deadstem\_ stor\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{deadstem\_ stor\_ mort} wcol_{p} - -.. math:: - :label: 33.64) - - CF_{livecroot\_ stor\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{livecroot\_ stor\_ mort} wcol_{p} - -.. math:: - :label: 33.65) - - CF_{deadcroot\_ stor\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{deadcroot\_ stor\_ mort} wcol_{p} - -.. math:: - :label: 33.66) - - CF_{gresp\_ stor\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{gresp\_ stor\_ mort} wcol_{p} - -.. math:: - :label: 33.67) - - CF_{leaf\_ xfer\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{leaf\_ xfer\_ mort} wcol_{p} - -.. math:: - :label: 33.68) - - CF_{froot\_ xfer\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{froot\_ xfer\_ mort} wcol_{p} - -.. math:: - :label: 33.69) - - CF_{livestem\_ xfer\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{livestem\_ xfer\_ mort} wcol_{p} - -.. math:: - :label: 33.70) - - CF_{deadstem\_ xfer\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{deadstem\_ xfer\_ mort} wcol_{p} - -.. math:: - :label: 33.71) - - CF_{livecroot\_ xfer\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{livecroot\_ xfer\_ mort} wcol_{p} - -.. math:: - :label: 33.72) - - CF_{deadcroot\_ xfer\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{deadcroot\_ xfer\_ mort} wcol_{p} - -.. math:: - :label: 33.73) - - CF_{gresp\_ xfer\_ mort,lit1} =\sum _{p=0}^{npfts}CF_{gresp\_ xfer\_ mort} wcol_{p} . - -Nitrogen mortality fluxes out of storage and transfer pools, including the storage pool for retranslocated nitrogen, are calculated as: - -.. math:: - :label: 33.74) - - NF_{leaf\_ stor\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{leaf\_ stor\_ mort} wcol_{p} - -.. math:: - :label: 33.75) - - NF_{froot\_ stor\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{froot\_ stor\_ mort} wcol_{p} - -.. math:: - :label: 33.76) - - NF_{livestem\_ stor\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{livestem\_ stor\_ mort} wcol_{p} - -.. math:: - :label: 33.77) - - NF_{deadstem\_ stor\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{deadstem\_ stor\_ mort} wcol_{p} - -.. math:: - :label: 33.78) - - NF_{livecroot\_ stor\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{livecroot\_ stor\_ mort} wcol_{p} - -.. math:: - :label: 33.79) - - NF_{deadcroot\_ stor\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{deadcroot\_ stor\_ mort} wcol_{p} - -.. math:: - :label: 33.80) - - NF_{retrans\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{retrans\_ mort} wcol_{p} - -.. math:: - :label: 33.81) - - NF_{leaf\_ xfer\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{leaf\_ xfer\_ mort} wcol_{p} - -.. math:: - :label: 33.82) - - NF_{froot\_ xfer\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{froot\_ xfer\_ mort} wcol_{p} - -.. math:: - :label: 33.83) - - NF_{livestem\_ xfer\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{livestem\_ xfer\_ mort} wcol_{p} - -.. math:: - :label: 33.84) - - NF_{deadstem\_ xfer\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{deadstem\_ xfer\_ mort} wcol_{p} - -.. math:: - :label: 33.85) - - NF_{livecroot\_ xfer\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{livecroot\_ xfer\_ mort} wcol_{p} - -.. math:: - :label: 33.86) - - NF_{deadcroot\_ xfer\_ mort,lit1} =\sum _{p=0}^{npfts}NF_{deadcroot\_ xfer\_ mort} wcol_{p} . + NF_{deadcroot\_ xfer\_ mort,lit1} =\sum _{p=0}^{n_{\mathrm{pft}}}NF_{deadcroot\_ xfer\_ mort} wcol_{p} . diff --git a/doc/source/tech_note/Plant_Respiration/CLM50_Tech_Note_Plant_Respiration.rst b/doc/source/tech_note/Plant_Respiration/CLM50_Tech_Note_Plant_Respiration.rst index 69f100f435..b43b5879a8 100644 --- a/doc/source/tech_note/Plant_Respiration/CLM50_Tech_Note_Plant_Respiration.rst +++ b/doc/source/tech_note/Plant_Respiration/CLM50_Tech_Note_Plant_Respiration.rst @@ -2,81 +2,87 @@ Plant Respiration ================= -CLM5 includes changes to plant respiration including - - A new leaf respiration algorithm based on Atkin et al. (2016) - - A lower growth respiration coefficient, based on Atkin et al. (2017) Autotrophic Respiration ---------------------------- -The model treats maintenance and growth respiration fluxes separately, even though it is difficult to measure them as separate fluxes (Lavigne and Ryan, 1997; Sprugel et al., 1995). Maintenance respiration is defined as the carbon cost to support the metabolic activity of existing live tissue, while growth respiration is defined as the additional carbon cost for the synthesis of new growth. +The model treats maintenance and growth respiration fluxes separately, even though it is difficult to measure them as separate fluxes (:ref:`Lavigne and Ryan 1997 `; :ref:`Sprugel et al. 1995 `). Maintenance respiration is defined as the carbon cost to support the metabolic activity of existing live tissue, while growth respiration is defined as the additional carbon cost for the synthesis of new growth. Maintenance Respiration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Atkin et al. (2016) propose a model for leaf respiration that is based on the leaf nitrogen content per unit area (:math:`NS_{narea}` , gN m\ :sup:`-2` leaf), with an intercept parameter that is PFT dependant, and an acclimation term that depends upon the average temperature of the previous 10 day period :math:`t_{2m,10days}`, in Celsius. +Maintenance respiration is calculated separately for leaves, live stems, live coarse roots, and fine roots. For leaf maintenance respiration (:math:`CF_{mr\_ leaf}`; gC m\ :sup:`-2` s\ :sup:`-1`), :ref:`Atkin et al. (2015)` propose a model that includes an intercept parameter that is PFT-dependent (:math:`i_{atkin,pft}`; see :numref:`Table Atkin leaf respiration model intercept values` for values), a term for leaf nitrogen content per unit area (:math:`NS_{narea}`; gN m\ :sup:`-2` leaf), and an acclimation term that depends on the average temperature of the previous 10 day period (:math:`t_{2m,10days}`; °C). Leaf maintenance respiration carbon flux is calculated as: .. math:: :label: 17.46) CF_{mr\_ leaf} = i_{atkin,pft} + (NS_{narea} 0.2061) - (0.0402 (t_{2m,10days})) -The temperature dependance of leaf maintenance (dark) respiration is described in Chapter :numref:`rst_Stomatal Resistance and Photosynthesis`. +The temperature dependence of leaf maintenance (dark) respiration is described in Chapter :numref:`rst_Stomatal Resistance and Photosynthesis`. + +Live stem (:math:`CF_{mr\_ livestem}`; gC m\ :sup:`-2` s\ :sup:`-1`), live coarse root (:math:`CF_{mr\_ livecroot}`; gC m\ :sup:`-2` s\ :sup:`-1`), and fine root (:math:`CF_{mr\_ froot}`; gC m\ :sup:`-2` s\ :sup:`-1`) maintenance respiration are calculated as the product of a nitrogen-scaled base respiration rate and a Q10-based temperature scaling. :math:`MR_{base}` (gC gN\ :sup:`-1` s\ :sup:`-1`) represents the base respiration rate per unit nitrogen, :math:`MR_{Q10}` (= 1.5) is the temperature sensitivity for maintenance respiration, and :math:`T_{2m}` (°C) is the air temperature at 2m height. :math:`NS_{livestem}` (gN m\ :sup:`-2` live stem), :math:`NS_{livecroot}` (gN m\ :sup:`-2` live coarse root), and :math:`NS_{froot}` (gN m\ :sup:`-2` fine root) represent nitrogen content per unit area for live stem, live coarse root, and fine root, respectively. Finally, fine root respiration is calculated as the sum of contributions from each soil level *j*. :math:`rootfr_{j}` represents the fraction of fine roots distributed in soil level *j* and :math:`Ts_{j}` (°C) is the soil temperature at level *j*. Thus, + +Live stem maintenance respiration carbon flux is calculated as: .. math:: :label: 17.47) CF_{mr\_ livestem} =NS_{livestem} MR_{base} MR_{Q10} ^{(T_{2m} -20)/10} +Live coarse root respiration carbon flux is calculated as: + .. math:: :label: 17.48) CF_{mr\_ livecroot} =NS_{livecroot} MR_{base} MR_{Q10} ^{(T_{2m} -20)/10} +Fine root maintenance respiration carbon flux is calculated as: + .. math:: :label: 17.49) CF_{mr\_ froot} =\sum _{j=1}^{nlevsoi}NS_{froot} rootfr_{j} MR_{base} MR_{Q10} ^{(Ts_{j} -20)/10} -where :math:`MR_{q10}` (= 2.0) is the temperature sensitivity for maintenance respiration, :math:`T_{2m}` (°C) is the air temperature at 2m height, :math:`Ts_{j}`* (°C) is the soil temperature at level *j*, and :math:`rootfr_{j}` is the fraction of fine roots distributed in soil level *j*. +The total maintenance respiration cost (:math:`CF_{mr}`; gC m\ :sup:`-2` s\ :sup:`-1`) is then calculated as the sum of leaf (:math:`CF_{mr\_ leaf}`), fine root (:math:`CF_{mr\_ froot}`), live stem (:math:`CF_{mr\_ livestem}`), and live coarse root (:math:`CF_{mr\_ livecroot}`) components: + +.. math:: + :label: 17.50) + + CF_{mr} =CF_{mr\_ leaf} +CF_{mr\_ froot} +CF_{mr\_ livestem} +CF_{mr\_ livecroot} + + +.. _Table Atkin leaf respiration model intercept values: .. table:: Atkin leaf respiration model intercept values. ======================== ============= Plant functional type :math:`i_{atkin}` ======================== ============= - NET Temperate 1.499 - NET Boreal 1.499 - NDT Boreal 1.499 - BET Tropical 1.756 - BET temperate 1.756 - BDT tropical 1.756 - BDT temperate 1.756 - BDT boreal 1.756 - BES temperate 2.075 - BDS temperate 2.075 - BDS boreal 2.075 - C\ :sub:`3` arctic grass 2.196 - C\ :sub:`3` grass 2.196 - C\ :sub:`4` grass 2.196 + NET Temperate 1.5 + NET Boreal 1.42 + NDT Boreal 1.22 + BET Tropical 1.93 + BET temperate 1.82 + BDT tropical 1.5 + BDT temperate 1.64 + BDT boreal 1.41 + BES temperate 2.07 + BDS temperate 2.07 + BDS boreal 2.07 + C\ :sub:`3` arctic grass 2.2 + C\ :sub:`3` grass 2.35 + C\ :sub:`4` grass 2.2 ======================== ============= -Note that, for woody vegetation, maintenance respiration costs are not calculated for the dead stem and dead coarse root components. These components are assumed to consist of dead xylem cells, with no metabolic function. By separating the small live component of the woody tissue (ray parenchyma, phloem, and sheathing lateral meristem cells) from the larger fraction of dead woody tissue, it is reasonable to assume a common base maintenance respiration rate for all live tissue types. +Note that, for woody vegetation, maintenance respiration costs are not calculated for dead stem and dead coarse root components. These components are assumed to consist of dead xylem cells with no metabolic function. By separating the small live component of the woody tissue (ray parenchyma, phloem, and sheathing lateral meristem cells) from the larger fraction of dead woody tissue, it is reasonable to assume a common base maintenance respiration rate for all live tissue types. -The total maintenance respiration cost is then given as: - -.. math:: - :label: 17.50) - - CF_{mr} =CF_{mr\_ leaf} +CF_{mr\_ froot} +CF_{mr\_ livestem} +CF_{mr\_ livecroot} . .. _Growth Respiration: Growth Respiration ^^^^^^^^^^^^^^^^^^^^^^^^^ -Growth respiration is calculated as a factor of 0.11 times the total carbon allocation to new growth (:math:`CF_{growth}`, after allocating carbon for N acquisition, Chapter :numref:`rst_FUN`.) on a given timestep, based on construction costs for a range of woody and non-woody tissues, with estimates of the growth respiration flux revised downswards following (Atkin et al. 2017). For new carbon and nitrogen allocation that enters storage pools for subsequent display, it is not clear what fraction of the associated growth respiration should occur at the time of initial allocation, and what fraction should occur later, at the time of display of new growth from storage. Eddy covariance estimates of carbon fluxes in forest ecosystems suggest that the growth respiration associated with transfer of allocated carbon and nitrogen from storage into displayed tissue is not significant (Churkina et al., 2003), and so it is assumed in CLM that all of the growth respiration cost is incurred at the time of initial allocation, regardless of the fraction of allocation that is displayed immediately (i.e. regardless of the value of :math:`f_{cur}`, section 13.5). This behavior is parameterized in such a way that if future research suggests that some fraction of the growth respiration cost should be incurred at the time of display from storage, a simple parameter modification will effect the change. [1]_ +Growth respiration is calculated as a factor of 0.11 times the total carbon allocated to new growth (:math:`CF_{growth}`) after allocating carbon for N acquisition (see Chapter :numref:`rst_CN Allocation`) on a given timestep, based on construction costs for a range of woody and non-woody tissues. Estimates of the growth respiration flux were revised downward following :ref:`Atkin et al. (2017)`. For new carbon and nitrogen allocation that enters storage pools for subsequent display, it is not clear what fraction of the associated growth respiration should occur at the time of initial allocation, and what fraction should occur later, at the time of display of new growth from storage. Eddy covariance estimates of carbon fluxes in forest ecosystems suggest that the growth respiration associated with transfer of allocated carbon and nitrogen from storage into displayed tissue is not significant (:ref:`Churkina et al. 2003 `), so it is assumed in CLM that all of the growth respiration cost is incurred at the time of initial allocation, regardless of the fraction of allocation that is displayed immediately (i.e. regardless of the value of :math:`f_{cur}`, section :numref:`Carbon Allocation to New Growth`). This behavior is parameterized in such a way that if future research suggests that some fraction of the growth respiration cost should be incurred at the time of display from storage, a simple parameter modification will effect the change. [1]_ .. [1] - Parameter :math:`\text{grpnow}` in routines CNGResp and CNAllocation, currently set to 1.0, could be changed to a smaller value to transfer some portion (1 - :math:`\text{grpnow}` ) of the growth respiration forward in time to occur at the time of growth display from storage. - + Parameter :math:`\text{grpnow}` in routines CNGRespMod.F90 and CNAllocationMod.F90, currently set to 1.0, could be changed to a smaller value to transfer some portion (1 - :math:`\text{grpnow}` ) of the growth respiration forward in time to occur at the time of growth display from storage. diff --git a/doc/source/tech_note/Radiative_Fluxes/CLM50_Tech_Note_Radiative_Fluxes.rst b/doc/source/tech_note/Radiative_Fluxes/CLM50_Tech_Note_Radiative_Fluxes.rst index df2b367b3a..4c7eed9d59 100644 --- a/doc/source/tech_note/Radiative_Fluxes/CLM50_Tech_Note_Radiative_Fluxes.rst +++ b/doc/source/tech_note/Radiative_Fluxes/CLM50_Tech_Note_Radiative_Fluxes.rst @@ -26,9 +26,7 @@ Solar Fluxes .. figure:: image1.png - Schematic diagram of (a) direct beam radiation, (b) diffuse solar radiation, and (c) longwave radiation absorbed, transmitted, and reflected by vegetation and ground. - -For clarity, terms involving :math:`T^{n+1} -T^{n}` are not shown in (c). + Schematic diagram of (a) direct beam radiation, (b) diffuse solar radiation, and (c) longwave radiation absorbed, transmitted, and reflected by vegetation and ground. For simplicity, terms involving :math:`T^{n+1} -T^{n}` (i.e. time stepping) are not shown in (c) but do get addressed later in this section. The total solar radiation absorbed by the vegetation and ground is @@ -79,7 +77,7 @@ with :math:`L^{sun}` and :math:`L^{sha}` the sunlit and shaded plant area index, L^{sun} =\frac{1-e^{-K(L+S)} }{K} -and the shaded leaf area index is :math:`L^{sha} =(L+S)-L^{sun}`. In calculating :math:`L^{sun}`, +and the shaded plant area index is :math:`L^{sha} =(L+S)-L^{sun}`. In calculating :math:`L^{sun}`, .. math:: :label: 4.8 @@ -182,7 +180,7 @@ These equations assume that absorptivity equals emissivity. The emissivity of th \varepsilon _{g} =\varepsilon _{soi} \left(1-f_{sno} \right)+\varepsilon _{sno} f_{sno} -where :math:`\varepsilon _{soi} =0.96` for soil, 0.97 for glacier, :math:`\varepsilon _{sno} =0.97`, and :math:`f_{sno}` is the fraction of ground covered by snow (section :numref:`Snow Covered Area Fraction`). The vegetation emissivity is +where :math:`\varepsilon _{soi} =0.96` for soil, :math:`\varepsilon _{sno} =0.97` for snow, which is also the same for glacier, and :math:`f_{sno}` is the fraction of ground covered by snow (section :numref:`Snow Covered Area Fraction`). The vegetation emissivity is .. math:: :label: 4.20 diff --git a/doc/source/tech_note/References/CLM50_Tech_Note_References.rst b/doc/source/tech_note/References/CLM50_Tech_Note_References.rst index 3aa6be1b71..373618b522 100644 --- a/doc/source/tech_note/References/CLM50_Tech_Note_References.rst +++ b/doc/source/tech_note/References/CLM50_Tech_Note_References.rst @@ -11,6 +11,10 @@ Aber, J.D., Melillo, J.M. and McClaugherty, C.A., 1990. Predicting long-term pat Aber, J.D., Goodale, C.L., Ollinger, S.V., Smith, M.-L., Magill, A.H., Martin, M.E., Hallett, R.A., and Stoddard, J.L. 2003. Is nitrogen deposition altering the nitrogen status of northeastern forests? BioScience 53:375-389. +.. _AinsworthRogers2007: + +Ainsworth, E. A. and Rogers, A. 2007. The response of photosynthesis and stomatal conductance to rising (CO2): mechanisms and environmental interactions, Plant Cell Environ. 30:258-270. + .. _AlduchovandEskridge1996: Alduchov, O.A., and Eskridge, R.E. 1996. Improved Magnus form approximation of saturation vapor pressure. J. Appl. Meteor. 35:601-609. @@ -63,13 +67,13 @@ Asner, G.P., Wessman, C.A., Schimel, D.S., and Archer, S. 1998. Variability in l Axelsson, E., and Axelsson, B. 1986. Changes in carbon allocation patterns in spruce and pine trees following irrigation and fertilization. Tree Phys. 2:189-204. -.. _Atkin2016: +.. _Atkinetal2015: -Atkin OK, Bloomfield KJ, Reich PB, Tjoelker MG, Asner GP, Bonal D et al (2015) Global variability in leaf respiration in relation to climate, plant functional types and leaf traits. New Phytologist 206:614–636 +Atkin O.K., Bloomfield K.J., Reich P.B., Tjoelker M.G., Asner G.P., Bonal D. et al. 2015. Global variability in leaf respiration in relation to climate, plant functional types and leaf traits. New Phytologist 206:614–636 -.. _Atkin2017: +.. _Atkinetal2017: -Leaf Respiration in Terrestrial Biosphere Models. In Plant Respiration: Metabolic Fluxes and Carbon Balance, Advances in Photosynthesis and Respiration 43, G. Tcherkez, J. Ghashghaie (eds.) Springer International Publishing AG 2017 +Atkin O.K., Abdul Bahar N., Bloomfield K., Griffin K.L., Heskel M.A., Huntingford C., Martinez-de la Torre A., Turnbull, M.H. 2017. Leaf Respiration in Terrestrial Biosphere Models. In Plant Respiration: Metabolic Fluxes and Carbon Balance, Advances in Photosynthesis and Respiration 43, G. Tcherkez, J. Ghashghaie (eds.) Springer International Publishing AG 2017 .. _BadgerandDirmeyer2015: @@ -83,6 +87,10 @@ Baird, A.J., Beckwith, C.W., Waldron, S. and Waddington, J.M., 2004. Ebullition Baldocchi, D., et al. 2001. FLUXNET: A new tool to study the temporal and spatial variability of ecosystem-scale carbon dioxide, water vapor, and energy flux densities. Bull. Amer. Meteor. Soc. 82:2415-2433. +.. _Balletal1987: + +Ball, J.T., Woodrow, I.E., and Berry, J.A. 1987. A model predicting stomatal conductance and its contribution to the control of photosynthesis under different environmental conditions. Dordrecht, The Netherlands, 221-224. + .. _Barbottinetal2005: Barbottin, A., Lecomte, C., Bouchard, C., and Jeuffroy, M.-H. 2005. Nitrogen remobilization during grain filling in wheat: Genotypic and environmental effects. Crop Sci. 45:1141-1150. @@ -91,6 +99,11 @@ Barbottin, A., Lecomte, C., Bouchard, C., and Jeuffroy, M.-H. 2005. Nitrogen rem Batjes, N.H., 2006. ISRIC-WISE derived soil properties on a 5 by 5 arc-minutes global grid. Report 2006/02 (available through : http://www.isric.org) +.. _Bauerleetal2012: + +Bauerle, W.L., Oren, R., Way, D.A., Qian, S.S., Stoy, P.C., Thornton, P.E., Bowden, J.D., Hoffman, F.M., and Reynolds, R.F. 2012. Photoperiodic regulation of the seasonal pattern of photosynthetic capacity and the implications for carbon cycling. Proc. Natl. Acad. Sci. USA, 109:8612-8617. + + .. _Berger1978a: Berger, A.L. 1978a. Long-term variations of daily insolation and quaternary climatic changes. J. Atmos. Sci. 35:2362-2367. @@ -111,6 +124,10 @@ Berkowitz, B., and Balberg, I. 1992. Percolation approach to the problem of hydr Beven, K.J., and Kirkby, M.J. 1979. A physically based variable contributing area model of basin hydrology. Hydrol. Sci. Bull. 24:43-69. +.. _Birchetal2021: + +Birch, L., Schwalm, C.R., Natali, S., Lombardozzi, D., Keppel-Aleks, G., Watts, J., Lin, X., Zona, D., Oechel, W., Sachs, T., Black, T.A., and Rogers, B.M. 2021. Addressing biases in Arctic–boreal carbon cycling in the Community Land Model Version 5, Geosci. Model Dev., 14, 3361–3382. + .. _BohrenHuffman1983: Bohren, C. F., and Huffman, D. R. 1983. Absorption and scattering of light by small particles. John Wiley & Sons, New York, NY. @@ -155,6 +172,10 @@ Bonan, G.B., Williams, M., Fisher, R.A., and Oleson, K.W. 2014. Modeling stomata Botta, A et al., 2000. A global prognostic scheme of leaf onset using satellite data. Global Change Biology 6.7, pp. 709-725. +.. _BrieglebLight2007: + +Briegleb, B. P. and Light, B.: A Delta-Eddington multiple scattering parameterization for solar radiation in the sea ice component of the Community Climate System Model, NCAR/TN- 472+STR, National Center for Atmospheric Research, 108 pp., 2007 + .. _Brownetal1997: Brown J., Ferrians O. J. Jr, Heginbottom J. A. and Melnikov E. S. 1997. Circum-Arctic Map of Permafrost and Ground-Ice Conditions (Boulder, CO: National Snow and Ice Data Center) version 2, DOI: 10.3133/cp45 @@ -187,9 +208,13 @@ Buzan, J.R., Oleson, K., and Huber, M. 2015: Implementation and comparison of a Byram, G.M., 1959. Combustion of forest fuels. In Forest fire: control and use.(Ed. KP Davis) pp. 61-89. +.. _Bytnerowiczetal2022: + +Bytnerowicz, T. A., Akana, P. R., Griffin, K. L., & Menge, D. N. L. 2022: Temperature sensitivity of woody nitrogen fixation across species and growing temperatures. Nature Plants, 8(3), 209-216. doi: 10.1038/s41477-021-01090-x. + .. _CampbellNorman1998: -Campbell, G.S., and Norman, J.M. 1998. An Introduction to Environmental Biophysics (2:math:`{}^{nd}` edition). Springer-Verlag, New York. +Campbell, G.S., and Norman, J.M. 1998. An Introduction to Environmental Biophysics (2nd edition). Springer-Verlag, New York. .. _Castilloetal2012: @@ -199,6 +224,10 @@ Castillo, G., Kendra, C., Levis, S., and Thornton, P. 2012. Evaluation of the ne Cao, M., Marshall, S. and Gregson, K., 1996. Global carbon exchange and methane emissions from natural wetlands: Application of a process-based model. J. Geophys. Res. 101(D9):14,399-14,414. +.. _Chenetal2023: + +Chen, Y., Hall, J., van Wees, D., Andela, N., Hantson, S., Giglio, L., van der Werf, G.R., Morton, D.C., Randerson, J.T. 2023. Multi-decadal trends and variability in burned area from the fifth version of the Global Fire Emissions Database (GFED5). Earth Syst. Sci. Data 15:5227-5259. + .. _Chengetal2019: Cheng, Y. et al., 2019. Parameterizing perennial bioenergy crops in Version 5 of the Community Land Model Based on Site‐Level Observations in the Central Midwestern United States. Journal of Advances in Modeling Earth Systems, 2(2013), 1–24. https://doi.org/10.1029/2019MS001719 @@ -239,6 +268,14 @@ Collatz, G.J., Ribas-Carbo, M., and Berry, J.A. 1992. Coupled photosynthesis-sto Colmer, T.D., 2003. Long-distance transport of gases in plants: a perspective on internal aeration and radial oxygen loss from roots. Plant Cell and Environment 26:17-36. +.. _ComstockEhleringer1986: + +Comstock, J. and Ehleringer, J.R. 1986. Photoperiod and photosynthetic capacity in *Lotus scoparius*. Plant Cell Environ. 9:609-612. + +.. _Comolaetal2019: + +Comola, F., Kok, J.F., Chamecki, M. and Martin, R.L., 2019. The intermittency of wind‐driven sand transport. Geophysical Research Letters, 46(22), pp.13430-13440. DOI:10.1029/2019GL085739. + .. _Conwayetal1996: Conway, H., Gades, A., and Raymond, C.F. 1996. Albedo of dirty snow during conditions of melt. Water Resour. Res. 32:1713-1718. @@ -261,7 +298,7 @@ Dai, Y., and Zeng, Q. 1997. A land surface model (IAP94) for climate studies. Pa .. _Daietal2001: -Dai, Y., et al. 2001. Common Land Model: Technical documentation and user's guide [Available online at http://climate.eas.gatech.edu/dai/clmdoc.pdf]. +Dai, Y., et al. 2001. Common Land Model: Technical documentation and user's guide [Available online at https://journals.ametsoc.org/view/journals/bams/84/8/bams-84-8-1013.xml]. .. _Daietal2003: @@ -275,6 +312,18 @@ Dai, Y., Dickinson, R.E., and Wang, Y.-P. 2004. A two-big-leaf model for canopy Dai, A., and Trenberth, K.E. 2002. Estimates of freshwater discharge from continents: Latitudinal and seasonal variations. J. Hydrometeor. 3:660-687. +.. _Damseauxetal2025: + +Damseaux, A., Matthes, H., Dutch, V.R., Wake, L., and Rutter, N. 2025. Impact of snow thermal conductivity schemes on pan-Arctic permafrost dynamics in the Community Land Model version 5.0, The Cryosphere, 19, 1539–1558, DOI:10.5194/tc-19-1539-2025. + +.. _Dangetal2019: + +Dang, C., Zender, C. S., & Flanner, M. G. (2019). Intercomparison and improvement of two‐stream shortwave radiative transfer schemes in Earth system models for a unified treatment of cryospheric surfaces. The Cryosphere, 13(9), 2325–2343. + +.. _Darmenovaetal2009: + +Darmenova, K., Sokolik, I.N., Shao, Y., Marticorena, B. and Bergametti, G., 2009. Development of a physically based dust emission module within the Weather Research and Forecasting (WRF) model: Assessment of dust emission parameterizations and input parameters for source regions in Central and East Asia. Journal of Geophysical Research: Atmospheres, 114(D14). DOI:10.1029/2008JD011236. + .. _DeFriesetal2000: DeFries, R.S., Hansen, M.C., Townshend, J.R.G., Janetos, A.C., and Loveland, T.R. 2000. A new global 1-km dataset of percentage tree cover derived from remote sensing. Global Change Biol. 6:247-254. @@ -331,6 +380,14 @@ Drewniak, B., Song, J., Prell, J., Kotamarthi, V.R., and Jacob, R. 2013. Modelin Dunfield, P., Knowles, R., Dumont, R. and Moore, T.R., 1993. Methane Production and Consumption in Temperate and Sub-Arctic Peat Soils - Response to Temperature and Ph. Soil Biology & Biochemistry 25:321-326. +.. _Dutchetal2022: + +Dutch, V.R., Rutter, N., Wake, L., Sandells, M., Derksen, C., Walker, B., Hould Gosselin, G., Sonnentag, O., Essery, R., Kelly, R., Marsh, P., King, J., Boike, J. 2022. Impact of measured and simulated tundra snowpack properties on heat transfer, The Cryosphere, 16, 4201–4222, doi:10.5194/tc-16-4201-2022. + +.. _Eiteletal2019: + +Eitel, J.U., Maguire, A.J., Boelman, N., Vierling, L.A., Griffin, K.L., Jensen, J., Magney, T.S., Mahoney, P.J., Meddens, A.J., Silva, C., and Sonnentag, O. 2019. Proximal remote sensing of tree physiology at northern treeline: Do late-season changes in the photochemical reflectance index (PRI) respond to climate or photoperiod? Remote Sens. Environ. 221:340–350. + .. _EntekhabiEagleson1989: Entekhabi, D., and Eagleson, P.S. 1989. Land surface hydrology parameterization for atmospheric general circulation models including subgrid scale spatial variability. J. Climate 2:816-831. @@ -339,6 +396,10 @@ Entekhabi, D., and Eagleson, P.S. 1989. Land surface hydrology parameterization Fang, X. and Stefan, H.G., 1996. Long-term lake water temperature and ice cover simulations/measurements. Cold Regions Science and Technology 24:289-304. +.. _Fangetal2026: + +Fang, B., Zhao, L., Oleson, K., Zhang, K., Lawrence, P., Sacks, B., Cao, C., He, C., Huang, Q., Liu, Z., and Lee, X. 2026. Representing dynamic urban land change in the Community Earth System Model (CESM). JAMES, in revision. + .. _Farouki1981: Farouki, O.T. 1981. The thermal properties of soils in cold regions. Cold Regions Sci. and Tech. 5:67-75. @@ -351,9 +412,13 @@ Farquhar, G.D., von Caemmerer, S., and Berry, J.A. 1980. A biochemical model of Farquhar, G.D., and von Caemmerer, S. 1982. Modeling of photosynthetic response to environmental conditions. pp. 549-587. In: O.L. Lange, P.S. Nobel, C.B. Osmond, and H. Zeigler (editors) Encyclopedia of Plant Physiology. Vol. 12B. Physiological Plant Ecology. II. Water Relations and Carbon Assimilation. Springer-Verlag, New York. +.. _Fecanetal1999: + +Fécan, F., Marticorena, B. and Bergametti, G., 1998, December. Parametrization of the increase of the aeolian erosion threshold wind friction velocity due to soil moisture for arid and semi-arid areas. In Annales Geophysicae (Vol. 17, No. 1, pp. 149-157). Berlin/Heidelberg: Springer-Verlag. DOI:10.1007/s00585-999-0149-7. + .. _FeddemaKauffman2016: -Feddema, J., Kauffman, B. 2016. Urban Properties Tool (Version 1.2). NCAR THESIS Tools Library. Retrieved from: https://svn-iam-thesis-release.cgd.ucar.edu/urban_properties/. doi:10.5065/D6R78CMT. +Feddema, J., Kauffman, B. 2016. Urban Properties Tool (Version 1.2). NCAR THESIS Tools Library. Retrieved from: https://zenodo.org/records/15501878. doi:10.5065/zrph-dq73 .. _Ferrari1999: @@ -375,6 +440,10 @@ Fisher, R. A., S. Muszala, M. Verteinstein, P. Lawrence, C. Xu, N. G. McDowell, Fisher, R.A., C.D. Koven, W.R.L. Anderegg, et al., 2018: Vegetation demographics in Earth System Models: A review of progress and priorities. Glob Change Biol. 2018;24:35–54. https://doi.org/10.1111/gcb.13910 +.. _Fisheretal2019: + +Fisher, R.A., Wieder, W.R., Sanderson, B., Koven, C.D., Oleson, K.W., Xu, C., Fisher, J.B., Shi, M., Walker, A.P., Lawrence, D.M. 2019. Parametric controls on vegetation responses to biogeochemical forcing in the CLM5. Journal of Advances in Modeling Earth Systems, 11, 2879–2895. DOI:10.1029/2019MS001609 + .. _FlannerZender2005: Flanner, M.G., and Zender. C.S. 2005. Snowpack radiative heating: Influence on Tibetan Plateau climate. Geophys. Res. Lett. 32:L06501. DOI:10.1029/2004GL022076. @@ -387,6 +456,10 @@ Flanner, M.G., and Zender, C.S. 2006. Linking snowpack microphysics and albedo e Flanner, M.G., Zender, C.S., Randerson, J.T., and Rasch, P.J. 2007. Present day climate forcing and response from black carbon in snow. J. Geophys. Res. 112:D11202. DOI:10.1029/2006JD008003. +.. _Flanneretal2021: + +Flanner, M. G., Arnheim, J. B., Cook, J. M., Dang, C., He, C., Huang, X., Singh, D., Skiles, S. M., Whicker, C. A., and Zender, C. S.: SNICAR-ADv3: a community tool for modeling spectral snow albedo, Geosci. Model Dev., 14, 7673–7704, 2021 + .. _Flatauetal1992: Flatau, P.J., Walko, R.L., and Cotton, W.R. 1992. Polynomial fits to saturation vapor pressure. J. Appl. Meteor. 31:1507-1513. @@ -419,6 +492,10 @@ Gallais, A., Coque, M., Gouis, J. L., Prioul, J. L., Hirel, B., and Quillere, I. Galloway, J.N., et al. 2004. Nitrogen cycles: past, present, and future. Biogeochem. 70:153-226. +.. _GaoOneill2020: + +Gao, J., and O'Neill, B.C. 2020. Mapping global urban land for the 21st century with data-driven simulations and Shared Socioeconomic Pathways. Nature Communications, 11(1), 2302. https://doi.org/10.1038/s41467-020-15788-7. + .. _Garciaetal1988: Garcia, R.L., Kanemasu, E.T., Blad, B.L., Bauer, A., Hatfield, J.L., Major, D.A., Reginato, R.J., and Hubbard, K.G. 1988. Interception and use efficiency of light in winter wheat under different nitrogen regimes. Agric. For. Meteor. 44:175-186. @@ -443,10 +520,6 @@ Ghimire, B., W. J. Riley, C. D. Koven, M. Mu, and J. T. Randerson, 2016: Represe Gholz, H.L., Perry, C.S., Cropper, W.P., Jr. and Hendry, L.C., 1985. Litterfall, decomposition, and nitrogen and phosphorous dynamics in a chronosequence of slash pine (*Pinus elliottii*) plantations. Forest Science, 31: 463-478. -.. _Giglioetal2006: - -Giglio, L., Csiszar, I., and Justice, C.O. 2006. Global distribution and seasonality of active fires as observed with the Terra and Aqua Moderate Resolution Imaging Spectroradiometer (MODIS) sensors. J. Geophys. Res. 111:G02016. DOI:10.1029/2005JG000142. - .. _GlobalSoilDataTask2000: Global Soil Data Task 2000. Global soil data products CD-ROM (IGBP-DIS). International Geosphere-Biosphere Programme-Data and Information Available Services [Available online at http://www.daac.ornl.gov]. @@ -507,6 +580,22 @@ Hansen, M., DeFries, R.S., Townshend, J.R.G., Carroll, M., Dimiceli, C., and Soh Hastings, D.A., Dunbar, P.K., Elphingstone, G.M., Bootz, M., Murakami, H., Maruyama, H., Masaharu, H., Holland, P., Payne, J., Bryant, N.A., Logan, T.L., Muller, J.-P., Schreier, G., and MacDonald, J.S., eds., 1999. The Global Land One-kilometer Base Elevation (GLOBE) Digital Elevation Model, Version 1.0. National Oceanic and Atmospheric Administration, National Geophysical Data Center, 325 Broadway, Boulder, Colorado 80305-3328, U.S.A. +.. _Hauseretal2023: + +Hauser, E., Wieder, W.R., Bonan, G.B., and Cleveland, C.C. 2023. Flexible foliar stoichiometry reduces the magnitude of the global land carbon sink. Geophys. Res. Lett. 50(21), e2023GL105493. DOI:10.1029/2023GL105493 + +.. _Heetal2017: + +He, C., Takano, Y., Liou, K. N., Yang, P., Li, Q., & Chen, F. (2017). Impact of snow grain shape and black carbon–snow internal mixing on snow optical properties: Parameterizations for climate models. Journal of Climate, 30(24), 10019–10036. + +.. _Heetal2019: + +He, C., Liou, K. N., Takano, Y., Chen, F., & Barlage, M. (2019). Enhanced snow absorption and albedo reduction by dust‐snow internal mixing: Modeling and parameterization. Journal of Advances in Modeling Earth Systems, 11(11), 3755–3776. + +.. _Heetal2024: + +He, C., Flanner, M., Lawrence, D. M., & Gu, Y. (2024). New features and enhancements in community land model (CLM5) snow albedo modeling: Description, sensitivity, and evaluation. Journal of Advances in Modeling Earth Systems, 16, e2023MS003861. + .. _Healdetal2008: Heald, C.L., Henze, D.K., Horowitz, L.W., Feddema, J., Lamarque, J.-F., Guenther, A., Hess, P.G., Vitt, F., Seinfeld, J.H., Goldstein, A.H., and Fung, I. 2008. Predicted change in global secondary organic aerosol concentrations in response to future climate, emissions, and land use change. J. Geophys. Res. 113:D05211. DOI:10.1029/2007JD009092. @@ -547,13 +636,17 @@ Hou, Z., Huang, M., Leung, L.R., Lin, G., and Ricciuto, D.M. 2012. Sensitivity o Houlton, B.Z., Wang, Y.P., Vitousek, P.M. and Field, C.B., 2008. A unifying framework for dinitrogen fixation in the terrestrial biosphere. Nature, 454(7202), p.327. +.. _Houltonetal2015: + +Houlton, B., Marklein, A. & Bai, E. Representation of nitrogen in climate change forecasts. Nature Clim Change 5, 398–401 (2015). https://doi.org/10.1038/nclimate2538 + .. _HuangLiang2006: Huang, M., and Liang, X. 2006. On the assessment of the impact of reducing parameters and identification of parameter uncertainties for a hydrologic model with applications to ungauged basins. J. Hydrol. 320:37-61. .. _Hugeliusetal2012: -Hugelius, G., C. Tarnocai, G. Broll, J.G. Canadell, P. Kuhry, adn D.K. Swanson, 2012. The Northern Circumpolar Soil Carbon Database: spatially distributed datasets of soil coverage and soil carbon storage in the northern permafrost regions. Earth Syst. Sci. Data Discuss., 5, 707-733 (available online at (http://dev1.geo.su.se/bbcc/dev/ncscd/). +Hugelius, G., C. Tarnocai, G. Broll, J.G. Canadell, P. Kuhry, adn D.K. Swanson, 2012. The Northern Circumpolar Soil Carbon Database: spatially distributed datasets of soil coverage and soil carbon storage in the northern permafrost regions. Earth Syst. Sci. Data Discuss., 5, 707-733 (available online at (https://essd.copernicus.org/articles/5/3/2013/essd-5-3-2013.html). .. _Huntetal1988: @@ -599,6 +692,10 @@ Jenkinson, D. and Coleman, K. 2008. The turnover of organic carbon in subsoils. Jordan, R. 1991. A One-dimensional Temperature Model for a Snow Cover: Technical Documentation for SNTHERM.89. U.S. Army Cold Regions Research and Engineering Laboratory, Special Report 91-16. +.. _Kou-Giesbrechtetal2025: + +Kou-Giesbrecht, C.R. Reis Ely, S.S. Perakis, C.C. Cleveland, D.N.L. Menge, S.C. Reed, B.N. Taylor, S.A. Batterman, T.E. Crews, K.A. Dynarski, M. Gei, M.J. Gundale, D.F. Herridge, S.E. Jovan, M.B. Peoples, J. Piipponen, E. Rodríguez-Caballero, V.G. Salmon, F.M. Soper, A.P. Staccone, B. Weber, C.A. Williams, & N. Wurzburger, 2025. Overestimated natural biological nitrogen fixation translates to an exaggerated CO2 fertilization effect in Earth system models, Proc. Natl. Acad. Sci. U.S.A. 122 (48) e2514628122, DOI:10.1073/pnas.2514628122. + .. _KattgeKnorr2007: Kattge, J., and Knorr, W. 2007. Temperature acclimation in a biochemical model of photosynthesis: a reanalysis of data from 36 species. Plant Cell Environ. 30:1176-1190. DOI:10.1111/j.1365-3040.2007.01690.x. @@ -627,6 +724,18 @@ Kimball, J.S., Thornton, P.E., White, M.A. and Running, S.W. 1997. Simulating fo Kohyama, T., Suzuki, E., Partomihardjo, T., and Yamada, T. 2001. Dynamic steady state of patch-mosaic tree size structure of a mixed diptocarp forest regulated by local crowding. Ecological Research 16:85-98. +.. _Koketal2012: + +Kok, J.F., Parteli, E.J., Michaels, T.I. and Karam, D.B., 2012. The physics of wind-blown sand and dust. Reports on progress in Physics, 75(10), p.106901. DOI:10.1088/0034-4885/75/10/106901. + +.. _Koketal2014a: + +Kok, J.F., Mahowald, N.M., Fratini, G., Gillies, J.A., Ishizuka, M., Leys, J.F., Mikami, M., Park, M.S., Park, S.U., Van Pelt, R.S. and Zobeck, T.M., 2014a. An improved dust emission model–Part 1: Model description and comparison against measurements. Atmospheric Chemistry and Physics, 14(23), pp.13023-13041. + +.. _Koketal2014b: + +Kok, J.F., Albani, S., Mahowald, N.M. and Ward, D.S., 2014b. An improved dust emission model–Part 2: Evaluation in the Community Earth System Model, with implications for the use of dust source functions. Atmospheric Chemistry and Physics, 14(23), pp.13043-13061. DOI: 10.5194/acp-14-13043-2014. + .. _Kourzeneva2009: Kourzeneva, E., 2009. Global dataset for the parameterization of lakes in Numerical Weather Prediction and Climate modeling. ALADIN Newsletter, No 37, July-December, 2009, F. Bouttier and C. Fischer, Eds., Meteo-France, Toulouse, France, 46-53. @@ -739,10 +848,6 @@ Lee, H., Swenson, S.C., Slater A.G. and Lawrence D.M., 2014. Effects of excess g Lehner, B., Verdin, K. and Jarvis, A., 2008. New global hydrograhy derived from spaceborne elevation data. Eos Trans., AGU, 89, 93 – 94. -.. _LePageetal2010: - -Le Page, Y., van der Werf, G.R., Morton, D.C., and Pereira, J.M.C. 2010. Modeling fire-driven deforestation potential in Amazonia under current and projected climate conditions. J. Geophys. Res. 115:G03012. DOI:10.1029/2009JG001190. - .. _Lerman1979: Lerman, A., 1979. Geochemical processes: Water and sediment environments. John Wiley and Sons, New York, N.Y. @@ -751,6 +856,14 @@ Lerman, A., 1979. Geochemical processes: Water and sediment environments. John W Letts, M.G., Roulet, N.T., Comer, N.T., Skarupa, M.R., and Verseghy, D.L. 2000. Parametrization of peatland hydraulic properties for the Canadian Land Surface Scheme. Atmos.-Ocean 38:141-160. +.. _Leungetal2023: + +Leung, D.M., Kok, J.F., Li, L., Okin, G.S., Prigent, C., Klose, M., Pérez García-Pando, C., Menut, L., Mahowald, N.M., Lawrence, D.M. and Chamecki, M., 2023. A new process-based and scale-aware desert dust emission scheme for global climate models–Part I: Description and evaluation against inverse modeling emissions. Atmos. Chem. Phys., 23(11), pp.6487-6523. DOI:10.5194/acp-23-6487-2023. + +.. _Leungetal2024: + +Leung, D.M., Kok, J.F., Li, L., Mahowald, N.M., Lawrence, D.M., Tilmes, S., Kluzek, E., Klose, M. and Pérez García-Pando, C., 2024. A new process-based and scale-aware desert dust emission scheme for global climate models–Part II: Evaluation in the Community Earth System Model version 2 (CESM2). Atmos. Chem. Phys., 24(4), pp.2287-2318. DOI:10.5194/acp-24-2287-2024. + .. _Levisetal2003: Levis, S., Wiedinmyer, C., Bonan, G.B., and Guenther, A. 2003. Simulating biogenic volatile organic compound emissions in the Community Climate System Model. J. Geophys. Res. 108:4659. DOI:10.1029/2002JD003203. @@ -771,6 +884,10 @@ Levis, S., Bonan, G., Kluzek, E., Thornton, P., Jones, A., Sacks, W., and Kuchar Levis, S., Badger, A., Drewniak, B., Nevison, C., Ren, X. 2016. CLMcrop yields and water requirements: avoided impacts by choosing RCP 4.5 over 8.5. Climatic Change. DOI:10.1007/s10584-016-1654-9. +.. _Liaoetal2023: + +Liao, C., Lu X., Huang Y., Tao F., Lawrence D.M, Koven C.D., Oleson K.W., Wieder W.R., Kluzek E., Huang X., Luo Y. 2023 . Matrix Approach to Accelerate Spin-Up of CLM5. Journal of Advances in Modeling Earth Systems, 15(8), e2023MS003625. doi:10.1029/2023MS003625. + .. _Lietal2000: Li, C., Aber, J., Stange, F., Butterbach-Bahl, K. and Papen, H. 2000. A process-oriented model of N2O and NO emissions from forest soils: 1. Model development. J. Geophys. Res. 105(D4):4369-4384. @@ -787,6 +904,14 @@ Li, F., Zeng, X. D., and Levis, S. 2012b. Corrigendum to "A process-based fire p Li, F., Levis, S., and Ward, D. S. 2013a. Quantifying the role of fire in the Earth system – Part 1: Improved global fire modeling in the Community Earth System Model (CESM1). Biogeosciences 10:2293-2314. +.. _Lietal2019: + +Li, F., Val Martin, M., Andreae, M.O., Arneth, A., Hantson, S., Kaiser, J.W., Lasslop, G., Yue, C., Bachelet, D., Forrest, M., Kluzek, E., Liu, X., Mangeon, S., Melton, J.R., Ward, D.S., Darmenov, A., Hickler, T., Ichoku, C., Magi, B.I., Sitch, S., van der Werf, G.R., Wiedinmyer, C., Rabin, S.S. 2019. Historical (1700-2012) global multi-model estimates of the fire emissions from the Fire Modeling Intercomparison Project (FireMIP). Atmos. Chem. Phys. 19:12545-12567. + +.. _Lietal2024b: + +Li, F. et al. 2024. Quantifying the role of fire in the Earth system: Improved global fire modeling in Earth system models. AGU Fall Meeting 2024, Washington, D.C., USA, 9-13 December 2024, GC41E-01. https://agu.confex.com/agu/agu24/meetingapp.cgi/Paper/1529786. + .. _LiLawrence2017: Li, F., and Lawrence, D. 2017. Role of fire in the global land water budget during the 20th century through changing ecosystems. J. Clim. 30: 1894-1908. @@ -807,6 +932,10 @@ Li, H., L. Leung, A. Getirana, M. Huang, H. Wu, Y. Xu, J. Guo and N. Voisin. 201 Li, H., L. Leung, T. Tesfa, N. Voisin, M. Hejazi, L. Liu, Y. Liu, J. Rice, H. Wu, and X. Yang. 2015. Modeling stream temperature in the Anthropocene: An earth system modeling approach, J. Adv. Model. Earth Syst., 7, doi:10.1002/2015MS000471. +.. _Lietal2024a: + +Li, X. "C", Zhao, L., Oleson, K., Zhou, Y., Qin, Y., Zhang, K., and Fang, B. 2024. Enhancing urban climate‐energy modeling in the Community Earth System Model (CESM) through explicit representation of urban air‐conditioning adoption. JAMES, 16, e2023MS004107. https://doi.org/10.1029/2023MS004107. + .. _Liangetal1994: Liang, X., Lettenmaier, D.P., Wood, E.F., and Burges, S.J. 1994. A simple hydrologically based model of land surface water and energy fluxes for GSMs. J. Geophys. Res. 99(D7):14,415–14,428. @@ -815,10 +944,6 @@ Liang, X., Lettenmaier, D.P., Wood, E.F., and Burges, S.J. 1994. A simple hydrol Lichstein, J.W. and S.W. Pacala, 2011. Local diversity in heterogeneous landscapes: quantitative assessment with a height-structured forest metacommunity model`. Theoretical Ecology 4.2, pp. 269-281. -.. _LipscombSacks2012: - -Lipscomb, W., and Sacks, W. 2012. The CESM land ice model documentation and user's guide. 46 pp. [Available online at http://www.cesm.ucar.edu/models/cesm1.1/cism/]. - .. _lischke2006: Lischke, H. et al., 2006. TreeMig: a forest-landscape model for simulating spatio-temporal patterns from stand to landscape scale. Ecological Modelling 199.4, pp. 409-420. 41 @@ -855,6 +980,10 @@ Luo, Y., Hui, D., and Zhang, D. 2006. Elevated CO2 stimulates net accumulations Luo J, Hess P G, Hall S, et al. Agricultural emissions of reactive nitrogen gases from constrained simulations using the Community Land Model. Authorea Preprints, 2025. +.. _Luetal2020: + +Lu, X., Du, Z., Huang, Y., Lawrence, D., Kluzek, E., Collier, N., Lombardozzi, D., Sobhani, N., Schuur, E.A. and Luo, Y., 2020. Full implementation of matrix approach to biogeochemistry module of CLM5. Journal of Advances in Modeling Earth Systems, 12(11), p.e2020MS002105. + .. _Magilletal1997: Magill, A.H. et al., 1997. Biogeochemical response of forest ecosystems to simulated chronic nitrogen deposition. Ecological Applications, 7: 402-415. @@ -863,6 +992,14 @@ Magill, A.H. et al., 1997. Biogeochemical response of forest ecosystems to simul Mahowald, N.M., Muhs, D.R., Levis, S., Rasch, P.J., Yoshioka, M., Zender, C.S., and Luo, C. 2006. Change in atmospheric mineral aerosols in response to climate: last glacial period, pre-industrial, modern and doubled CO\ :sub:`2` climates. J. Geophys. Res\ *.* 111:D10202. DOI:10.1029/2005JD006653. +.. _Maireetal2012: + +Maire, V., Martre, P., Kattge, J., Gastal, F., Esser, G., Fontaine, S., and Soussana, F. 2012. The coordination of leaf photosynthesis links C and N fluxes in C3 plant species, PLos ONE, 7:e38245. doi:38310.31371/journal.pone.0038345. + +.. _MajasalmiBright2019: + +Majasalmi, T., and Bright, R.M. 2019. Evaluation of leaf-level optical properties employed in land surface models. Geosci. Model Dev. 12:3923-3938. https://doi.org/10.5194/gmd-12-3923-2019. + .. _Makela2002: Makela, A. 2002. Derivation of stem taper from the pipe model theory in a carbon balance framework. Tree Phys. 22:891-905. @@ -875,6 +1012,10 @@ Mao, J., Thornton, P.E., Shi, X., Zhao, M., and Post, W.M. 2012. Remote sensing Mao, J., Shi, X., Thornton, P.E., Hoffman, F.M., Zhu, Z., and Ranga B. Myneni, R.B. 2013. Global latitudinal-asymmetric vegetation growth trends and their driving mechanisms: 1982-2009. Remote Sensing 5:1484-1497. +.. _MarticorenaBergametti1995: + +Marticorena, B. and Bergametti, G., 1995. Modeling the atmospheric dust cycle: 1. Design of a soil‐derived dust emission scheme. Journal of geophysical research: atmospheres, 100(D8), pp.16415-16430. DOI: 10.1029/95JD00690. + .. _Martinetal1980: Martin, J.P., Haider, K. and Kassim, G., 1980. Biodegradation and stabilization after 2 years of specific crop, lignin, and polysaccharide carbons in soils. Soil Science Society of America Journal 44:1250-1255. @@ -908,6 +1049,10 @@ https://doi.org/10.5194/gmd-15-2365-2022 Melzer, E., and O'Leary, M.H. 1987. Anapleurotic CO2 Fixation by Phosphoenolpyruvate Carboxylase in C3 Plants. Plant. Physiol. 84:58. +.. _Mengetal2022: + +Meng, J., Huang, Y., Leung, D.M., Li, L., Adebiyi, A.A., Ryder, C.L., Mahowald, N.M. and Kok, J.F., 2022. Improved parameterization for the size distribution of emitted dust aerosols reduces model underestimation of super coarse dust. Geophysical Research Letters, 49(8), p.e2021GL097287. DOI:10.1029/2021GL097287. + .. _Milleretal1994: Miller, J.R., Russell, G.L., and Caliri, G. 1994. Continental-scale river flow in climate models. J. Climate 7:914-928. @@ -952,9 +1097,17 @@ Negron-Juarez, R. Koven, C.D., Riley, W.J., Knox, R.G., Chambers, J.Q. 2015. Env Nemani, R.R., and Running, S.W. 1996. Implementation of a hierarchical global vegetation classification in ecosystem function models. J. Veg. Sci. 7:337-346. +.. _Nevisonetal2022: + +Nevison, C., Hess, P., Goodale, C., Zhu Q., and Vira, J. 2022. Nitrification, Denitrification, and Competition for Soil N: Evaluation of Two Earth System Models against Observations. Ecological Applications 32(4): e2528. doi:10.1002/eap.2528 + .. _Niinemetstal1998: -Niinemets, U., Kull, O., and Tenhunen, J.D. 1998. An analysis of light effects on foliar morphology, physiology, and light interception in temperate deciduous woody species of contrasting shade tolerance. Tree Phys. 18:681-696. +Niinemets, Ü., Kull, O., and Tenhunen, J.D. 1998. An analysis of light effects on foliar morphology, physiology, and light interception in temperate deciduous woody species of contrasting shade tolerance. Tree Phys. 18:681-696. + +.. _NiinetmetsTenhunen1997: + +Niinemets, Ü. and Tenhunen, J.D. 1997. A model separating leaf structural and biphysiological effects on carbon gain along light gradients for the shade-tolerant species *Acer saccharum*. Plant Cell Environ., 20:845-86. .. _Niuetal2005: @@ -978,7 +1131,11 @@ Oikawa, S., Hikosaka, K. and Hirose, T., 2005. Dynamics of leaf area and nitroge .. _Oke1987: -Oke, T. 1987. Boundary Layer Climates (2:math:`{}^{nd}` edition). Routledge, London and New York. +Oke, T. 1987. Boundary Layer Climates (2nd edition). Routledge, London and New York. + +.. _Okin2008: + +Okin, G.S., 2008. A new model of wind erosion in the presence of vegetation. Journal of Geophysical Research: Earth Surface, 113(F2). DOI: 10.1029/2007JF000758. .. _OlesonBonan2000: @@ -1012,9 +1169,9 @@ Oleson, K.W., Bonan, G.B., Feddema, J., Vertenstein, M., and Kluzek, E. 2010b. T Oleson, K.W., et al. 2013. Technical description of version 4.5 of the Community Land Model (CLM). NCAR Technical Note NCAR/TN-503+STR, National Center for Atmospheric Research, Boulder, CO, 420 pp. -.. _OlesonFeddema2018: +.. _OlesonFeddema2020: -Oleson, K.W., and Feddema, J. 2018. Parameterization and surface data improvements and new capabilities for the Community Land Model Urban (CLMU). JAMES, submitted. +Oleson, K.W., and Feddema, J. 2020. Parameterization and surface data improvements and new capabilities for the Community Land Model Urban (CLMU). JAMES, 12, e2018MS0001586, https://doi.org/10.1029/2018MS001586. .. _Olson1963: @@ -1040,6 +1197,10 @@ Ozdogan, M., Rodell, M., Beaudoing, H.K., and Toll, D.L. 2010. Simulating the ef Page, S.E., Siegert, F., Rieley, J.O., Boehm, H-D.V., Jaya, A., and Limin, S. 2002. The amount of carbon released from peat and forest fires in Indonesia in 1997. Nature 420:61-65. +.. _Panofskyetal1977: + +Panofsky, H.A., Tennekes, H., Lenschow, D.H. and Wyngaard, J.C., 1977. The characteristics of turbulent velocity components in the surface layer under convective conditions. Boundary-Layer Meteorology, 11(3), pp.355-361. DOI:10.1007/BF02186086. + .. _PanofskyDutton1984: Panofsky, H.A., and Dutton, J.A. 1984. Atmospheric Turbulence: Models and Methods for Engineering Applications. John Wiley and Sons, New York. @@ -1080,6 +1241,10 @@ Peterson, D.L. and K.C. Ryan, 1986. Modeling postfire conifer mortality for long Petrescu, A.M.R. et al. 2010. Modeling regional to global CH4 emissions of boreal and arctic wetlands. Global Biogeochemical Cycles, 24(GB4009). +.. _Picardetal2016: + +Picard, G., Libois, Q., & Arnaud, L. (2016). Refinement of the ice absorption spectrum in the visible using radiance profile measurements in Antarctic snow. The Cryosphere, 10(6), 2655–2672. + .. _pfeiffer2013: Pfeiffer, M., A. Spessa, and J.O. Kaplan, 2013. A model for global biomass burning in preindustrial time: LPJ-LMfire (v1. 0). Geoscientific Model Development 6.3, pp. 643-685. @@ -1092,6 +1257,10 @@ Philip, J.R. 1957. Evaporation, and moisture and heat fields in the soil. J. Met Piao, S.L., et al. 2012. The carbon budget of terrestrial ecosystems in East Asia over the last two decades. Biogeosciences 9:3571-3586. +.. _Pierreetal2014: + +Pierre, C., Bergametti, G., Marticorena, B., Kergoat, L., Mougin, E. and Hiernaux, P., 2014. Comparing drag partition schemes over a herbaceous Sahelian rangeland. Journal of Geophysical Research: Earth Surface, 119(10), pp.2291-2313. DOI: 10.1002/2014JF003177. + .. _Pivovarov1972: Pivovarov, A.A., 1972. Thermal Conditions in Freezing Lakes and Reservoirs. John Wiley, New York. @@ -1108,10 +1277,18 @@ Pomeroy, J. W., D. M. Gray, K. R. Shook, B. Toth, R. L. H. Essery, A. Pietroniro Portmann, F.T., Siebert, S., and Döll, P. 2010. MIRCA2000 - Global monthly irrigated and rainfed crop areas around the year 2000: A new high-resolution data set for agricultural and hydrological modeling. Global Biogeochem. Cycles. 24, GB1011. DOI:10.1029/2008GB003435. +.. _Potosnaketal2014: + +Potosnak, M. J., LeStourgeon, L., Pallardy, S. G., Hosman, K. P., Gu, L., Karl, T., et al. (2014). Observed and modeled ecosystem isoprene fluxes from an oak-dominated temperate forest and the influence of drought stress. Atmospheric Environment, 84, 314–322. http://www.sciencedirect.com/science/article/pii/S1352231013009059 + .. _Pressetal1992: Press, W.H., Teukolsky, S.A., Vetterling, W.T., and Flannery, B.P. 1992. Numerical Recipes in FORTRAN: The Art of Scientific Computing. Cambridge University Press, New York. +.. _Prigentetal2005: + +Prigent, C., Tegen, I., Aires, F., Marticorena, B. and Zribi, M., 2005. Estimation of the aerodynamic roughness length in arid and semi‐arid regions over the globe with the ERS scatterometer. Journal of Geophysical Research: Atmospheres, 110(D9). DOI:10.1029/2004JD005370. + .. _Prigentetal2007: Prigent, C., Papa, F., Aires, F., Rossow, W.B. and Matthews, E. 2007. Global inundation dynamics inferred from multiple satellite observations, 1993-2000. J. Geophys. Res. 112(D12). @@ -1248,6 +1425,10 @@ Sellers, P.J., Randall, D.A., Collatz, G.J., Berry, J.A., Field, C.B., Dazlich, Sellers, Piers J et al. (1996). A revised land surface parameterization (SiB2) for atmospheric GCMs. Part II: The generation of global fields of terrestrial biophysical parameters from satellite data. Journal of climate 9.4, pp. 706-737. +.. _ShaoLu2000: + +Shao, Y. and Lu, H., 2000. A simple expression for wind erosion threshold friction velocity. Journal of Geophysical Research: Atmospheres, 105(D17), pp.22437-22443. DOI:10.1029/2000JD900304. + .. _Shietal2013: Shi, X., Mao, J., Thornton, P.E., and Huang, M. 2013. Spatiotemporal patterns of evapotranspiration in response to multiple environmental factors simulated by the Community Land Model. Environ. Res. Lett. 8:024012. @@ -1296,10 +1477,19 @@ Smith, A.M.S., Wooster, M.J., Drake, N.A., Dipotso, F.M. and Perry, G.L.W., 2005 Smith, A.M. and M. Stitt, 2007. Coordination of carbon supply and plant growth. Plant, cell & environment 30.9, pp. 1126-1149. +.. _Smith1937: + +Smith, E. 1937. The influence of light and carbon dioxide on photosynthesis. General Physiology, 20:807-830. + .. _Sollins1982: Sollins, P., 1982. Input and decay of coarse woody debris in coniferous stands in western Oregon and Washington. Canadian Journal of Forest Research, 12: 18-28. + +.. _Songetal2013: + +Song, Y.H., Ito, S., and Imaizumi, T. 2013. Flowering time regulation: photoperiod- and temperature-sensing in leaves. Trends Plant Sci. 18:575–583. + .. _SonGower1991: Son, Y. and Gower, S.T., 1991. Aboveground nitrogen and phosphorus use by five plantation-grown trees with different leaf longevities. Biogeochemistry, 14: 167-191. @@ -1344,6 +1534,10 @@ Strahler, A.H., Muchoney, D., Borak, J., Friedl, M., Gopal, S., Lambin, E., and Stull, R.B. 1988. An Introduction to Boundary Layer Meteorology. Kluwer Academic Publishers, Dordrecht. +.. _Sturmetal1997: + +Sturm, M., Holmgren, J., Konig, M., and Morris, K. 1997. The thermal conductivity of seasonal snow. Journal of Glaciology 43:26-41. + .. _Subinetal2012a: Subin, Z.M., Riley, W.J. and Mironov, D. 2012a. Improved lake model for climate simulations, J. Adv. Model. Earth Syst., 4, M02001. DOI:10.1029/2011MS000072. @@ -1356,6 +1550,10 @@ Subin, Z.M., Murphy, L.N., Li, F., Bonfils, C. and Riley, W.J., 2012b. Boreal la Sun, Y., Gu, L., and Dickinson, R. E. 2012. A numerical issue in calculating the coupled carbon and water fluxes in a climate model, J. Geophys. Res., 117, D22103. DOI:10.1029/2012JD018059. +.. _Suzukietal2001: + +Suzuki, Y., Makino, A. and Mae, T. 2001. Changes in the turnover of Rubisco and levels of mRNAs of rbcL and rbcS in rice leaves from emergence to senescence. Plant, Cell & Environment, 24:1353-1360. DOI:10.1046/j.0016-8025.2001.00789.x + .. _Swensonetal2012: Swenson, S.C., Lawrence, D.M., and Lee, H. 2012. Improved Simulation of the Terrestrial Hydrological Cycle in Permafrost Regions by the Community Land Model. JAMES, 4, M08002. DOI:10.1029/2012MS000165. @@ -1372,6 +1570,18 @@ Swenson, S.C., and D. M. Lawrence. 2014. Assessing a dry surface layer-based soi Swenson, S.C., and D. M. Lawrence. 2015. A GRACE-based assessment of interannual groundwater dynamics in the Community Land Model. WRR, 51, doi:10.1002/2015WR017582. +.. _Swensonetal2019: + +Swenson, S.C., M. Clark, Y. Fan, D.M. Lawrence, and J. Perket. 2019. Representing intra-hillslope lateral subsurface flow in the community land model. JAMES, 11, doi:10.1002/2015WR017582. + +.. _Swensonetal2019b: + +Swenson, S.C., S.P. Burns, and D. M. Lawrence. 2019. The impact of biomass heat storage on the canopy energy balance and atmospheric stability in the community land model. JAMES, 11, https://doi.org/10.1029/2018MS001476. + +.. _SwensonLawrence2025: + +Swenson, S.C., and D. M. Lawrence. 2025. Development of a global representative hillslope data set for use in Earth system modelsA GRACE-based assessment of interannual groundwater dynamics in the Community Land Model. JAMES, 17, https://doi.org/10.1029/2024MS004410. + .. _TaWeiland1992: Ta, C.T. and Weiland, R.T. 1992. Nitrogen partitioning in maize during ear development. Crop Sci. 32:443-451. @@ -1498,16 +1708,36 @@ Vionnet, V., E. Brun, S. Morin, A. Boone, S. Faroux, P. Le Moigne, E. Martin, an .. _Viovy2011: -Viovy, N. 2011. CRUNCEP dataset. [Description available at http://dods.extra.cea.fr/data/p529viov/cruncep/readme.htm. Data available at http://dods.extra.cea.fr/store/p529viov/cruncep/V4\_1901\_2011/]. +Viovy, N. 2011. CRUNCEP dataset. [Description available at https://rda.ucar.edu/datasets/d314003/ Data available at https://rda.ucar.edu/datasets/d314003/dataaccess/]. .. _VitousekHowarth1991: Vitousek, P.M., and Howarth, R.W. 1991. Nitrogen limitation on land and in the sea: How can it occur? Biogeochem. 13:87-115. +.. _Walkeretal2014: + +Walker, A. P., Beckerman, A. P., Gu, L., Kattge, J., Cernusak, L. A., Domingues, T. F., Scales, J. C., Wohlfahrt, G., Wullschleger, S. D., and Woodward, F. I. 2014. The relationship of leaf photosynthetic traits - Vcmax and Jmax - to leaf nitrogen, leaf phosphorus, and specific leaf area: a meta-analysis and modeling study. Ecology and Evolution, 4:3218-3235. + .. _Walteretal2001: Walter, B.P., Heimann, M. and Matthews, E., 2001. Modeling modern methane emissions from natural wetlands 1. Model description and results. J. Geophys. Res. 106(D24):34189-34206. +.. _WangZeng2009: + +Wang, A., and Zeng, X. 2009. Improving the treatment of vertical snow burial fraction over short vegetation in the NCAR CLM3. Adv. Atmos. Sci. 26:877-886. DOI:10.1007/s00376-009-8098-3. + +.. _Wangetal2022: + +Wang, H., Lu, X., Seco, R., Stavrakou, T., Karl, T., Jiang, X., et al. 2022. Modeling Isoprene Emission Response to Drought and Heatwaves Within MEGAN Using Evapotranspiration Data and by Coupling With the Community Land Model. Journal of Advances in Modeling Earth Systems, 14, e2022MS003174. https://doi.org/10.1029/2022MS003174. + +.. _Wangetal2024a: + +Wang, H., Welch, A., Nagalingam, S., Leong, C., Kittitananuvong, P., Barsanti, K. C., et al. 2024a. Arctic Heatwaves Could Significantly Influence the Isoprene Emissions From Shrubs. Geophysical Research Letters, 51, e2023GL107599. https://doi.org/10.1029/2023GL107599. + +.. _Wangetal2024b: + +Wang, H., Welch, A. M., Nagalingam, S., Leong, C., Czimczik, C. I., Tang, J., et al. 2024b. High temperature sensitivity of Arctic isoprene emissions explained by sedges. Nature Communications, 15(1), 6144. https://doi.org/10.1038/s41467-024-49960-0. + .. _Waniaetal2009: Wania, R., Ross, I. and Prentice, I.C. 2009. Integrating peatlands and permafrost into a dynamic global vegetation model: 2. Evaluation and sensitivity of vegetation and carbon cycle processes. Global Biogeochem. Cycles 23. @@ -1516,9 +1746,9 @@ Wania, R., Ross, I. and Prentice, I.C. 2009. Integrating peatlands and permafros Wania, R., Ross, I. and Prentice, I.C. 2010. Implementation and evaluation of a new methane model within a dynamic global vegetation model LPJ-WHyMe v1.3. Geoscientific Model Development Discussions 3:1-59. -.. _WangZeng2009: +.. _WarrenBrandt2008: -Wang, A., and Zeng, X. 2009. Improving the treatment of vertical snow burial fraction over short vegetation in the NCAR CLM3. Adv. Atmos. Sci. 26:877-886. DOI:10.1007/s00376-009-8098-3. +Warren, S. G., & Brandt, R. E. (2008). Optical constants of ice from the ultraviolet to the microwave: A revised compilation. Journal of Geophysical Research, 113(D14), D14220. .. _weng2014: @@ -1536,6 +1766,14 @@ White, M.A., Thornton, P.E., Running, S.W., and Nemani, R.R. 2000. Parameterizat Wieder, W. R., Cleveland, C. C., Lawrence, D. M., and Bonan, G. B. 2015. Effects of model structural uncertainty on carbon cycle projections: biological nitrogen fixation as a case study. Environmental Research Letters, 10(4), 044016. +.. _Wiederetal2019: + +Wieder, W.R., Lawrence, D.M., Fisher, R.A., Bonan, G.B., Cheng, S.J., Goodale, C.L., Grandy, A.S., Koven, C.D., Lombardozzi, D.L., Oleson, K.W. and Thomas, R.Q., 2019. Beyond static benchmarking: Using experimental manipulations to evaluate land model assumptions. Global Biogeochemical Cycles, 33(10), 1289-1309. DOI:10.1029/2018GB006141 + +.. _Wiederetal2021: + +Wieder, W.R., Butterfield, Z., Lindsay, K., Lombardozzi, D.L., Keppel-Aleks, G. 2021. Interannual and seasonal drivers of carbon cycle variability represented by the Community Earth System Model (CESM2). Global Biogeochemical Cycles, 35, e2021GB007034. DOI:10.1029/2021GB007034 + .. _Williamsetal1996: Williams, M., Rastetter, E.B., Fernandes, D.N., Goulden, M.L., Wofsy, S.C., Shaver, G.R., Melillo, J.M., Munger, J.W., Fan, S.M. and Nadelhoffer, K.J. 1996. Modelling the soil-plant-atmosphere continuum in a Quercus–Acer stand at Harvard Forest: the regulation of stomatal conductance by light, nitrogen and soil/plant hydraulic properties. Plant, Cell & Environment, 19: 911–927. doi:10.1111/j.1365-3040.1996.tb00456.x @@ -1560,6 +1798,10 @@ Wu, H., J. S. Kimball, N. Mantua, and J. Stanford, 2011: Automated upscaling of Wu, H., J. S. Kimball, H. Li, M. Huang, L. R. Leung, and R. F. Adler, 2012. A New Global River Network Database for Macroscale Hydrologic modeling, Water Resour. Res., 48, W09701, doi:10.1029/2012WR012313. +.. _Wullschleger1993: + +Wullschleger, S.D. 1993. Biochemical limitations to carbon assimilation in C3 plants: a retrospective analysis of A/Ci curves from 109 species. J. Exp Bot. 44:907-920. + .. _xiaodong2005: Xiaodong, Y. and H.H. Shugart, 2005. FAREAST: a forest gap model to simulate dynamics and patterns of eastern Eurasian forests. Journal of Biogeography 32.9, pp. 1641-1658. @@ -1568,10 +1810,18 @@ Xiaodong, Y. and H.H. Shugart, 2005. FAREAST: a forest gap model to simulate dyn Xu, C., R. Fisher, S. D. Wullschleger, C. J. Wilson, M. Cai, and N. G. McDowell, 2012: Toward a mechanistic modeling of nitrogen limitation on vegetation dynamics. PloS one, 7:e37914. +.. _Yangetal1995: + +Yang, Z.-L., R.E. Dickinson, A. Henderson-Sellers, and A.J. Pitman, 1995. Preliminary study of spin-up processes in land surface models with the first stage data of Project for Intercomparison of Land Surface Parameterization Schemes Phase 1(a). J. Geophys. Res. 100:16,553-16,578. + .. _Yang1998: Yang, Z.-L. 1998. Technical note of a 10-layer soil moisture and temperature model. Unpublished manuscript. +.. _ZaehleandFriend2010: + +Zaehle, S. and A.D.Friend 2010. Carbon and nitrogen cycle dynamics in the O-CN land surface model: 1. Model description, site-scale evaluation, and sensitivity to parameter estimates, Global Biogeochem. Cycles, 24, GB1005, DOI:10.1029/2009GB003521. + .. _Zenderetal2003: Zender, C.S., Bian, H., and Newman, D. 2003. Mineral dust entrainment and deposition (DEAD) model: Description and 1990s dust climatology. ** J. Geophys. Res\ *.* 108(D14):4416. DOI:10.1029/2002JD002775. @@ -1600,6 +1850,8 @@ Zeng, X., Dickinson, R.E., Barlage, M., Dai, Y., Wang, G., and Oleson, K. 2005. Zeng, X., and Wang, A. 2007. Consistent parameterization of roughness length and displacement height for sparse and dense canopies in land models. J. Hydrometeor. 8:730-737. +.. _ZengandDecker2009: + Zeng, X., and Decker, M. 2009. Improving the numerical solution of soil moisture-based Richards equation for land models with a deep or shallow water table. J. Hydrometeor. 10:308-319. .. _Zengetal2008: diff --git a/doc/source/tech_note/Snow_Hydrology/CLM50_Tech_Note_Snow_Hydrology.rst b/doc/source/tech_note/Snow_Hydrology/CLM50_Tech_Note_Snow_Hydrology.rst index eefa967b80..b416f50c6c 100644 --- a/doc/source/tech_note/Snow_Hydrology/CLM50_Tech_Note_Snow_Hydrology.rst +++ b/doc/source/tech_note/Snow_Hydrology/CLM50_Tech_Note_Snow_Hydrology.rst @@ -3,7 +3,7 @@ Snow Hydrology =============== -The parameterizations for snow are based primarily on :ref:`Anderson (1976) `, :ref:`Jordan (1991) `, and :ref:`Dai and Zeng (1997) `. The snowpack can have up to twelve layers. These layers are indexed in the Fortran code as :math:`i=-11,-10,...,-1,0` where layer :math:`i=0` is the snow layer next to the top soil layer and layer :math:`i=-11` is the top layer of a twelve-layer snow pack. Since the number of snow layers varies according to the snow depth, we use the notation :math:`snl+1` to describe the top layer of snow for the variable layer snow pack, where :math:`snl` is the negative of the number of snow layers. Refer to :numref:`Figure three layer snow pack` for an example of the snow layer structure for a three layer snow pack. +The parameterizations for snow are based primarily on :ref:`Anderson (1976) `, :ref:`Jordan (1991) `, and :ref:`Dai and Zeng (1997) `. The snowpack can have up to twelve layers. These layers are indexed in the Fortran code as :math:`i=-11,-10,...,-1,0` where layer :math:`i=0` is the snow layer next to the top soil layer and layer :math:`i=-11` is the top layer of a twelve-layer snowpack. Since the number of snow layers varies according to the snow depth, we use the notation :math:`snl+1` to describe the top layer of snow for the variable layer snowpack, where :math:`snl` is the negative of the number of snow layers. Refer to :numref:`Figure three layer snow pack` for an example of the snow layer structure for a three layer snowpack. .. _Figure three layer snow pack: @@ -30,7 +30,7 @@ The state variables for snow are the mass of water :math:`w_{liq,i}` (kg m\ :sup \text{Water equivalent} = \text{Ice equivalent} \times \frac{\rho_\text{ice}}{\rho_\text{liq}} -Section :numref:`Snow Covered Area Fraction` describes the calculation of fractional snow covered area, which is used in the surface albedo calculation (Chapter :numref:`rst_Surface Albedos`) and the surface flux calculations (Chapter :numref:`rst_Momentum, Sensible Heat, and Latent Heat Fluxes`). The following two sections (:numref:`Ice Content` and :numref:`Water Content`) describe the ice and water content of the snow pack assuming that at least one snow layer exists. Section :numref:`Black and organic carbon and mineral dust within snow` describes how black and organic carbon and mineral dust particles are represented within snow, including meltwater flushing. See Section :numref:`Initialization of snow layer` for a description of how a snow layer is initialized. +Section :numref:`Snow Covered Area Fraction` describes the calculation of fractional snow covered area, which is used in the surface albedo calculation (Chapter :numref:`rst_Surface Albedos`) and the surface flux calculations (Chapter :numref:`rst_Momentum, Sensible Heat, and Latent Heat Fluxes`). Sections (:numref:`Ice Content` and :numref:`Water Content`) describe the ice and water content of the snowpack assuming that at least one snow layer exists. Section :numref:`Black and organic carbon and mineral dust within snow` describes how black and organic carbon and mineral dust particles are represented within snow, including meltwater scavenging. See Section :numref:`Initialization of snow layer` for a description of how a snow layer is initialized. .. _Snow Covered Area Fraction: @@ -113,8 +113,8 @@ The temperature dependent term is given by (:ref:`van Kampenhout et al. (2017) < \rho_{T} = \left\{\begin{array}{lr} - 50 + 1.7 \left(17\right)^{1.5} & \qquad T_{atm} >T_{f} +2 \ \\ - 50+1.7 \left(T_{atm} -T_{f} + 15\right)^{1.5} & \qquad T_{f} - 15 < T_{atm} \le T_{f} + 2 \ \\ + 50 + 1.7 \ \left(17\right)^{1.5} & \qquad T_{atm} >T_{f} +2 \ \\ + 50+1.7 \ \left(T_{atm} -T_{f} + 15\right)^{1.5} & \qquad T_{f} - 15 < T_{atm} \le T_{f} + 2 \ \\ -3.833 \ \left( T_{atm} -T_{f} \right) - 0.0333 \ \left( T_{atm} -T_{f} \right)^{2} &\qquad T_{atm} \le T_{f} - 15 \end{array}\right\} @@ -167,7 +167,7 @@ The snow water equivalent :math:`W_{sno}` is capped to not exceed 10,000 kg m\ : Water Content ^^^^^^^^^^^^^^^^^^^ -The conservation equation for mass of water in snow layers is +The conservation equation for mass of liquid water in snow layers is .. math:: :label: 8.26 @@ -228,7 +228,7 @@ Equations :eq:`8.29` - :eq:`8.33` are solved sequentially from top (:math:`i=snl Black and organic carbon and mineral dust within snow ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Particles within snow originate from atmospheric aerosol deposition (:math:`D_{sp}` in Table 2.3 (kg m\ :sup:`-2` s\ :sup:`-1`) and influence snow radiative transfer (sections :numref:`Snow Albedo`, :numref:`Snowpack Optical Properties`, and :numref:`Snow Aging`). Particle masses and mixing ratios are represented with a simple mass-conserving scheme. The model maintains masses of the following eight particle species within each snow layer: hydrophilic black carbon, hydrophobic black carbon, hydrophilic organic carbon, hydrophobic organic carbon, and four species of mineral dust with the following particle sizes: 0.1-1.0, 1.0-2.5, 2.5-5.0, and 5.0-10.0 :math:`\mu m`. Each of these species has unique optical properties (:numref:`Table Single-scatter albedo values used for snowpack impurities and ice`) and meltwater removal efficiencies (:numref:`Table Meltwater scavenging`). +Particles within snowpack originate from atmospheric aerosol deposition (:math:`D_{sp}` in Table 2.3, kg m\ :sup:`-2` s\ :sup:`-1`) and influence snowpack radiative transfer (sections :numref:`Snow Albedo`, :numref:`Snowpack Optical Properties`, and :numref:`Snow Aging`). Particle masses and mixing ratios are represented with a simple mass-conserving scheme. The model maintains masses of the following eight particle species within each snow layer: hydrophilic black carbon, hydrophobic black carbon, hydrophilic organic carbon, hydrophobic organic carbon, and four species of mineral dust with the following particle sizes: 0.1-1.0, 1.0-2.5, 2.5-5.0, and 5.0-10.0 :math:`\mu m`. Each of these species has unique optical properties (:numref:`Table Single-scatter albedo values used for snowpack impurities and ice`) and meltwater removal efficiencies (:numref:`Table Meltwater scavenging`). The black carbon and organic carbon deposition rates described in Table 2.3 are combined into four categories as follows @@ -252,7 +252,7 @@ The black carbon and organic carbon deposition rates described in Table 2.3 are D_{oc,\, hphob} =D_{oc,\, dryhphob} -Deposited particles are assumed to be instantly mixed (homogeneously) within the surface snow layer and are added after the inter-layer water fluxes are computed (section :numref:`Water Content`) so that some aerosol is in the top layer after deposition and is not immediately washed out before radiative calculations are done. Particle masses are then redistributed each time step based on meltwater drainage through the snow column (section :numref:`Water Content`) and snow layer combination and subdivision (section :numref:`Snow Layer Combination and Subdivision`). The change in mass of each of the particle species :math:`\Delta m_{sp,\, i}` (kg m\ :sup:`-2`) is +Deposited particles are assumed to be instantly mixed within the surface snow layer (black carbon and dust can be either internally or externally mixed with snow grains; section :numref:`Snow Albedo`) and are added after the inter-layer water fluxes are computed (section :numref:`Water Content`) so that some aerosol is in the top layer after deposition and is not immediately washed out before radiative calculations are done. Particle masses are then redistributed each time step based on meltwater drainage through the snow column (section :numref:`Water Content`) and snow layer combination and subdivision (section :numref:`Snow Layer Combination and Subdivision`). The change in mass of each of the particle species :math:`\Delta m_{sp,\, i}` (kg m\ :sup:`-2`) is .. math:: :label: 8.38 @@ -469,7 +469,7 @@ The latter equation (for the mobility index :math:`M_\mathrm{O}`) is a simplific Snow Layer Combination and Subdivision ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -After the determination of snow temperature including phase change(Chapter :numref:`rst_Soil and Snow Temperatures`), snow hydrology (Chapter :numref:`rst_Snow Hydrology`), and the compaction calculations (section :numref:`Snow Compaction`), the number of snow layers is adjusted by either combining or subdividing layers. The combination and subdivision of snow layers is based on :ref:`Jordan (1991) `. +After the determination of snow temperature including phase change (Chapter :numref:`rst_Soil and Snow Temperatures`), snow hydrology (Chapter :numref:`rst_Snow Hydrology`), and the compaction calculations (section :numref:`Snow Compaction`), the number of snow layers is adjusted by either combining or subdividing layers. The combination and subdivision of snow layers is based on :ref:`Jordan (1991) `. .. _Combination: @@ -617,5 +617,5 @@ then adjusted as, T_{2}^{n+1} = T_{2}^{n} +\left(\frac{T_{1}^{n} -T_{2}^{n} }{{\left(\Delta z_{1} +\Delta z_{2}^{n} \right)\mathord{\left/ {\vphantom {\left(\Delta z_{1} +\Delta z_{2}^{n} \right) 2}} \right.} 2} } \right)\left(\frac{\Delta z_{2}^{n+1} }{2} \right) & \qquad T'_{3} ` + +Thermal conductivity :math:`\lambda _{i}` (W m\ :sup:`-1` K\ :sup:`-1`) for snow in CLM6.0 is modified from :ref:`Sturm et al. (1997)`, as applied by :ref:`Dutch et al. (2022)` and :ref:`Damseaux et al. (2025)`. The Sturm function uses the bulk density of snow to determine the thermal conductivity of snow layer (:math:`_{i}`) as: .. math:: :label: 6.87 - \lambda _{i} =\lambda _{air} +\left(7.75\times 10^{-5} \rho _{sno,\, i} +1.105\times 10^{-6} \rho _{sno,\, i}^{2} \right)\left(\lambda _{ice} -\lambda _{air} \right) + \lambda _{i} = \left\{ + \begin{array}{lr} + 0.023 + 0.234(\rho _{sno,\, i} /1000) &\qquad \rho _{sno,\, i} <= 156 \\ + 0.138 - 1.01(\rho _{sno,\, i} /1000) + 3.233(\rho _{sno,\, i} /1000)^2 &\qquad \rho _{sno,\, i} > 156 + \end{array}\right\} -where :math:`\lambda _{air}` is the thermal conductivity of air (:numref:`Table Physical Constants`) and :math:`\rho _{sno,\, i}` is the bulk density of snow (kg m\ :sup:`-3`) + +with the bulk density of snow :math:`\rho _{sno,\, i}` (kg m\ :sup:`-3`) calculated as the mass of ice and liquid water per unit volume of snow layer .. math:: :label: 6.88 \rho _{sno,\, i} =\frac{w_{ice,\, i} +w_{liq,\, i} }{\Delta z_{i} } . + +Previous versions of CLM used the :ref:`Jordan (1991) ` parameterization for snow thermal conductivity, which uses the thermal conductivity of air and the bulk density of snow as: + +.. math:: + :label: 6.89 + + \lambda _{i} =\lambda _{air} +\left(7.75\times 10^{-5} \rho _{sno,\, i} +1.105\times 10^{-6} \rho _{sno,\, i}^{2} \right)\left(\lambda _{ice} -\lambda _{air} \right) + +where :math:`\lambda _{air}` is the thermal conductivity of air (:numref:`Table Physical Constants`) and :math:`\rho _{sno,\, i}` calculated, as in :eq:`6.88`. + +The :ref:`Sturm et al. (1997)` parameterization is used in CLM6 over vegetated, glacier, and lake land units, but users can choose to use the Jordan (1991) parameterization over any of these land units. This can be accomplished through a change to the lnd_in namelist by using user_nl_clm. The volumetric heat capacity :math:`c_{i}` (J m\ :sup:`-3` K\ :sup:`-1`) for soil is from :ref:`de Vries (1963) ` and depends on the heat capacities of the soil solid, liquid water, and ice constituents .. math:: - :label: 6.89 + :label: 6.90 c_{i} =c_{s,\, i} \left(1-\theta _{sat,\, i} \right)+\frac{w_{ice,\, i} }{\Delta z_{i} } C_{ice} +\frac{w_{liq,\, i} }{\Delta z_{i} } C_{liq} where :math:`C_{liq}` and :math:`C_{ice}` are the specific heat capacities (J kg\ :sup:`-1` K\ :sup:`-1`) of liquid water and ice, respectively (:numref:`Table Physical Constants`). The heat capacity of soil solids :math:`c_{s,i}` \ (J m\ :sup:`-3` K\ :sup:`-1`) is .. math:: - :label: 6.90 + :label: 6.91 c_{s,i} =(1-f_{om,i} )c_{s,\min ,i} +f_{om,i} c_{s,om} where the heat capacity of mineral soil solids :math:`c_{s,\min,\, i}` (J m\ :sup:`-3` K\ :sup:`-1`) is .. math:: - :label: 6.91 + :label: 6.92 \begin{array}{lr} c_{s,\min ,\, i} =\left(\frac{2.128{\rm \; }\left(\% sand\right)_{i} +{\rm 2.385\; }\left(\% clay\right)_{i} }{\left(\% sand\right)_{i} +\left(\% clay\right)_{i} } \right)\times 10^{6} &\qquad i=1,\ldots ,N_{levsoi} \\ @@ -764,18 +781,18 @@ where the heat capacity of mineral soil solids :math:`c_{s,\min,\, i}` (J m\ :su where :math:`c_{s,bedrock} =2\times 10^{6}` J m\ :sup:`-3` K\ :sup:`-1` is the heat capacity of bedrock and :math:`c_{s,om} =2.5\times 10^{6}` \ J m\ :sup:`-3` K\ :sup:`-1` (:ref:`Farouki 1981 `) is the heat capacity of organic matter. For glaciers and snow .. math:: - :label: 6.92 + :label: 6.93 c_{i} =\frac{w_{ice,\, i} }{\Delta z_{i} } C_{ice} +\frac{w_{liq,\, i} }{\Delta z_{i} } C_{liq} . For the special case when snow is present (:math:`W_{sno} >0`) but there are no explicit snow layers (:math:`snl=0`), the heat capacity of the top layer is a blend of ice and soil heat capacity .. math:: - :label: 6.93 + :label: 6.94 c_{1} =c_{1}^{*} +\frac{C_{ice} W_{sno} }{\Delta z_{1} } -where :math:`c_{1}^{*}` is calculated from :eq:`6.89` or :eq:`6.92`. +where :math:`c_{1}^{*}` is calculated from :eq:`6.90` or :eq:`6.93`. .. _Excess Ground Ice: @@ -785,14 +802,14 @@ Excess Ground Ice An optional parameterization of excess ground ice melt and respective subsidence based on (:ref:`Lee et al., (2014) `). Initial excess ground ice concentrations for soil columns are derived from (:ref:`Brown et al., (1997) `). When the excess ground ice is present in the soil column, soil depth for a given layer (:math:`z_{i}`) is adjusted by the amount of excess ice in the column: .. math:: - :label: 6.94 + :label: 6.95 z_{i}^{'}=\Sigma_{j=1}^{i} \ z_{j}^{'}+\frac{w_{exice,\, j}}{\rho_{ice} } where :math:`w_{exice,\,j}` is excess ground ice amount (kg m :sup:`-2`) in layer :math:`j` and :math:`\rho_{ice}` is the density of ice (kg m :sup:`-3`). After adjustment of layer depths have been made, all of the soil temperature equations (from :eq:`6.80` to :eq:`6.89`) are calculted based on the adjusted depths. Thermal properties are additionally adjusted (:eq:`6.8` and :eq:`6.8`) in the following way: .. math:: - :label: 6.95 + :label: 6.96 \begin{array}{lr} \theta_{sat}^{'} =\frac{\theta _{liq} }{\theta _{liq} +\theta _{ice} +\theta_{exice}}{\theta_{sat}} \\ @@ -803,7 +820,7 @@ where :math:`w_{exice,\,j}` is excess ground ice amount (kg m :sup:`-2`) in laye Soil subsidence at the timestep :math:`n+1` (:math:`z_{exice}^{n+1}`, m) is then calculated as: .. math:: - :label: 6.96 + :label: 6.97 z_{exice}^{n+1}=\Sigma_{i=1}^{N_{levgrnd}} \ z_{j}^{',\ ,n+1}-z_{j}^{',\ ,n } diff --git a/doc/source/tech_note/Surface_Albedos/CLM50_Tech_Note_Surface_Albedos.rst b/doc/source/tech_note/Surface_Albedos/CLM50_Tech_Note_Surface_Albedos.rst index f28d5583f1..1409584a45 100644 --- a/doc/source/tech_note/Surface_Albedos/CLM50_Tech_Note_Surface_Albedos.rst +++ b/doc/source/tech_note/Surface_Albedos/CLM50_Tech_Note_Surface_Albedos.rst @@ -8,7 +8,7 @@ Surface Albedos Canopy Radiative Transfer ----------------------------- -Radiative transfer within vegetative canopies is calculated from the two-stream approximation of :ref:`Dickinson (1983) ` and :ref:`Sellers (1985) ` as described by :ref:`Bonan (1996) ` +Radiative transfer within vegetated canopies is calculated from the two-stream approximation of :ref:`Dickinson (1983) ` and :ref:`Sellers (1985) ` as described by :ref:`Bonan (1996) ` .. math:: :label: 3.1 @@ -82,14 +82,14 @@ For vegetation, :math:`\omega _{\Lambda }^{veg} =\alpha _{\Lambda } +\tau _{\Lam .. math:: :label: 3.11 - \alpha _{\Lambda } =\alpha _{\Lambda }^{leaf} w_{leaf} +\alpha _{\Lambda }^{stem} w_{stem} + \alpha _{\Lambda } =\max(\alpha _{\Lambda }^{leaf} w_{leaf} +\alpha _{\Lambda }^{stem} w_{stem},1e-6) -where :math:`w_{leaf} ={L\mathord{\left/ {\vphantom {L \left(L+S\right)}} \right.} \left(L+S\right)}` and :math:`w_{stem} ={S\mathord{\left/ {\vphantom {S \left(L+S\right)}} \right.} \left(L+S\right)}`. :math:`\tau _{\Lambda }` is a weighted combination of the leaf and stem transmittances (:math:`\tau _{\Lambda }^{leaf}, \tau _{\Lambda }^{stem}`) +where :math:`w_{leaf} =\max({L\mathord{\left/ {\vphantom {L \left(L+S\right)}} \right.} \left(L+S\right)},1e-6)` and :math:`w_{stem} =\max({S\mathord{\left/ {\vphantom {S \left(L+S\right)}} \right.} \left(L+S\right)},1e-6)`. :math:`\tau _{\Lambda }` is a weighted combination of the leaf and stem transmittances (:math:`\tau _{\Lambda }^{leaf}, \tau _{\Lambda }^{stem}`) .. math:: :label: 3.12 - \tau _{\Lambda } =\tau _{\Lambda }^{leaf} w_{leaf} +\tau _{\Lambda }^{stem} w_{stem} . + \tau _{\Lambda } =\max(\tau _{\Lambda }^{leaf} w_{leaf} +\tau _{\Lambda }^{stem} w_{stem},1e-6) . The upscatter for diffuse radiation is @@ -121,6 +121,8 @@ where the single scattering albedo is Note here the restriction on :math:`\mu \phi _{2} +G\left(\mu \right)`. We have seen cases where small values can cause unrealistic single scattering albedo associated with the log calculation, thereby eventually causing a negative soil albedo. +Note that the parameters :math:`h_{1}` –:math:`h_{10}`, :math:`\sigma`, :math:`h`, :math:`s_{1}`, and :math:`s_{2}` in the following equations [:eq:`3.17` - :eq:`3.30`] are defined in :eq:`3.31` - :eq:`3.57`. + The upward diffuse fluxes per unit incident direct beam and diffuse flux (i.e., the surface albedos) are .. math:: @@ -138,7 +140,7 @@ The downward diffuse fluxes per unit incident direct beam and diffuse radiation, .. math:: :label: 3.19 - I\, \downarrow _{\Lambda }^{\mu } =\frac{h_{4} }{\sigma } e^{-K\left(L+S\right)} +h_{5} s_{1} +\frac{h_{6} }{s_{1} } + I\, \downarrow _{\Lambda }^{\mu } =\frac{h_{4} }{\sigma } s_{2} +h_{5} s_{1} +\frac{h_{6} }{s_{1} } .. math:: :label: 3.20 @@ -150,7 +152,7 @@ With reference to :numref:`Figure Radiation Schematic`, the direct beam flux tra .. math:: :label: 3.21 - \vec{I}_{\Lambda }^{\mu } =1-I\, \uparrow _{\Lambda }^{\mu } -\left(1-\alpha _{g,\, \Lambda } \right)I\, \downarrow _{\Lambda }^{\mu } -\left(1-\alpha _{g,\, \Lambda }^{\mu } \right)e^{-K\left(L+S\right)} + \vec{I}_{\Lambda }^{\mu } =1-I\, \uparrow _{\Lambda }^{\mu } -\left(1-\alpha _{g,\, \Lambda } \right)I\, \downarrow _{\Lambda }^{\mu } -\left(1-\alpha _{g,\, \Lambda }^{\mu }\right) s_{2} .. math:: :label: 3.22 @@ -346,7 +348,7 @@ The parameters :math:`h_{1}` –:math:`h_{10}`, :math:`\sigma`, :math:`h`, :math h_{10} =\frac{-s_{1} \left(u_{2} -\bar{\mu }h\right)}{d_{2} } . -Plant functional type optical properties (:numref:`Table Plant functional type optical properties`) for trees and shrubs are from :ref:`Dorman and Sellers (1989) `. Leaf and stem optical properties (VIS and NIR reflectance and transmittance) were derived for grasslands and crops from full optical range spectra of measured optical properties (:ref:`Asner et al. 1998 `). Optical properties for intercepted snow (:numref:`Table Intercepted snow optical properties`) are from :ref:`Sellers et al. (1986) `. +Plant functional type optical properties (:numref:`Table Plant functional type optical properties`) for :math:`\chi _{L}`, :math:`\alpha _{vis}^{leaf}`, :math:`\alpha _{nir}^{leaf}`, :math:`\alpha _{vis}^{stem}`, :math:`\alpha _{nir}^{stem}`, :math:`\tau _{vis}^{leaf}`, and :math:`\tau _{nir}^{leaf}` are from :ref:`Majasalmi and Bright (2019) `. One of these parameter values was tuned based on a Perturbed Parameter Ensemble. Specifically, :math:`\chi _{L}` for BET Tropical was changed from 0.32 to 0.45. :math:`\tau _{vis}^{stem}` and :math:`\tau _{nir}^{stem}` for trees and shrubs are from :ref:`Dorman and Sellers (1989) `. :math:`\tau _{vis}^{stem}` and :math:`\tau _{nir}^{stem}` for grassland and crops were derived from full optical range spectra of measured optical properties (:ref:`Asner et al. 1998 `). Optical properties for intercepted snow (:numref:`Table Intercepted snow optical properties`) are from :ref:`Sellers et al. (1986) `. .. _Table Plant functional type optical properties: @@ -355,55 +357,55 @@ Plant functional type optical properties (:numref:`Table Plant functional type o +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ | Plant Functional Type | :math:`\chi _{L}` | :math:`\alpha _{vis}^{leaf}` | :math:`\alpha _{nir}^{leaf}` | :math:`\alpha _{vis}^{stem}` | :math:`\alpha _{nir}^{stem}` | :math:`\tau _{vis}^{leaf}` | :math:`\tau _{nir}^{leaf}` | :math:`\tau _{vis}^{stem}` | :math:`\tau _{nir}^{stem}` | +==================================+======================+=================================+=================================+=================================+=================================+===============================+===============================+===============================+===============================+ - | NET Temperate | 0.01 | 0.07 | 0.35 | 0.16 | 0.39 | 0.05 | 0.10 | 0.001 | 0.001 | + | NET Temperate | 0.01 | 0.09 | 0.41 | 0.12 | 0.36 | 0.04 | 0.32 | 0.001 | 0.001 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | NET Boreal | 0.01 | 0.07 | 0.35 | 0.16 | 0.39 | 0.05 | 0.10 | 0.001 | 0.001 | + | NET Boreal | 0.01 | 0.09 | 0.41 | 0.12 | 0.36 | 0.04 | 0.32 | 0.001 | 0.001 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | NDT Boreal | 0.01 | 0.07 | 0.35 | 0.16 | 0.39 | 0.05 | 0.10 | 0.001 | 0.001 | + | NDT Boreal | 0.01 | 0.08 | 0.39 | 0.12 | 0.36 | 0.06 | 0.42 | 0.001 | 0.001 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | BET Tropical | 0.10 | 0.10 | 0.45 | 0.16 | 0.39 | 0.05 | 0.25 | 0.001 | 0.001 | + | BET Tropical | 0.45 | 0.11 | 0.46 | 0.21 | 0.49 | 0.06 | 0.33 | 0.001 | 0.001 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | BET temperate | 0.10 | 0.10 | 0.45 | 0.16 | 0.39 | 0.05 | 0.25 | 0.001 | 0.001 | + | BET temperate | 0.32 | 0.11 | 0.46 | 0.21 | 0.49 | 0.06 | 0.33 | 0.001 | 0.001 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | BDT tropical | 0.01 | 0.10 | 0.45 | 0.16 | 0.39 | 0.05 | 0.25 | 0.001 | 0.001 | + | BDT tropical | 0.20 | 0.08 | 0.41 | 0.21 | 0.49 | 0.06 | 0.43 | 0.001 | 0.001 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | BDT temperate | 0.25 | 0.10 | 0.45 | 0.16 | 0.39 | 0.05 | 0.25 | 0.001 | 0.001 | + | BDT temperate | 0.59 | 0.08 | 0.41 | 0.21 | 0.49 | 0.06 | 0.43 | 0.001 | 0.001 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | BDT boreal | 0.25 | 0.10 | 0.45 | 0.16 | 0.39 | 0.05 | 0.25 | 0.001 | 0.001 | + | BDT boreal | 0.59 | 0.08 | 0.41 | 0.21 | 0.49 | 0.06 | 0.43 | 0.001 | 0.001 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | BES temperate | 0.01 | 0.07 | 0.35 | 0.16 | 0.39 | 0.05 | 0.10 | 0.001 | 0.001 | + | BES temperate | 0.32 | 0.11 | 0.46 | 0.21 | 0.49 | 0.06 | 0.33 | 0.001 | 0.001 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | BDS temperate | 0.25 | 0.10 | 0.45 | 0.16 | 0.39 | 0.05 | 0.25 | 0.001 | 0.001 | + | BDS temperate | 0.59 | 0.08 | 0.41 | 0.21 | 0.49 | 0.06 | 0.43 | 0.001 | 0.001 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | BDS boreal | 0.25 | 0.10 | 0.45 | 0.16 | 0.39 | 0.05 | 0.25 | 0.001 | 0.001 | + | BDS boreal | 0.59 | 0.08 | 0.41 | 0.21 | 0.49 | 0.06 | 0.43 | 0.001 | 0.001 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | C\ :sub:`3` arctic grass | -0.30 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | C\ :sub:`3` arctic grass | -0.23 | 0.05 | 0.28 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | C\ :sub:`3` grass | -0.30 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | C\ :sub:`3` grass | -0.23 | 0.05 | 0.28 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | C\ :sub:`4` grass | -0.30 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | C\ :sub:`4` grass | -0.23 | 0.05 | 0.28 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | C\ :sub:`3` Crop | -0.30 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | C\ :sub:`3` Crop | 0.30 | 0.08 | 0.42 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | Temp Corn | -0.50 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | Temp Corn | 0.30 | 0.08 | 0.42 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | Spring Wheat | -0.50 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | Spring Wheat | 0.30 | 0.08 | 0.42 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | Temp Soybean | -0.50 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | Temp Soybean | 0.30 | 0.08 | 0.42 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | Cotton | -0.50 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | Cotton | 0.30 | 0.08 | 0.42 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | Rice | -0.50 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | Rice | 0.30 | 0.08 | 0.42 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | Sugarcane | -0.50 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | Sugarcane | 0.30 | 0.08 | 0.42 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | Tropical Corn | -0.50 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | Tropical Corn | 0.30 | 0.08 | 0.42 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | Tropical Soybean | -0.50 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | Tropical Soybean | 0.30 | 0.08 | 0.42 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | Miscanthus | -0.50 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | Miscanthus | 0.30 | 0.08 | 0.42 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ - | Switchgrass | -0.50 | 0.11 | 0.35 | 0.31 | 0.53 | 0.05 | 0.34 | 0.120 | 0.250 | + | Switchgrass | 0.30 | 0.08 | 0.42 | 0.31 | 0.53 | 0.05 | 0.40 | 0.120 | 0.250 | +----------------------------------+----------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+ .. _Table Intercepted snow optical properties: @@ -439,24 +441,38 @@ The overall direct beam :math:`\alpha _{g,\, \Lambda }^{\mu }` and diffuse :math where :math:`f_{sno}` is the fraction of the ground covered with snow (section :numref:`Snow Covered Area Fraction`). -:math:`\alpha _{soi,\, \Lambda }^{\mu }` and :math:`\alpha _{soi,\, \Lambda }` vary with glacier, lake, and soil surfaces. Glacier albedos are from :ref:`Paterson (1994) ` +:math:`\alpha _{soi,\, \Lambda }^{\mu }` and :math:`\alpha _{soi,\, \Lambda }` vary with glacier, lake, and soil surfaces. Glacier albedos were originally from :ref:`Paterson (1994) ` but were adjusted to the following values agreed upon by the Land Ice Working Group leadership team + +.. math:: \alpha _{soi,\, vis}^{\mu } =\alpha _{soi,\, vis} =0.5 -.. math:: \alpha _{soi,\, vis}^{\mu } =\alpha _{soi,\, vis} =0.6 +.. math:: \alpha _{soi,\, nir}^{\mu } =\alpha _{soi,\, nir} =0.3. -.. math:: \alpha _{soi,\, nir}^{\mu } =\alpha _{soi,\, nir} =0.4. +Note that these are read in from the ``clm_inparm`` namelist group (variable ``albice``). -Unfrozen lake albedos depend on the cosine of the solar zenith angle :math:`\mu` +Unfrozen lake direct albedos depend on the cosine of the solar zenith angle :math:`\mu` .. math:: :label: 3.60 - \alpha _{soi,\, \Lambda }^{\mu } =\alpha _{soi,\, \Lambda } =0.05\left(\mu +0.15\right)^{-1} . + \alpha _{soi,\, \Lambda }^{\mu } =0.05\left(\max (0.001,\mu +0.15\right))^{-1} . + +For diffuse radiation the expression in equation :eq:`3.60` is integrated over the full sky to yield :math:`\alpha _{soi,\, \Lambda } =0.10`. + +For frozen lakes without resolved snow layers (:math:`snl=0`), the albedo at cold temperatures :math:`a_0` is 0.60 for visible and 0.40 for near infrared radiation. As the temperature at the ice surface, :math:`{T}_{g}`, approaches freezing [ :math:`{T}_{f}` (K) (:numref:`Table Physical Constants`)], the albedo is relaxed towards 0.10 based on :ref:`Mironov et al. (2010)`: + +.. math:: + :label: AlbFrozenLakeSnl0Dir + + \alpha _{soi,\, \Lambda }^{\mu }=a_{0} \left(1-x\right)+\max(0.10,\alpha _{soi,\, \Lambda }^{\mu })x,x=\exp \left(-95\frac{T_{f} -T_{g} }{T_{f} } \right) + +.. math:: + :label: AlbFrozenLakeSnl0Dif -Frozen lake albedos are from NCAR LSM (:ref:`Bonan 1996 `) + \alpha _{soi,\, \Lambda }=a_{0} \left(1-x\right)+0.10x,x=\exp \left(-95\frac{T_{f} -T_{g} }{T_{f} } \right) -.. math:: \alpha _{soi,\, vis}^{\mu } =\alpha _{soi,\, vis} =0.60 +where :math:`\alpha _{soi,\, \Lambda }^{\mu }` is calculated from :eq:`3.60` for direct radiation. -.. math:: \alpha _{soi,\, nir}^{\mu } =\alpha _{soi,\, nir} =0.40. +For frozen lakes with resolved snow layers, the reflectance of the ice surface is fixed at :math:`a_0`, and the snow reflectance is calculated as over non-vegetated surfaces (Chapter :numref:`rst_Surface Albedos`). These two reflectances are combined to obtain the snow-fraction-weighted albedo as in over non-vegetated surfaces (Chapter :numref:`rst_Surface Albedos`). As in NCAR LSM (:ref:`Bonan 1996 `), soil albedos vary with color class @@ -467,7 +483,7 @@ As in NCAR LSM (:ref:`Bonan 1996 `), soil albedos vary with color cla where :math:`\Delta` depends on the volumetric water content of the first soil layer :math:`\theta _{1}` (section :numref:`Soil Water`) as :math:`\Delta =0.11-0.40\theta _{1} >0`, and :math:`\alpha _{sat,\, \Lambda }` and :math:`\alpha _{dry,\, \Lambda }` are albedos for saturated and dry soil color classes (:numref:`Table Dry and saturated soil albedos`). -CLM soil colors are prescribed so that they best reproduce observed MODIS local solar noon surface albedo values at the CLM grid cell following the methods of :ref:`Lawrence and Chase (2007) `. The soil colors are fitted over the range of 20 soil classes shown in :numref:`Table Dry and saturated soil albedos` and compared to the MODIS monthly local solar noon all-sky surface albedo as described in :ref:`Strahler et al. (1999) ` and :ref:`Schaaf et al. (2002) `. The CLM two-stream radiation model was used to calculate the model equivalent surface albedo using climatological monthly soil moisture along with the vegetation parameters of PFT fraction, LAI, and SAI. The soil color that produced the closest all-sky albedo in the two-stream radiation model was selected as the best fit for the month. The fitted monthly soil colors were averaged over all snow-free months to specify a representative soil color for the grid cell. In cases where there was no snow-free surface albedo for the year, the soil color derived from snow-affected albedo was used to give a representative soil color that included the effects of the minimum permanent snow cover. +Albedos associated with CLM soil colors were updated for CLM4 using the procedure described below (:ref:`Lawrence et al. (2011) `) but have not been updated since then. CLM soil colors are prescribed so that they best reproduce observed MODIS local solar noon surface albedo values at the CLM grid cell following the methods of :ref:`Lawrence and Chase (2007) `. The soil colors are fitted over the range of 20 soil classes shown in :numref:`Table Dry and saturated soil albedos` and compared to the MODIS monthly local solar noon all-sky surface albedo as described in :ref:`Strahler et al. (1999) ` and :ref:`Schaaf et al. (2002) `. The CLM two-stream radiation model was used to calculate the model equivalent surface albedo using climatological monthly soil moisture along with the vegetation parameters of PFT fraction, LAI, and SAI. The soil color that produced the closest all-sky albedo in the two-stream radiation model was selected as the best fit for the month. The fitted monthly soil colors were averaged over all snow-free months to specify a representative soil color for the grid cell. In cases where there was no snow-free surface albedo for the year, the soil color derived from snow-affected albedo was used to give a representative soil color that included the effects of the minimum permanent snow cover. .. _Table Dry and saturated soil albedos: @@ -504,9 +520,9 @@ CLM soil colors are prescribed so that they best reproduce observed MODIS local Snow Albedo ^^^^^^^^^^^^^^^^^ -Snow albedo and solar absorption within each snow layer are simulated with the Snow, Ice, and Aerosol Radiative Model (SNICAR), which incorporates a two-stream radiative transfer solution from :ref:`Toon et al. (1989) `. Albedo and the vertical absorption profile depend on solar zenith angle, albedo of the substrate underlying snow, mass concentrations of atmospheric-deposited aerosols (black carbon, mineral dust, and organic carbon), and ice effective grain size (:math:`r_{e}`), which is simulated with a snow aging routine described in section :numref:`Snow Aging`. Representation of impurity mass concentrations within the snowpack is described in section :numref:`Black and organic carbon and mineral dust within snow`. Implementation of SNICAR in CLM is also described somewhat by :ref:`Flanner and Zender (2005) ` and :ref:`Flanner et al. (2007) `. +Snow albedo and solar absorption within each snow layer are simulated with the Snow, Ice, and Aerosol Radiative Model (SNICAR-ADv3; :ref:`Flanner et al., 2021 `), which incorporates an adding-doubling radiative transfer solution (:ref:`Dang et al., 2019 `; :ref:`Briegleb and Light, 2007 `; Note that the original SNICAR uses the tri-diagonal matrix two-stream radiative transfer solution from :ref:`Toon et al., 1989 `). Snow albedo and the vertical light absorption profile depend on solar zenith angle, albedo of the substrate underlying snow, mass concentrations of atmospheric-deposited aerosols (black carbon, mineral dust, and organic carbon), snow layer thickness, snow density, and ice effective grain size (:math:`r_{e}`) that is simulated with a snow aging routine described in section :numref:`Snow Aging`. Representation of impurity mass concentrations within the snowpack is described in section :numref:`Black and organic carbon and mineral dust within snow`. Implementation of SNICAR-ADv3 in CTSM/CLM is described by :ref:`He et al. (2024) `, while the original SNICAR implementation is described by :ref:`Flanner and Zender (2005) `, and :ref:`Flanner et al. (2007) `. -The two-stream solution requires the following bulk optical properties for each snow layer and spectral band: extinction optical depth (:math:`\tau`), single-scatter albedo (:math:`\omega`), and scattering asymmetry parameter (*g*). The snow layers used for radiative calculations are identical to snow layers applied elsewhere in CLM, except for the case when snow mass is greater than zero but no snow layers exist. When this occurs, a single radiative layer is specified to have the column snow mass and an effective grain size of freshly-fallen snow (section :numref:`Snow Aging`). The bulk optical properties are weighted functions of each constituent *k*, computed for each snow layer and spectral band as +The adding-doubling two-stream solution requires the following bulk optical properties for each snow layer and spectral band: extinction optical depth (:math:`\tau`), single-scatter albedo (:math:`\omega`), and scattering asymmetry parameter (*g*). The snow layers used for radiative calculations are identical to snow layers applied elsewhere in CLM, except for the case when snow mass is greater than zero but no snow layers exist. When this occurs, a single radiative layer is specified to have the column snow mass and an effective grain size of freshly-fallen snow (section :numref:`Snow Aging`). For aerosols externally mixed with snow grains, the bulk optical properties are weighted functions of each constituent *k*, computed for each snow layer and spectral band as .. math:: :label: 3.62 @@ -523,14 +539,16 @@ The two-stream solution requires the following bulk optical properties for each g=\frac{\sum _{1}^{k}g_{k} \omega _{k} \tau _{k} }{\sum _{1}^{k}\omega _{k} \tau _{k} } -For each constituent (ice, two black carbon species, two organic carbon species, and four dust species), :math:`\omega`, *g*, and the mass extinction cross-section :math:`\psi` (m\ :sup:`2` kg\ :sub:`-1`) are computed offline with Mie Theory, e.g., applying the computational technique from :ref:`Bohren and Huffman (1983) `. The extinction optical depth for each constituent depends on its mass extinction cross-section and layer mass, :math:`w _{k}` (kg\ m\ :sup:`-1`) as +For each constituent (ice, two black carbon species, two organic carbon species, and four dust species), :math:`\omega`, *g*, and the mass extinction cross-section :math:`\psi` (m\ :sup:`2` kg\ :sup:`-1`) are pre-computed offline with Mie Theory by assuming lognormal size distribution for each constituent and applying the computational technique from :ref:`Bohren and Huffman (1983) `. The extinction optical depth for each constituent depends on its mass extinction cross-section and layer mass, :math:`w _{k}` (kg\ m\ :sup:`-1`) as .. math:: :label: 3.65 \tau _{k} =\psi _{k} w_{k} -The two-stream solution (:ref:`Toon et al. (1989) `) applies a tri-diagonal matrix solution to produce upward and downward radiative fluxes at each layer interface, from which net radiation, layer absorption, and surface albedo are easily derived. Solar fluxes are computed in five spectral bands, listed in :numref:`Table Spectral bands and weights used for snow radiative transfer`. Because snow albedo varies strongly across the solar spectrum, it was determined that four bands were needed to accurately represent the near-infrared (NIR) characteristics of snow, whereas only one band was needed for the visible spectrum. Boundaries of the NIR bands were selected to capture broad radiative features and maximize accuracy and computational efficiency. We partition NIR (0.7-5.0 :math:`\mu` m) surface downwelling flux from CLM according to the weights listed in :numref:`Table Spectral bands and weights used for snow radiative transfer`, which are unique for diffuse and direct incident flux. These fixed weights were determined with offline hyperspectral radiative transfer calculations for an atmosphere typical of mid-latitude winter (:ref:`Flanner et al. (2007) `). The tri-diagonal solution includes intermediate terms that allow for easy interchange of two-stream techniques. We apply the Eddington solution for the visible band (following :ref:`Wiscombe and Warren 1980 `) and the hemispheric mean solution ((:ref:`Toon et al. (1989) `) for NIR bands. These choices were made because the Eddington scheme works well for highly scattering media, but can produce negative albedo for absorptive NIR bands with diffuse incident flux. Delta scalings are applied to :math:`\tau`, :math:`\omega`, and :math:`g` (:ref:`Wiscombe and Warren 1980 `) in all spectral bands, producing effective values (denoted with :math:`*`) that are applied in the two-stream solution +Compared to the original SNICAR implementation, the SNICAR-ADv3 implementation includes two new features: nonspherical snow grain shape (:ref:`He et al., 2017 `) and aerosol-snow internal mixing for black carbon (BC) and dust (:ref:`He et al., 2017 `; :ref:`He et al., 2019 `). The original SNICAR assumes spherical snow grains, which however may not be a realistic representation since nonspherical snow grains are ubiquitous in reality. Thus, in SNICAR-ADv3, four typical snow grain shapes representative of real‐world observations, including sphere, spheroid, hexagonal plate/column, and fractal snowflake are used. The :ref:`He et al. (2017) ` parameterizations are used to quantify snow grain nonsphericity impacts on snow asymmetry factor (*g*) before the calculation of bulk optical properties (equation :eq:`3.64`). Snow extinction optical depth (:math:`\tau`) and single-scattering albedo (:math:`\omega`) are not modified. The default snow grain shape is set to hexagonal plate/column (:ref:`Flanner et al., 2021 `). The snow grain shape can be controlled via namelist option (:ref:`He et al., 2024 `). For BC internal mixing with snow grain, the original SNICAR assumes BC‐snow external mixing, with hydrophilic BC treated as coated BC. However, in reality BC can also be internally mixed with snow grains. The :ref:`He et al. (2017) ` parameterizations are used to quantify BC-snow internal mixing effects on snow single-scattering albedo (:math:`\omega`), with no changes in snow extinction optical depth (:math:`\tau`) and asymmetry factor (*g*) due to neglibile impacts. The hydrophilic BC is no longer treated as coated BC because sulfate coating on the BC particle surface is dissolvable into water during wet deposition. The hydrophilic BC is hence treated as internally mixed with snow grains. For dust-snow internal mixing, the :ref:`He et al. (2019) ` parameterizations are used to quantify its impact on snow single-scattering albedo (:math:`\omega`), with no changes in snow extinction optical depth (:math:`\tau`) and asymmetry factor (*g*). Currently, dust-snow internal mixing (if activated) applies to all dust size bins. Both BC-snow and dust-snow internal/external mixing can be controlled by namelist options (:ref:`He et al., 2024 `). By default, BC and dust are externally mixed with snow grains, and it is recommended not to activate both internal mixing together which has not been fully tested. + +The original SNICAR two-stream solution (:ref:`Toon et al., 1989 `) applies a tri-diagonal matrix solution to produce upward and downward radiative fluxes at each layer interface, from which net radiation, layer absorption, and surface albedo are easily derived. The SNICAR-ADv3 instead uses a more accurate adding-doubling radiative transfer solution (:ref:`Dang et al., 2019 `; :ref:`Briegleb and Light, 2007 `). Solar fluxes are computed in either five spectral bands (default) listed in :numref:`Table Spectral bands and weights used for snow radiative transfer` or 480 hyperspectral bands (from 200 nm to 5000 nm with 10-nm spectral resolution; :ref:`Flanner et al., 2021 `). Because snow albedo varies strongly across the solar spectrum, it was determined that at least four bands were needed to accurately represent the near-infrared (NIR) characteristics of snow, whereas only one band was needed for the visible spectrum, which is why the five bands are used by default to achieve a balance between computational time and accuracy. Boundaries of the four NIR bands were selected to capture broad radiative features and maximize accuracy and computational efficiency. The 480-band capability can be used via namelist option (:ref:`He et al., 2024 `). We partition NIR (0.7-5.0 :math:`\mu` m) surface downwelling flux from CLM according to the weights from six typical atmospheric conditions (:ref:`Flanner et al., 2021 `), including Mid‐latitude winter, Mid‐latitude summer, Sub‐Arctic winter, Sub‐Arctic summer, Summit (Greenland), and High mountain, which are unique for diffuse and direct incident flux and can be selected via namelist options (:ref:`He et al., 2024 `). By default, the mid‐latitude winter downward solar spectrum (:numref:`Table Spectral bands and weights used for snow radiative transfer`) is used. These prescribed weights were determined with offline hyperspectral atmospheric radiative transfer calculations. The radiative transfer solution includes intermediate terms that allow for easy interchange of two-stream techniques. We apply the delta-Eddington solution to the layer bulk optical properties following :ref:`Briegleb and Light (2007) `. Specifically, Delta scalings are applied to :math:`\tau`, :math:`\omega`, and :math:`g` in all spectral bands, producing effective values (denoted with :math:`*`) that are applied in the two-stream solution. .. math:: :label: 3.66 @@ -545,7 +563,7 @@ The two-stream solution (:ref:`Toon et al. (1989) `) applies a tri .. math:: :label: 3.68 - g^{*} =\frac{g}{1+g} + g^{*} =\frac{g-g^{2}}{1-g^{2}} .. _Table Spectral bands and weights used for snow radiative transfer: @@ -556,18 +574,18 @@ The two-stream solution (:ref:`Toon et al. (1989) `) applies a tri +=========================================================+======================+==================+ | Band 1: 0.3-0.7\ :math:`\mu`\ m (visible) | (1.0) | (1.0) | +---------------------------------------------------------+----------------------+------------------+ - | Band 2: 0.7-1.0\ :math:`\mu`\ m (near-IR) | 0.494 | 0.586 | + | Band 2: 0.7-1.0\ :math:`\mu`\ m (near-IR) | 0.494 | 0.634 | +---------------------------------------------------------+----------------------+------------------+ - | Band 3: 1.0-1.2\ :math:`\mu`\ m (near-IR) | 0.181 | 0.202 | + | Band 3: 1.0-1.2\ :math:`\mu`\ m (near-IR) | 0.180 | 0.186 | +---------------------------------------------------------+----------------------+------------------+ - | Band 4: 1.2-1.5\ :math:`\mu`\ m (near-IR) | 0.121 | 0.109 | + | Band 4: 1.2-1.5\ :math:`\mu`\ m (near-IR) | 0.123 | 0.094 | +---------------------------------------------------------+----------------------+------------------+ - | Band 5: 1.5-5.0\ :math:`\mu`\ m (near-IR) | 0.204 | 0.103 | + | Band 5: 1.5-5.0\ :math:`\mu`\ m (near-IR) | 0.203 | 0.086 | +---------------------------------------------------------+----------------------+------------------+ -Under direct-beam conditions, singularities in the radiative approximation are occasionally approached in spectral bands 4 and 5 that produce unrealistic conditions (negative energy absorption in a layer, negative albedo, or total absorbed flux greater than incident flux). When any of these three conditions occur, the Eddington approximation is attempted instead, and if both approximations fail, the cosine of the solar zenith angle is adjusted by 0.02 (conserving incident flux) and a warning message is produced. This situation occurs in only about 1 in 10 :sup:`6` computations of snow albedo. After looping over the five spectral bands, absorption fluxes and albedo are averaged back into the bulk NIR band used by the rest of CLM. +Under direct-beam conditions, the two-stream approximations become poor for large solar zenith angle, which is mostly contributed by the errors of near-IR band calculations, especially for optically thick snowpacks. To improve the performance of two-stream algorithms, the :ref:`Dang et al. (2019) ` parameterization that corrects the underestimated near-IR snow albedo at large solar zenith angles (>75deg) is used for NIR bands (:ref:`He et al., 2024 `). -Soil albedo (or underlying substrate albedo), which is defined for visible and NIR bands, is a required boundary condition for the snow radiative transfer calculation. Currently, the bulk NIR soil albedo is applied to all four NIR snow bands. With ground albedo as a lower boundary condition, SNICAR simulates solar absorption in all snow layers as well as the underlying soil or ground. With a thin snowpack, penetrating solar radiation to the underlying soil can be quite large and heat cannot be released from the soil to the atmosphere in this situation. Thus, if the snowpack has total snow depth less than 0.1 m (:math:`z_{sno} < 0.1`) and there are no explicit snow layers, the solar radiation is absorbed by the top soil layer. If there is a single snow layer, the solar radiation is absorbed in that layer. If there is more than a single snow layer, 75% of the solar radiation is absorbed in the top snow layer, and 25% is absorbed in the next lowest snow layer. This prevents unrealistic soil warming within a single timestep. +Soil albedo (or underlying substrate albedo), which is defined for visible and NIR bands, is a required boundary condition for the snow radiative transfer calculation. Currently, the bulk NIR soil albedo is applied to all four NIR snow bands. With ground albedo as a lower boundary condition, SNICAR-ADv3 simulates solar absorption in all snow layers as well as the underlying soil or ground. With a thin snowpack, penetrating solar radiation to the underlying soil can be quite large and heat cannot be released from the soil to the atmosphere in this situation. Thus, if the snowpack has total snow depth less than 0.1 m (:math:`z_{sno} < 0.1`) and there are no explicit snow layers, the solar radiation is absorbed by the top soil layer. If there is a single snow layer, the solar radiation is absorbed in that layer. If there is more than a single snow layer, 75% of the solar radiation is absorbed in the top snow layer, and 25% is absorbed in the next lowest snow layer. This prevents unrealistic soil warming within a single timestep. The radiative transfer calculation is performed twice for each column containing a mass of snow greater than :math:`1 \times 10^{-30}` kg\ m\ :sup:`-2` (excluding lake and urban columns); once each for direct-beam and diffuse incident flux. Absorption in each layer :math:`i` of pure snow is initially recorded as absorbed flux per unit incident flux on the ground (:math:`S_{sno,\, i}` ), as albedos must be calculated for the next timestep with unknown incident flux. The snow absorption fluxes that are used for column temperature calculations are @@ -583,7 +601,7 @@ This weighting is performed for direct-beam and diffuse, visible and NIR fluxes. Snowpack Optical Properties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Ice optical properties for the five spectral bands are derived offline and stored in a namelist-defined lookup table for online retrieval (see CLM5.0 User's Guide). Mie properties are first computed at fine spectral resolution (470 bands), and are then weighted into the five bands applied by CLM according to incident solar flux, :math:`I^{\downarrow } (\lambda )`. For example, the broadband mass-extinction cross section (:math:`\bar{\psi }`) over wavelength interval :math:`\lambda _{1}` to :math:`\lambda _{2}` is +Ice optical properties for the five or 480 spectral bands are derived offline based on Mie calculations and stored in a namelist-defined lookup table for online retrieval (:ref:`He et al., 2024 `). The ice refractive index used in Mie calculation follows the updates in (:ref:`Flanner et al., 2021 `), which is a compilation of the :ref:`Picard et al. (2016) ` and :ref:`Warren and Brandt (2008) ` datasets. Mie properties are first computed at fine spectral resolution (480 bands from 200 nm to 5000 nm with 10-nm spectral resolution), and are then weighted into the five bands according to incident solar flux, :math:`I^{\downarrow } (\lambda )`, under six different atmospheric conditions (section :numref:`Snow Albedo`). For example, the broadband mass-extinction cross section (:math:`\bar{\psi }`) over wavelength interval :math:`\lambda _{1}` to :math:`\lambda _{2}` is .. math:: :label: 3.70 @@ -597,9 +615,9 @@ Broadband single-scatter albedo (:math:`\bar{\omega }`) is additionally weighted \bar{\omega }=\frac{\int _{\lambda _{1} }^{\lambda _{2} }\omega (\lambda )I^{\downarrow } ( \lambda )\alpha _{sno} (\lambda ){\rm d}\lambda }{\int _{\lambda _{1} }^{\lambda _{2} }I^{\downarrow } ( \lambda )\alpha _{sno} (\lambda ){\rm d}\lambda } -Inclusion of this additional albedo weight was found to improve accuracy of the five-band albedo solutions (relative to 470-band solutions) because of the strong dependence of optically-thick snowpack albedo on ice grain single-scatter albedo (:ref:`Flanner et al. (2007) `). The lookup tables contain optical properties for lognormal distributions of ice particles over the range of effective radii: 30\ :math:`\mu`\ m :math:`< r _{e} < \text{1500} \mu \text{m}`, at 1 :math:`\mu` m resolution. Single-scatter albedos for the end-members of this size range are listed in :numref:`Table Single-scatter albedo values used for snowpack impurities and ice`. +Inclusion of this additional albedo weight was found to improve accuracy of the five-band albedo solutions (relative to 480-band solutions) because of the strong dependence of optically-thick snowpack albedo on ice grain single-scatter albedo (:ref:`Flanner et al., 2007 `). The lookup tables contain optical properties for lognormal distributions of ice particles over the range of effective radii: 30\ :math:`\mu`\ m :math:`< r _{e} < \text{1500} \mu \text{m}`, at 1 :math:`\mu` m resolution. Single-scatter albedos for the end-members of this size range are listed in :numref:`Table Single-scatter albedo values used for snowpack impurities and ice`. -Optical properties for black carbon are described in :ref:`Flanner et al. (2007) `. Single-scatter albedo, mass extinction cross-section, and asymmetry parameter values for all snowpack species, in the five spectral bands used, are listed in :numref:`Table Single-scatter albedo values used for snowpack impurities and ice`, :numref:`Table Mass extinction values`, and :numref:`Table Asymmetry scattering parameters used for snowpack impurities and ice`. These properties were also derived with Mie Theory, using various published sources of indices of refraction and assumptions about particle size distribution. Weighting into the five CLM spectral bands was determined only with incident solar flux, as in equation :eq:`3.69`. +Optical properties for black carbon, organic carbon, and mineral dust are described in :ref:`Flanner et al. (2021) `. Three types of dust can be selected via namelist options (:ref:`He et al., 2024 `), including Saharan dust (default), Colorado dust, and Greenland dust, due to their substantially different optical properties. Single-scatter albedo, mass extinction cross-section, and asymmetry parameter values for all snowpack species under diffuse radiation with the default atmospheric condition (mid-latitude winter), in the five spectral bands used, are listed in :numref:`Table Single-scatter albedo values used for snowpack impurities and ice`, :numref:`Table Mass extinction values`, and :numref:`Table Asymmetry scattering parameters used for snowpack impurities and ice`. These properties were also derived with Mie Theory, using various published sources of indices of refraction and assumptions about particle size distribution (:ref:`Flanner et al., 2021 `). Weighting into the five CLM spectral bands was determined using the 480-band values with incident solar flux under six different atmospheric conditions (section :numref:`Snow Albedo`), as in equation :eq:`3.70`. .. _Table Single-scatter albedo values used for snowpack impurities and ice: @@ -608,25 +626,25 @@ Optical properties for black carbon are described in :ref:`Flanner et al. (2007) +----------------------------------------------------------------+----------+----------+----------+----------+----------+ | Species | Band 1 | Band 2 | Band 3 | Band 4 | Band 5 | +================================================================+==========+==========+==========+==========+==========+ - | Hydrophilic black carbon | 0.516 | 0.434 | 0.346 | 0.276 | 0.139 | + | Hydrophilic black carbon | 0.366 | 0.302 | 0.252 | 0.217 | 0.152 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Hydrophobic black carbon | 0.288 | 0.187 | 0.123 | 0.089 | 0.040 | + | Hydrophobic black carbon | 0.366 | 0.302 | 0.252 | 0.217 | 0.152 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Hydrophilic organic carbon | 0.997 | 0.994 | 0.990 | 0.987 | 0.951 | + | Hydrophilic organic carbon | 0.772 | 0.990 | 0.987 | 0.983 | 0.971 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Hydrophobic organic carbon | 0.963 | 0.921 | 0.860 | 0.814 | 0.744 | + | Hydrophobic organic carbon | 0.772 | 0.990 | 0.987 | 0.983 | 0.971 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Dust 1 | 0.979 | 0.994 | 0.993 | 0.993 | 0.953 | + | Dust 1 | 0.945 | 0.991 | 0.992 | 0.992 | 0.983 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Dust 2 | 0.944 | 0.984 | 0.989 | 0.992 | 0.983 | + | Dust 2 | 0.870 | 0.976 | 0.989 | 0.992 | 0.991 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Dust 3 | 0.904 | 0.965 | 0.969 | 0.973 | 0.978 | + | Dust 3 | 0.802 | 0.948 | 0.965 | 0.974 | 0.984 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Dust 4 | 0.850 | 0.940 | 0.948 | 0.953 | 0.955 | + | Dust 4 | 0.730 | 0.913 | 0.943 | 0.954 | 0.965 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Ice (:math:`r _{e}` = 30 :math:`\mu` m) | 0.9999 | 0.9999 | 0.9992 | 0.9938 | 0.9413 | + | Ice (:math:`r _{e}` = 30 :math:`\mu` m) | 0.9999 | 0.9999 | 0.9993 | 0.9954 | 0.9510 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Ice (:math:`r _{e}` = 1500 :math:`\mu` m) | 0.9998 | 0.9960 | 0.9680 | 0.8730 | 0.5500 | + | Ice (:math:`r _{e}` = 1500 :math:`\mu` m) | 0.9998 | 0.9963 | 0.9678 | 0.8735 | 0.5492 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ .. _Table Mass extinction values: @@ -636,25 +654,25 @@ Optical properties for black carbon are described in :ref:`Flanner et al. (2007) +----------------------------------------------------------------+----------+----------+----------+----------+----------+ | Species | Band 1 | Band 2 | Band 3 | Band 4 | Band 5 | +================================================================+==========+==========+==========+==========+==========+ - | Hydrophilic black carbon | 25369 | 12520 | 7739 | 5744 | 3527 | + | Hydrophilic black carbon | 12389 | 7971 | 5744 | 4654 | 3155 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Hydrophobic black carbon | 11398 | 5923 | 4040 | 3262 | 2224 | + | Hydrophobic black carbon | 12389 | 7971 | 5744 | 4654 | 3155 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Hydrophilic organic carbon | 37774 | 22112 | 14719 | 10940 | 5441 | + | Hydrophilic organic carbon | 4933 | 1390 | 628 | 375 | 143 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Hydrophobic organic carbon | 3289 | 1486 | 872 | 606 | 248 | + | Hydrophobic organic carbon | 4933 | 1390 | 628 | 375 | 143 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Dust 1 | 2687 | 2420 | 1628 | 1138 | 466 | + | Dust 1 | 2543 | 2242 | 1469 | 1013 | 458 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Dust 2 | 841 | 987 | 1184 | 1267 | 993 | + | Dust 2 | 803 | 950 | 1144 | 1205 | 1000 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Dust 3 | 388 | 419 | 400 | 397 | 503 | + | Dust 3 | 369 | 399 | 378 | 380 | 488 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Dust 4 | 197 | 203 | 208 | 205 | 229 | + | Dust 4 | 188 | 193 | 197 | 197 | 212 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Ice (:math:`r _{e}` = 30 :math:`\mu` m) | 55.7 | 56.1 | 56.3 | 56.6 | 57.3 | + | Ice (:math:`r _{e}` = 30 :math:`\mu` m) | 55.7 | 56.1 | 56.4 | 56.7 | 57.2 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Ice (:math:`r _{e}` = 1500 :math:`\mu` m) | 1.09 | 1.09 | 1.09 | 1.09 | 1.1 | + | Ice (:math:`r _{e}` = 1500 :math:`\mu` m) | 1.09 | 1.09 | 1.09 | 1.09 | 1.09 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ .. _Table Asymmetry scattering parameters used for snowpack impurities and ice: @@ -664,23 +682,23 @@ Optical properties for black carbon are described in :ref:`Flanner et al. (2007) +----------------------------------------------------------------+----------+----------+----------+----------+----------+ | Species | Band 1 | Band 2 | Band 3 | Band 4 | Band 5 | +================================================================+==========+==========+==========+==========+==========+ - | Hydrophilic black carbon | 0.52 | 0.34 | 0.24 | 0.19 | 0.10 | + | Hydrophilic black carbon | 0.44 | 0.34 | 0.28 | 0.24 | 0.18 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Hydrophobic black carbon | 0.35 | 0.21 | 0.15 | 0.11 | 0.06 | + | Hydrophobic black carbon | 0.44 | 0.34 | 0.28 | 0.24 | 0.18 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Hydrophilic organic carbon | 0.77 | 0.75 | 0.72 | 0.70 | 0.64 | + | Hydrophilic organic carbon | 0.58 | 0.47 | 0.39 | 0.34 | 0.25 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Hydrophobic organic carbon | 0.62 | 0.57 | 0.54 | 0.51 | 0.44 | + | Hydrophobic organic carbon | 0.58 | 0.47 | 0.39 | 0.34 | 0.25 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Dust 1 | 0.69 | 0.72 | 0.67 | 0.61 | 0.44 | + | Dust 1 | 0.71 | 0.72 | 0.67 | 0.62 | 0.48 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Dust 2 | 0.70 | 0.65 | 0.70 | 0.72 | 0.70 | + | Dust 2 | 0.73 | 0.66 | 0.71 | 0.74 | 0.73 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Dust 3 | 0.79 | 0.75 | 0.68 | 0.63 | 0.67 | + | Dust 3 | 0.82 | 0.76 | 0.68 | 0.63 | 0.67 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Dust 4 | 0.83 | 0.79 | 0.77 | 0.76 | 0.73 | + | Dust 4 | 0.87 | 0.80 | 0.78 | 0.76 | 0.73 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ - | Ice (:math:`r _{e}` = 30\ :math:`\mu`\ m) | 0.88 | 0.88 | 0.88 | 0.88 | 0.90 | + | Ice (:math:`r _{e}` = 30\ :math:`\mu`\ m) | 0.88 | 0.88 | 0.88 | 0.88 | 0.89 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ | Ice (:math:`r _{e}` = 1500\ :math:`\mu`\ m) | 0.89 | 0.90 | 0.90 | 0.92 | 0.97 | +----------------------------------------------------------------+----------+----------+----------+----------+----------+ @@ -767,9 +785,9 @@ The obliquity of the Earth :math:`\varepsilon` (degrees) is .. math:: :label: 3.79 - \varepsilon =\varepsilon *+\sum _{i=1}^{i=47}A_{i} \cos \left(f_{i} t+\delta _{i} \right) + \varepsilon =\varepsilon^{*}+\sum _{i=1}^{i=47}A_{i} \cos \left(f_{i} t+\delta _{i} \right) -where :math:`\varepsilon *` is a constant of integration (:numref:`Table Orbital parameters`), :math:`A_{i}`, :math:`f_{i}`, and :math:`\delta _{i}` are amplitude, mean rate, and phase terms in the cosine series expansion (:ref:`Berger (1978a,b) `, and :math:`t=t_{0} -1950` where :math:`t_{0}` is the year. The series expansion terms are not shown here but can be found in the source code file shr\_orb\_mod.F90. +where :math:`\varepsilon^{*}` is a constant of integration (:numref:`Table Orbital parameters`), :math:`A_{i}`, :math:`f_{i}`, and :math:`\delta _{i}` are amplitude, mean rate, and phase terms in the cosine series expansion (:ref:`Berger (1978a,b) `, and :math:`t=t_{0} -1950` where :math:`t_{0}` is the year. The series expansion terms are not shown here but can be found in the source code file ``shr_orb_mod.F90``. The true longitude of the Earth :math:`\lambda` (radians) is counted counterclockwise from the vernal equinox (:math:`\lambda =0` at the vernal equinox) @@ -806,7 +824,7 @@ where \begin{array}{l} {e^{\cos } =\sum _{j=1}^{19}M_{j} \cos \left(g_{j} t+B_{j} \right) ,} \\ {e^{\sin } =\sum _{j=1}^{19}M_{j} \sin \left(g_{j} t+B_{j} \right) } \end{array} -are the cosine and sine series expansions for :math:`e`, and :math:`M_{j}`, :math:`g_{j}`, and :math:`B_{j}` are amplitude, mean rate, and phase terms in the series expansions (:ref:`Berger (1978a,b) `). The longitude of the perihelion relative to the moving vernal equinox :math:`\tilde{\omega }` (degrees) is +are the cosine and sine series expansions for :math:`e`, and :math:`M_{j}`, :math:`g_{j}`, and :math:`B_{j}` are amplitude, mean rate, and phase terms in the series expansions (:ref:`Berger (1978a,b) `) (series expansion terms not shown but can be found in the source code file ``shr_orb_mod.F90``). The longitude of the perihelion relative to the moving vernal equinox :math:`\tilde{\omega }` (degrees) is .. math:: :label: 3.85 @@ -820,7 +838,7 @@ where :math:`\Pi` is the longitude of the perihelion measured from the reference \psi =\frac{\tilde{\psi }t}{3600} +\zeta +\sum _{i=1}^{78}F_{i} \sin \left(f_{i} ^{{'} } t+\delta _{i} ^{{'} } \right) -where :math:`\tilde{\psi }` (arcseconds) and :math:`\zeta` (degrees) are constants (:numref:`Table Orbital parameters`), and :math:`F_{i}`, :math:`f_{i} ^{{'} }`, and :math:`\delta _{i} ^{{'} }` are amplitude, mean rate, and phase terms in the sine series expansion (:ref:`Berger (1978a,b) `)). The longitude of the perihelion :math:`\Pi` (radians) depends on the sine and cosine series expansions for the eccentricity :math:`e`\ as follows: +where :math:`\tilde{\psi }` (arcseconds) and :math:`\zeta` (degrees) are constants (:numref:`Table Orbital parameters`), and :math:`F_{i}`, :math:`f_{i} ^{{'} }`, and :math:`\delta _{i} ^{{'} }` are amplitude, mean rate, and phase terms in the sine series expansion (:ref:`Berger (1978a,b) `) (series expansion terms not shown but can be found in the source code file ``shr_orb_mod.F90``). The longitude of the perihelion :math:`\Pi` (radians) depends on the sine and cosine series expansions for the eccentricity :math:`e` as follows: .. math:: :label: 3.87 @@ -834,7 +852,7 @@ where :math:`\tilde{\psi }` (arcseconds) and :math:`\zeta` (degrees) are constan \tan ^{-1} \left[\frac{e^{\sin } }{e^{\cos } } \right] & \qquad {\rm for\; }e^{\cos } >{\rm 1}\times {\rm 10}^{{\rm -8}} {\rm \; and\; }e^{\sin } \ge 0 \end{array}\right\}. -The numerical solution for the longitude of the perihelion :math:`\tilde{\omega }` is constrained to be between 0 and 360 degrees (measured from the autumn equinox). A constant 180 degrees is then added to :math:`\tilde{\omega }` because the Sun is considered as revolving around the Earth (geocentric coordinate system) (:ref:`Berger et al. 1993 `)). +The numerical solution for the longitude of the perihelion :math:`\tilde{\omega }` is constrained to be between 0 and 360 degrees (measured from the autumn equinox). A constant 180 degrees is then added to :math:`\tilde{\omega }` because the Sun is considered as revolving around the Earth (geocentric coordinate system) (:ref:`Berger et al. 1993 `). .. _Table Orbital parameters: @@ -843,7 +861,7 @@ The numerical solution for the longitude of the perihelion :math:`\tilde{\omega +--------------------------------------+-------------+ | Parameter | | +======================================+=============+ - | :math:`\varepsilon *` | 23.320556 | + | :math:`\varepsilon^{*}` | 23.320556 | +--------------------------------------+-------------+ | :math:`\tilde{\psi }` (arcseconds) | 50.439273 | +--------------------------------------+-------------+ diff --git a/doc/source/tech_note/Urban/CLM50_Tech_Note_Urban.rst b/doc/source/tech_note/Urban/CLM50_Tech_Note_Urban.rst index 8777c7be74..e352d1a9e6 100644 --- a/doc/source/tech_note/Urban/CLM50_Tech_Note_Urban.rst +++ b/doc/source/tech_note/Urban/CLM50_Tech_Note_Urban.rst @@ -3,23 +3,35 @@ Urban Model (CLMU) ====================== -At the global scale, and at the coarse spatial resolution of current climate models, urbanization has negligible impact on climate. However, the urban parameterization (CLMU; :ref:`Oleson et al. (2008b) `; :ref:`Oleson et al. (2008c) `) allows simulation of the urban environment within a climate model, and particularly the temperature where people live. As such, the urban model allows scientific study of how climate change affects the urban heat island and possible urban planning and design strategies to mitigate warming (e.g., white roofs). +The urban parameterization (CLMU; :ref:`Oleson et al. (2008b) `; :ref:`Oleson et al. (2008c) `; :ref:`Oleson and Feddema (2020) `) allows simulation of the urban environment within a climate model, and particularly the temperature/humidity where people live. As such, the urban model allows scientific study of how climate change affects the urban heat island and possible urban planning and design strategies to mitigate warming (e.g., white roofs). Urban areas in CLM are represented by up to three urban landunits per gridcell according to density class. The urban landunit is based on the "urban canyon" concept of :ref:`Oke (1987) ` in which the canyon geometry is described by building height (:math:`H`) and street width (:math:`W`) (:numref:`Figure schematic representation of the urban landunit`). The canyon system consists of roofs, walls, and canyon floor. Walls are further divided into shaded and sunlit components. The canyon floor is divided into pervious (e.g., to represent residential lawns, parks) and impervious (e.g., to represent roads, parking lots, sidewalks) fractions. Vegetation is not explicitly modeled for the pervious fraction; instead evaporation is parameterized by a simplified bulk scheme. -Each of the five urban surfaces is treated as a column within the landunit (:numref:`Figure schematic representation of the urban landunit`). Radiation parameterizations account for trapping of solar and longwave radiation inside the canyon. Momentum fluxes are determined for the urban landunit using a roughness length and displacement height appropriate for the urban canyon and stability formulations from CLM. A one-dimensional heat conduction equation is solved numerically for a multiple-layer (:math:`N_{levurb} =10`) column to determine conduction fluxes into and out of canyon surfaces. - -A new building energy model has been developed for CLM5.0. It accounts for the conduction of heat through interior surfaces (roof, sunlit and shaded walls, and floors), convection (sensible heat exchange) between interior surfaces and building air, longwave radiation exchange between interior surfaces, and ventilation (natural infiltration and exfiltration). Idealized HAC systems are assumed where the system capacity is infinite and the system supplies the amount of energy needed to keep the indoor air temperature (:math:`T_{iB}`) within maximum and minimum emperatures (:math:`T_{iB,\, \max },\, T_{iB,\, \min }` ), thus explicitly resolving space heating and air conditioning fluxes. Anthropogenic sources of waste heat (:math:`Q_{H,\, waste}` ) from HAC that account for inefficiencies in the heating and air conditioning equipment and from energy lost in the conversion of primary energy sources to end use energy are derived from :ref:`Sivak (2013) `. These sources of waste heat are incorporated as modifications to the canyon energy budget. +Each of the five urban surfaces is treated as a column within the landunit (:numref:`Figure schematic representation of the urban landunit`). Radiation parameterizations account for trapping of solar and longwave radiation inside the canyon. Momentum fluxes are determined for the urban landunit using a roughness length and displacement height appropriate for the urban canyon and stability formulations adopted from CLM. A one-dimensional heat conduction equation is solved numerically for a multiple-layer (:math:`N_{levurb} =10`) column to determine conduction fluxes into and out of canyon surfaces. Turbulent [sensible heat (:math:`Q_{H,\, u}` ) and latent heat (:math:`Q_{E,\, u}` )] and storage (:math:`Q_{S,\, u}` ) heat fluxes and surface (:math:`T_{u,\, s}` ) and internal (:math:`T_{u,\, i=1,\, N_{levgrnd} }` ) temperatures are determined for each urban surface :math:`u`. Hydrology on the roof and canyon floor is simulated and walls are hydrologically inactive. A snowpack can form on the active surfaces. A certain amount of liquid water is allowed to pond on these surfaces which supports evaporation. Water in excess of the maximum ponding depth runs off (:math:`R_{roof},\, R_{imprvrd},\, R_{prvrd}` ). The heat and moisture fluxes from each surface interact with each other through a bulk air mass that represents air in the urban canopy layer for which specific humidity (:math:`q_{ac}` ) and temperature (:math:`T_{ac}` ) are prognosed (:numref:`Figure schematic of urban and atmospheric model coupling`). The air temperature can be compared with that from surrounding vegetated/soil (rural) surfaces in the model to ascertain heat island characteristics. As with other landunits, the CLMU is forced either with output from a host atmospheric model (e.g., the Community Atmosphere Model (CAM)) or observed forcing (e.g., reanalysis or field observations). The urban model produces sensible, latent heat, and momentum fluxes, emitted longwave, and reflected solar radiation, which are area-averaged with fluxes from non-urban "landunits" (e.g., vegetation, lakes) to supply grid cell averaged fluxes to the atmospheric model. -Present day global urban extent and urban properties were developed by :ref:`Jackson et al. (2010) `. Urban extent, defined for four classes [tall building district (TBD), and high, medium, and low density (HD, MD, LD)], was derived from LandScan 2004, a population density dataset derived from census data, nighttime lights satellite observations, road proximity, and slope (:ref:`Dobson et al. 2000 `). The urban extent data for TBD, HD, and MD classes are aggregated from the original 1 km resolution to both a 0.05° by 0.05° global grid for high-resolution studies or a 0.5° by 0.5° grid. For the current implementation, the LD class is not used because it is highly rural and better modeled as a vegetated/soil surface. Although the TBD, HD, and MD classes are represented as individual urban landunits, urban model history output is currently a weighted average of the output for individual classes. +The version of the urban model that was first released as a component of CLM4.0 is separately described in the urban technical note (:ref:`Oleson et al. (2010b) `). The main changes in the urban model from CLM4.0 to CLM4.5 were 1) an expansion of the single urban landunit to up to three landunits per grid cell stratified by urban density types, 2) the number of urban layers for roofs and walls was no longer constrained to be equal to the number of ground layers, 3) space heating and air conditioning (AC) wasteheat factors were set to zero by default so that the user could customize these factors for their own application, 4) the elevation threshold used to eliminate urban areas in the surface dataset creation routines was increased from 2200 meters to 2600 meters, 5) hydrologic and thermal calculations for the pervious road followed CLM4.5 parameterizations. + +The main changes in the urban model from CLM4.5 to CLM5.0 were 1) a more sophisticated and realistic building space heating and AC submodel (described below) that prognoses interior building air temperature and includes more realistic space heating and AC wasteheat factors (see above), 2) the maximum building temperature (which determines AC demand) was now read in from a file specified from the ``urbantv_streams`` namelist group instead of the surface dataset which allowed for dynamic control of this input variable. The maximum building temperatures that were defined in :ref:`Jackson et al. (2010) ` are only implemented beginning in year 1950 (thus AC is off in prior years) and AC is turned off in year 2100 (because the buildings are not suitable for AC in some extreme global warming scenarios), 3) the inclusion of an optional updated urban properties dataset and new scenario tool. These features are described in more detail in :ref:`Oleson and Feddema (2020) `. In addition, a module of heat stress indices calculated online in the model that can be used to assess human thermal comfort for rural and urban areas was added. This last development is described and evaluated by :ref:`Buzan et al. (2015) `. + +The main changes in the urban model from CLM5.0 to CLM6.0 are (see below) 1) an explicit AC scheme for the building energy model (BEM) that better captures AC energy flux, 2) the addition of transient urban capability (annual changes in urban fraction over the course of a simulation), 3) a slightly modified set of urban properties that were an option in CLM5.0 and are now used by default, 4) new datasets of urban extent (urban fraction of the grid cell) for 1700-2023 (2024- data expected soon also) based on CMIP7 LUH3 data. + +The building energy model introduced in :ref:`Oleson and Feddema (2020) ` accounts for the conduction of heat through interior surfaces (roof, sunlit and shaded walls, and floors), convection (sensible heat exchange) between interior surfaces and building air, longwave radiation exchange between interior surfaces, and ventilation (natural infiltration and exfiltration). Idealized HAC systems are assumed where the system capacity is infinite and the system supplies the amount of energy needed to keep the indoor air temperature (:math:`T_{iB}`) within maximum and minimum emperatures (:math:`T_{iB,\, \max },\, T_{iB,\, \min }` ), thus explicitly resolving space heating and AC fluxes. Anthropogenic sources of waste heat (:math:`Q_{H,\, waste}` ) from HAC that account for inefficiencies in the heating and AC equipment and from energy lost in the conversion of primary energy sources to end use energy are derived from :ref:`Sivak (2013) `. These sources of waste heat are incorporated as modifications to the canyon energy budget. + +An explicit AC adoption parameterization for the BEM was developed for CLM6.0 (:ref:`Li et al. (2024) `). An AC adoption parameter is introduced (:math:`p_{AC}` ). The AC flux is first calculated under saturated AC adoption (i.e., :math:`p_{AC}=100%` ). The actual AC flux removed from the indoor air is then scaled based on :math:`p_{AC}` and the waste heat added to the urban canyon due to AC energy use is also scaled by :math:`p_{AC}`. A global, spatially explicit dataset for the AC adoption rate was developed at country- and sub-country-level from sources such as the International Energy Agency (IEA), national surveys, scientific literature, and others. For use with CLM, the AC adoption parameter was regridded to 0.9° latitude by 1.25° longitude and is read in for each of the three urban density classes using the file specified by the ``urbantv_streams`` namelist group (variables ``p_ac_MD``, ``p_ac_HD``, ``p_ac_TBD``). The maximum building interior temperature is also specified by the file in the ``urbantv_streams`` namelist group and is now considered to be the AC proxy setpoint in the parameterization and is set to 300K for all urban density classes (variables ``tbuildmax_MD``', ``tbuildmax_HD``, ``tbuildmax_TBD``). The explicit AC adoption parameterization in combination with the AC adoption rate dataset significantly improve CLM's performance in model building AC energy flux, both in magnitude and spatial variability (:ref:`Li et al. (2024) `). + +Global urban properties were originally developed by :ref:`Jackson et al. (2010) `. For each of 33 distinct regions across the globe and four urban density classes [tall building district (TBD), and high, medium, and low density (HD, MD, LD)], thermal (e.g., heat capacity and thermal conductivity), radiative (e.g., albedo and emissivity) and morphological (e.g., height to width ratio, roof fraction, average building height, and pervious fraction of the canyon floor) properties, are provided for each of the density classes. Building interior minimum and maximum temperatures are prescribed based on climate and socioeconomic considerations. As described in :ref:`Oleson and Feddema (2020) ` the urban properties dataset in :ref:`Jackson et al. (2010) ` was modified with respect to wall and roof thermal properties to correct for biases in heat transfer due to layer and building type averaging. Further changes to the dataset reflect the need for scenario development, thus allowing for the creation of hypothetical wall types, and the easier interchange of wall facets. This slightly modified dataset was an option in CLM5.0. + +The "raw" urban properties dataset used by the model is created from the urban properties tool which is available as part of the Toolbox for Human-Earth System Integration & Scaling (THESIS) tool set (https://github.com/NCAR/THESISUrbanPropertiesTool; :ref:`Oleson and Feddema (2020) `). The driver script (``urban_prop.csh``) specifies three input csv files (by default, ``mat_prop.csv``, ``lam_spec.csv``, and ``city_spec.csv``; (:numref:`Figure schematic of THESIS urban properties tool`)) that describe the morphological, radiative, and thermal properties of urban areas, plus the minimum building interior temperature, and generates a global dataset at 0.05° latitude by longitude in NetCDF format. This dataset, when combined with the urban extent data described below, is then ingested into the ``mksurfdata_esmf`` tool to create surface datasets at the desired spatial and temporal resolutions. + +Urban extent (circa-year 2000), defined for the four density classes, was originally provided by :ref:`Jackson et al. (2010) ` and derived from LandScan 2004, a population density dataset derived from census data, nighttime lights satellite observations, road proximity, and slope (:ref:`Dobson et al. 2000 `). Note that the LD class is not used in CLM because it is highly rural (dominated by vegetation) and better modeled as a vegetated/soil surface. This dataset was used for model versions CLM5.0 and earlier. A more up to date urban extent dataset was derived for use with CLM6.0 from a 0.05° urban landcover projection dataset (:ref:`Gao and O'Neill (2020) `) as described in :ref:`Fang et al. (2026) ` (code and auxiliary datasets available at https://figshare.com/s/4a890655b34498c1d082). The :ref:`Gao and O'Neill (2020) ` dataset provides global urban land cover for 2000-2100 in decadal intervals for a historical baseline (year 2000) and five CMIP6 ScenarioMIP Shared Socioeconomic Pathways (SSPs) at 0.05° resolution (2010-2100). Briefly, because the :ref:`Gao and O'Neill (2020) ` dataset only provides the data as a single urban class, the urban area in each grid cell is partitioned according to the ratio of the density types in that grid cell in the :ref:`Jackson et al. (2010) ` dataset. The decadal urban data are then linearly interpolated to generate annual urban data from 2015-2100. To provide data prior to 2015, the average urban fraction of the five SSP scenarios was calculated in 2010 and 2015. Then annual urban fraction from 2000 to 2014 were obtained by interpolating betwen urban fraction in the historical baseline year 2000, and average SSP years 2010 and 2015. Finally, due to a lack of historical data, data for 1850-1999 were simply copied from year 2000 data. The yearly :ref:`Gao and O'Neill (2020) ` historical and SSP datasets are available for an intermediate model version (CTSM5.3) at 0.05° resolution. -For each of 33 distinct regions across the globe, thermal (e.g., heat capacity and thermal conductivity), radiative (e.g., albedo and emissivity) and morphological (e.g., height to width ratio, roof fraction, average building height, and pervious fraction of the canyon floor) properties are provided for each of the density classes. Building interior minimum and maximum temperatures are prescribed based on climate and socioeconomic considerations. The surface dataset creation routines (see CLM5.0 User's Guide) aggregate the data to the desired resolution. +However, it was deemed desirable to create a dataset consistent with CMIP7 landcover change protocols. CMIP7 provides urban fraction at 0.25° resolution for 1700-2023. Again, since the dataset only provides the data as a single urban class, the urban area in each grid cell is partitioned according to the ratio of the density types in that grid cell in a year 2023 0.25° resolution version of the :ref:`Gao and O'Neill (2020) ` dataset created as described above. An exception is that the TBD class is not allowed before year 1900 as skyscrapers, etc. had not yet begun to be built. In that case, the urban fraction was split proportionally between the HD and MD classes. Datasets for future scenarios, i.e., 2024-, will be created similarly when CMIP7 data is available. -An optional urban properties dataset, including a tool that allows for generating future urban development scenarios is also available (:ref:`Oleson and Feddema (2018) `). This will become the default dataset in future model versions. As described in :ref:`Oleson and Feddema (2018) ` the urban properties dataset in :ref:`Jackson et al. (2010) ` was modified with respect to wall and roof thermal properties to correct for biases in heat transfer due to layer and building type averaging. Further changes to the dataset reflect the need for scenario development, thus allowing for the creation of hypothetical wall types, and the easier interchange of wall facets. The new urban properties tool is available as part of the Toolbox for Human-Earth System Integration & Scaling (THESIS) tool set (http://www.cgd.ucar.edu/iam/projects/thesis/thesis-urbanproperties-tool.html; :ref:`Feddema and Kauffman (2016) `). The driver script (urban_prop.csh) specifies three input csv files (by default, mat_prop.csv, lam_spec.csv, and city_spec.csv; (:numref:`Figure schematic of THESIS urban properties tool`)) that describe the morphological, radiative, and thermal properties of urban areas, and generates a global dataset at 0.05° latitude by longitude in NetCDF format (urban_properties_data.05deg.nc). A standalone NCL routine (gen_data_clm.ncl) can be run separately after the mksurfdata_esmf tool creates the CLM surface dataset. This creates a supplementary streams file of setpoints for the maximum interior building temperature at yearly time resolution. +To accomodate the transient urban datasets developed above, dynamic urban capability was implemented into the model as described in :ref:`Fang et al. (2026) ` in a manner similar to the implementation of other land cover transient datasets including ensuring conservation for total gridcell water and energy content. See Chapter :numref:`rst_Transient Landcover Change` for further details. .. Figure 12.1. Schematic representation of the urban land unit @@ -45,6 +57,4 @@ An optional urban properties dataset, including a tool that allows for generatin Schematic of THESIS urban properties tool. Executable scripts are in orange, input files are blue, and output files are green. Items within the black box outline are either read in as input, executed, or output by the driver script (urban_prop.csh). -The urban model that was first released as a component of CLM4.0 is separately described in the urban technical note (:ref:`Oleson et al. (2010b) `). The main changes in the urban model from CLM4.0 to CLM4.5 were 1) an expansion of the single urban landunit to up to three landunits per grid cell stratified by urban density types, 2) the number of urban layers for roofs and walls was no longer constrained to be equal to the number of ground layers, 3) space heating and air conditioning wasteheat factors were set to zero by default so that the user could customize these factors for their own application, 4) the elevation threshold used to eliminate urban areas in the surface dataset creation routines was increased from 2200 meters to 2600 meters, 5) hydrologic and thermal calculations for the pervious road followed CLM4.5 parameterizations. -The main changes in the urban model from CLM4.5 to CLM5.0 are 1) a more sophisticated and realistic building space heating and air conditioning submodel that prognoses interior building air temperature and includes more realistic space heating and air conditioning wasteheat factors (see above), 2) the maximum building temperature (which determines air conditioning demand) is now read in from a namelist-defined file which allows for dynamic control of this input variable. The maximum building temperatures that are defined in :ref:`Jackson et al. (2010) ` are implemented in year 1950 (thus air conditioning is off in prior years) and air conditioning is turned off in year 2100 (because the buildings are not suitable for air conditioning in some extreme global warming scenarios), 3) an optional updated urban properties dataset and new scenario tool. These features are described in more detail in :ref:`Oleson and Feddema (2018) `. In addition, a module of heat stress indices calculated online in the model that can be used to assess human thermal comfort for rural and urban areas has been added. This last development is described and evaluated by :ref:`Buzan et al. (2015) `. diff --git a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst index 5bb4dc9e40..2178baa32f 100644 --- a/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst +++ b/doc/source/tech_note/Vegetation_Phenology_Turnover/CLM50_Tech_Note_Vegetation_Phenology_Turnover.rst @@ -18,89 +18,89 @@ Fluxes of carbon and nitrogen from storage pools and into displayed tissue pools Example of annual phenology cycle for seasonal deciduous. -14.1.1 Onset Periods +Onset Periods ^^^^^^^^^^^^^^^^^^^^ -The deciduous phenology algorithms specify the occurrence of onset growth periods (Figure 14.1). Carbon fluxes from the transfer pools into displayed growth are calculated during these periods as: +The deciduous phenology algorithms specify the occurrence of onset growth periods (:numref:`Figure annual phenology cycle`). Carbon fluxes from the transfer pools into displayed growth are calculated during these periods as: .. math:: - :label: 20.1) + :label: C_transfer_leaf CF_{leaf\_ xfer,leaf} =r_{xfer\_ on} CS_{leaf\_ xfer} .. math:: - :label: 20.2) + :label: C_transfer_froot CF_{froot\_ xfer,froot} =r_{xfer\_ on} CS_{froot\_ xfer} .. math:: - :label: 20.3) + :label: C_transfer_livestem CF_{livestem\_ xfer,livestem} =r_{xfer\_ on} CS_{livestem\_ xfer} .. math:: - :label: 20.4) + :label: C_transfer_deadstem CF_{deadstem\_ xfer,deadstem} =r_{xfer\_ on} CS_{deadstem\_ xfer} .. math:: - :label: 20.5) + :label: C_transfer_livecroot CF_{livecroot\_ xfer,livecroot} =r_{xfer\_ on} CS_{livecroot\_ xfer} .. math:: - :label: 20.6) + :label: C_transfer_deadcroot CF_{deadcroot\_ xfer,deadcroot} =r_{xfer\_ on} CS_{deadcroot\_ xfer} , with corresponding nitrogen fluxes: .. math:: - :label: 20.7) + :label: N_transfer_leaf NF_{leaf\_ xfer,leaf} =r_{xfer\_ on} NS_{leaf\_ xfer} .. math:: - :label: 20.8) + :label: N_transfer_froot NF_{froot\_ xfer,froot} =r_{xfer\_ on} NS_{froot\_ xfer} .. math:: - :label: 20.9) + :label: N_transfer_livestem NF_{livestem\_ xfer,livestem} =r_{xfer\_ on} NS_{livestem\_ xfer} .. math:: - :label: 20.10) + :label: N_transfer_deadstem NF_{deadstem\_ xfer,deadstem} =r_{xfer\_ on} NS_{deadstem\_ xfer} .. math:: - :label: 20.11) + :label: N_transfer_livecroot NF_{livecroot\_ xfer,livecroot} =r_{xfer\_ on} NS_{livecroot\_ xfer} .. math:: - :label: 20.12) + :label: N_transfer_deadcroot NF_{deadcroot\_ xfer,deadcroot} =r_{xfer\_ on} NS_{deadcroot\_ xfer} , where CF is the carbon flux, CS is stored carbon, NF is the nitrogen flux, NS is stored nitrogen, :math:`{r}_{xfer\_on}` (s\ :sup:`-1`) is a time-varying rate coefficient controlling flux out of the transfer pool: .. math:: - :label: ZEqnNum852972 + :label: onset_rate_coeff r_{xfer\_ on} =\left\{\begin{array}{l} {{2\mathord{\left/ {\vphantom {2 t_{onset} }} \right.} t_{onset} } \qquad {\rm for\; }t_{onset} \ne \Delta t} \\ {{1\mathord{\left/ {\vphantom {1 \Delta t}} \right.} \Delta t} \qquad {\rm for\; }t_{onset} =\Delta t} \end{array}\right. -and *t*\ :sub:`onset` (s) is the number of seconds remaining in the current phenology onset growth period (Figure 14.1). The form of Eq. :eq:`ZEqnNum852972` produces a flux from the transfer pool which declines linearly over the onset growth period, approaching zero flux in the final timestep. +and *t*\ :sub:`onset` (s) is the number of seconds remaining in the current phenology onset growth period (:numref:`Figure annual phenology cycle`). The form of Eq. :eq:`onset_rate_coeff` produces a flux from the transfer pool which declines linearly over the onset growth period, approaching zero flux in the final timestep. -14.1.2 Offset Periods +Offset Periods ^^^^^^^^^^^^^^^^^^^^^ The deciduous phenology algorithms also specify the occurrence of litterfall during offset periods. In contrast to the onset periods, only leaf and fine root state variables are subject to litterfall fluxes. Carbon fluxes from display pools into litter are calculated during these periods as: .. math:: - :label: 20.14) + :label: C_litterfall_leaf CF_{leaf,litter}^{n} =\left\{\begin{array}{l} {CF_{leaf,litter}^{n-1} + r_{xfer\_ off} \left(CS_{leaf} -CF_{leaf,litter}^{n-1} {\kern 1pt} t_{offset} \right)\qquad {\rm for\; }t_{offset} \ne \Delta t} \\ {\left({CS_{leaf} \mathord{\left/ {\vphantom {CS_{leaf} \Delta t}} \right.} \Delta t} \right) @@ -108,137 +108,137 @@ The deciduous phenology algorithms also specify the occurrence of litterfall dur +CF_{alloc,leaf} \qquad {\rm for\; }t_{offset} =\Delta t} \end{array}\right. .. math:: - :label: 20.15) + :label: C_litterfall_froot CF_{froot,litter}^{n} =\left\{\begin{array}{l} {CF_{froot,litter}^{n-1} + r_{xfer\_ off} \left(CS_{froot} -CF_{froot,litter}^{n-1} {\kern 1pt} t_{offset} \right)\qquad {\rm for\; }t_{offset} \ne \Delta t} \\ {\left({CS_{froot} \mathord{\left/ {\vphantom {CS_{froot} \Delta t}} \right.} \Delta t} \right)+CF_{alloc,\, froot} \qquad \qquad \qquad {\rm for\; }t_{offset} =\Delta t} \end{array}\right. .. math:: - :label: 20.16) + :label: rate_coeff_offset r_{xfer\_ off} =\frac{2\Delta t}{t_{offset} ^{2} } -where superscripts *n* and *n-1* refer to fluxes on the current and previous timesteps, respectively. The rate coefficient :math:`{r}_{xfer\_off}` varies with time to produce a linearly increasing litterfall rate throughout the offset period. The :math:`biofuel\_harvfrac` (:numref:`Harvest to food and seed`) is the harvested fraction of aboveground biomass (leaf & livestem) for bioenergy crops. The special case for fluxes in the final litterfall timestep (:math:`{t}_{offset}` = :math:`\Delta t`\ ) ensures that all of the displayed growth is sent to the litter pools or biofuel feedstock pools. The fraction (:math:`biofuel\_harvfrac`) of leaf biomass going to the biofuel feedstock pools (Equation :eq:`25.9`) is defined in Table 26.3 and is only non-zero for prognostic crops. The remaining fraction of leaf biomass (:math:`1-biofuel\_harvfrac`) for deciduous plant types is sent to the litter pools. Similar modifications made for livestem carbon pools for prognostic crops can be found in section :numref:`Harvest to food and seed` in Equations :eq:`25.9`-:eq:`25.14`. +where superscripts *n* and *n-1* refer to fluxes on the current and previous timesteps, respectively. The rate coefficient :math:`{r}_{xfer\_off}` varies with time to produce a linearly increasing litterfall rate throughout the offset period. The *biofuel_harvfrac* (:numref:`Harvest to food and seed`) is the harvested fraction of aboveground biomass (leaf & livestem) for bioenergy crops. The special case for fluxes in the final litterfall timestep (:math:`{t}_{offset}` = :math:`\Delta t`\ ) ensures that all of the displayed growth is sent to the litter pools or biofuel feedstock pools. The fraction (*biofuel_harvfrac*) of leaf biomass going to the biofuel feedstock pools is an adjustable parameter and is only non-zero for prognostic crops (Equation :eq:`25.9`). The remaining fraction of leaf biomass (*1-biofuel_harvfrac*) for deciduous plant types is sent to the litter pools. Similar modifications made for livestem carbon pools for prognostic crops can be found in section :numref:`Harvest to food and seed` in Equations :eq:`25.9`-:eq:`25.14`. Corresponding nitrogen fluxes during litterfall take into account retranslocation of nitrogen out of the displayed leaf pool prior to litterfall (:math:`{NF}_{leaf,retrans}`, gN m\ :sup:`-2` s\ :sup:`-1`). Retranslocation of nitrogen out of fine roots is assumed to be negligible. The fluxes are: .. math:: - :label: 20.17) + :label: N_litterfall_leaf NF_{leaf,litter} ={CF_{leaf,litter} \mathord{\left/ {\vphantom {CF_{leaf,litter} CN_{leaf\_ litter} }} \right.} CN_{leaf\_ litter} } .. math:: - :label: 20.18) + :label: N_litterfall_froot NF_{froot,litter} ={CF_{leaf,litter} \mathord{\left/ {\vphantom {CF_{leaf,litter} CN_{froot} }} \right.} CN_{froot} } .. math:: - :label: 20.19) + :label: N_retranslocation_leaf NF_{leaf,retrans} =\left({CF_{leaf,litter} \mathord{\left/ {\vphantom {CF_{leaf,litter} CN_{leaf} }} \right.} CN_{leaf} } \right)-NF_{leaf,litter} . where CN is C:N. -14.1.3 Background Onset Growth +Background Onset Growth ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The stress-deciduous phenology algorithm includes a provision for the case when stress signals are absent, and the vegetation shifts from a deciduous habit to an evergreen habit, until the next occurrence of an offset stress trigger. In that case, the regular onset flux mechanism is switched off and a background onset growth algorithm is invoked (:math:`{r}_{bgtr} > 0`). During this period, small fluxes of carbon and nitrogen from the storage pools into the associated transfer pools are calculated on each time step, and the entire contents of the transfer pool are added to the associated displayed growth pool on each time step. The carbon fluxes from transfer to display pools under these conditions are: .. math:: - :label: 20.20) + :label: C_transfer_leaf_BGonset CF_{leaf\_ xfer,leaf} ={CS_{leaf\_ xfer} \mathord{\left/ {\vphantom {CS_{leaf\_ xfer} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.21) + :label: C_transfer_froot_BGonset CF_{froot\_ xfer,froot} ={CS_{froot\_ xfer} \mathord{\left/ {\vphantom {CS_{froot\_ xfer} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.22) + :label: C_transfer_livestem_BGonset CF_{livestem\_ xfer,livestem} ={CS_{livestem\_ xfer} \mathord{\left/ {\vphantom {CS_{livestem\_ xfer} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.23) + :label: C_transfer_deadstem_BGonset CF_{deadstem\_ xfer,deadstem} ={CS_{deadstem\_ xfer} \mathord{\left/ {\vphantom {CS_{deadstem\_ xfer} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.24) + :label: C_transfer_livecroot_BGonset CF_{livecroot\_ xfer,livecroot} ={CS_{livecroot\_ xfer} \mathord{\left/ {\vphantom {CS_{livecroot\_ xfer} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.25) + :label: C_transfer_deadcroot_BGonset CF_{deadcroot\_ xfer,deadcroot} ={CS_{deadcroot\_ xfer} \mathord{\left/ {\vphantom {CS_{deadcroot\_ xfer} \Delta t}} \right.} \Delta t} , and the corresponding nitrogen fluxes are: .. math:: - :label: 20.26) + :label: N_transfer_leaf_BGonset NF_{leaf\_ xfer,leaf} ={NS_{leaf\_ xfer} \mathord{\left/ {\vphantom {NS_{leaf\_ xfer} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.27) + :label: N_transfer_froot_BGonset NF_{froot\_ xfer,froot} ={NS_{froot\_ xfer} \mathord{\left/ {\vphantom {NS_{froot\_ xfer} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.28) + :label: N_transfer_livestem_BGonset NF_{livestem\_ xfer,livestem} ={NS_{livestem\_ xfer} \mathord{\left/ {\vphantom {NS_{livestem\_ xfer} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.29) + :label: N_transfer_deadstem_BGonset NF_{deadstem\_ xfer,deadstem} ={NS_{deadstem\_ xfer} \mathord{\left/ {\vphantom {NS_{deadstem\_ xfer} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.30) + :label: N_transfer_livecroot_BGonset NF_{livecroot\_ xfer,livecroot} ={NS_{livecroot\_ xfer} \mathord{\left/ {\vphantom {NS_{livecroot\_ xfer} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.31) + :label: N_transfer_deadcroot_BGonset NF_{deadcroot\_ xfer,deadcroot} ={NS_{deadcroot\_ xfer} \mathord{\left/ {\vphantom {NS_{deadcroot\_ xfer} \Delta t}} \right.} \Delta t} . -14.1.4 Background Litterfall +Background Litterfall ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Both evergreen and stress-deciduous phenology algorithms can specify a litterfall flux that is not associated with a specific offset period, but which occurs instead at a slow rate over an extended period of time, referred to as background litterfall. For evergreen types the background litterfall is the only litterfall flux. For stress-deciduous types either the offset period litterfall or the background litterfall mechanism may be active, but not both at once. Given a specification of the background litterfall rate (:math:`{r}_{bglf}`, s\ :sup:`-1`), litterfall carbon fluxes are calculated as .. math:: - :label: 20.32) + :label: C_BGlitter_leaf CF_{leaf,litter} =r_{bglf} CS_{leaf} .. math:: - :label: 20.33) + :label: C_BGlitter_froot CS_{froot,litter} =r_{bglf} CS_{froot} , with corresponding nitrogen litterfall and retranslocation fluxes: .. math:: - :label: 20.34) + :label: N_BGlitter_leaf NF_{leaf,litter} ={CF_{leaf,litter} \mathord{\left/ {\vphantom {CF_{leaf,litter} CN_{leaf\_ litter} }} \right.} CN_{leaf\_ litter} } .. math:: - :label: 20.35) + :label: N_BGlitter_froot NF_{froot,litter} ={CF_{froot,litter} \mathord{\left/ {\vphantom {CF_{froot,litter} CN_{froot} }} \right.} CN_{froot} } .. math:: - :label: 20.36) + :label: N_BGretranslocation_leaf NF_{leaf,retrans} =\left({CF_{leaf,litter} \mathord{\left/ {\vphantom {CF_{leaf,litter} CN_{leaf} }} \right.} CN_{leaf} } \right)-NF_{leaf,litter} . -14.1.5 Livewood Turnover +Livewood Turnover ^^^^^^^^^^^^^^^^^^^^^^^^ The conceptualization of live wood vs. dead wood fractions for stem and coarse root pools is intended to capture the difference in maintenance respiration rates between these two physiologically distinct tissue types. Unlike displayed pools for leaf and fine root, which are lost to litterfall, live wood cells reaching the end of their lifespan are retained as a part of the dead woody structure of stems and coarse roots. A mechanism is therefore included in the phenology routine to effect the transfer of live wood to dead wood pools, which also takes into account the different nitrogen concentrations typical of these tissue types. @@ -246,225 +246,231 @@ The conceptualization of live wood vs. dead wood fractions for stem and coarse r A live wood turnover rate (:math:`{r}_{lwt}`, s\ :sup:`-1`) is defined as .. math:: - :label: 20.37) + :label: live_wood_turnover_rate r_{lwt} ={p_{lwt} \mathord{\left/ {\vphantom {p_{lwt} \left(365\cdot 86400\right)}} \right.} \left(365\cdot 86400\right)} where :math:`{p}_{lwt} = 0.7` is the assumed annual live wood turnover fraction. Carbon fluxes from live to dead wood pools are: .. math:: - :label: 20.38) + :label: Cflux_live2dead_stem CF_{livestem,deadstem} =CS_{livestem} r_{lwt} .. math:: - :label: 20.39) + :label: Cflux_live2dead_croot CF_{livecroot,deadcroot} =CS_{livecroot} r_{lwt} , and the associated nitrogen fluxes, including retranslocation of nitrogen out of live wood during turnover, are: .. math:: - :label: 20.40) + :label: Nflux_live2dead_stem NF_{livestem,deadstem} ={CF_{livestem,deadstem} \mathord{\left/ {\vphantom {CF_{livestem,deadstem} CN_{dw} }} \right.} CN_{dw} } .. math:: - :label: 20.41) + :label: Nflux_livestem_retranslocation NF_{livestem,retrans} =\left({CF_{livestem,deadstem} \mathord{\left/ {\vphantom {CF_{livestem,deadstem} CN_{lw} }} \right.} CN_{lw} } \right)-NF_{livestem,deadstem} .. math:: - :label: 20.42) + :label: Nflux_live2dead_croot NF_{livecroot,deadcroot} ={CF_{livecroot,deadcroot} \mathord{\left/ {\vphantom {CF_{livecroot,deadcroot} CN_{dw} }} \right.} CN_{dw} } .. math:: - :label: 20.43) + :label: Nflux_livecroot_retranslocation NF_{livecroot,retrans} =\left({CF_{livecroot,deadcroot} \mathord{\left/ {\vphantom {CF_{livecroot,deadcroot} CN_{lw} }} \right.} CN_{lw} } \right)-NF_{livecroot,deadcroot} . Evergreen Phenology ------------------------ -The evergreen phenology algorithm is by far the simplest of the three possible types. It is assumed for all evergreen types that all carbon and nitrogen allocated for new growth in the current timestep goes immediately to the displayed growth pools (i.e. f\ :math:`{f}_{cur} = 1.0` (Chapter 13)). As such, there is never an accumulation of carbon or nitrogen in the storage or transfer pools, and so the onset growth and background onset growth mechanisms are never invoked for this type. Litterfall is specified to occur only through the background litterfall mechanism – there are no distinct periods of litterfall for evergreen types, but rather a continuous (slow) shedding of foliage and fine roots. This is an obvious area for potential improvements in the model, since it is known, at least for evergreen needleleaf trees in the temperate and boreal zones, that there are distinct periods of higher and lower leaf litterfall (Ferrari, 1999; Gholz et al., 1985). The rate of background litterfall (:math:`{r}_{bglf}`, section 14.1.4) depends on the specified leaf longevity (:math:`\tau_{leaf}`\, y), as +The evergreen phenology algorithm is by far the simplest of the three possible types. It is assumed for all evergreen types that all carbon and nitrogen allocated for new growth in the current timestep goes immediately to the displayed growth pools (i.e. :math:`{f}_{cur} = 1.0`). As such, there is never an accumulation of carbon or nitrogen in the storage or transfer pools, and so the onset growth and background onset growth mechanisms are never invoked for this type. Litterfall is specified to occur only through the background litterfall mechanism – there are no distinct periods of litterfall for evergreen types, but rather a continuous (slow) shedding of foliage and fine roots. This is an obvious area for potential improvements in the model, since it is known, at least for evergreen needleleaf trees in the temperate and boreal zones, that there are distinct periods of higher and lower leaf litterfall (:ref:`Ferrari, 1999`; :ref:`Gholz et al., 1985)`. The rate of background litterfall (:math:`{r}_{bglf}`) depends on the specified leaf longevity (:math:`\tau_{leaf}`\, y), as .. math:: - :label: 20.44) + :label: BG_litterfall_rate r_{bglf} =\frac{1}{\tau _{leaf} \cdot 365\cdot 86400} . Seasonal-Deciduous Phenology --------------------------------- -The seasonal-deciduous phenology algorithm derives directly from the treatment used in the offline model Biome-BGC v. 4.1.2, (Thornton et al., 2002), which in turn is based on the parameterizations for leaf onset and offset for temperate deciduous broadleaf forest from White et al. (1997). Initiation of leaf onset is triggered when a common degree-day summation exceeds a critical value, and leaf litterfall is initiated when daylength is shorter than a critical value. Because of the dependence on daylength, the seasonal deciduous phenology algorithm is only valid for latitudes outside of the tropical zone, defined here as :math:`\left|{\rm latitude}\right|>19.5{\rm {}^\circ }`. Neither the background onset nor background litterfall mechanism is invoked for the seasonal-deciduous phenology algorithm. The algorithm allows a maximum of one onset period and one offset period each year. +The seasonal-deciduous phenology algorithm derives directly from the treatment used in Biome-BGC v. 4.1.2, :ref:`(Thornton et al., 2002)`, which in turn is based on the parameterizations for leaf onset and offset for temperate deciduous broadleaf forest from :ref:`(White et al., 1997)`. Initiation of leaf onset is triggered when a common degree-day summation exceeds a critical value, and leaf litterfall is initiated when daylength is shorter than a critical value. Because of the dependence on daylength, the seasonal deciduous phenology algorithm is only valid for latitudes outside of the tropical zone, defined here as :math:`\left|{\rm latitude}\right|>19.5{\rm {}^\circ }`. For high latitudes, onset and offset are modified following :ref:`Birch et al. (2021)` where onset is governed by more mechanistic environmental thresholds (soil temperature, air temperature, and snowpack) and the photoperiod threshold for offset is increased. Neither the background onset nor background litterfall mechanism is invoked for the seasonal-deciduous phenology algorithm. The algorithm allows a maximum of one onset period and one offset period each year. The algorithms for initiation of onset and offset periods use the winter and summer solstices as coordination signals. The period between winter and summer solstice is identified as :math:`{dayl}_{n} > {dayl}_{n-1}`, and the period between summer and winter solstice is identified as :math:`{dayl}_{n} < {dayl}_{n-1}`, where :math:`{dayl}_{n}` and :math:`{dayl}_{n-1}` are the day length(s) calculated for the current and previous timesteps, respectively, using .. math:: - :label: 20.45) + :label: day_length dayl=2\cdot 13750.9871\cdot acos\left(\frac{-\sin (lat)\sin (decl)}{\cos (lat)\cos (decl)} \right), where *lat* and *decl* are the latitude and solar declination (radians), respectively, and the factor 13750.9871 is the number of seconds per radian of hour-angle. -14.3.1 Seasonal-Deciduous Onset Trigger +Seasonal-Deciduous Onset Trigger ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The onset trigger for the seasonal-deciduous phenology algorithm is based on an accumulated growing-degree-day approach (White et al., 1997). The growing-degree-day summation (:math:`{GDD}_{sum}`) is initiated ( :math:`{GDD}_{sum} = 0`) when the phenological state is dormant and the model timestep crosses the winter solstice. Once these conditions are met, :math:`{GDD}_{sum}` is updated on each timestep as +The onset trigger for the seasonal-deciduous phenology algorithm is based on an accumulated growing-degree-day approach :ref:`(White et al., 1997)` with modifications for boreal and arctic plants :ref:`(Birch et al. 2021)`. The growing-degree-day summation (:math:`{GDD}_{sum}`) is initiated ( :math:`{GDD}_{sum} = 0`) when the phenological state is dormant and the model timestep crosses the winter solstice. Once these conditions are met, :math:`{GDD}_{sum}` is updated on each timestep as .. math:: - :label: ZEqnNum510730 + :label: GDDsum_update - GDD_{sum}^{n} =\left\{\begin{array}{l} {GDD_{sum}^{n-1} +\left(T_{s,3} -TKFRZ\right)f_{day} \qquad {\rm for\; }T_{s,3} >TKFRZ} \\ {GDD_{sum}^{n-1} \qquad \qquad \qquad {\rm for\; }T_{s,3} \le TKFRZ} \end{array}\right. + GDD_{sum}^{n} =\left\{\begin{array}{l} {GDD_{sum}^{n-1} +\left(T_{s,l} -TKFRZ\right)f_{day} \qquad {\rm for\; }T_{s,l} >TKFRZ} \\ {GDD_{sum}^{n-1} \qquad \qquad \qquad {\rm for\; }T_{s,l} \le TKFRZ} \end{array}\right. -where :math:`{T}_{s,3}` (K) is the temperature of the third soil layer, and :math:`f_{day} ={\Delta t\mathord{\left/ {\vphantom {\Delta t 86400}} \right.} 86400}`. The onset period is initiated if :math:`GDD_{sum} >GDD_{sum\_ crit}`, where +where :math:`{T}_{s,l}` (K) is the temperature of the soil layer prescribed by the *phenology_soil_depth* parameter (default is layer 3), and :math:`f_{day} ={\Delta t\mathord{\left/ {\vphantom {\Delta t 86400}} \right.} 86400}`. The onset period is initiated if :math:`GDD_{sum} >GDD_{sum\_ crit}`, where .. math:: - :label: ZEqnNum598907 + :label: GDDsum_crit - GDD_{sum\_ crit} =\exp \left(4.8+0.13{\kern 1pt} \left(T_{2m,ann\_ avg} -TKFRZ\right)\right) + GDD_{sum\_ crit} =sf\cdot \exp \left(4.8+0.13{\kern 1pt} \left(T_{2m,ann\_ avg} -TKFRZ\right)\right) -and where :math:`{T}_{2m,ann\_avg}` (K) is the annual average of the 2m air temperature, and TKFRZ is the freezing point of water (273.15 K). The following control variables are set when a new onset growth period is initiated: +and where *sf* is a tunable scaling parameter (*crit_onset_gdd_sf=1*), :math:`{T}_{2m,ann\_avg}` (K) is the annual average of the 2m air temperature, and TKFRZ is the freezing point of water (273.15 K). + +For boreal and arctic seasonal-deciduous plants, the spring onset environmental criteria is modified based on :ref:`Birch et al. (2021)`. Onset is initiated when all three of the following criteria are met: the 10-day average soil temperature at *phenology_soil_depth* exceeds :math:`0^\circ C`, the 5-day average 2 m air temperature exceeds :math:`0^\circ C`, and the 5-day snow depth falls below a threshold (*snow5d_thresh_for_onset = 0.2 m*). + +The following control variables are set when a new onset growth period is initiated: .. math:: - :label: 20.48) + :label: GDDsum_reset GDD_{sum} =0 .. math:: - :label: 20.49) + :label: Tonset_reset t_{onset} =86400\cdot n_{days\_ on} , -where :math:`{n}_{days\_on}` is set to a constant value of 30 days. Fluxes from storage into transfer pools occur in the timestep when a new onset growth period is initiated. Carbon fluxes are: +where :math:`{n}_{days\_on}` is a parameter with default value of 30 days. Fluxes from storage into transfer pools occur in the timestep when a new onset growth period is initiated. Carbon fluxes are: .. math:: - :label: ZEqnNum904388 + :label: Cflux_stor2xfer_leaf CF_{leaf\_ stor,leaf\_ xfer} ={f_{stor,xfer} CS_{leaf\_ stor} \mathord{\left/ {\vphantom {f_{stor,xfer} CS_{leaf\_ stor} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.51) + :label: Cflux_stor2xfer_froot CF_{froot\_ stor,froot\_ xfer} ={f_{stor,xfer} CS_{froot\_ stor} \mathord{\left/ {\vphantom {f_{stor,xfer} CS_{froot\_ stor} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.52) + :label: Cflux_stor2xfer_livestem CF_{livestem\_ stor,livestem\_ xfer} ={f_{stor,xfer} CS_{livestem\_ stor} \mathord{\left/ {\vphantom {f_{stor,xfer} CS_{livestem\_ stor} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.53) + :label: Cflux_stor2xfer_deadstem CF_{deadstem\_ stor,deadstem\_ xfer} ={f_{stor,xfer} CS_{deadstem\_ stor} \mathord{\left/ {\vphantom {f_{stor,xfer} CS_{deadstem\_ stor} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.54) + :label: Cflux_stor2xfer_livecroot CF_{livecroot\_ stor,livecroot\_ xfer} ={f_{stor,xfer} CS_{livecroot\_ stor} \mathord{\left/ {\vphantom {f_{stor,xfer} CS_{livecroot\_ stor} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.55) + :label: Cflux_stor2xfer_deadcroot CF_{deadcroot\_ stor,deadcroot\_ xfer} ={f_{stor,xfer} CS_{deadcroot\_ stor} \mathord{\left/ {\vphantom {f_{stor,xfer} CS_{deadcroot\_ stor} \Delta t}} \right.} \Delta t} .. math:: - :label: ZEqnNum195642 + :label: Cflux_stor2xfer_gresp CF_{gresp\_ stor,gresp\_ xfer} ={f_{stor,xfer} CS_{gresp\_ stor} \mathord{\left/ {\vphantom {f_{stor,xfer} CS_{gresp\_ stor} \Delta t}} \right.} \Delta t} and the associated nitrogen fluxes are: .. math:: - :label: ZEqnNum812152 + :label: Nflux_stor2xfer_leaf NF_{leaf\_ stor,leaf\_ xfer} ={f_{stor,xfer} NS_{leaf\_ stor} \mathord{\left/ {\vphantom {f_{stor,xfer} NS_{leaf\_ stor} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.58) + :label: Nflux_stor2xfer_froot NF_{froot\_ stor,froot\_ xfer} ={f_{stor,xfer} NS_{froot\_ stor} \mathord{\left/ {\vphantom {f_{stor,xfer} NS_{froot\_ stor} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.59) + :label: Nflux_stor2xfer_livestem NF_{livestem\_ stor,livestem\_ xfer} ={f_{stor,xfer} NS_{livestem\_ stor} \mathord{\left/ {\vphantom {f_{stor,xfer} NS_{livestem\_ stor} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.60) + :label: Nflux_stor2xfer_deadstem NF_{deadstem\_ stor,deadstem\_ xfer} ={f_{stor,xfer} NS_{deadstem\_ stor} \mathord{\left/ {\vphantom {f_{stor,xfer} NS_{deadstem\_ stor} \Delta t}} \right.} \Delta t} .. math:: - :label: 20.61) + :label: Nflux_stor2xfer_livecroot NF_{livecroot\_ stor,livecroot\_ xfer} ={f_{stor,xfer} NS_{livecroot\_ stor} \mathord{\left/ {\vphantom {f_{stor,xfer} NS_{livecroot\_ stor} \Delta t}} \right.} \Delta t} .. math:: - :label: ZEqnNum605338 + :label: Nflux_stor2xfer_deadcroot NF_{deadcroot\_ stor,deadcroot\_ xfer} ={f_{stor,xfer} NS_{deadcroot\_ stor} \mathord{\left/ {\vphantom {f_{stor,xfer} NS_{deadcroot\_ stor} \Delta t}} \right.} \Delta t} where :math:`{f}_{stor,xfer}` is the fraction of current storage pool moved into the transfer pool for display over the incipient onset period. This fraction is set to 0.5, based on the observation that seasonal deciduous trees are capable of replacing their canopies from storage reserves in the event of a severe early-season disturbance such as frost damage or defoliation due to insect herbivory. -If the onset criterion (:math:`{GDD}_{sum} > {GDD}_{sum\_crit}`) is not met before the summer solstice, then :math:`{GDD}_{sum}` is set to 0.0 and the growing-degree-day accumulation will not start again until the following winter solstice. This mechanism prevents the initiation of very short growing seasons late in the summer in cold climates. The onset counter is decremented on each time step after initiation of the onset period, until it reaches zero, signaling the end of the onset period: +If the onset criteria are not met before the summer solstice, then :math:`{GDD}_{sum}` is set to 0.0 and the growing-degree-day accumulation will not start again until the following winter solstice. This mechanism prevents the initiation of very short growing seasons late in the summer in cold climates. The onset counter is decremented on each time step after initiation of the onset period, until it reaches zero, signaling the end of the onset period: .. math:: - :label: 20.63) + :label: t_onset_decrement - t_{onfset}^{n} =t_{onfset}^{n-1} -\Delta t + t_{onset}^{n} =t_{onset}^{n-1} -\Delta t -14.3.2 Seasonal-Deciduous Offset Trigger +Seasonal-Deciduous Offset Trigger ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -After the completion of an onset period, and once past the summer solstice, the offset (litterfall) period is triggered when daylength is shorter than 39300 s. The offset counter is set at the initiation of the offset period: :math:`t_{offset} =86400\cdot n_{days\_ off}`, where :math:`{n}_{days\_off}` is set to a constant value of 15 days. The offset counter is decremented on each time step after initiation of the offset period, until it reaches zero, signaling the end of the offset period: +After the completion of an onset period, and once past the summer solstice, the offset (litterfall) period is triggered when daylength is shorter than 11 h. The offset counter is set at the initiation of the offset period: :math:`t_{offset} =86400\cdot n_{days\_ off}`, where :math:`{n}_{days\_off}` is a constant parameter with default value of 15 days. The offset counter is decremented on each time step after initiation of the offset period, until it reaches zero, signaling the end of the offset period: .. math:: - :label: 20.64) + :label: t_offset_decrement t_{offset}^{n} =t_{offset}^{n-1} -\Delta t +At high latitudes, :math:`\left|{\rm latitude}\right|>65{\rm {}^\circ }`, a more accurate timing for senescence is a daylength of 15 h :ref:`Eitel et al., (2019)`. As in :ref:`Birch et al., (2021)`, the daylength threshold is set to 15 h above :math:`65{\rm {}^\circ }` and scaled linearly along a latitudinal gradient to :math:`45{\rm {}^\circ }`. + Stress-Deciduous Phenology ------------------------------- -The stress-deciduous phenology algorithm was developed specifically for the CLM based in part on the grass phenology model proposed by White et al. (1997). The algorithm handles phenology for vegetation types such as grasses and tropical drought-deciduous trees that respond to both cold and drought-stress signals, and that can have multiple growing seasons per year. The algorithm also allows for the possibility that leaves might persist year-round in the absence of a suitable stress trigger. In that case the phenology switches to an evergreen habit, maintaining a marginally-deciduous leaf longevity (one year) until the occurrence of the next stress trigger. +The stress-deciduous phenology algorithm was developed specifically for the CLM based in part on the grass phenology model proposed by :ref:`(White et al., 1997)`. The algorithm handles phenology for vegetation types such as grasses and tropical drought-deciduous trees that respond to both cold and drought-stress signals, and that can have multiple growing seasons per year. The algorithm also allows for the possibility that leaves might persist year-round in the absence of a suitable stress trigger. In that case the phenology switches to an evergreen habit, maintaining a marginally-deciduous leaf longevity (one year) until the occurrence of the next stress trigger. -14.4.1 Stress-Deciduous Onset Triggers +Stress-Deciduous Onset Triggers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In climates that are warm year-round, onset triggering depends on soil water availability. At the beginning of a dormant period (end of previous offset period), an accumulated soil water index (:math:`{SWI}_{sum}`, d) is initialized (:math:`{SWI}_{sum} = 0`), with subsequent accumulation calculated as: .. math:: - :label: ZEqnNum503826 + :label: soil_water_index_accumulation SWI_{sum}^{n} =\left\{\begin{array}{l} {SWI_{sum}^{n-1} +f_{day} \qquad {\rm for\; }\Psi _{s,3} \ge \Psi _{onset} } \\ {SWI_{sum}^{n-1} \qquad \qquad {\rm for\; }\Psi _{s,3} <\Psi _{onset} } \end{array}\right. -where :math:`\Psi`\ :sub:`s,3` is the soil water potential (MPa) in the third soil layer and :math:`{\Psi}_{onset} = -0.6 MPa` is the onset soil water potential threshold. Onset triggering is possible once :math:`{SWI}_{sum} > 15`. To avoid spurious onset triggering due to soil moisture in the third soil layer exceeding the threshold due only to soil water suction of water from deeper in the soil column, an additional precipitation trigger is included which requires at least 20 mm of rain over the previous 10 days :ref:`(Dahlin et al., 2015) `. If the cold climate growing degree-day accumulator is not active at the time when the soil moisture and precipitation thresholds are reached (see below), and if the daylength is greater than 6 hours, then onset is triggered. Except as noted below, :math:`{SWI}_{sum}` continues to accumulate according to Eq. :eq:`ZEqnNum503826` during the dormant period if the daylength criterion prevents onset triggering, and onset is then triggered at the timestep when daylength exceeds 6 hours. +where :math:`\Psi`\ :sub:`s,3` is the soil water potential (MPa) in the third soil layer and :math:`{\Psi}_{onset} = -0.6 MPa` is the onset soil water potential threshold. Onset triggering is possible once :math:`{SWI}_{sum} > 15`. To avoid spurious onset triggering due to soil moisture in the third soil layer exceeding the threshold due only to soil water suction of water from deeper in the soil column, an additional precipitation trigger is included which requires at least 20 mm of rain over the previous 10 days :ref:`(Dahlin et al., 2015) `. If the cold climate growing degree-day accumulator is not active at the time when the soil moisture and precipitation thresholds are reached (see below), and if the daylength is greater than 6 hours, then onset is triggered. Except as noted below, :math:`{SWI}_{sum}` continues to accumulate according to Eq. :eq:`soil_water_index_accumulation` during the dormant period if the daylength criterion prevents onset triggering, and onset is then triggered at the timestep when daylength exceeds 6 hours. In climates with a cold season, onset triggering depends on both accumulated soil temperature summation and adequate soil moisture. At the beginning of a dormant period a freezing day accumulator (:math:`{FD}_{sum}`, d) is initialized (:math:`{FD}_{sum} = 0`), with subsequent accumulation calculated as: .. math:: - :label: 20.66) + :label: freezing_day_accumulation FD_{sum}^{n} =\left\{\begin{array}{l} {FD_{sum}^{n-1} +f_{day} \qquad {\rm for\; }T_{s,3} >TKFRZ} \\ {FD_{sum}^{n-1} \qquad \qquad {\rm for\; }T_{s,3} \le TKFRZ} \end{array}\right. . -If :math:`{FD}_{sum} > 15` during the dormant period, then a cold-climate onset triggering criterion is introduced, following exactly the growing degree-day summation (:math:`{GDD}_{sum}`) logic of Eqs. :eq:`ZEqnNum510730` and :eq:`ZEqnNum598907`. At that time :math:`{SWI}_{sum}` is reset (:math:`{SWI}_{sum} = 0`). Onset triggering under these conditions depends on meeting all three of the following criteria: :math:`{SWI}_{sum} > 15`, :math:`{GDD}_{sum} > {GDD}_{sum\_crit}`, and daylength greater than 6 hrs. +If :math:`{FD}_{sum} > 15` during the dormant period, then a cold-climate onset triggering criterion is introduced, following exactly the growing degree-day summation (:math:`{GDD}_{sum}`) logic of Eqs. :eq:`GDDsum_update` and :eq:`GDDsum_crit`. At that time :math:`{SWI}_{sum}` is reset (:math:`{SWI}_{sum} = 0`). Onset triggering under these conditions depends on meeting all three of the following criteria: :math:`{SWI}_{sum} > 15`, :math:`{GDD}_{sum} > {GDD}_{sum\_crit}`, and daylength greater than 6 hrs. -The following control variables are set when a new onset growth period is initiated: :math:`{SWI}_{sum} = 0`, :math:`{FD}_{sum} = 0`, :math:`{GDD}_{sum} = 0`, :math:`{n}_{days\_active} = 0`, and :math:`t_{onset} = 86400\cdot n_{days\_ on}`, where :math:`{n}_{days\_on}` is set to a constant value of 30 days. Fluxes from storage into transfer pools occur in the timestep when a new onset growth period is initiated, and are handled identically to Eqs. :eq:`ZEqnNum904388` -:eq:`ZEqnNum195642` for carbon fluxes, and to Eqs. :eq:`ZEqnNum812152` - :eq:`ZEqnNum605338` for nitrogen fluxes. The onset counter is decremented on each time step after initiation of the onset period, until it reaches zero, signaling the end of the onset period: +The following control variables are set when a new onset growth period is initiated: :math:`{SWI}_{sum} = 0`, :math:`{FD}_{sum} = 0`, :math:`{GDD}_{sum} = 0`, :math:`{n}_{days\_active} = 0`, and :math:`t_{onset} = 86400\cdot n_{days\_ on}`, where :math:`{n}_{days\_on}` is a constant parameter with default setting of 30 days. Fluxes from storage into transfer pools occur in the timestep when a new onset growth period is initiated, and are handled identically to Eqs. :eq:`Cflux_stor2xfer_leaf` -:eq:`Cflux_stor2xfer_gresp` for carbon fluxes, and to Eqs. :eq:`Nflux_stor2xfer_leaf` - :eq:`Nflux_stor2xfer_deadcroot` for nitrogen fluxes. The onset counter is decremented on each time step after initiation of the onset period, until it reaches zero, signaling the end of the onset period: .. math:: - :label: 20.67) + :label: t_onset_decrement_stress_deciduous - t_{onfset}^{n} =t_{onfset}^{n-1} -\Delta t + t_{onset}^{n} =t_{onset}^{n-1} -\Delta t -14.4.2 Stress-Deciduous Offset Triggers +Stress-Deciduous Offset Triggers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Any one of the following three conditions is sufficient to initiate an offset period for the stress-deciduous phenology algorithm: sustained period of dry soil, sustained period of cold temperature, or daylength shorter than 6 hours. Offset triggering due to dry soil or cold temperature conditions is only allowed once the most recent onset period is complete. Dry soil condition is evaluated with an offset soil water index accumulator (:math:`{OSWI}_{sum}`, d). To test for a sustained period of dry soils, this control variable can increase or decrease, as follows: .. math:: - :label: 20.68) + :label: offset_soil_water_index_accumulation OSWI_{sum}^{n} =\left\{\begin{array}{l} {OSWI_{sum}^{n-1} +f_{day} \qquad \qquad \qquad {\rm for\; }\Psi _{s,3} \le \Psi _{offset} } \\ {{\rm max}\left(OSWI_{sum}^{n-1} -f_{day} ,0\right)\qquad {\rm for\; }\Psi _{s,3} >\Psi _{onset} } \end{array}\right. @@ -473,33 +479,33 @@ where :math:`{\Psi}_{offset} = -0.8 MPa` is the offset soil water potential thre The cold temperature trigger is calculated with an offset freezing day accumulator (:math:`{OFD}_{sum}`, d). To test for a sustained period of cold temperature, this variable can increase or decrease, as follows: .. math:: - :label: 20.69) + :label: offset_freezing_day_accumulation OFD_{sum}^{n} =\left\{\begin{array}{l} {OFD_{sum}^{n-1} +f_{day} \qquad \qquad \qquad {\rm for\; }T_{s,3} \le TKFRZ} \\ {{\rm max}\left(OFD_{sum}^{n-1} -f_{day} ,0\right)\qquad \qquad {\rm for\; }T_{s,3} >TKFRZ} \end{array}\right. An offset period is triggered if the previous onset period is complete and :math:`{OFD}_{sum} > {OFD}_{sum\_crit}`, where :math:`{OFD}_{sum\_crit} = 15`. -The offset counter is set at the initiation of the offset period: :math:`t_{offset} =86400\cdot n_{days\_ off}`, where :math:`{n}_{days\_off}` is set to a constant value of 15 days. The offset counter is decremented on each time step after initiation of the offset period, until it reaches zero, signaling the end of the offset period: +The offset counter is set at the initiation of the offset period: :math:`t_{offset} =86400\cdot n_{days\_ off}`, where :math:`{n}_{days\_off}` is a constant parameter with default setting of 15 days. The offset counter is decremented on each time step after initiation of the offset period, until it reaches zero, signaling the end of the offset period: .. math:: - :label: 20.70) + :label: t_offset_decrement_stress_deciduous t_{offset}^{n} =t_{offset}^{n-1} -\Delta t -14.4.3 Stress-Deciduous: Long Growing Season +Stress-Deciduous: Long Growing Season ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Under conditions when the stress-deciduous conditions triggering offset are not met for one year or longer, the stress-deciduous algorithm shifts toward the evergreen behavior. This can happen in cases where a stress-deciduous vegetation type is assigned in a climate where suitably strong stresses occur less frequently than once per year. This condition is evaluated by tracking the number of days since the beginning of the most recent onset period (:math:`{n}_{days\_active}`, d). At the end of an offset period :math:`{n}_{days\_active}` is reset to 0. A long growing season control variable (*LGS*, range 0 to 1) is calculated as: .. math:: - :label: 20.71) + :label: long_growing_season LGS=\left\{\begin{array}{l} {0\qquad \qquad \qquad {\rm for\; }n_{days\_ active} <365} \\ {\left({n_{days\_ active} \mathord{\left/ {\vphantom {n_{days\_ active} 365}} \right.} 365} \right)-1\qquad {\rm for\; }365\le n_{days\_ active} <730} \\ {1\qquad \qquad \qquad {\rm for\; }n_{days\_ active} \ge 730} \end{array}\right. . The rate coefficient for background litterfall (:math:`{r}_{bglf}`, s\ :sup:`-1`) is calculated as a function of *LGS*: .. math:: - :label: 20.72) + :label: lgs_BGlitterfall_rate_coef r_{bglf} =\frac{LGS}{\tau _{leaf} \cdot 365\cdot 86400} @@ -508,139 +514,139 @@ where :math:`{\tau}_{leaf}` is the leaf longevity. The result is a shift to cont The rate coefficient for background onset growth from the transfer pools ( :math:`{r}_{bgtr}`, s\ :sup:`-1`) also depends on *LGS*, as: .. math:: - :label: 20.73) + :label: lgs_BGtr_rate_coef r_{bgtr} =\frac{LGS}{365\cdot 86400} . On each timestep with :math:`{r}_{bgtr}` :math:`\neq` 0, carbon fluxes from storage to transfer pools are calculated as: .. math:: - :label: 20.74) + :label: Cflux_stor2xfer_leaf_stress_deciduous CF_{leaf\_ stor,leaf\_ xfer} =CS_{leaf\_ stor} r_{bgtr} .. math:: - :label: 20.75) + :label: Cflux_stor2xfer_froot_stress_deciduous CF_{froot\_ stor,froot\_ xfer} =CS_{froot\_ stor} r_{bgtr} .. math:: - :label: 20.76) + :label: Cflux_stor2xfer_livestem_stress_deciduous CF_{livestem\_ stor,livestem\_ xfer} =CS_{livestem\_ stor} r_{bgtr} .. math:: - :label: 20.77) + :label: Cflux_stor2xfer_deadstem_stress_deciduous CF_{deadstem\_ stor,deadstem\_ xfer} =CS_{deadstem\_ stor} r_{bgtr} .. math:: - :label: 20.78) + :label: Cflux_stor2xfer_livecroot_stress_deciduous CF_{livecroot\_ stor,livecroot\_ xfer} =CS_{livecroot\_ stor} r_{bgtr} .. math:: - :label: 20.79) + :label: Cflux_stor2xfer_deadcroot_stress_deciduous CF_{deadcroot\_ stor,deadcroot\_ xfer} =CS_{deadcroot\_ stor} r_{bgtr} , with corresponding nitrogen fluxes: .. math:: - :label: 20.80) + :label: Nflux_stor2xfer_leaf_stress_deciduous NF_{leaf\_ stor,leaf\_ xfer} =NS_{leaf\_ stor} r_{bgtr} .. math:: - :label: 20.81) + :label: Nflux_stor2xfer_froot_stress_deciduous NF_{froot\_ stor,froot\_ xfer} =NS_{froot\_ stor} r_{bgtr} .. math:: - :label: 20.82) + :label: Nflux_stor2xfer_livestem_stress_deciduous NF_{livestem\_ stor,livestem\_ xfer} =NS_{livestem\_ stor} r_{bgtr} .. math:: - :label: 20.83) + :label: Nflux_stor2xfer_deadstem_stress_deciduous NF_{deadstem\_ stor,deadstem\_ xfer} =NS_{deadstem\_ stor} r_{bgtr} .. math:: - :label: 20.84) + :label: Nflux_stor2xfer_livecroot_stress_deciduous NF_{livecroot\_ stor,livecroot\_ xfer} =NS_{livecroot\_ stor} r_{bgtr} .. math:: - :label: 20.85) + :label: Nflux_stor2xfer_deadcroot_stress_deciduous NF_{deadcroot\_ stor,deadcroot\_ xfer} =NS_{deadcroot\_ stor} r_{bgtr} . -The result, in conjunction with the treatment of background onset growth, is a shift to continuous transfer from storage to display pools at a rate that would result in complete turnover of the storage pools in one year at steady state, once *LGS* reaches 1 (i.e. after two years without stress-deciduous offset conditions). If and when conditions cause stress-deciduous triggering again, :math:`{r}_{bgtr}` is rest to 0. +The result, in conjunction with the treatment of background onset growth, is a shift to continuous transfer from storage to display pools at a rate that would result in complete turnover of the storage pools in one year at steady state, once *LGS* reaches 1 (i.e. after two years without stress-deciduous offset conditions). If and when conditions cause stress-deciduous triggering again, :math:`{r}_{bgtr}` is reset to 0. Litterfall Fluxes Merged to the Column Level ------------------------------------------------- -CLM uses three litter pools, defined on the basis of commonly measured chemical fractionation of fresh litter into labile (LIT1 = hot water and alcohol soluble fraction), cellulose/hemicellulose (LIT2 = acid soluble fraction) and remaining material, referred to here for convenience as lignin (LIT3 = acid insoluble fraction) (Aber et al., 1990; Taylor et al., 1989). While multiple plant functional types can coexist on a single CLM soil column, each soil column includes a single instance of the litter pools. Fluxes entering the litter pools due to litterfall are calculated using a weighted average of the fluxes originating at the PFT level. Carbon fluxes are calculated as: +CLM uses three litter pools, defined on the basis of commonly measured chemical fractionation of fresh litter into labile (LIT1 = hot water and alcohol soluble fraction), cellulose/hemicellulose (LIT2 = acid soluble fraction) and remaining material, referred to here for convenience as lignin (LIT3 = acid insoluble fraction) (:ref:`(Aber et al., 1990)`; :ref:`(Taylor et al., 1989)`). While multiple plant functional types can coexist on a single CLM soil column, each soil column includes a single instance of the litter pools. Fluxes entering the litter pools due to litterfall are calculated using a weighted average of the fluxes originating at the PFT level. Carbon fluxes are calculated as: .. math:: - :label: 20.86) + :label: Cflux_leat2lit1 CF_{leaf,lit1} =\sum _{p=0}^{npfts}CF_{leaf,litter} f_{lab\_ leaf,p} wcol_{p} .. math:: - :label: 20.87) + :label: Cflux_leaf2lit2 CF_{leaf,lit2} =\sum _{p=0}^{npfts}CF_{leaf,litter} f_{cel\_ leaf,p} wcol_{p} .. math:: - :label: 20.88) + :label: Cflux_leaf2lit3 CF_{leaf,lit3} =\sum _{p=0}^{npfts}CF_{leaf,litter} f_{lig\_ leaf,p} wcol_{p} .. math:: - :label: 20.89) + :label: Cflux_froot2lit1 CF_{froot,lit1} =\sum _{p=0}^{npfts}CF_{froot,litter} f_{lab\_ froot,p} wcol_{p} .. math:: - :label: 20.90) + :label: Cflux_froot2lit2 CF_{froot,lit2} =\sum _{p=0}^{npfts}CF_{froot,litter} f_{cel\_ froot,p} wcol_{p} .. math:: - :label: 20.91) + :label: Cflux_froot2lit3 CF_{froot,lit3} =\sum _{p=0}^{npfts}CF_{froot,litter} f_{lig\_ froot,p} wcol_{p} , where :math:`{f}_{lab\_leaf,p}`, :math:`{f}_{cel\_leaf,p}`, and :math:`{f}_{lig\_leaf,p}` are the labile, cellulose/hemicellulose, and lignin fractions of leaf litter for PFT *p*, :math:`{f}_{lab\_froot,p}`, :math:`{f}_{cel\_froot,p}`, and :math:`{f}_{lig\_froot,p}` are the labile, cellulose/hemicellulose, and lignin fractions of fine root litter for PFT *p*, :math:`{wtcol}_{p}` is the weight relative to the column for PFT *p*, and *p* is an index through the plant functional types occurring on a column. Nitrogen fluxes to the litter pools are assumed to follow the C:N of the senescent tissue, and so are distributed using the same fractions used for carbon fluxes: .. math:: - :label: 20.92) + :label: Nflux_leaf2lit1 NF_{leaf,lit1} =\sum _{p=0}^{npfts}NF_{leaf,litter} f_{lab\_ leaf,p} wcol_{p} .. math:: - :label: 20.93) + :label: Nflux_leaf2lit2 NF_{leaf,lit2} =\sum _{p=0}^{npfts}NF_{leaf,litter} f_{cel\_ leaf,p} wcol_{p} .. math:: - :label: 20.94) + :label: Nflux_leaf2lit3 NF_{leaf,lit3} =\sum _{p=0}^{npfts}NF_{leaf,litter} f_{lig\_ leaf,p} wcol_{p} .. math:: - :label: 20.95) + :label: Nflux_froot2lit1 NF_{froot,lit1} =\sum _{p=0}^{npfts}NF_{froot,litter} f_{lab\_ froot,p} wcol_{p} .. math:: - :label: 20.96) + :label: Nflux_froot2lit2 NF_{froot,lit2} =\sum _{p=0}^{npfts}NF_{froot,litter} f_{cel\_ froot,p} wcol_{p} .. math:: - :label: 20.97) + :label: Nflux_froot2lit3 NF_{froot,lit3} =\sum _{p=0}^{npfts}NF_{froot,litter} f_{lig\_ froot,p} wcol_{p} . diff --git a/doc/source/tech_note/index.rst b/doc/source/tech_note/index.rst index bff1c31688..61ccae4361 100644 --- a/doc/source/tech_note/index.rst +++ b/doc/source/tech_note/index.rst @@ -47,6 +47,7 @@ CLM Technical Note DGVM/CLM50_Tech_Note_DGVM.rst BVOCs/CLM50_Tech_Note_BVOCs.rst Dust/CLM50_Tech_Note_Dust.rst + Hillslope_Hydrology/CLM50_Tech_Note_Hillslope_Hydrology.rst Isotopes/CLM50_Tech_Note_Isotopes.rst Land-Only_Mode/CLM50_Tech_Note_Land-Only_Mode.rst References/CLM50_Tech_Note_References.rst diff --git a/doc/source/tech_note/mizuRoute/Tech_Note_mizuRoute.rst b/doc/source/tech_note/mizuRoute/Tech_Note_mizuRoute.rst index 45e86bd2dc..299f000a90 100644 --- a/doc/source/tech_note/mizuRoute/Tech_Note_mizuRoute.rst +++ b/doc/source/tech_note/mizuRoute/Tech_Note_mizuRoute.rst @@ -1,6 +1,6 @@ .. _rst_mizuRoute: -River Routing Model (mizuRoute) +River Routing Model (MizuRoute) ==================================================== .. _Overview mizuRoute: @@ -8,18 +8,24 @@ River Routing Model (mizuRoute) Overview --------- -mizuRoute is a river transport model designed for applications across local, regional and global scales that can use either regular grids or more intricate unstructured grids on Hydrologic Response Units (HRU's). -When run with regular grids those grids still need to be formatted to an unstructured grid format, for use by mizuRoute. And mizuRoute currently only handles data over land and not data over ocean. +MizuRoute is a river transport model designed for applications across local, regional and global scales that can use either regular grids or more intricate unstructured grids on Hydrologic Response Units (HRU's). +When run with regular grids those grids still need to be formatted to an unstructured grid format for use by mizuRoute, as mizuRoute currently only handles data over land and not data over ocean. The name corresponds to the Japanese word for water, "mizu", and the English word "route," reflecting its purpose in modeling water flow through river systems. -mizuRoute is a significant advancement beyond the MOSART model used in CLM50. -A few notable mizuRoute features include: -1. Ability to run on HRU's allows for more sophisticated hydrology applications. -1. A lake model which allows the modelling of lake volumes and flow from natural and managed lakes. -1. mizuRoute like MOSART can also be run connected to the Hillslope option in CTSM. -mizuRoute Technical Note +MizuRoute is a significant advancement beyond the MOSART model used in CLM50. A few notable mizuRoute features include: + +#. Ability to run on HRU's allows for more sophisticated hydrology applications. + +#. Hybrid (MPI Distributed Memory + OpenMP Shared Memory) parallelization. + +#. A lake model which enables the simulations of lake volumes and flow from natural and managed lakes. + +#. MizuRoute like MOSART can also be run connected to the Hillslope option in CTSM. + +Further reading ------------------------- -The mizuRoute web page is here: https://escomp.github.io/mizuRoute/ -And the mizuRoute Technical Note is here: https://mizuroute.readthedocs.io/en/latest/tech_note/index.html +For more information about mizuRoute, please read `mizuRoute Technical note`_. + +.. _mizuRoute Technical note: https://mizuroute.readthedocs.io/en/latest/tech_note/index.html diff --git a/doc/source/users_guide/adding-new-resolutions/Adding-or-Changing-Default-Filenames.rst b/doc/source/users_guide/adding-new-resolutions/Adding-or-Changing-Default-Filenames.rst index a39ffa9426..47cbad9dc6 100644 --- a/doc/source/users_guide/adding-new-resolutions/Adding-or-Changing-Default-Filenames.rst +++ b/doc/source/users_guide/adding-new-resolutions/Adding-or-Changing-Default-Filenames.rst @@ -17,17 +17,3 @@ To add or change the default filenames you edit the ``$CTSMROOT/bld/namelist_fil Other ``fsurdat`` files are distinguished from this one by their resolution (``hgrid``), simulation year (``sim_year``) and prognostic crop (``use_crop``) attributes. ----------------------------- -What are the required files? ----------------------------- - -Different types of simulations and different types of configurations for CLM require different lists of files. The |version|-BGC or Carbon Nitrogen (cn) Biogeochemistry model for example requires ``stream_fldfilename_ndep`` files, which are NOT required by CLMSP. Transient simulations also require transient datasets, and the names of these datasets are sometimes different from the static versions (sometimes both are required as in the dynamic PFT cases). - -In the following table we list the different files used by CLM, they are listed in order of importance, dependencies, and customizing. So the required files are all near the top, and the files used only under different conditions are listed later, and files with the fewest dependencies are near the top, as are the files that are least likely to be customized. - -.. _reqd-files-table: - -Table 3-1. Required Files for Different Configurations and Simulation Types ---------------------------------------------------------------------------- -.. todo:: - Insert table 3-1 diff --git a/doc/source/users_guide/overview/getting-help.rst b/doc/source/users_guide/overview/getting-help.rst index 7c33071db9..439d764823 100644 --- a/doc/source/users_guide/overview/getting-help.rst +++ b/doc/source/users_guide/overview/getting-help.rst @@ -35,7 +35,7 @@ There is a rich and diverse set of people that use the CESM, and often it is use The CLM web pages ----------------- -The main `CLM web page `_ contains information on the CLM, its history, developers, as well as downloads for previous model versions. Some other links are available at the `CESM2 land component webpage `. There are also documentation text files in the `$CTSMROOT/doc directory `_ that give some quick information on using CLM. +The main `CLM web page `_ contains information on the CLM, its history, developers, as well as downloads for previous model versions. Some other links are available at the `CESM2 land component webpage `. There are also documentation text files in the `$CTSMROOT/doc directory `_ that give some quick information on using CLM. Also note that several of the XML database files can help with namelist options, namelist defaults, or compsets. For the most recent release: @@ -56,7 +56,7 @@ Some archives are available for previous versions: Reporting bugs in |version| ---------------------------- -If you have any problems, additional questions, bug reports, or any other feedback, please report it as an issue on GitHub https://github.com/ESCOMP/ctsm/issues or for CIME scripts and infrastructure to https://github.com/ESMCI/CIME/issues. Or send an email to <`cesmhelp@cgd.ucar.edu `_> or <`ctsm-software@ucar.edu `_>. If you find bad, wrong, or misleading information in this users guide report it as an issue on CTSM. +If you have any problems, additional questions, bug reports, or any other feedback, please report it as an issue on GitHub `https://github.com/ESCOMP/ctsm/issues ` or for CIME scripts and infrastructure to `https://github.com/ESMCI/cime/issues `. Or send an email to <`cesmhelp@cgd.ucar.edu `_> or <`ctsm-software@ucar.edu `_>. If you find bad, wrong, or misleading information in this users guide report it as an issue on CTSM. .. _acronyms-and-terms: diff --git a/doc/source/users_guide/overview/introduction.rst b/doc/source/users_guide/overview/introduction.rst index 927b7989cf..1dcf901ff8 100644 --- a/doc/source/users_guide/overview/introduction.rst +++ b/doc/source/users_guide/overview/introduction.rst @@ -40,6 +40,9 @@ The :ref:`model history section ` section gives a synopsis of the - `CLM 4.5 ChangeLog file `_ - `CLM 5.0 ChangeLog file `_ - `CTSM 1.0 ChangeLog file `_ +- `CTSM 5.2 WhatsNew file `_ +- `CTSM 5.3 WhatsNew file `_ +- `CTSM 5.4 WhatsNew file `_ - `Latest ChangeLog file `_ Previous release pages give similar list of changes for previous versions of the model. @@ -68,7 +71,7 @@ In :ref:`running-special-cases-section`, again for the expert user, we give deta In the appendices we talk about some issues that are useful for advanced users and developers of |version|. -Finally on Github we give `instructions `_ on how to build the documentation associated with |version| (i.e. how to build this document). This document is included in every CLM distribution and can be built so that you can view a local copy rather than having to go to the CESM website. This also could be useful for developers who need to update the documentation due to changes they have made. +Finally on Github we give `instructions `_ on how to build the documentation associated with |version| (i.e. how to build this document). This document is included in every CLM distribution and can be built so that you can view a local copy rather than having to go to the CESM website. This also could be useful for developers who need to update the documentation due to changes they have made. .. _readme: @@ -78,7 +81,7 @@ README file describing |version| The README (which can be found in ``$CTSMROOT/doc``) is repeated here. -.. include:: ../../../../README +.. include:: ../../../../README.md :literal: .. _best-practices-for-usage: diff --git a/doc/source/users_guide/overview/scientific_validation.rst b/doc/source/users_guide/overview/scientific_validation.rst index a41aacc3ec..1040b25ba0 100644 --- a/doc/source/users_guide/overview/scientific_validation.rst +++ b/doc/source/users_guide/overview/scientific_validation.rst @@ -12,7 +12,7 @@ In this section we go over what has been extensively tested and scientifically v Standard Configuration and Namelist Options that are Validated -------------------------------------------------------------- -See `http://www.cesm.ucar.edu/models/cesm1.2/clm/CLM_configurations_CESM1.2.pdf `_ for an explanation of what configurations are scientifically validated for |version|. For CLM4.0 changes to the science of the model are minimal since CESM1.1.1 so we expect answers to be very similar to using it. +See `https://files.cesm.ucar.edu/models/clm/CLM_configurations_CESM1.2.pdf `_ for an explanation of what configurations are scientifically validated for |version|. For CLM4.0 changes to the science of the model are minimal since CESM1.1.1 so we expect answers to be very similar to using it. In the sections below we go through configuration and/or namelist options or modes that the user should be especially wary of using. You are of course free to use these options, and you may find that they work functionally. Although in some cases you will find issues even with functionality of using them. If so you will need to test, debug and find solutions for these issues on your own. But in every case you will need to go through more extensive work to validate these options from a scientific standpoint. Some of these options are only for |version| while others are for both CLM4.0 AND |version| we explicitly say which they apply to. diff --git a/doc/source/users_guide/running-single-points/predefined-single-point-regional-resolutions.rst b/doc/source/users_guide/running-single-points/predefined-single-point-regional-resolutions.rst index 4ad8995511..207ec33481 100644 --- a/doc/source/users_guide/running-single-points/predefined-single-point-regional-resolutions.rst +++ b/doc/source/users_guide/running-single-points/predefined-single-point-regional-resolutions.rst @@ -33,4 +33,4 @@ Then setup, build and run as normal. We make sure initial conditions are NOT use Note, that when running with ``PTS_MODE`` the number of processors is automatically set to one. When running a single grid point you can only use a single processor. You might also want to set the ``env_build.xml`` variable: ``MPILIB=mpi-serial`` to ``TRUE`` so that you can also run interactively without having to use MPI to start up your job. -On many machines, batch queues have a minimum number of nodes or processors that can be used. On these machines you may have to change the queue and possibly the time-limits of the job, to get it to run in the batch queue. On the NCAR machine, cheyenne, this is done for you automatically, and the "share" or "caldera" queue is used for such single-processor simulations. For single point mode you also may want to consider using a smaller workstation or cluster, rather than a super-computer, because you can't take advantage of the multi-processing power of the super-computer anyway. +On many machines, batch queues have a minimum number of nodes or processors that can be used. On these machines you may have to change the queue and possibly the time-limits of the job, to get it to run in the batch queue. On the NCAR machine, derecho, single-processor simulations (more generally simulations requesting fewer than 64 tasks) that request walltime less than one hour will automatically end up in the develop queue, instead of the main queue. For single point mode you also may want to consider using a smaller workstation or cluster, rather than a super-computer, because you can't take advantage of the multi-processing power of the super-computer anyway. diff --git a/doc/source/users_guide/running-special-cases/Clm60SP_ctsm54030_1deg_CRUJRA2024_arbi_2000_SP_Spinup.png b/doc/source/users_guide/running-special-cases/Clm60SP_ctsm54030_1deg_CRUJRA2024_arbi_2000_SP_Spinup.png new file mode 100644 index 0000000000..0b5718f657 --- /dev/null +++ b/doc/source/users_guide/running-special-cases/Clm60SP_ctsm54030_1deg_CRUJRA2024_arbi_2000_SP_Spinup.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e5e40d4c7d804e46c4e0081fb14a373572a80428735b0df44713bd1d1ff3ce41 +size 309672 diff --git a/doc/source/users_guide/running-special-cases/Clm60SP_ctsm54030_1deg_CRUJRA2024_fini_2000_SP_Spinup.png b/doc/source/users_guide/running-special-cases/Clm60SP_ctsm54030_1deg_CRUJRA2024_fini_2000_SP_Spinup.png new file mode 100644 index 0000000000..e133508b89 --- /dev/null +++ b/doc/source/users_guide/running-special-cases/Clm60SP_ctsm54030_1deg_CRUJRA2024_fini_2000_SP_Spinup.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:037bb5e14e492cb2d661b75b1e8dc8baa10ee0019f71365ca6cb70fd7fc3327f +size 301363 diff --git a/doc/source/users_guide/running-special-cases/Running-with-MOAR-data-as-atmospheric-forcing-to-spinup-the-model.rst b/doc/source/users_guide/running-special-cases/Running-with-MOAR-data-as-atmospheric-forcing-to-spinup-the-model.rst index 7c18cee009..3cfc4cf46b 100644 --- a/doc/source/users_guide/running-special-cases/Running-with-MOAR-data-as-atmospheric-forcing-to-spinup-the-model.rst +++ b/doc/source/users_guide/running-special-cases/Running-with-MOAR-data-as-atmospheric-forcing-to-spinup-the-model.rst @@ -11,7 +11,7 @@ Because it takes so long to spinup the CN model (as we just saw previously), if you are doing fully coupled simulations with active atmosphere and ocean, you will want to do the spinup portion of this "offline". So instead of doing expensive fully coupled simulations for the spinup duration, you run CLM in a very cheap "I" compset using atmospheric forcing from a shorter fully coupled simulation (or a simulation run previously by someone else). -In this example we will use the ``I1850Clm50BgcSpinup compset`` to setup CLM to run with atmospheric forcing from a previous fully coupled simulation with data that is already stored on disk on Cheyenne. There are several simulations that have high frequency data for which we can do this. You can also do this on a machine other than Cheyenne, but would need to download the data from the Earth System Grid and change the datapath similar to Example :numref:`eg-sim-data-from-prev-sim`. +In this example we will use the ``I1850Clm50BgcSpinup compset`` to setup CLM to run with atmospheric forcing from a previous fully coupled simulation with data that is already stored on disk on derecho. There are several simulations that have high frequency data for which we can do this. You can also do this on a machine other than derecho, but would need to download the data from the Earth System Grid and change the datapath similar to Example :numref:`eg-sim-data-from-prev-sim`. Example: Simulation with MOAR Data on derecho ------------------------------------------------------------- diff --git a/doc/source/users_guide/running-special-cases/Running-with-custom-crop-calendars.rst b/doc/source/users_guide/running-special-cases/Running-with-custom-crop-calendars.rst index b03e73066b..5e2b1998cc 100644 --- a/doc/source/users_guide/running-special-cases/Running-with-custom-crop-calendars.rst +++ b/doc/source/users_guide/running-special-cases/Running-with-custom-crop-calendars.rst @@ -93,4 +93,4 @@ The entire process can be illustrated with the RXCROPMATURITY system test. E.g.: :: - run_sys_tests -t RXCROPMATURITY_Lm61.f10_f10_mg37.IHistClm60BgcCrop.cheyenne_intel.clm-cropMonthOutput --skip-generate --skip-compare + run_sys_tests -t RXCROPMATURITY_Lm61.f10_f10_mg37.IHistClm60BgcCrop.derecho_intel.clm-cropMonthOutput --skip-generate --skip-compare diff --git a/doc/source/users_guide/running-special-cases/Running-with-your-own-previous-simulation-as-atmospheric-forcing-to-spinup-the-model.rst b/doc/source/users_guide/running-special-cases/Running-with-your-own-previous-simulation-as-atmospheric-forcing-to-spinup-the-model.rst index 88d209c0d1..94ad61c5e6 100644 --- a/doc/source/users_guide/running-special-cases/Running-with-your-own-previous-simulation-as-atmospheric-forcing-to-spinup-the-model.rst +++ b/doc/source/users_guide/running-special-cases/Running-with-your-own-previous-simulation-as-atmospheric-forcing-to-spinup-the-model.rst @@ -8,7 +8,7 @@ Another way that you might want to spinup the model is to run your own simulation for a relatively short period (either a B, E, or F compset) and then use it as forcing for your "I" case later. By only running 20 to 50 years for the fully coupled case, you'll save a substantial amount of computer time rather than running the entire spinup period with a fully coupled model. -The first thing we need to do is to run a fully coupled case and save the atmospheric coupling fields on a three hourly basis. In this example, we will run on cheyenne and archive the data to a local disk that we can then use in the next simulation. +The first thing we need to do is to run a fully coupled case and save the atmospheric coupling fields on a three hourly basis. In this example, we will run on derecho and archive the data to a local disk that we can then use in the next simulation. Example: Fully Coupled Simulation to Create Data to Force Next Example Simulation ---------------------------------------------------------------------------------------------- diff --git a/doc/source/users_guide/running-special-cases/Spinning-up-the-Satellite-Phenology-Model-CLMSP-spinup.rst b/doc/source/users_guide/running-special-cases/Spinning-up-the-Satellite-Phenology-Model-CLMSP-spinup.rst index eb482efdd6..6580860a83 100644 --- a/doc/source/users_guide/running-special-cases/Spinning-up-the-Satellite-Phenology-Model-CLMSP-spinup.rst +++ b/doc/source/users_guide/running-special-cases/Spinning-up-the-Satellite-Phenology-Model-CLMSP-spinup.rst @@ -6,20 +6,77 @@ Spinning up the Satellite Phenology Model =========================================== -To spin-up the CLMSP model you merely need to run CLMSP for about 50 simulation years starting from arbitrary initial conditions. You then use the final restart file for initial conditions in other simulations. Because this is a straight forward operation we will NOT give the details on how to do that here, but leave it as an exercise for the reader. See the Example :numref:`eg-final-clmbgc-spinup` as an example of doing this as the last step for CLMCN. +The spin-up of a land surface model is generally defined as an adjustment process as the model approaches equilibrium in its state variables (:ref:`Yang et al. 1995`). This is usually accomplished by forcing the model with repeated years of identical atmospheric forcing until the model state at year ``n+1`` is the same as that at year ``n`` within some defined threshold in the state variables. -You can also start from a default initial file that is setup as part of the selected compset. :numref:`Figure SP spinup plot for 1850` shows spinup behavior for an 1850 SP case that loops over one year of coupler history output for atmospheric forcing (generated from the fully coupled model), initialized with an initial file generated from a GSWP3 atmospheric forcing case. Note that it takes less than 10 years for state variables such as FSH (sensible heat flux), EFLX_LH_TOT (latent heat flux), GPP (photosynthesis), H2OSOI (soil water), and TSOI (soil temperature) to reach a specified equilibrium state (denoted by the dotted lines) due to the different atmospheric forcing. TWS (total water storage) may take a bit longer. +To spin-up the CLM60SP model you generally need to run CLM60SP for a few cycles of repeated atmospheric forcing starting from arbitrary initial conditions, the main goal being to ensure that the turbulent fluxes and soil water and temperature have reached equilibrium (minimal trends). You then use the final restart file resulting from that simulation as initial conditions in other simulations. Alternatively, you can also start from an initial file that is typically already provided for you as part of the selected compset. Generally, this will allow for shorter spinup times if your simulation configuration is similar to the one run to generate the default initial file. -.. _Figure SP spinup plot for 1850: +The following steps illustrate how to setup and run a 51 year CLM60SP spinup from arbitrary initial conditions using the ``I2000Clm60SpCrujra`` compset and ``f09_t232`` spatial resolution. From a checkout of the CLM code (choose your own case name): +:: -.. figure:: image1.png + cd cime/scripts + ./create_newcase --case Clm60SP_ctsm54030_1deg_CRUJRA2024_arbi_2000 --compset I2000Clm60SpCrujra --res f09_t232 --run-unsupported --project XX + cd Clm60SP_ctsm54030_1deg_CRUJRA2024_arbi_2000/ + ./case.setup + ./xmlchange CLM_FORCE_COLDSTART=on + ./xmlchange RUN_STARTDATE=0001-01-01 + ./xmlchange DATM_YR_START=1991 + ./xmlchange DATM_YR_END=2000 + ./xmlchange DATM_YR_ALIGN=1 + ./xmlchange STOP_OPTION=nyears + ./xmlchange STOP_N=51 + ./case.build + ./case.submit - SP spinup plot for year 1850. Variables examined are FSH (sensible heat flux), EFLX_LH_TOT (latent heat flux), GPP (photosynthesis), TWS (total water storage), H2OSOI (volumetric soil water in layer 8) and TSOI (soil temperature in layer 10). Generated using .../tools/contrib/SpinupStability_SP.ncl. +Setting ``CLM_FORCE_COLDSTART=on`` forces the model to use arbitrary initial conditions (see Section :numref:`Initialization` for a description of these initial conditions). This will result in ``finidat=' '`` in the ``lnd_in`` namelist. Spinups are generally started at year 1 (``RUN_STARTDATE=0001-01-01``). Here we've chosen to loop over years 1991-2000 (``DATM_YR_START=1991``, ``DATM_YR_END=2000``) of the atmospheric forcing (10 years total), align model year 1 (``DATM_YR_ALIGN=1``) with the first year of atmospheric forcing, and run for 51 years (``STOP_OPTION=nyears``, ``STOP_N=51``). Ten years of atmospheric forcing was chosen to introduce some interannual variability in the forcing, e.g., to increase the chances of the model being forced by wet and dry years. -:numref:`Figure SP spinup plot for 2000 CO2` shows spinup behavior for the same case but also changes CO2 to present-day conditions (379ppmv). Again, it takes about 10 years to reach equilibrium. +The spinup stability script available in the CLM checkout at ``tools/contrib/SpinupStability_SP_v10.ncl`` can be used to assess the stability or equilibrium of key model variables. Key settings in that script for this example simulation are +:: -.. _Figure SP spinup plot for 2000 CO2: + caseid = "Clm60SP_ctsm54030_1deg_CRUJRA2024_arbi_2000" + subper = 10 -.. figure:: image2.png +The ``subper`` setting tells the script how many years of atmospheric forcing were repeated, thus the equilibrium state of the model in this example is evaluated every 10 years. - SP spinup plot for year 2000 CO2. Variables examined are FSH (sensible heat flux), EFLX_LH_TOT (latent heat flux), GPP (photosynthesis), TWS (total water storage), H2OSOI (volumetric soil water in layer 8) and TSOI (soil temperature in layer 10). Generated using .../tools/contrib/SpinupStability_SP.ncl. +:numref:`Figure CLM60SP spinup plot for arbitrary initial conditions` shows spinup behavior for this simulation. Variables are plotted every 10 years, hence six points (years 1, 11, 21, 31, 41, and 51) are plotted in the leftmost plots for each variable. These include FSH (sensible heat flux), EFLX_LH_TOT (latent heat flux), FPSN (photosynthesis), H2OSOI (soil water at layer 8 which is about 1 meter), TSOI (soil temperature at layer 10 which is about 3 meters), and TWS (total water storage). The speed at which these variables reach a specified equilibrium state (denoted by falling within the dotted lines in the rightmost plots for each variable) varies by variable, TWS generally takes the longest to equilibrium. The plot in the lower left denotes the percent of land area that is not in TWS equilibrium. The contour plots show which grid cells are not in equilibrium for the last two cycles of atmospheric forcing. The equilibrium thresholds are fairly arbitrary for the SP configuration and can be chosen by the user. The current settings are +:: + + glob_thresh_fsh = 0.02 ; global threshold for FSH equilibrium (delta W m-2 / yr) + glob_thresh_lh = 0.02 ; global threshold for EFLX_LH_TOT equilibrium (delta W m-2 / yr) + glob_thresh_gpp = 0.02 ; global threshold for FPSN equilibrium (delta PgC / yr) + glob_thresh_tws = 0.001 ; global threshold for TWS equilibrium (delta m / yr) + glob_thresh_h2osoi = 0.01 ; global threshold for H2OSOI equilibrium (delta mm mm-3 / yr) + glob_thresh_tsoi = 0.02 ; global threshold for TSOI equilibrium (delta K / yr) + glob_thresh_area = 3.0 ; global threshold percent area with TWS disequilibrium gt 0.01 m + +.. _Figure CLM60SP spinup plot for arbitrary initial conditions: + +.. figure:: Clm60SP_ctsm54030_1deg_CRUJRA2024_arbi_2000_SP_Spinup.png + + SP spinup plot for arbitrary initial conditions. Variables examined are FSH (sensible heat flux), EFLX_LH_TOT (latent heat flux), GPP (photosynthesis), TWS (total water storage), H2OSOI (volumetric soil water in layer 8) and TSOI (soil temperature in layer 10). Generated using ``tools/contrib/SpinupStability_SP_v10.ncl``. + +You can also start from a default initial file that is provided as part of the selected compset. The following steps illustrate how to setup and run a 51 year CLM60SP spinup from default initial conditions again using the ``I2000Clm60SpCrujra`` compset and ``f09_t232`` spatial resolution. From a checkout of the CLM code (choose your own case name): +:: + + cd cime/scripts + ./create_newcase --case Clm60SP_ctsm54030_1deg_CRUJRA2024_fini_2000 --compset I2000Clm60SpCrujra --res f09_t232 --run-unsupported --project XX + cd Clm60SP_ctsm54030_1deg_CRUJRA2024_fini_2000/ + ./case.setup + echo "use_init_interp = .true" >> user_nl_clm + ./xmlchange RUN_STARTDATE=0001-01-01 + ./xmlchange DATM_YR_START=1991 + ./xmlchange DATM_YR_END=2000 + ./xmlchange DATM_YR_ALIGN=1 + ./xmlchange STOP_OPTION=nyears + ./xmlchange STOP_N=51 + ./case.build + ./case.submit + +The difference from the previous simulation is that we don't set ``CLM_FORCE_COLDSTART=on`` so that the model uses the default provided initial conditions. In this case, setting ``use_init_interp = .true`` is required because the model configuration used is slightly different from that used to generate the initial file. + +:numref:`Figure CLM60SP spinup plot for default initial conditions` shows spinup behavior for this simulation. Here we can see that equilbrium is reached much sooner because the default initial file is from a spinup where the model configuration was very similar to this one. + +.. _Figure CLM60SP spinup plot for default initial conditions: + +.. figure:: Clm60SP_ctsm54030_1deg_CRUJRA2024_fini_2000_SP_Spinup.png + + SP spinup plot for default initial conditions. Variables examined are FSH (sensible heat flux), EFLX_LH_TOT (latent heat flux), GPP (photosynthesis), TWS (total water storage), H2OSOI (volumetric soil water in layer 8) and TSOI (soil temperature in layer 10). Generated using ``tools/contrib/SpinupStability_SP_v10.ncl``. diff --git a/doc/source/users_guide/running-special-cases/Spinning-up-the-biogeochemistry-BGC-spinup.rst b/doc/source/users_guide/running-special-cases/Spinning-up-the-biogeochemistry-BGC-spinup.rst index 8376c280b1..4372c946f0 100644 --- a/doc/source/users_guide/running-special-cases/Spinning-up-the-biogeochemistry-BGC-spinup.rst +++ b/doc/source/users_guide/running-special-cases/Spinning-up-the-biogeochemistry-BGC-spinup.rst @@ -3,101 +3,124 @@ .. _spinning-up-clm-bgc: ============================= - Spinup of |version|-BGC-Crop + Spinup of CLM-BGC-Crop ============================= -To get the |version|-BGC model to a steady state, you first run it from arbitrary initial conditions using the "accelerated decomposition spinup" (``-bgc_spinup on`` in CLM ``configure``, see example below) mode for about 200 simulation years. :numref:`Figure BGC AD spinup plot for 1850 GSWP3` shows spinup behavior for an 1850 BGC accelerated decomposition (AD) case using GSWP3 atmospheric forcing. Generally, the criteria that less than 3% of the land surface be in total ecosystem carbon disequilibrium takes the longest to satisfy due to slow soil carbon (TOTSOMC) turnover times in the Arctic. +To get the CLM-BGC-Crop model to a steady state, you start it from arbitrary initial conditions using the "accelerated decomposition spinup" (``CLM_ACCELERATED_SPINUP on`` in CLM `env_run.xml`, see example below) mode for 300-400 simulation years. :numref:`Figure BGC-Crop AD spinup plot for 1850` shows spinup behavior for an 1850 BGC-Crop accelerated decomposition (AD) case using CRUJRA atmospheric forcing. Generally, the criterion that less than 3% of the land surface be in total ecosystem carbon disequilibrium takes the longest to satisfy due to slow soil carbon (TOTSOMC) turnover times in the Arctic. -.. _Figure BGC AD spinup plot for 1850 GSWP3: +.. _Figure BGC-Crop AD spinup plot for 1850: -.. figure:: image3.png +.. figure:: ctsm5.4.CMIP7_ciso_ctsm5.3.075_f09_124_AD_Spinup-0.png - BGC AD spinup plot for a year 1850 case with GSWP3 atmospheric forcing. Variables examined are TOTECOSYSC (total ecosystem carbon), TOTSOMC (total soil organic matter carbon), TOTVEGC (total vegetation carbon), TLAI (total leaf area index), GPP (gross primary production) and TWS (total water storage). Generated using .../tools/contrib/SpinupStability.ncl. + BGC-Crop AD spinup plot for a year 1850 case with CRUJRA atmospheric forcing. Variables examined are TOTECOSYSC (total ecosystem carbon), TOTSOMC (total soil organic matter carbon), TOTVEGC (total vegetation carbon), TLAI (total leaf area index), GPP (gross primary production) and TWS (total water storage). Generated using .../tools/contrib/SpinupStability_BGC_v11.ncl. -After this you branch from this mode in the "final spinup" (``-bgc_spinup off`` in CLM ``configure``, see example below), and run for several hundred simulation years. :numref:`Figure BGC pAD spinup plot for 1850 GSWP3` shows spinup behavior for an 1850 BGC post accelerated decomposition (pAD) case using GSWP3 atmospheric forcing. As before, the criteria that less than 3% of the land surface be in total ecosystem carbon disequilibrium takes the longest to satisfy. It can be difficult to meet this strict criteria in less than 1000 years and users may want to relax this criteria depending on their application. +After this you continue in "SASU" mode (``CLM_ACCELERATED_SPINUP sasu`` in CLM `env_run.xml`, see example below), and run for 300-350 simulation years. :numref:`Figure BGC-Crop SASU spinup plot for 1850` shows spinup behavior for an 1850 BGC-Crop SASU case using CRUJRA atmospheric forcing. The criterion that less than 3% of the land surface be in total ecosystem carbon disequilibrium takes the longest to satisfy and need not be met for this step. -.. _Figure BGC pAD spinup plot for 1850 GSWP3: +.. _Figure BGC-Crop SASU spinup plot for 1850: -.. figure:: image4.png +.. figure:: ctsm5.4.CMIP7_ciso_ctsm5.3.075_f09_124_SASU_Spinup-0.png - BGC pAD spinup plot for a year 1850 case with GSWP3 atmospheric forcing and initialization from the end of the BGC AD spinup case. Variables examined are TOTECOSYSC (total ecosystem carbon), TOTSOMC (total soil organic matter carbon), TOTVEGC (total vegetation carbon), TLAI (total leaf area index), GPP (gross primary production) and TWS (total water storage). Generated using .../tools/contrib/SpinupStability.ncl. + BGC-Crop SASU spinup plot for a year 1850 case with CRUJRA atmospheric forcing and initialization from the end of the BGC-Crop AD spinup case. Variables examined are TOTECOSYSC (total ecosystem carbon), TOTSOMC (total soil organic matter carbon), TOTVEGC (total vegetation carbon), TLAI (total leaf area index), GPP (gross primary production) and TWS (total water storage). Generated using .../tools/contrib/SpinupStability_BGC_v11.ncl. -You can also start from a default initial file that is setup as part of the selected compset. :numref:`Figure BGC initialized spinup plot for 1850` shows spinup behavior for an 1850 pAD BGC case that loops over one year of coupler history output for atmospheric forcing (generated from the fully coupled model), initialized with a BGC initial file generated from a GSWP3 atmospheric forcing case. Note that it takes about 10 years for variables such as TLAI (total leaf area index), GPP (gross primary production), and TWS (total water storage) to reach a specified equilibrium state (denoted by the dotted lines) due to the different atmospheric forcing. +After this you continue in standard mode for 200 years. We refer to this phase as post-SASU, pSASU, or normal mode (``CLM_ACCELERATED_SPINUP off`` in CLM `env_run.xml`, see example below). :numref:`Figure BGC-Crop normal mode plot for 1850` shows spinup behavior for an 1850 BGC-Crop normal mode case using CRUJRA atmospheric forcing. As before, the criterion that less than 3% of the land surface be in total ecosystem carbon disequilibrium takes the longest to satisfy. -.. _Figure BGC initialized spinup plot for 1850: +.. _Figure BGC-Crop normal mode plot for 1850: -.. figure:: image5.png +.. figure:: ctsm5.4.CMIP7_ciso_ctsm5.3.075_f09_124_pSASU_Spinup-0.png - BGC initialized spinup plot for year 1850. Variables examined are TOTECOSYSC (total ecosystem carbon), TOTSOMC (total soil organic matter carbon), TOTVEGC (total vegetation carbon), TLAI (total leaf area index), GPP (gross primary production) and TWS (total water storage). Generated using .../tools/contrib/SpinupStability.ncl. + BGC-Crop normal mode plot for a year 1850 case with CRUJRA atmospheric forcing and initialization from the end of the BGC-Crop SASU spinup case. Variables examined are TOTECOSYSC (total ecosystem carbon), TOTSOMC (total soil organic matter carbon), TOTVEGC (total vegetation carbon), TLAI (total leaf area index), GPP (gross primary production) and TWS (total water storage). Generated using .../tools/contrib/SpinupStability_BGC_v11.ncl. -:numref:`Figure BGC initialized spinup plot for 2000 CO2` shows spinup behavior for the same case but also changes CO2 to present-day conditions (379ppmv). Again, it takes about 10 years to reach equilibrium for TLAI, GPP, and TWS. +As an alternative to spinning up, one may start from a default initial file that is setup as part of the selected compset. When the simulation's spatial resolution is identical to the initial file's resolution, it may still take 10 or more years for variables such as TLAI (total leaf area index), GPP (gross primary production), and TWS (total water storage) to reach a new equilibrium state due to the different atmospheric forcing. Similarly, it may take 10 or more years for these variables to reach a new equilibrium when switching atmospheric CO2 from 1850 to a present-day value. -.. _Figure BGC initialized spinup plot for 2000 CO2: - -.. figure:: image6.png - - BGC initialized spinup plot for year 2000 CO2. Variables examined are TOTECOSYSC (total ecosystem carbon), TOTSOMC (total soil organic matter carbon), TOTVEGC (total vegetation carbon), TLAI (total leaf area index), GPP (gross primary production) and TWS (total water storage). Generated using .../tools/contrib/SpinupStability.ncl. - -If you use the default initial file and you signficantly change model behavior or atmospheric forcing, and you are concerned about the carbon equilibrium (e.g., TOTECOSYSC, TOTSOMC, TOTVEGC), particularly at high latitudes, then we recommend you put the model back into AD mode to reach a new equilibrium. In this configuration, this will also automatically reseed "dead" plant functional types in the initial file with a bit of leaf carbon to give those plant functional types another chance to grow under the new atmospheric forcing or model conditions. - -**1. |version| accelerated-decomposition (AD) spinup** - For the first step of running 200+ years in ``-bgc_spinup on`` mode, you will setup a case, and then edit the values in env_build.xml and env_run.xml so that the right configuration is turned on and the simulation is setup to run for the required length of simulation time. So do the following: - -Example: AD_SPINUP Simulation for |version|-BGC +Example: AD_spinup Simulation for CLM-BGC-Crop -------------------------------------------------------- +For the first step of running in ``CLM_ACCELERATED_SPINUP on`` mode, you will setup a case, and then edit the values in env_build.xml and env_run.xml so that the right configuration is turned on and the simulation is setup to run for the required length of simulation time. Try the following: + :: > cd cime/scripts - > ./create_newcase -case BGC_spinup -res f19_g17_gl4 -compset I1850Clm50BgcCropCru - > cd BGC_spinup + > ./create_newcase -case AD_spinup -res f19_g17 -compset I1850Clm60BgcCrop --run-unsupported + > cd AD_spinup # Change accelerated spinup mode > ./xmlchange CLM_ACCELERATED_SPINUP="on" # Now setup - > ./case.setup -case + > ./case.setup + # The following makes sure we run with MOSART off + > ./xmlchange MOSART_MODE=NULL # Now build > ./case.build - # The following sets RESUBMIT to 3 times in env_run.xml (you could also use an editor) - # The following sets STOP_DATE,STOP_N and STOP_OPTION to Jan/1/0201, 20, "nyears" in env_run.xml (you could also use an editor) - > ./xmlchange RESUBMIT=3,STOP_N=50,STOP_OPTION=nyears,STOP_DATE=02010101 - # Now run normally + # The following sets RESUBMIT to 7 times, STOP_N to 50, and STOP_OPTION to "nyears" in env_run.xml (you could also modify these with an editor) + > ./xmlchange RESUBMIT=7,STOP_N=50,STOP_OPTION=nyears + # Now run > ./case.submit -.. note:: This same procedure works for |version|-CN as well. +While this simulation progresses, use SpinupStability_BGC_v11.ncl to assess whether the simulation is approaching equilibrium. When the simulation ends, save the last restart file for use in the SASU_spinup step. + +Using the SpinupStability.ncl scripts +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In CLM's /tools/contrib directory there are three versions of this .ncl script: + +- SpinupStability_BGC_v11.ncl for Bgc and BgcCrop compsets run on 2D lat/lon grids. +- SpinupStability_BGC_v12_SE.ncl for Bgc, BgcCrop, or Fates compsets run on certain spectral element grids (currently ne120, ne30, ne16). +- SpinupStability_SP_v10.ncl for Sp compsets run on 2D lat/lon grids. See section :numref:`spinning-up-sp` for helpful pointers about this script that may also apply to the BGC-Crop versions. -Afterwards save the last restart file from this simulation to use in the next step. +To run one of these scripts on derecho, one loads ncl (``module load ncl``) and submits with ``ncl SpinupStability_BGC_v11.ncl``, for example. Before running one needs to confirm a few easy settings appearing near the top of each script. -**2. Final spinup for |version|-BGC** - Next save the last restart file from this step and use it as the ``finidat`` file to use for one more spinup for at least 400+ years in normal mode. So do the following: +One of the settings that may not be intuitive at first glance is ``annual_hist``. By default the phases AD_spinup and SASU_spinup generate annual history, so set this to "True", while normal mode generates monthly history, so set this to "False". -.. _eg-final-clmbgc-spinup: +.. _eg-sasu-spinup: -Example: Final CLMBGC Spinup Simulation for |version|-BGC +Example: SASU_spinup Simulation for CLM-BGC-Crop ------------------------------------------------------------------ :: > cd cime/scripts - > ./create_newcase -case BGC_finalspinup -res f19_g17_gl4 -compset I1850Clm50BgcCropCru - > cd BGC_finalspinup - # Now, Copy the last CLM restart file from the earlier case into your run directory - > cp /ptmp/$LOGIN/archive/BGC_spinup/rest/BGC_spinup.clm*.r*.0201-01-01-00000.nc \ - /glade/scratch/$LOGIN/CN_finalspinup/run - # Set the runtype to startup - > ./xmlchange RUN_TYPE=startup - # And copy the rpointer files for datm and drv from the earlier case - > cp /glade/scratch/$LOGIN/archive/BGC_spinup/rest/rpointer.atm /glade/scratch/$LOGIN/CN_finalspinup/run - # Set the finidat file to the last restart file saved in previous step - > echo ' finidat = "BGC_spinup.clm2.r.0201-01-01-00000.nc"' > user_nl_clm + > ./create_newcase -case SASU_spinup -res f19_g17 -compset I1850Clm60BgcCrop --run-unsupported + > cd SASU_spinup + # Change accelerated spinup mode, turn off coldstart, and change runtype to hybrid to allow use of a finidat + > ./xmlchange CLM_ACCELERATED_SPINUP="sasu",CLM_FORCE_COLDSTART=off,RUN_TYPE=hybrid # Now setup > ./case.setup - > Now build + # Copy the last restart files from the AD_spinup case into your run directory + # On NSF-NCAR's derecho computer, cd to /glade/derecho/scratch/$USER + > cp archive/AD_spinup/rest/0401-01-01-00000/* SASU_spinup/run + # Set finidat to the restart file copied in the previous step + > echo ' finidat = "AD_spinup.clm2.r.0401-01-01-00000.nc"' > user_nl_clm + # The following makes sure we run with MOSART off + > ./xmlchange MOSART_MODE=NULL + # Now build > ./case.build - # The following sets RESUBMIT to 7 times in env_run.xml (you could also use an editor) - # The following sets STOP_N and STOP_OPTION to 50 and "nyears" in env_run.xml (you could also use an editor) - > ./xmlchange RESUBMIT=7,STOP_OPTION=nyears,STOP_N=50 - > Now run as normal + # The following sets RESUBMIT to 6 times, STOP_N to 50, and STOP_OPTION to "nyears" in env_run.xml (you could also modify these with an editor) + > ./xmlchange RESUBMIT=6,STOP_OPTION=nyears,STOP_N=50 + # Now run > ./case.submit -To assess if the model is spunup, plot trends for CLMBGC variables of interest using .../tools/contrib/SpinupStability.ncl. If you don't meet the equilibrium criteria, you may need to run the simulation longer. Finally save the restart file from the end of this simulation to use as an "finidat" file for future simulations. +Save the last restart file from this step and use it as the ``finidat`` file for the normal mode simulation. Save the restart file from the end of the normal mode simulation to use as a "finidat" file for future simulations. + -.. note:: This same final spinup procedure works for |version|-CN as well. +Example: Normal mode simulation for CLM-BGC-Crop +-------------------------------------------------- +:: + + > cd cime/scripts + > ./create_newcase -case pSASU_spinup -res f19_g17 -compset I1850Clm60BgcCrop --run-unsupported + > cd pSASU_spinup + # Change accelerated spinup mode, turn off coldstart, and change runtype to hybrid to allow use of a finidat + > ./xmlchange CLM_ACCELERATED_SPINUP="off",CLM_FORCE_COLDSTART=off,RUN_TYPE=hybrid + # Now setup + > ./case.setup + # Copy the last restart files from the SASU_spinup case into your run directory + # On NSF-NCAR's derecho computer, cd to /glade/derecho/scratch/$USER + > cp archive/SASU_spinup/rest/0351-01-01-00000/* pSASU_spinup/run + # Set finidat to the restart file copied in the previous step + > echo ' finidat = "SASU_spinup.clm2.r.0351-01-01-00000.nc"' > user_nl_clm + # The following makes sure we run with MOSART off + > ./xmlchange MOSART_MODE=NULL + # Now build + > ./case.build + # The following sets RESUBMIT to 3 times, STOP_N to 50, and STOP_OPTION to "nyears" in env_run.xml (you could also modify these with an editor) + > ./xmlchange RESUBMIT=3,STOP_OPTION=nyears,STOP_N=50 + # Now run + > ./case.submit diff --git a/doc/source/users_guide/running-special-cases/ctsm5.4.CMIP7_ciso_ctsm5.3.075_f09_124_AD_Spinup-0.png b/doc/source/users_guide/running-special-cases/ctsm5.4.CMIP7_ciso_ctsm5.3.075_f09_124_AD_Spinup-0.png new file mode 100644 index 0000000000..0db353da62 --- /dev/null +++ b/doc/source/users_guide/running-special-cases/ctsm5.4.CMIP7_ciso_ctsm5.3.075_f09_124_AD_Spinup-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5019303d5d02530c1ad6a58512ee956072e8c793774bceecbc84041c7d7fa95d +size 67505 diff --git a/doc/source/users_guide/running-special-cases/ctsm5.4.CMIP7_ciso_ctsm5.3.075_f09_124_SASU_Spinup-0.png b/doc/source/users_guide/running-special-cases/ctsm5.4.CMIP7_ciso_ctsm5.3.075_f09_124_SASU_Spinup-0.png new file mode 100644 index 0000000000..d7e5787054 --- /dev/null +++ b/doc/source/users_guide/running-special-cases/ctsm5.4.CMIP7_ciso_ctsm5.3.075_f09_124_SASU_Spinup-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b12cbf832a022eb6390eb3c75b0fe97dd47b2704206d282e2c2c65b30420855 +size 72370 diff --git a/doc/source/users_guide/running-special-cases/ctsm5.4.CMIP7_ciso_ctsm5.3.075_f09_124_pSASU_Spinup-0.png b/doc/source/users_guide/running-special-cases/ctsm5.4.CMIP7_ciso_ctsm5.3.075_f09_124_pSASU_Spinup-0.png new file mode 100644 index 0000000000..f41afe0036 --- /dev/null +++ b/doc/source/users_guide/running-special-cases/ctsm5.4.CMIP7_ciso_ctsm5.3.075_f09_124_pSASU_Spinup-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b1eae04e80108750a2f7770ba151f419196dd5ddb51dd9a11d9c3e5c8170c56 +size 62444 diff --git a/doc/source/users_guide/running-special-cases/image1.png b/doc/source/users_guide/running-special-cases/image1.png deleted file mode 100644 index fba40ddfa1..0000000000 --- a/doc/source/users_guide/running-special-cases/image1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7d17c1ff7945bfa5d86958f8cc90b96fbd58bbeb81003aaf2cdcc2e6104788da -size 318875 diff --git a/doc/source/users_guide/running-special-cases/image2.png b/doc/source/users_guide/running-special-cases/image2.png deleted file mode 100644 index 79cc812929..0000000000 --- a/doc/source/users_guide/running-special-cases/image2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bf3d0b888e7c442838f1fa4290987b29c4a54f82a49aac7d5070db5e3e5abfe1 -size 320601 diff --git a/doc/source/users_guide/running-special-cases/image3.png b/doc/source/users_guide/running-special-cases/image3.png deleted file mode 100644 index 0c11688829..0000000000 --- a/doc/source/users_guide/running-special-cases/image3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:347a4e32e072c6b5d9f87ae7fd36ee3621c8436910691b18f63d9365f853d8de -size 280086 diff --git a/doc/source/users_guide/running-special-cases/image4.png b/doc/source/users_guide/running-special-cases/image4.png deleted file mode 100644 index 09456b93af..0000000000 --- a/doc/source/users_guide/running-special-cases/image4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4587fe62aa8c34906e56d13c99749b69d2600f4c770c50781d81faf2480b8842 -size 287344 diff --git a/doc/source/users_guide/running-special-cases/image5.png b/doc/source/users_guide/running-special-cases/image5.png deleted file mode 100644 index f0d073565f..0000000000 --- a/doc/source/users_guide/running-special-cases/image5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:991c6fa7d321f0a0e50f38c82f951eb978ba3ae62efe184bc941fcacaf4352c5 -size 316593 diff --git a/doc/source/users_guide/running-special-cases/image6.png b/doc/source/users_guide/running-special-cases/image6.png deleted file mode 100644 index 949acde48d..0000000000 --- a/doc/source/users_guide/running-special-cases/image6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:65a5121d47597ae3d508a8bda8989708c928e3f0b9e183009dfc4bcd661ad4b6 -size 311278 diff --git a/doc/source/users_guide/runsed.csh b/doc/source/users_guide/runsed.csh deleted file mode 100755 index 56e3445397..0000000000 --- a/doc/source/users_guide/runsed.csh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/csh - -foreach file ( */*.rst ) - sed -f sedscript.txt $file > $file.tmp - mv $file.tmp $file -end diff --git a/doc/source/users_guide/sedscript.txt b/doc/source/users_guide/sedscript.txt deleted file mode 100644 index ca537f84a6..0000000000 --- a/doc/source/users_guide/sedscript.txt +++ /dev/null @@ -1,17 +0,0 @@ -s/CLM4.5/+|version|/g -s/clm4.5/+|version|/g -s/CLM5.0/+|version|/g -s/clm5.0/+|version|/g -s/CESM2.0/+|cesmrelease|/g -s/cesm2.0/+|cesmrelease|/g -s/CESM1.2.0/+|cesmrelease|/g -s/cesm1.2.0/+|cesmrelease|/g -s#models/lnd/clm#$CTSMROOT#g -s#tools/shared/#tools/#g -s#shared/#./#g -s/yellowstone/cheyenne/g -s/I1850SPINUPCN/I1850Clm50BgcSpinup/g -s/I1850CRUCLM45BGC/I1850Clm50BgcCropCru/g -s/I1850CRUCLM45BGC/I1850Clm50BgcCrop/g -s/f19_g16/f19_g17_gl4/g -s/f09_g16/f09_g17_gl4/g diff --git a/doc/source/users_guide/setting-up-and-running-a-case/customizing-the-clm-configuration.rst b/doc/source/users_guide/setting-up-and-running-a-case/customizing-the-clm-configuration.rst index 7b1a4d8ad0..112e8f5a84 100644 --- a/doc/source/users_guide/setting-up-and-running-a-case/customizing-the-clm-configuration.rst +++ b/doc/source/users_guide/setting-up-and-running-a-case/customizing-the-clm-configuration.rst @@ -6,7 +6,7 @@ Customizing CLM's Configuration ******************************** -The section of the |cesmrelease| Quickstart `CESM Create a Case `_ gives instructions on creating a case. Also see a similar section in the CIME User's Guide `CIME Create a case `_. What is of interest here is how to customize your use of CLM for the case that you created. +The section of the |cesmrelease| Quickstart `CESM Create a Case `_ gives instructions on creating a case. Also see a similar section in the CIME User's Guide `CIME Create a case `_. What is of interest here is how to customize your use of CLM for the case that you created. For CLM when ``preview_namelist``, ``case.build``, or ``case.run`` are called there are two steps that take place: @@ -18,7 +18,7 @@ When customizing your case at the ``case.setup`` step you are able to modify the There are five different types of customization for the configuration that we will discuss: |version| in |cesmrelease| build-time options, |version| in |cesmrelease| run-time options, User Namelist, other noteworthy |cesmrelease| configuration items, the CLM ``configure`` script options, and the CLM ``build-namelist`` script options. -Information on all of the CLM script, configuration, build and run items is found under ``$CTSMROOT/cime_config/config_component.xml``. See `CLM CASEROOT Variable Definitions `_. +Information on all of the CLM script, configuration, build and run items is found under ``$CTSMROOT/cime_config/config_component.xml``. See `CLM CASEROOT Variable Definitions `_. ================================ CLM Script configuration items @@ -503,7 +503,7 @@ Like other datasets, if you want to use a given initial condition file to be use Other noteworthy configuration items ------------------------------------ -For running "I" cases there are several other noteworthy configuration items that you may want to work with. Most of these involve settings for the DATM, but one ``CCSM_CO2_PPMV`` applies to all models. The list of DATM settings is `here `_. If you are running a B, E, or F case that doesn't use the DATM obviously the DATM_* settings will not be used. All of the settings below are in your ``env_build.xml`` and ``env_run.xml`` files +For running "I" cases there are several other noteworthy configuration items that you may want to work with. Most of these involve settings for the DATM, but one ``CCSM_CO2_PPMV`` applies to all models. The list of DATM settings is `here `_, although note that the values there are currently out of date. If you are running a B, E, or F case that doesn't use the DATM obviously the DATM_* settings will not be used. All of the settings below are in your ``env_build.xml`` and ``env_run.xml`` files :: CCSM_CO2_PPMV diff --git a/doc/source/users_guide/setting-up-and-running-a-case/customizing-the-clm-namelist.rst b/doc/source/users_guide/setting-up-and-running-a-case/customizing-the-clm-namelist.rst index dacc24fbc6..3cd6c3a8db 100644 --- a/doc/source/users_guide/setting-up-and-running-a-case/customizing-the-clm-namelist.rst +++ b/doc/source/users_guide/setting-up-and-running-a-case/customizing-the-clm-namelist.rst @@ -36,7 +36,7 @@ Below we will give examples of user namelists that activate different commonly u The default namelist -------------------- -Here we give the default namelist as it would be created for an "I1850Clm50BgcCropCru" compset at 0.9x1.25 resolution with a gx1v7 land-mask on cheyenne. To edit the namelist you would edit the ``user_nl_clm`` user namelist with just the items you want to change. For simplicity we will just show the CLM namelist and NOT the entire file. In the sections below, for simplicity we will just show the user namelist (``user_nl_clm``) that will add (or modify existing) namelist items to the namelist. +Here we give the default namelist as it would be created for an "I1850Clm50BgcCropCru" compset at 0.9x1.25 resolution with a gx1v7 land-mask on derecho. To edit the namelist you would edit the ``user_nl_clm`` user namelist with just the items you want to change. For simplicity we will just show the CLM namelist and NOT the entire file. In the sections below, for simplicity we will just show the user namelist (``user_nl_clm``) that will add (or modify existing) namelist items to the namelist. Example 1-2. Default CLM Namelist --------------------------------- diff --git a/doc/source/users_guide/setting-up-and-running-a-case/customizing-the-datm-namelist.rst b/doc/source/users_guide/setting-up-and-running-a-case/customizing-the-datm-namelist.rst index d92d4e3a3e..91239ee1de 100644 --- a/doc/source/users_guide/setting-up-and-running-a-case/customizing-the-datm-namelist.rst +++ b/doc/source/users_guide/setting-up-and-running-a-case/customizing-the-datm-namelist.rst @@ -11,7 +11,7 @@ When running "I" compsets with CLM you use the DATM model to give atmospheric fo 1. **DATM Main Namelist and Stream Namelist group** (``datm_in``) 2. **DATM stream files** -The `Data Model Documentation `_ gives the details of all the options for the data models and for DATM specifically. It goes into detail on all namelist items both for DATM and for DATM streams. So here we won't list ALL of the DATM namelist options, nor go into great details about stream files. But, we will talk about a few of the different options that are relevant for running with CLM. All of the options for changing the namelists or stream files is done by editing the ``user_nl_datm`` file. +The `Data Model Documentation `_ gives the details of all the options for the data models and for DATM specifically, although note that the values there are currently out of date. It goes into detail on all namelist items both for DATM and for DATM streams. So here we won't list ALL of the DATM namelist options, nor go into great details about stream files. But, we will talk about a few of the different options that are relevant for running with CLM. All of the options for changing the namelists or stream files is done by editing the ``user_nl_datm`` file. Because, they aren't useful for work with CLM we will NOT discuss any of the options for the main DATM namelist. Use the DATM Users Guide at the link above to find details of that. For the streams namelist we will discuss three items: @@ -56,7 +56,7 @@ CLMCRUNCEPv7 mode and it's DATM settings In ``CLMCRUNCEPv7`` mode the CRUNCEP dataset is used and all of it's data is on a 6-hourly interval. Like ``CLM_QIAN`` the dataset is divided into those three data streams: solar, precipitation, and everything else (temperature, pressure, humidity and wind). The time-stamps of the data were also adjusted so that they are the beginning of the interval for solar, and the middle for the other two. Because, of this the ``offset`` is set to zero, and the ``tintalgo`` is: ``coszen``, ``nearest``, and ``linear`` for the solar, precipitation and other data respectively. ``taxmode`` is set to ``cycle`` and ``mapalgo`` is set to ``bilinear`` so that the data is spatially interpolated from the input exact half degree grid to the grid the atmosphere model is being run at (to run at this same model resolution use the 360x720cru_360x720cru resolution)... note:: The "everything else" data stream (of temperature, pressure, humidity and wind) also includes the data for longwave downward forcing as well. Our simulations showed sensitivity to this field, so we backed off in using it, and let DATM calculate longwave down from the other fields. -For more information on CRUNCEP forcing see `http://dods.extra.cea.fr/data/p529viov/cruncep/ `_. +For more information on CRUNCEP forcing see `https://rda.ucar.edu/datasets/d314003/ `_. .. _clmcruncep-and-its-datm: diff --git a/doc/source/users_guide/setting-up-and-running-a-case/history_fields_fates.rst b/doc/source/users_guide/setting-up-and-running-a-case/history_fields_fates.rst index ea964fc433..a886a3f6ce 100644 --- a/doc/source/users_guide/setting-up-and-running-a-case/history_fields_fates.rst +++ b/doc/source/users_guide/setting-up-and-running-a-case/history_fields_fates.rst @@ -2,9 +2,9 @@ CTSM History Fields (fates) ============================= -CAUTION: Not all variables are relevant / present for all CTSM cases. -NOTE: Instantaneous fields will appear in history files labeled with h0i, h1i, ... and non-instantaneous fields will appear in history files labeled with h0a, h1a, ... +NOTE: Instantaneous fields will appear in history files - labeled h0i, h1i, ... - representing individual model time steps documented in each file's metadata (variables time, nstep). Non-instantaneous fields will appear in history files - labeled h0a, h1a, ... - representing the mid-point of the time bounds documented in each file's metadata (variables time, time_bounds). +CAUTION: Not all variables are relevant / present for all CTSM cases. Key flags used in this CTSM case: use_cn = F use_crop = F diff --git a/doc/source/users_guide/setting-up-and-running-a-case/history_fields_nofates.rst b/doc/source/users_guide/setting-up-and-running-a-case/history_fields_nofates.rst index bb8826c72e..8a8f4c6e38 100644 --- a/doc/source/users_guide/setting-up-and-running-a-case/history_fields_nofates.rst +++ b/doc/source/users_guide/setting-up-and-running-a-case/history_fields_nofates.rst @@ -2,6 +2,8 @@ CTSM History Fields (nofates) ============================= +NOTE: Instantaneous fields will appear in history files - labeled h0i, h1i, ... - representing individual model time steps documented in each file's metadata (variables time, nstep). Non-instantaneous fields will appear in history files - labeled h0a, h1a, ... - representing the mid-point of the time bounds documented in each file's metadata (variables time, time_bounds). + CAUTION: Not all variables are relevant / present for all CTSM cases. Key flags used in this CTSM case: use_cn = T diff --git a/doc/source/users_guide/testing/testing.rst b/doc/source/users_guide/testing/testing.rst index a9b0be0462..0534226f84 100644 --- a/doc/source/users_guide/testing/testing.rst +++ b/doc/source/users_guide/testing/testing.rst @@ -14,12 +14,12 @@ Technically, you could use the customization we gave in :ref:`customizing_sectio CIME Testing scripts ==================== -We first introduce the test scripts that work for all CESM components. The CIME script ``create_test`` runs a specific type of test, at a given resolution, for a given compset using a given machine. See `CIME Chapter on Testing `_ for how to use it to run single tests as well as lists of tests. The standard testname for CLM is "aux_clm" for cheyenne with intel and gnu compilers as well as the CGD machine hobart for intel, nag, and pgi compilers. There's also a shorter test list called "clm_short". Also see the `CTSM Wiki on Testing `_. +We first introduce the test scripts that work for all CESM components. The CIME script ``create_test`` runs a specific type of test, at a given resolution, for a given compset using a given machine. See `CIME Chapter on Testing `_ for how to use it to run single tests as well as lists of tests. The standard testname for CLM is "aux_clm" for derecho with intel and gnu compilers as well as the CGD machine izumi for intel, nag, and pgi compilers. There's also a shorter test list called "clm_short". Also see the `CTSM Wiki on Testing `_. CTSM Fortran Unit Tests ======================= -.. include:: ../../../../src/README.unit_testing +.. include:: ../../../../src/README.unit_testing.md :literal: CTSM Build-namelist Tests diff --git a/doc/source/users_guide/trouble-shooting/index.rst b/doc/source/users_guide/trouble-shooting/index.rst index de6b0c053a..c92a7e3ba8 100644 --- a/doc/source/users_guide/trouble-shooting/index.rst +++ b/doc/source/users_guide/trouble-shooting/index.rst @@ -12,6 +12,6 @@ Troubleshooting ##################################### .. toctree:: - :maxdepth: 2 + :maxdepth: 5 trouble-shooting.rst diff --git a/doc/source/users_guide/trouble-shooting/trouble-shooting.rst b/doc/source/users_guide/trouble-shooting/trouble-shooting.rst index a971b7f2cb..0e1a5e241f 100644 --- a/doc/source/users_guide/trouble-shooting/trouble-shooting.rst +++ b/doc/source/users_guide/trouble-shooting/trouble-shooting.rst @@ -2,27 +2,256 @@ .. _trouble-shooting: -*************** -Troubleshooting -*************** +********************************************* +Introduction +********************************************* In this chapter we give some guidance on what to do when you encounter some of the most common problems. In general you may run into one of four types of problems: 1. *case-creation* -#. *setup-time* -#. *build-time* -#. *run-time* +2. *setup-time* +3. *build-time* +4. *run-time* -Start with the `CIME Trouble Shooting Guide `_ , especially if you encounter one of the first three types of problems. The CIME troubleshooting guide also provides some useful tips regarding run-time errors. If this doesn't identify and solve your problem, then try some of the suggestions below for run-time errors. +Start with the `CIME Trouble Shooting Guide `_ , especially if you encounter one of the first three types of problems. The CIME troubleshooting guide also provides some useful tips regarding run-time errors. If this doesn't identify and solve your problem, then try some of the suggestions below for run-time errors. +********************************************* General Advice on Debugging Run time Problems -============================================= +********************************************* -The model has been run for thousands and thousands of simulation years in many different configurations, both fully-coupled and in land-only modes, without problems. If you have modified the model in any way, by using either different input datasets or new or modified code, then that is the first place to look if you encounter an error. However, the model is not completely infallible, as noted below. +Release versions of the model have been run for thousands and thousands of simulation years in many different configurations, both fully-coupled and in land-only modes, without problems. If you have modified the model in any way, by using either different input datasets or new or modified code, then that is the first place to look if you encounter an error. In particular, see the following section :numref:`List of common problems to watch out for when developing / reviewing code` for advice on problems to watch out for when developing or reviewing code. -It is important to examine all of the component log files in the run directory for errors. An error in the land model may not appear in the lnd log file, it may show up in the cesm log. In a land-only simulation, errors associated with the data atmosphere model may show up in the atm log or the cesm log, or both. The two logs together may contain useful information about the error. Frequently, the error output in the log files will include a **traceback** of code where the error occurred. Identifying the specific line of code where the error occurred is the first step in diagnosing the error and developing a solution. If a traceback doesn't appear in the log files, then try running in debug mode as noted in the CIME troubleshooting guide. An example of a traceback in the cesm log is given below +.. _List of common problems to watch out for when developing / reviewing code: + +===================================================================================================== +List of common problems to watch out for when developing / reviewing code +===================================================================================================== + +----------------------------------------------------------------------------------------------------- +Possible sources of model crashes or non-physical results +----------------------------------------------------------------------------------------------------- + +Potential for divide-by-zero +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Solution: put code in a conditional that checks for 0, and handles 0 values specially + +Potential for other floating point exceptions (e.g,. raising 0 to a negative power, etc.) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Solution: put code in a conditional that handles mathematically impossible cases specially + +Potential for a quantity that should be non-negative to go negative, due to rounding errors +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Solutions: +:: + + foo = max(foo, 0._r8) + +or use the ``truncate_small_values`` subroutine in ``NumericsMod``. + +----------------------------------------------------------------------------------------------------- +Possible sources of science bugs and maintainability problems +----------------------------------------------------------------------------------------------------- + +Block of code is copy & pasted, or effectively duplicated +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This is one of the most common issues we encounter. It causes both maintainability problems and future bugs (when one block of code gets modified and thus becomes out of sync with the other block). Sometimes a block of code is copied and pasted entirely; other times this issue is more subtle, with logic effectively duplicated in two places even though the code looks somewhat different. + +This problem can be identified by asking yourself: If I make a change in place A, will I need to make a corresponding change in place B? + +Possible solutions: + +- Introduce a subroutine that holds the common code, with parameters to allow for any differences in behavior between the different locations + +- Save the result of a calculation in a variable that can be reused in multiple places + +Variable is missing from the restart file, or is on the restart file when it doesn't need to be +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Variables need to be written to and read from the restart file if their value persists from one time step to the next. This is mainly the case for the model's fundamental state variables. However, in order to minimize restart file size (reasons of disk usage, performance, and understandability), we try to avoid adding variables to the restart file unless they're truly needed. + +Some good rules of thumb to use are: + +- If a variable's value at time ``t`` directly depends on its value at time ``t-1``, often through evolution equations of the form ``x = x + flux*dtime``, then it likely needs to be on the restart file. + +- Imagine setting a variable to 0 at the start of each time step. Would this cause incorrect results? If so, it likely needs to be on the restart file. + +- However, if a variable can be recalculated based on other variables, then it probably should *not* be on the restart file. Instead, its initial value can be calculated in model initialization, after reading the restart file. + +There are also some cases where a variable is needed on the restart file because its value is referenced (i.e., it appears on the right-hand side of an equation) earlier in the driver loop than where it is set. This is a subtle issue, and needs to be kept in mind when developing and reviewing code. For example, the relevant parts of the driver loop could look like this: +:: + + foo = bar*2 + + (more code here) + + bar = ... + +In reality, these lines will be in subroutines called from the main driver loop, so an understanding is needed of the calling order of the model's subroutines. + +An ideal solution in this case is to reorder the code so that ``bar`` is calculated before it is used. The next most ideal solution is to recalculate ``bar`` from other variables in initialization after the restart file is read. However, if neither of these are possible, then ``bar`` needs to be added to the restart file. + +We have many restart tests in the automated test suite; these catch many problems with variables being absent from the restart file that should be there. However, these tests cannot catch all problems - particularly if a variable's value only needs to persist between time steps in certain circumstances (such as if the restart is done mid-day). In addition, these tests cannot catch problems with variables being added to the restart file unnecessarily. + +Variable is used on right-hand side of an equation before it has its "final" value +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example: +:: + + bar = ... + + foo = bar + 1._r8 + + (more code here) + + bar = bar + 1._r8 + +In this case, it's possible that the ``foo`` assignment should really have happened after the increment to ``bar``. + +Solution: Check code carefully for assignments to variables that are used on the right-hand side of equations. Ideally, this search would only need to be done within the current subroutine. But in practice, variables in CTSM are sometimes updated in multiple subroutines, so you should extend this search to make sure your new code happens in the correct place in the driver loop. (i.e., make sure that there aren't subroutines called later in the driver that update the quantity that you're using on the right-hand side of the equation.) + +------------------------------------------------------------------------------------------------------------ +Possible sources of answer changes with changing processor count (PEM test failures, also seen in ERP tests) +------------------------------------------------------------------------------------------------------------ + +Problems specific to parallelization +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +PEM and ERP tests are designed to catch problems specific to parallelization. In CTSM, these aren't the most common sources of errors with these tests, but we'll start with a few parallel-specific reasons that these tests could fail. + +Missing or incorrect broadcast for a namelist variable +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + +Namelist variables are read on the master proc and then should be broadcast to all other processors. If a broadcast statement is missing or incorrect for a namelist variable, then the namelist value could be wrong on all other processors. This will lead to answer changes with changing processor count because changing processor count will change which grid cells are on the master proc (with the correct namelist value) vs. other processors. + +Processor count dependence of a parallel algorithm +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + +An obvious source of answer changes with changing processor count is processor count dependence of a parallel algorithm. A common issue here is an MPI reduction that depends on the processor count – e.g., a sum across multiple processors, which could depend on the order in which the sum is taken. + +However, we do not have many parallel algorithms in CTSM; these would mainly apply in cases where there is communication between grid cells. + +Incorrect indexing of a subgrid variable +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +One common cause of processor count dependence is the incorrect indexing of a subgrid variable. For example, if a patch variable is indexed by ``g`` instead of ``p``, then it will access the wrong index. This will be picked up in a PEM (or ERP) test because exactly which point it accesses is processor count-dependent. + +Here are some ``git grep`` commands that can help find this problem: + +.. code:: shell + + git grep -i '_patch \*( \*[glc] \*)' + git grep -i '_col \*( \*[glp] \*)' + git grep -i '_lun \*( \*[gcp] \*)' + git grep -i '_grc \*( \*[lcp] \*)' + +However, since we often strip the suffix in associate statements, you cannot rely on these grep commands to detect this issue. + +Scalar variable used before it is set in a given loop iteration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Another common cause of answer changes with changing processor counts is a scalar variable being used before it is set in a given loop iteration. This means that its value depends on a previous loop iteration, or possibly the value that was set in an earlier loop in this subroutine. Changing processor counts changes which grid cell is operated on first in a loop for a given processor, and also which grid cell is the previous loop iteration for a given grid cell. + +There are a few common specific ways that this appears in CTSM code, as noted below: + +Missing setting of ``c``, ``l`` or ``g`` in a loop +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + +Often, a loop over one subgrid level will access variables in arrays at a coarser subgrid level. For example, a loop over patches will access column and gridcell-level variables. This requires settings like ``c = patch%column(p)``. Sometimes there is a bug where a given loop is missing one of these needed settings; instead its setting comes from the previous loop in that subroutine. In this case, all patches – on all grid cells – will use the same ``c`` value. + +Scalar variable set in a conditional but accessed outside that conditional +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + +Sometimes a scalar variable is set inside a conditional but is accessed outside that conditional. There may be multiple branches of the conditional with the intent that the scalar is set for all cases, but there may be a missing branch, so in some situations the scalar doesn't end up getting set for a particular point. The value will then be taken from the previous loop iteration. + +------------------------------------------------------------------------------------------------------------ +Possible sources of threading bugs +------------------------------------------------------------------------------------------------------------ + +Whole-array assignment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + foo(:) = 0._r8 + +should be replaced by the following, assuming ``foo`` is a column-level array: +:: + + foo(bounds%begc:bounds%endc) = 0._r8 + +or, better, initialize ``foo`` within a loop over the appropriate filter, or a loop over ``bounds%begc`` to ``bounds%endc``, ideally subset by active points. + +Forgetting to index into a variable for assignment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +E.g., ``variable_patch = 0._r8`` instead of ``variable_patch(p) = 0._r8``. + +Improper argument passing +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +See [this page on the old wiki](https://wiki.ucar.edu/display/ccsm/CLM+Coding+Conventions#CLMCodingConventions-ArgumentPassingargPass) + +Identify specific loops with issues by turning off threading for loops +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +One way to identify threaded loops with issues is to turn off more and more loops until you identify ones with issues. + +For example a subroutine with a loop like this... +:: + + !$OMP PARALLEL DO PRIVATE (nc,bounds_clump) + do nc = 1,nclumps + call get_clump_bounds(nc, bounds_clump) + ... + end do + !$OMP END PARALLEL DO + +Incorrect list of private variables in threaded loops +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For threading each processor thread needs to have its own version of temporary or loop indexing variables. For longer loops the list needed can be quite long, if you don't have the right list of variables in the private list, different threads will share these variables and result in strange behavior. + +So in the above example, if either ``nc``, or ``bounds_clump`` weren't in the private list the loop would not be able to function correctly. + +Turn off OpenMP parallelism by removing the first line or adding an extra comment character (!) to comment it out. + +----------------------------------------------------------------------------------------------------- +Possible sources of performance problems +----------------------------------------------------------------------------------------------------- + +Doing an operation on all array elements rather than just active points +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Active points are (generally, but not entirely) ones with > 0 weight on the grid cell. + +Solution: Use the filters, which only include active points + +Nested loops in the wrong order for cache-friendliness and/or vectorizability +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +----------------------------------------------------------------------------------------------------- +Other things to look for in a PR review +----------------------------------------------------------------------------------------------------- + +Binary files committed without the use of git lfs +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If someone commits a binary file without git lfs enabled, it will actually be committed directly. The same thing will happen even if they have git lfs enabled if the file has an extension that isn't currently tracked by git lfs. Look for any such binary files when looking through the list of changed files. These will often appear in the doc directory. + +See the .gitattributes file at the top level of the repository for files typically handled by git lfs. + +.. _A specific troubleshooting example: + +===================================================================================================== +A specific troubleshooting example +===================================================================================================== + +First of all, it is important to examine all of the component log files in the run directory for errors. An error in the land model may not appear in the lnd log file, it may show up in the cesm log. In a land-only simulation, errors associated with the data atmosphere model may show up in the atm log or the cesm log, or both. The two logs together may contain useful information about the error. Frequently, the error output in the log files will include a **traceback** of code where the error occurred. Identifying the specific line of code where the error occurred is the first step in diagnosing the error and developing a solution. If a traceback doesn't appear in the log files, then try running in debug mode as noted in the CIME troubleshooting guide. An example of a traceback in the cesm log is given below (this specific example is from cesm2_2_beta05) :: 398: ERROR: Carbon or Nitrogen patch negative = -60.0630620423182 @@ -59,7 +288,7 @@ It is important to examine all of the component log files in the run directory f 398:libc.so.6 00002B8B95D306E5 __libc_start_main Unknown Unknown 398:cesm.exe 0000000000408C29 Unknown Unknown Unknown -Here, the output is identifying the sequence of Fortran statements involved in the error, starting with line 133 in cime_driver.F90 and ending with line 114 in shr_abort_mod.F90. In this case the run is triggering an error check in the model related to negative carbon/nitrogen at line 693 of CNPrecisionControlMod.F90. In addition, there is additional information related to the error indicating the carbon or nitrogen state is critically negative at line 209 in CNPrecisionControlMod.F90, which is +Here, the output is identifying the sequence of Fortran statements involved in the error, starting with line 133 in ``cime_driver.F90`` and ending with line 114 in ``shr_abort_mod.F90``. In this case the run is triggering an error check in the model related to negative carbon/nitrogen at line 693 of ``CNPrecisionControlMod.F90``. In addition, there is additional information related to the error indicating the carbon or nitrogen state is critically negative at line 207 in ``CNPrecisionControlMod.F90``, which is a subroutine call :: call TruncateCandNStates( bounds, filter_soilp, num_soilp, cs%leafc_patch(bounds%begp:bounds%endp), & @@ -72,7 +301,6 @@ So here we know that it is either leaf nitrogen (leafn) or leaf carbon (leafc) t At this point it is useful as a next step to identify the particular patch index and perhaps the pft type that is triggering the error. In this case, the endrun call is already written to provide this information: the patch index and pft type causing the error, along with some other information, are printed in the lines beginning with ``iam``. The ``iam`` value gives the CTSM processor number (this can be obtained in the code via the ``iam`` variable defined in ``spmdMod``). The local patch index is the value of ``p`` in the current patch loop; "local" implies that it refers to this processor's indexing. However, this same value of ``p`` may appear on other processors, since the local indexing on each processor starts with 1. So, to get the unique patch causing the problem, you either need to use the processor's ``iam`` index (there is only one patch with local index 482 on processor 362), or use the global indices printed below the local index. The "global" term here refers to the global index space across all processors (there is only one patch with a global index of 163723 across all processors). See below for how to use the ``get_global_index`` function to translate from local to global indices. If you are writing your own ``endrun`` call, you can get this additional information by specifying the ``subgrid_index`` and ``subgrid_level`` arguments; for example: - :: call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, msg=errMsg(sourcefile, __LINE__)) @@ -80,7 +308,6 @@ If you are writing your own ``endrun`` call, you can get this additional informa (The ``subgrid_level_patch`` constant, and similar constants for the other subgrid levels, are defined in ``decompMod``, so can be accessed via ``use decompMod, only : subgrid_level_patch``.) You can get this same information without aborting the run via a call to ``write_point_context``, which is also defined in the ``abortutils`` module; e.g.: - :: if (abs(carbon_patch(p)) < ccrit) then @@ -88,7 +315,6 @@ You can get this same information without aborting the run via a call to ``write end if Or, if all you want is the global index of ``p`` for the sake of writing extra diagnostic prints like the example below, then you can use the ``get_global_index`` function defined in ``decompMod``, like: - :: if (abs(carbon_patch(p)) < ccrit) then @@ -96,10 +322,9 @@ Or, if all you want is the global index of ``p`` for the sake of writing extra d p, get_global_index(subgrid_index=p, subgrid_level=subgrid_level_patch) end if -In all of these cases, the output will appear in either the cesm or lnd log file. In the above example, we see that the local patch index is 482 on processor 362 and the global patch index is 163723. From there, one can use this patch index to write out variables that are used in updating leafc, for example, leafc is updated a number of times in CNCStateUpdate1Mod.F90. +In all of these cases, the output will appear in either the cesm or lnd log file. In the above example, we see that the local patch index is 482 on processor 362 and the global patch index is 163723. From there, one can use this patch index to write out variables that are used in updating leafc, for example, leafc is updated a number of times in ``CNCStateUpdate1Mod.F90``. There are two equivalent methods to write a conditional statement to provide more output for the problem patch within a loop over all patches. The first method is to translate the local index to a global index: - :: use decompMod, only : get_global_index, subgrid_level_patch @@ -110,7 +335,6 @@ There are two equivalent methods to write a conditional statement to provide mor end if The second method is to use the local index along with the processor number: - :: use spmdMod, only : iam @@ -122,10 +346,13 @@ The second method is to use the local index along with the processor number: By placing these write statements in the code, one can get a sense of how leafc is evolving toward a negative state and why. This is a very complex example of troubleshooting. To make a long story short, as described `here `_, the error turned out to be caused by a few lines in the phenology code that weren't handling a 20 minute time step properly, thus an actual bug in the code. This was also a good example of where a much less computationally expensive land-only simulation was able to be used for debugging instead of the orginal expensive fully-coupled simulation. -Another method of troubleshooting is to use the ``point_of_interest`` module. +Another method of troubleshooting is to :ref:`Use the point_of_interest module`. + +.. _Use the point_of_interest module: +===================================================================================================== Use the point_of_interest module --------------------------------- +===================================================================================================== It is common, when debugging, to want to print the values of various variables for all patches or columns of certain landunit types within a certain grid cell of interest. For example, one might be able to identify a certain grid cell with an erroneous value for a particular history field variable (e.g., GPP) using for example ncview. Once the latitude and longitude of this grid cell has been determined, the point_of_interest module (``src/utils/point_of_interest.F90``) helps create the logical functions needed to do this. This module is compiled into every CTSM build, but is not invoked by default. To use it @@ -159,8 +386,9 @@ Here are some other suggestions on how to track down a problem encountered while #. *Run a simpler case* #. *Run with a debugger* +===================================================================================================== Run with a smaller set of processors ------------------------------------- +===================================================================================================== One way to simplify the system is to run with a smaller set of processors. You will need to clean the setup and edit ``env_mach_pes.xml``. For example, to run with four processors: :: @@ -171,8 +399,9 @@ One way to simplify the system is to run with a smaller set of processors. You w Another recommended simplification is to run without threading, so set the NTHRDS for each component to "1" if it isn't already. Sometimes, multiprocessing problems require a certain number of processors before they occur so you may not be able to debug the problem without enough processors. But, it's always good to reduce it to as low a number as possible to make it simpler. For threading problems you may have to have threading enabled to find the problem, but you can run with 1, 2, or 3 threads to see what happens. +===================================================================================================== Run in serial mode with a single processor ------------------------------------------- +===================================================================================================== Simplifying to one processor removes all multi-processing problems and makes the case as simple as possible. If you can enable ``MPILIB=mpi-serial`` you will also be able to run interactively rather than having to submit to a job queue, which sometimes makes it easier to run and debug. If you can use ``MPILIB=mpi-serial`` you can also use threading, but still run interactively in order to use more processors to make it faster if needed. :: @@ -190,18 +419,21 @@ Simplifying to one processor removes all multi-processing problems and makes the # Then build your case # And finally run, by running the *.run script interactively +===================================================================================================== Run at a lower resolution -------------------------- +===================================================================================================== If you can create a new case running at a lower resolution and replicate the problem it may be easier to solve. This of course requires creating a whole new case, and trying out different lower resolutions. +===================================================================================================== Run a simpler case ------------------- +===================================================================================================== Along the same lines, you might try running a simpler case, trying another compset with a simpler setup and see if you can replicate the problem and then debug from that simpler case. Again, of course you will need to create new cases to do this. +===================================================================================================== Run with a debugger -------------------- +===================================================================================================== Another suggestion is to run the model with a debugger such as: ``ddt``, ``dbx``, ``gdb``, or ``totalview``. Often to run with a debugger you will need to reduce the number of processors as outlined above. Some debuggers such as ``dbx`` will only work with one processor, while more advanced debuggers such as ``totalview`` can work with both MPI tasks and OMP threads. Even simple debuggers though can be used to query core files, to see where the code was at when it died (for example using the ``where`` in ``dbx`` for a core file can be very helpful. For help in running with a debugger you will need to contact your system administrators for the machine you are running on. diff --git a/doc/source/users_guide/using-clm-tools/GlobalDomain.jpeg b/doc/source/users_guide/using-clm-tools/GlobalDomain.jpeg deleted file mode 100644 index 7e2df5ad90..0000000000 --- a/doc/source/users_guide/using-clm-tools/GlobalDomain.jpeg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9000cdb3c7761a9838e9af059f36dfcc204c7a02bdab6d5206da0de1bf3051ac -size 38541 diff --git a/doc/source/users_guide/using-clm-tools/LegendCLMToolDataFlow.jpeg b/doc/source/users_guide/using-clm-tools/LegendCLMToolDataFlow.jpeg deleted file mode 100644 index e0f1559cbd..0000000000 --- a/doc/source/users_guide/using-clm-tools/LegendCLMToolDataFlow.jpeg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d71ecdf638e4582f66f1c2b101b6548bd9d47fe2cb3de0f58386048f6ce6cfbc -size 15711 diff --git a/doc/source/users_guide/using-clm-tools/building-the-clm-tools.rst b/doc/source/users_guide/using-clm-tools/building-the-clm-tools.rst deleted file mode 100644 index b0d30d11c7..0000000000 --- a/doc/source/users_guide/using-clm-tools/building-the-clm-tools.rst +++ /dev/null @@ -1,24 +0,0 @@ -======================== - Building the CLM tools -======================== - -.. include:: ../substitutions.rst - -.. todo:: - Update the below, as domain files aren't needed with nuopc. - -The tools **cprnc** and **gen_domain** use the CIME configure/build system which is described in the next section. - -The only CLM FORTRAN tool is mksurfdata_esmf which has it's own build system that takes advantage of the cime build. - -================================================================ - Building the CLM tools that use the CIME configure/build system -================================================================ - -.. todo:: - Update the below, as domain files aren't needed with nuopc. - -``cprnc`` and ``gen_domain`` both use the CIME configure/build system rather than the CLM specific version described above. - -See `CIME documentation on adding grids `_ for more information on adding grids, creating mapping files, and running ``gen_domain``. Also see the CIME file: ``$CTSMROOT/tools/mapping/gen_domain_files/INSTALL`` for how to build ``gen_domain``. - diff --git a/doc/source/users_guide/using-clm-tools/cprnc.rst b/doc/source/users_guide/using-clm-tools/cprnc.rst index 81418877c9..bae6982fd6 100644 --- a/doc/source/users_guide/using-clm-tools/cprnc.rst +++ b/doc/source/users_guide/using-clm-tools/cprnc.rst @@ -20,5 +20,5 @@ Options: -kpr -See the ``cprnc`` `README `_ file for more details. +See the ``cprnc`` `README `_ file for more details. diff --git a/doc/source/users_guide/using-clm-tools/creating-domain-files.rst b/doc/source/users_guide/using-clm-tools/creating-domain-files.rst deleted file mode 100644 index 90814e1927..0000000000 --- a/doc/source/users_guide/using-clm-tools/creating-domain-files.rst +++ /dev/null @@ -1,40 +0,0 @@ -.. include:: ../substitutions.rst - -.. _creating-domain-files: - -***************************** - Creating CLM domain files -***************************** - -.. todo:: - Delete this page? Domain files aren't needed with nuopc. - -``gen_domain`` to create a domain file for datm from a mapping file. ``gen_domain`` is a tool that is a part of CIME. The domain file is then used by BOTH DATM AND CLM to define the grid and land-mask. The general data flow is shown in two figures. :numref:`Figure mkmapdata.sh` shows the general flow for a general global case (or for a regional grid that DOES include ocean). :numref:`Figure mknoocnmap.pl` shows the use of ``mknoocnmap.pl`` (see :ref:`using-mkocnmap`) to create a regional or single-point map file that is then run through ``gen_domain`` to create the domain file for it. As stated before :numref:`Figure Data_Flow_Legend` is the legend for both of these figures. See `the $CIMEROOT/tools/mapping/gen_domain_files/README `_ file for more help on ``gen_domain``. - -Here we create domain files for a regular global domain. - -Global Domain file creation -=========================== - -.. _Figure Global-Domain: - -.. figure:: GlobalDomain.jpeg - - Global Domain file creation - -Starting from SCRIP grid files for both your atmosphere and ocean, you use ``$CIMEROOT/tools/mapping/gen_mapping_files/gen_cesm_maps.sh`` to create a mapping file between the atmosphere and ocean. That mapping file is then used as input to ``gen_domain`` to create output domain files for both atmosphere and ocean. The atmosphere domain file is then used by both CLM and DATM for I compsets, while the ocean domain file is ignored. For this process you have to define your SCRIP grid files on your own. For a regional or single-point case that doesn't include ocean see :numref:`Figure mknoocnmap.pl`. (See :numref:`Figure Global-Domain` for the legend for this figure.) - -Note that the SCRIP grid file used to start this process is also used in ``mkmapdata.sh`` (see :ref:`using-mkocnmap`). Next we create domain files for a single-point or regional domain. - -Domain file creation using mknoocnmap.pl -======================================== - -.. _Figure mknoocnmap.pl: - -.. figure:: mknoocnmap.jpeg - - Domain file creation using mknoocnmap.pl - -For a regular latitude/longitude grid that can be used for regional or single point simulations -- you can use ``mknoocnmap.pl``. It creates a SCRIP grid file that can then be used as input to ``mkmapdata.sh`` as well as a SCRIP mapping file that is then input to ``gen_domain``. The output of ``gen_domain`` is a atmosphere domain file used by both CLM and DATM and a ocean domain file that is ignored. (See :numref:`Figure mknoocnmap.pl` for the legend for this figure.) - -In this case the process creates both SCRIP grid files to be used by ``mkmapdata.sh`` as well as the domain files that will be used by both CLM and DATM. diff --git a/doc/source/users_guide/using-clm-tools/creating-input-for-surface-dataset-generation.rst b/doc/source/users_guide/using-clm-tools/creating-input-for-surface-dataset-generation.rst index 66a65adbde..0949236164 100644 --- a/doc/source/users_guide/using-clm-tools/creating-input-for-surface-dataset-generation.rst +++ b/doc/source/users_guide/using-clm-tools/creating-input-for-surface-dataset-generation.rst @@ -6,105 +6,10 @@ Creating input for surface dataset generation ********************************************* -Generating SCRIP grid files +Generating ESMF mesh files ================================== -The utility ``mkmapdata.sh`` requires SCRIP format input files to describe the input and output grids that maps are generated for. CLM provides a utility, ``mkmapgrids`` that generates those files. The program converts old formats of CAM or CLM grid files to SCRIP grid format. There is also a NCL script (``mkscripgrid.ncl``) to create regular latitude longitude regional or single-point grids at the resolution the user desires. +The ``mksurfdata_esmf`` tool requires ESMF mesh files to describe the input and output grids used for generating fsurdat and landuse files. CLM provides the ``mesh_maker`` tool for generating such files. See section :numref:`how-to-make-mesh` for details. -SCRIP grid files for all the standard model resolutions and the raw surface datasets have already been done and the files are in the XML database. Hence, this step doesn't need to be done -- EXCEPT WHEN YOU ARE CREATING YOUR OWN GRIDS. +ESMF mesh files for all the standard model resolutions and the raw surface datasets already exist and the files are in the XML database. Hence, you may skip this step -- UNLESS YOU ARE CREATING YOUR OWN GRIDS. -.. _using-mkocnmap: - -Using mknocnmap.pl to create grid and maps for single-point regional grids --------------------------------------------------------------------------- - -.. todo:: - Update the below, as domain files aren't needed with nuopc. - -If you want to create a regular latitude/longitude single-point or regional grid, we suggest you use ``mknoocnmap.pl`` in ``$CTSMROOT/tools/mkmapdata`` which will create both the SCRIP grid file you need (using ``$CTSMROOT/tools/mkmapgrids/mkscripgrid.ncl``) AND an identity mapping file assuming there is NO ocean in your grid domain. If you HAVE ocean in your domain you could modify the mask in the SCRIP grid file for ocean, and then use ``ESMF_RegridWeightGen`` to create the mapping file, and ``gen_domain`` to create the domain file. Like other tools, ``./mkmapdata/mknoocnmap.pl`` has a help option with the following: -:: - - SYNOPSIS - mknoocnmap.pl [options] Gets map and grid files for a single land-only point. - REQUIRED OPTIONS - -centerpoint [or -p] Center latitude,longitude of the grid to create. - -name [-or -n] Name to use to describe point - - OPTIONS - -dx Size of total grid in degrees in longitude direction - (default is 0.1) - -dy Size of total grid in degrees in latitude direction - (default is 0.1) - -silent [or -s] Make output silent - -help [or -h] Print usage to STDOUT. - -verbose [or -v] Make output more verbose. - -nx Number of longitudes (default is 1) - -ny Number of latitudes (default is 1) - -See :numref:`Figure mknoocnmap.pl` for a visual representation of this process. - -Creating mapping files for mksurfdata_esmf -============================================== - -``mkmapdata.sh`` uses the above SCRIP grid input files to create SCRIP mapping data files (uses ESMF). - -The bash shell script ``$CTSMROOT/tools/mkmapgrids/mkmapdata.sh`` uses ``ESMF_RegridWeightGen`` to create a list of maps from the raw datasets that are input to ``mksurfdata_esmf``. Each dataset that has a different grid, or land-mask needs a different mapping file for it, but many different raw datasets share the same grid/land-mask as other files. Hence, there doesn't need to be a different mapping file for EACH raw dataset---just for each raw dataset that has a DIFFERENT grid or land-mask. See :numref:`Figure mkmapdata.sh` for a visual representation of how this works. The bash script figures out which mapping files it needs to create and then runs ``ESMF_RegridWeightGen`` for each one. You can then either enter the datasets into the XML database (see Chapter :numref:`adding-new-resolutions-section`), or leave the files in place and use the ``-res usrspec -usr_gname -usr_gdate`` options to ``mksurfdata_esmf``. ``mkmapdata.sh`` has a help option with the following -:: - - ../../tools/mkmapdata/mkmapdata.sh - - ********************** - usage on cheyenne:Figure mkmapdata.sh - ./mkmapdata.sh - - valid arguments: - [-f|--gridfile ] - Full pathname of model SCRIP grid file to use - This variable should be set if this is not a supported grid - This variable will override the automatic generation of the - filename generated from the -res argument - the filename is generated ASSUMING that this is a supported - grid that has entries in the file namelist_defaults_clm.xml - the -r|--res argument MUST be specied if this argument is specified - [-r|--res ] - Model output resolution (default is 10x15) - [-t|--gridtype ] - Model output grid type - supported values are [regional,global], (default is global) - [-b|--batch] - Toggles batch mode usage. - If you want to run in batch mode - you need to have a separate batch script for a supported machine - that calls this script interactively - you cannot submit this - script directory to the batch system - [-l|--list] - List mapping files required (use check_input_data to get them) - also writes data to clm.input_data_list - [-d|--debug] - Toggles debug-only (don't actually run mkmapdata just echo what would happen) - [-h|--help] - Displays this help message - [-v|--verbose] - Toggle verbose usage -- log more information on what is happening - - You can also set the following env variables: - ESMFBIN_PATH - Path to ESMF binaries - (default is /contrib/esmf-5.3.0-64-O/bin) - CSMDATA ------ Path to CESM input data - (default is /glade/p/cesm/cseg/inputdata) - MPIEXEC ------ Name of mpirun executable - (default is mpirun.lsf) - REGRID_PROC -- Number of MPI processors to use - (default is 8) - - **pass environment variables by preceding above commands - with 'env var1=setting var2=setting ' - ********************** - -.. _Figure mkmapdata.sh: - -.. figure:: mkmapdata_details.jpeg - - Details of running mkmapdata.sh - -Each of the raw datasets for ``mksurfdata_esmf`` needs a mapping file to map from the output grid you are running on to the grid and land-mask for that dataset. This is what ``mkmapdata.sh`` does. To create the mapping files you need a SCRIP grid file to correspond with each resolution and land mask that you have a raw data file in ``mksurfdata_esmf``. Some raw datasets share the same grid and land mask -- hence they can share the same SCRIP grid file. The output maps created here go into ``mksurfdata_esmf`` see :numref:`Figure Workflow of CLM5 Land Use Data Tool and mksurfdata_esmf Tool`. diff --git a/doc/source/users_guide/using-clm-tools/creating-surface-datasets.rst b/doc/source/users_guide/using-clm-tools/creating-surface-datasets.rst index bb07a7414f..f45afe9ec6 100644 --- a/doc/source/users_guide/using-clm-tools/creating-surface-datasets.rst +++ b/doc/source/users_guide/using-clm-tools/creating-surface-datasets.rst @@ -2,59 +2,72 @@ .. _creating-surface-datasets: -=========================== - Creating Surface Datasets -=========================== +Creating Surface Datasets +========================= -When just creating a replacement file for an existing one, the relevant tool should be used directly to create the file. When you are creating a set of files for a new resolution there are some dependencies between the tools that you need to keep in mind when creating them. The main dependency is that you MUST create a SCRIP grid file first as the SCRIP grid dataset is then input into the other tools. Also look at Table :numref:`reqd-files-table` which gives information on the files required and when. :numref:`Figure Data_Flow` shows an overview of the general data-flow for creation of the fsurdat datasets. +mksurfdata_esmf purpose +----------------------- -.. _Figure Data_Flow: +This tool is intended to generate fsurdat files (surface datasets) and landuse files for the CTSM. It can generate global, regional, and single-point fsurdat files, as long as a mesh file is available for the grid. -.. figure:: mkmapdata_mksurfdata.jpeg +The subset_data tool allows users to make fsurdat files from existing fsurdat files when a mesh file is unavailable. Generally, users are encouraged to use the subset_data tool for generating regional and single-point fsurdat files. - Data Flow for Creation of Surface Datasets from Raw SCRIP Grid Files +Build Requirements +------------------ -Starting from a SCRIP grid file that describes the grid you will run the model on, you first run ```mkmapdata.sh`` to create a list of mapping files. See :numref:`Figure mkmapdata.sh` for a more detailed view of how ``mkmapdata.sh`` works. The mapping files tell ``mksurfdata_esmf`` how to map between the output grid and the raw datasets that it uses as input. The output of ``mksurfdata_esmf`` is a surface dataset that you then use for running the model. See :numref:`Figure Workflow of CLM5 Land Use Data Tool and mksurfdata_esmf Tool` for a more detailed view of how ``mksurfdata_esmf`` works. +mksurfdata_esmf is a distributed memory parallel program (using Message Passing Interface -- MPI) that utilizes both ESMF (Earth System Modelling Framework) for regridding as well as PIO (Parallel I/O) and NetCDF output. As such, libraries must be built for the following: -:numref:`Figure Data_Flow_Legend` is the legend for this figure (:numref:`Figure Data_Flow`) and other figures in this chapter (:numref:`Figure Global-Domain` and :numref:`Figure mknoocnmap.pl`). +1. MPI +2. NetCDF +3. PIO +4. ESMF -.. _Figure Data_Flow_Legend: +In addition for the build: python, bash-shell, CMake and GNU-Make are required -.. figure:: LegendCLMToolDataFlow.jpeg +These libraries need to be built such that they can all work together in the same executable. Hence, the above order may be required in building them. - Legend for Data Flow Figures +CTSM submodules cime and ccs_config are required, and we will show how these come in. A python environment that includes particular packages is also required. We demonstrate how to use the ctsm_pylib environment that we support in CTSM. -Green arrows define the input to a program, while red arrows define the output. Cylinders define files that are either created by a program or used as input for a program. Boxes are programs. +Note, PNETCDF is an optional library that can be used, but is NOT required. -You start with a description of a SCRIP grid file for your output grid file and then create mapping files from the raw datasets to it. Once, the mapping files are created ``mksurfdata_esmf`` is run to create the surface dataset to run the model. +.. rubric:: Use cime to manage the build requirements -Creating a Complete Set of Files for Input to CLM -------------------------------------------------- +.. important:: -1. Create SCRIP grid datasets (if NOT already done) + CURRENTLY WORKS ONLY ON DERECHO IN CTSM (not CESM) CHECKOUTS - First you need to create a descriptor file for your grid, that includes the locations of cell centers and cell corners. There is also a "mask" field, but in this case the mask is set to one everywhere (i.e. all of the masks for the output model grid are "nomask"). An example SCRIP grid file is: ``$CSMDATA/lnd/clm2/mappingdata/grids/SCRIPgrid_10x15_nomask_c110308.nc``. The ``mkmapgrids`` and ``mkscripgrid.ncl`` NCL script in the ``$CTSMROOT/tools/mkmapgrids`` directory can help you with this. SCRIP grid files for all the standard CLM grids are already created for you. See the Section called Creating an output SCRIP grid file at a resolution to run the model on for more information on this. +For users working on cime machines you can use the build script to build the tool. On other machines you'll need to do a port to cime and tell how to build for that machine. That's talked about in the cime documentation. And you'll have to make some modifications to the build script. -.. todo:: - Update the below, as domain files aren't needed with nuopc. +https://github.com/ESMCI/cime/wiki/Porting-Overview -2. Create domain dataset (if NOT already done) +Machines that already run CTSM or CESM have been ported to cime. So if you can run the model on your machine, you will be able to build the tool there. - Next use ``gen_domain`` to create a domain file for use by DATM and CLM. This is required, unless a domain file was already created. See the Section called Creating a domain file for CLM and DATM for more information on this. +To get a list of the machines that have been ported to cime: -3. Create mapping files for ``mksurfdata_esmf`` (if NOT already done) +.. code-block:: - Create mapping files for ``mksurfdata_esmf`` with ``mkmapdata.sh`` in ``$CTSMROOT/tools/mkmapdata``. See the Section called Creating mapping files that ``mksurfdata_esmf`` will use for more information on this. + # Assuming pwd is your CTSM or CESM checkout + cd cime/scripts + ./query_config --machines -4. Create surface datasets +.. note:: - Next use ``mksurfdata_esmf`` to create a surface dataset, using the mapping datasets created on the previous step as input. There is a version for either clm4_0 or |version| for this program. See the Section called Using ``mksurfdata_esmf`` to create surface datasets from grid datasets for more information on this. + In addition to having a port to cime, the machine also needs to have PIO built and able to be referenced with the env variable PIO which will need to be in the porting instructions for the machine. An independent PIO library is available on supported CESM machines. -5. Enter the new datasets into the ``build-namelist`` XML database - The last optional thing to do is to enter the new datasets into the ``build-namelist`` XML database. See Chapter 3 for more information on doing this. This is optional because the user may enter these files into their namelists manually. The advantage of entering them into the database is so that they automatically come up when you create new cases. +.. important:: -The ``$CTSMROOT/tools/README.md`` goes through the complete process for creating input files needed to run CLM. We repeat that file here: + Currently we have run and tested mksurfdata_esmf on Derecho. Please see this github issue about mksurfdata_esmf on other CESM machines: + +https://github.com/ESCOMP/CTSM/issues/2341 + +The complete process +-------------------- + +If you have read the previous section, you are ready to proceed. The ``$CTSMROOT/tools/README.md`` goes through the complete process for creating input files needed to run CLM. The ``$CTSMROOT/tools/mksurfdata_esmf/README.md`` specifically goes through the complete process of generating surface and landuse datasets. We repeat those files here: .. include:: ../../../../tools/README.md :code: markdown +.. include:: ../../../../tools/mksurfdata_esmf/README.md + :code: markdown + diff --git a/doc/source/users_guide/using-clm-tools/index.rst b/doc/source/users_guide/using-clm-tools/index.rst index b721b3e7d6..53e904b6c4 100644 --- a/doc/source/users_guide/using-clm-tools/index.rst +++ b/doc/source/users_guide/using-clm-tools/index.rst @@ -15,11 +15,9 @@ Using CLM tools :maxdepth: 2 what-are-the-clm-tools.rst - building-the-clm-tools.rst using-ctsm-pylib.rst creating-input-for-surface-dataset-generation.rst creating-surface-datasets.rst - creating-domain-files.rst observational-sites-datasets.rst cprnc.rst paramfile-tools.md diff --git a/doc/source/users_guide/using-clm-tools/mkmapdata_details.jpeg b/doc/source/users_guide/using-clm-tools/mkmapdata_details.jpeg deleted file mode 100644 index b8d33578b8..0000000000 --- a/doc/source/users_guide/using-clm-tools/mkmapdata_details.jpeg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:56399b80b49aa4705b27a0e98758b120f78c4eb62d993f85944db2c1d2122d0f -size 51018 diff --git a/doc/source/users_guide/using-clm-tools/mkmapdata_mksurfdata.jpeg b/doc/source/users_guide/using-clm-tools/mkmapdata_mksurfdata.jpeg deleted file mode 100644 index 7e59cee7f3..0000000000 --- a/doc/source/users_guide/using-clm-tools/mkmapdata_mksurfdata.jpeg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d85feb3d5c6aba70963f51b10406cd45ff334c60f2daf965ccb9b1abbc158985 -size 41951 diff --git a/doc/source/users_guide/using-clm-tools/mknoocnmap.jpeg b/doc/source/users_guide/using-clm-tools/mknoocnmap.jpeg deleted file mode 100644 index 308fde0e1c..0000000000 --- a/doc/source/users_guide/using-clm-tools/mknoocnmap.jpeg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2c4d6c677d6e68761f9c6677be4bc94d93cd75c26989c834cd3e022db432359d -size 33914 diff --git a/doc/source/users_guide/using-clm-tools/mksurfdata_details.jpeg b/doc/source/users_guide/using-clm-tools/mksurfdata_details.jpeg deleted file mode 100644 index 9d6e829891..0000000000 --- a/doc/source/users_guide/using-clm-tools/mksurfdata_details.jpeg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:32104479195bd2612b09df1322b97c5b2db220d8d0115e32e6020e17ade597e0 -size 41837 diff --git a/doc/source/users_guide/using-clm-tools/observational-sites-datasets.rst b/doc/source/users_guide/using-clm-tools/observational-sites-datasets.rst index 71f4783b92..54c48e5e03 100644 --- a/doc/source/users_guide/using-clm-tools/observational-sites-datasets.rst +++ b/doc/source/users_guide/using-clm-tools/observational-sites-datasets.rst @@ -6,9 +6,8 @@ Observational Sites Datasets ******************************* -.. todo:: - Update this. +A way to customize the model input datasets is to customize the inputs to the tools that create the datasets. One can also overwrite the data of already generated datasets. Depending on the tool, the dataset, and the planned simulation, one way or the other may be simpler, or a combination of both methods may make sense. -There are two ways to customize datasets for a particular observational site. The first is to customize the input to the tools that create the dataset, and the second is to overwrite the default data after you've created a given dataset. Depending on the tool it might be easier to do it one way or the other. In Table :numref:`reqd-files-table` we list the files that are most likely to be customized and the way they might be customized. Of those files, the ones you are most likely to customize are: ``fatmlndfrc``, ``fsurdat``, ``faerdep`` (for DATM), and ``stream_fldfilename_ndep``. Note ``mksurfdata_esmf`` as documented previously has options to overwrite the vegetation and soil types. For more information on this also see :ref:`generic_single_point_runs`. +Files that you may customize include ``fatmlndfrc``, ``fsurdat``, ``faerdep`` (for DATM), and ``stream_fldfilename_ndep``. To customize ``fsurdat`` files, one may modify the inputs needed by the ``mksurfdata_esmf`` tool. In addition (or instead) we strongly recommend using the ``subset_data`` tool for single-point and regional simulations (see :ref:`generic_single_point_runs`). A combination of methods may make the most sense in some cases. -Another aspect of customizing your input datasets is customizing the input atmospheric forcing datasets; see :ref:`generic_single_point_runs` for more information on this. +Another aspect of customizing your input datasets is customizing the input atmospheric forcing datasets; see :ref:`generic_single_point_runs` for information on this. diff --git a/doc/source/users_guide/using-clm-tools/paramfile-tools.md b/doc/source/users_guide/using-clm-tools/paramfile-tools.md index eddba06d94..84b4d496eb 100644 --- a/doc/source/users_guide/using-clm-tools/paramfile-tools.md +++ b/doc/source/users_guide/using-clm-tools/paramfile-tools.md @@ -3,7 +3,7 @@ This guide describes the features and usage of the `query_paramfile` and `set_paramfile` tools, located in `tools/param_utils/`. These utilities help users inspect and modify CLM parameter files. -Note that you need to have the `ctsm_pylib` conda environment activated to use these tools. See Sect. :numref:`using-ctsm-pylib` for more information. +Note that you need to have the `ctsm_pylib` conda environment activated to use these tools. See Sect. {numref}`using-ctsm-pylib` for more information. ## `query_paramfile` **Purpose:** Print the values of one or more parameters from a CTSM parameter file (netCDF format). diff --git a/doc/source/users_guide/using-clm-tools/using-ctsm-pylib.rst b/doc/source/users_guide/using-clm-tools/using-ctsm-pylib.rst index da4ba0eb05..8975556596 100644 --- a/doc/source/users_guide/using-clm-tools/using-ctsm-pylib.rst +++ b/doc/source/users_guide/using-clm-tools/using-ctsm-pylib.rst @@ -12,3 +12,5 @@ Many of our Python-based tools require non-standard Python modules to be install ./py_env_create and that script will install the ``ctsm_pylib`` environment for you. If ``ctsm_pylib`` already exists, it will give you options on how to handle that. + +As CTSM Python tools continue to be developed, they may evolve to require an updated version of ``ctsm_pylib``. If you encounter "Module not found" errors, you may need to run ``py_env_create`` again; for a given CTSM commit (version), this will always install what's needed to run all the CTSM Python tools in that commmit. diff --git a/doc/source/users_guide/using-clm-tools/what-are-the-clm-tools.rst b/doc/source/users_guide/using-clm-tools/what-are-the-clm-tools.rst index 27c7c8efe4..ce721ebbef 100644 --- a/doc/source/users_guide/using-clm-tools/what-are-the-clm-tools.rst +++ b/doc/source/users_guide/using-clm-tools/what-are-the-clm-tools.rst @@ -6,27 +6,13 @@ What are the CLM tools ======================== -.. todo:: - Remove references to mkprocdata_map? - There are several tools provided with CLM that allow you to create your own input datasets at resolutions you choose, or to interpolate initial conditions to a different resolution, or used to compare CLM history files between different cases. The tools are all available in the ``$CTSMROOT/tools`` directory. Most of the tools are FORTRAN stand-alone programs in their own directory, but there is also a suite of NCL scripts in the ``$CTSMROOT/tools//ncl_scripts`` directory, and some of the tools are scripts that may also call the ESMF regridding program. Some of the NCL scripts are very specialized and not meant for general use, and we won't document them here. They still contain documentation in the script itself and the README file in the tools directory. The tools produce files that can be used for CLM4.5 and |version|. They do **NOT** produce files that can be used for CLM4.0. If you need files for CLM4.0, you'll need to use a previous version of CLM. The list of generally important scripts and programs are as follows. -1. ``./mkmapgrids`` to create SCRIP grid data files from old CLM format grid files that can then be used to create new CLM datasets (deprecated). There is also a NCL script (``./mkmapgrids/mkscripgrid.ncl``) to create SCRIP grid files for regular latitude/longitude grids. - -#. ``./mkmapdata`` to create SCRIP mapping data file from SCRIP grid files (uses ESMF). - -#. ``mksurfdata_esmf`` to create surface datasets from grid datasets (clm4_0 and |version| versions). - -.. todo:: - Update the below, as domain files aren't needed with nuopc. - -#. *$CIMEROOT/tools/mapping/gen_domain_files/gen_domain* to create a domain file for datm from a mapping file. The domain file is then used by BOTH datm AND CLM to define the grid and land-mask. - -#. ``$CIMEROOT/tools/mapping/gen_domain_files/gen_domain`` to create a domain file for datm from a mapping file. The domain file is then used by BOTH datm AND CLM to define the grid and land-mask. +1. ``mksurfdata_esmf`` to create surface datasets from gridded datasets that we refer to as raw datasets (ctsm5_2 and newer versions). #. ``$CIMEROOT/tools/cprnc`` to compare two NetCDF files. @@ -40,21 +26,9 @@ In the following sections, we will outline how to make these files available for Running FORTRAN tools with namelists ------------------------------------ -``mksurfdata_esmf`` runs with a namelist that is read from standard input. Hence, you create a namelist and then run them by redirecting the namelist file into standard input as follows: -:: +``mksurfdata_esmf`` runs with a namelist that is read from standard input. First you create a namelist, then you create a jobscript that runs mksurfdata_esmf by redirecting the namelist file into standard input as follows:: ./program < namelist -**mksurfdata_esmf** also has a script that creates the namelist and runs the program for you. The namelist values are also documented along with the other namelists in the: -:: - - $CTSMROOT/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml`` file - ------------------------------------------------ -Running FORTRAN tools with command line options ------------------------------------------------ - -.. todo:: - Update the below, as domain files aren't needed with nuopc. +There is a tool that generates the namelist called ``$CTSMROOT/tools/mksurfdata_esmf/gen_mksurfdata_namelist.py``. The namelist contains information gathered from the file ``$CTSMROOT/tools/mksurfdata_esmf/gen_mksurfdata_namelist.xml``. There is also a tool that generates a jobscript for running, and this is called ``$CTSMROOT/tools/mksurfdata_esmf/gen_mksurfdata_jobscript_single.py``. -**gen_domain** and **cprnc** run with command line arguments. The detailed sections below will give you more information on the command line arguments specific to each tool. Also running the tool without any arguments will give you a general synopsis on how to run the tool. diff --git a/doc/source/users_guide/working-with-documentation/bld-prev-docs-casper.md b/doc/source/users_guide/working-with-documentation/bld-prev-docs-casper.md new file mode 100644 index 0000000000..9a650c9ca0 --- /dev/null +++ b/doc/source/users_guide/working-with-documentation/bld-prev-docs-casper.md @@ -0,0 +1,77 @@ +(bld-prev-docs-casper)= + +# Building and previewing the documentation on Casper (RECOMMENDED) + +```{contents} +:depth: 1 +:local: +``` + +## Initial Casper setup + +You don't need to install any software! This is why Casper is the recommended method for building and previewing the docs. + +## Building docs on Casper +Casper uses the Podman software for running containers like the one we recommend for building the CTSM documentation. Make sure it's enabled before building: `module load podman`. Then do: + +```{include} embed-build-cmd.md +``` + +See the "Container software or Conda environment" sections for {ref}`Mac ` or {ref}`Windows ` for more information on these two methods. + +```{tip} +[2026-04-07] If you get an error saying something like `Error: could not find a working conmon binary`, do this and retry: +~~~ +module load ncarenv/24.12 +module load podman +~~~ +The bug making this necessary should hopefully be resolved soon. It has to do with the installation of podman in the module `ncarenv/25.10`; see [this Slack thread](https://ncarhpcusergroup.slack.com/archives/C044MS8N3UP/p1775511217126589) for more information. +``` + +## Previewing docs on Casper + +There are a few different ways to do this. + +### Previewing docs on Casper with OnDemand + +```{tip} +This will be somewhat easier if your CTSM checkout is in (or symlinked to) your home directory (`$HOME`). +``` + +The simplest way to preview your built documentation on Casper is to use [NCAR's OnDemand service](https://ondemand.hpc.ucar.edu/pun/sys/dashboard). After you [open a new Casper Login VNC Desktop session](https://ondemand.hpc.ucar.edu/pun/sys/dashboard/batch_connect/sys/login_desktop_ncar/session_contexts/new), wait for it to start, then click the "Launch Casper Login VNC Desktop" button. This will open a Linux desktop in your browser. Click on the "Home" icon and navigate to your CTSM checkout, then the `doc/_build/html` directory, then open the `index.html` file. (If your checkout isn't in your home directory, you'll need to click on `Devices > /` in the sidebar of the window that opens, then navigate all the way to your checkout.) That should open it in the Linux desktop's Firefox, at which point you can browse around as usual. + +If you rebuild the documentation but don't see your changes updated in the webpage, and the reload button doesn't work, you may need to navigate to a different page and then come back. + +### Previewing docs on Casper via SSH tunnel + +If the OnDemand method doesn't work for whatever reason, open a terminal on your local machine and do this: +```shell +ssh YOUR_USERNAME@casper.hpc.ucar.edu echo $((10000 + $(id -u) % 50000)) +``` + +This will print an integer that we will call `YOUR_PORT`. + +Then open a new SSH connection to the server like so, replacing `YOUR_PORT` with the integer you got above: +```shell +ssh -L YOUR_PORT:localhost:YOUR_PORT YOUR_USERNAME@casper.hpc.ucar.edu +``` + +Once that's connected, we're going to spin up a web server. It's best to do this on a compute node rather than a login node. Use the `qinteractive` command to open an interactive session on a Casper compute node. (Find more info about `qinteractive` [here](https://ncar-hpc-docs.readthedocs.io/en/latest/pbs/#qinteractive).) + +Once your interactive compute session is open, start the web server in it like so (again replacing `YOUR_PORT`): +```shell +cd /path/to/your/ctsm/repo +cd doc/_build/html +python3 -m http.server YOUR_PORT +``` + +Now you're ready to view your documentation! Just open a web browser on your computer and navigate to `http://localhost:YOUR_PORT`. You should see a rendered version of the documentation that you can browse as usual. + +### Fallback preview method + +If neither of the above work, you can download the `doc/_build/html` directory to your computer (e.g., with `scp` or `rsync`) and open `html/index.html` in a web browser. + +### A note about previewing the docs + +```{include} embed-preview-menu.md +``` diff --git a/doc/source/users_guide/working-with-documentation/building-docs-prereqs-mac.md b/doc/source/users_guide/working-with-documentation/bld-prev-docs-mac.md similarity index 72% rename from doc/source/users_guide/working-with-documentation/building-docs-prereqs-mac.md rename to doc/source/users_guide/working-with-documentation/bld-prev-docs-mac.md index c5629ba0ea..3f4c15873d 100644 --- a/doc/source/users_guide/working-with-documentation/building-docs-prereqs-mac.md +++ b/doc/source/users_guide/working-with-documentation/bld-prev-docs-mac.md @@ -1,29 +1,35 @@ -.. _building-docs-prereqs-mac: +(bld-prev-docs-mac)= -# Initial setup: Mac +# Building and previewing the documentation on Mac + +```{contents} +:depth: 1 +:local: +``` + +## Initial Mac setup Note that you may need administrator privileges on your Mac for the installation steps detailed here. -.. _building-docs-git-tools: +(building-docs-git-tools)= -## Python +### Python To test whether you already have the required Python version, open a Terminal window and try the following: ```shell python3 --version ``` -If python3 is already set up, you'll see a version number. If that version is 3.7 or later, you should be ready as far as Python goes; continue to :ref:`additional-reqs`. +If python3 is already set up, you'll see a version number. If that version is 3.7 or later, you should be ready as far as Python goes; continue to {ref}`additional-reqs`. -If not, recent versions of macOS should print a messsage saying, "xcode-select: No developer tools were found, requesting install." A dialog box will then pop up that says, "The 'python3' command requires the command line developer tools. Would you like to install the tools now?" Press Install and go through the installation process. This will take a while; once it's done, test by doing ``python3 --version`` again. (You may need to open a new Terminal window.) If the printed version number looks good, continue to :ref:`additional-reqs`. +If not, recent versions of macOS should print a messsage saying, "xcode-select: No developer tools were found, requesting install." A dialog box will then pop up that says, "The 'python3' command requires the command line developer tools. Would you like to install the tools now?" Press Install and go through the installation process. This will take a while; once it's done, test by doing ``python3 --version`` again. (You may need to open a new Terminal window.) If the printed version number looks good, continue to {ref}`additional-reqs`. -.. - The paragraph above was tested 2025-04-25 on a fresh-ish installation of macOS 15.3.2. +% The paragraph above was tested 2025-04-25 on a fresh-ish installation of macOS 15.3.2. -If instead `python3` gives "command not found," or the version is less than 3.7, you might need to install Python; continue to :ref:`aliasing-python3-to-python`. Otherwise, continue to :ref:`additional-reqs`. +If instead `python3` gives "command not found," or the version is less than 3.7, you might need to install Python; continue to {ref}`aliasing-python3-to-python`. Otherwise, continue to {ref}`additional-reqs`. -.. _aliasing-python3-to-python: +(aliasing-python3-to-python)= -### Aliasing `python3` to `python` +#### Aliasing `python3` to `python` Try the same command as above, but instead of `python3` just do `python` (no number). If that version is 3.7 or later, you can tell your Mac that when you say `python3` you want it to use `python`: ```bash echo alias python3="$(which python)" >> ~/.bashrc @@ -32,10 +38,10 @@ echo alias python3="$(which python)" >> ~/.zshrc This will make it so that bash scripts, like what we use to build our docs, know what to do for `python3`. `python3` will also be available in new Terminal sessions if your shell is `zsh` (the default since macOS 10.15) or `bash`. -If you were able to do this, you can continue to :ref:`additional-reqs`. If not, continue to the next section. +If you were able to do this, you can continue to {ref}`additional-reqs`. If not, continue to the next section. -### Conda -If your `python` doesn't exist or is too old, we suggest using Python via Conda. First, check whether you already have Conda installed: :ref:`do-i-already-have-conda` If not, install Conda (:ref:`installing-conda-for-docs`), then come back here. +#### Conda +If your `python` doesn't exist or is too old, we suggest using Python via Conda. First, check whether you already have Conda installed: {ref}`do-i-already-have-conda` If not, install Conda ({ref}`installing-conda-for-docs`), then come back here. Try this to check the Python version in the `base` Conda environment: ```shell @@ -44,16 +50,16 @@ conda run -n base python3 --version Repeat with all your Conda environments as needed until you find one that's Python 3.7 or later. Let's say your `ENVNAME` environment works. In that case, just make sure to do `conda activate ENVNAME` before running the commands in the documentation-building instructions. -.. _additional-reqs: +(additional-reqs)= -## Additional requirements +### Additional requirements -.. _container-or-conda-mac: +(container-or-conda-mac)= -### Container software or Conda environment +#### Container software or Conda environment We recommend building the software in what's called a container—basically a tiny little operating system with just some apps and utilities needed by the doc-building process. This is nice because, if we change the doc-building process in ways that require new versions of those apps and utilities, that will be completely invisible to you. You won't need to manually do anything to update your setup to work with the new process; it'll just happen automatically. -We recommend using the container software Podman, which you can install with Homebrew. (:ref:`install-homebrew-mac`) +We recommend using the container software Podman, which you can install with Homebrew. ({ref}`install-homebrew-mac`) 1. Install Podman with `brew install podman`. 1. Set up and start a Podman "virtual machine" with `podman machine init --now`. @@ -61,12 +67,12 @@ We recommend using the container software Podman, which you can install with Hom You may not be able to install Podman or any other containerization software, so there is an alternative method: a Conda environment. -1. Install Conda, if needed (see :ref:`installing-conda-for-docs`). -1. Follow the instructions for setting up the `ctsm_pylib` Conda environment in Sect. :numref:`using-ctsm-pylib`. +1. Install Conda, if needed (see {ref}`installing-conda-for-docs`). +1. Follow the instructions for setting up the `ctsm_pylib` Conda environment in Sect. {numref}`using-ctsm-pylib`. -.. _docs-git-tools: +(docs-git-tools)= -### Git tools +#### Git tools Note: Do this section after handling Python, because the Python installation process might bring the Git tools with it. To test whether you have the required Git tools already, open a Terminal window and try the following: @@ -75,27 +81,27 @@ git --version git-lfs --version ``` -If either of those fail with "command not found," you'll need to install them. The recommended way is with Homebrew. (:ref:`install-homebrew-mac`) +If either of those fail with "command not found," you'll need to install them. The recommended way is with Homebrew. ({ref}`install-homebrew-mac`) 2. Use Homebrew to [install Git](https://formulae.brew.sh/formula/git#default), if needed. 3. Use Homebrew to [install Git LFS](https://formulae.brew.sh/formula/git-lfs#default), if needed. -## Frequently-asked questions +### Frequently-asked questions -.. _what-kind-of-mac-chip: +(what-kind-of-mac-chip)= -### What kind of chip does my Mac have? +#### What kind of chip does my Mac have? For certain steps in this installation process, you may need to know whether your Mac has an Intel (`x86_64`) or an Apple Silicon (`arm64`) chip. If you don't know, visit Apple's [Mac computers with Apple silicon](https://support.apple.com/en-us/116943) page for instructions. -.. _install-homebrew-mac: +(install-homebrew-mac)= -### How do I install Homebrew? +#### How do I install Homebrew? 1. Install Homebrew using the instructions at https://brew.sh/. Make sure to follow the instructions during this process for adding Homebrew to your path. 1. Check your installation by making sure that `brew --version` doesn't error. -.. _do-i-already-have-conda: +(do-i-already-have-conda)= -### Do I already have Conda installed? +#### Do I already have Conda installed? You can check whether you have Conda installed like so: ```shell conda env list @@ -103,8 +109,8 @@ conda env list If that shows you something like ``` -# conda environments: -# +## conda environments: +## base /Users/you/... another_env /Users/you/.../... ... @@ -112,12 +118,30 @@ another_env /Users/you/.../... instead of the "command not found" error, then you do have conda installed! (Note that the second column doesn't really matter.) -.. _installing-conda-for-docs: +(installing-conda-for-docs)= -### How do I install Conda? +#### How do I install Conda? We suggest installing Conda, if needed, via Miniforge: -1. [Download Miniforge](https://conda-forge.org/download/) and install it. (:ref:`what-kind-of-mac-chip`) You can also [install Miniforge via Homebrew](https://formulae.brew.sh/cask/miniforge#default), if you already have that installed. (:ref:`install-homebrew-mac`) +1. [Download Miniforge](https://conda-forge.org/download/) and install it. ({ref}`what-kind-of-mac-chip`) You can also [install Miniforge via Homebrew](https://formulae.brew.sh/cask/miniforge#default), if you already have that installed. ({ref}`install-homebrew-mac`) 2. Activate Conda permanently in your shell by opening a new Terminal window and doing `conda init "$(basename $SHELL)"`. -You should now have `conda` and an up-to-date version of `python3` available, although will need to open another new Terminal window for it to work. \ No newline at end of file +You should now have `conda` and an up-to-date version of `python3` available, although will need to open another new Terminal window for it to work. + +## Building docs on Mac +Open a terminal window and navigate to your CTSM checkout. Then do: + +```{include} embed-build-cmd.md +``` + +See {ref}`container-or-conda-mac` for more information on those two methods. + +## Previewing docs on Mac + +You can open your build of the documentation in your default browser with +```shell +open _build/html/index.html +``` + +```{include} embed-preview-menu.md +``` diff --git a/doc/source/users_guide/working-with-documentation/building-docs-prereqs-windows.md b/doc/source/users_guide/working-with-documentation/bld-prev-docs-windows.md similarity index 73% rename from doc/source/users_guide/working-with-documentation/building-docs-prereqs-windows.md rename to doc/source/users_guide/working-with-documentation/bld-prev-docs-windows.md index ceb701b5cf..2894334199 100644 --- a/doc/source/users_guide/working-with-documentation/building-docs-prereqs-windows.md +++ b/doc/source/users_guide/working-with-documentation/bld-prev-docs-windows.md @@ -1,22 +1,29 @@ -.. _building-docs-prereqs-windows: +(bld-prev-docs-windows)= -# Initial setup: Windows +# Building and previewing the documentation on Windows + +```{contents} +:depth: 1 +:local: +``` + +## Initial Windows setup Note that you may need administrator privileges on your PC (or approval from your IT department) for various steps here. -.. _install-wsl: +(install-wsl)= -## Install Linux subsystem +### Install Linux subsystem We don't support building our documentation in the native Windows command-line environment. Thus, you will need to install a little version of Linux inside a virtual machine (VM) to use instead. The process for doing this varies depending on how tightly the installation process is controlled on your computer. -### NCAR computers +#### NCAR computers Please follow the [Windows Subsystem for Linux (WSL) setup instructions](https://wiki.ucar.edu/pages/viewpage.action?pageId=514032264&spaceKey=CONFIGMGMT&title=Setup) on the UCAR Wiki. In the step about installing a Linux distribution, choose Ubuntu. Feel free to peruse the [overall WSL documentation](https://wiki.ucar.edu/spaces/CONFIGMGMT/pages/514032242/Windows+Subsystem+for+Linux) on and linked from the UCAR Wiki for additional information. -### Non-NCAR computers +#### Non-NCAR computers If your computer is managed by an organization other than NCAR, please check with your IT department or equivalent for instructions on installing Windows Subsystem for Linux (WSL) and Ubuntu. Otherwise, follow these instructions: @@ -28,61 +35,61 @@ If Ubuntu opens in that last step but you see an error, you may need to manually Once Ubuntu is working and open, you'll be asked to create a new UNIX username and password. This doesn't have to match your Windows username and password, but do make sure to save this information somewhere secure. -.. _windows-docs-ubuntu-utilities: +(windows-docs-ubuntu-utilities)= -## Install utilities +### Install utilities Enter the following commands **into your Ubuntu terminal** to install any missing utilities we need (the `which ... ||` should make it so that no installation happens if you already have it): ```shell -# Refresh the list of available software +## Refresh the list of available software sudo apt-get update -# make: Part of the docs-building process +## make: Part of the docs-building process which make || sudo apt-get -y install make -# git and git-lfs, needed for getting and contributing to the CTSM code and docs +## git and git-lfs, needed for getting and contributing to the CTSM code and docs which git || sudo apt-get -y install git which git-lfs || sudo apt-get -y install git-lfs -# WSL utilities, which will give us the wslview command for opening HTML pages in a Windows browser +## WSL utilities, which will give us the wslview command for opening HTML pages in a Windows browser which wslview || sudo apt-get -y install wslu ``` -.. _container-or-conda-windows: +(container-or-conda-windows)= -## Install container software or Conda environment +### Install container software or Conda environment We recommend building the software in what's called a container—basically a tiny little operating system with just some apps and utilities needed by the doc-building process. This is nice because, if we change the doc-building process in ways that require new versions of those apps and utilities, that will be completely invisible to you. You won't need to manually do anything to update your setup to work with the new process; it'll just happen automatically. For builds in WSL (Ubuntu), we recommend using the container software Docker. You can install it in Ubuntu like so: ```shell -# If needed, download and run the Docker installation script. -# Ignore the message saying "We recommend using Docker Desktop for Windows." -# The script will make you wait 20 seconds to make sure this is want you want, -# and then it should continue automatically. +## If needed, download and run the Docker installation script. +## Ignore the message saying "We recommend using Docker Desktop for Windows." +## The script will make you wait 20 seconds to make sure this is want you want, +## and then it should continue automatically. which docker || curl -fsSL https://get.docker.com -o get-docker.sh which docker || sudo sh ./get-docker.sh -# Set up the docker "group," if needed, and add your username to it. +## Set up the docker "group," if needed, and add your username to it. sudo groupadd docker # Create docker group if it doesn't exist sudo usermod -aG docker $USER # Add your user to the docker group newgrp docker # Apply the new group membership (avoids needing to log out and back in) -# Make sure it worked: This should print a "Hello from Docker!" message +## Make sure it worked: This should print a "Hello from Docker!" message docker run hello-world ``` You may not be able to install Docker or any other containerization software, so there is an alternative method: a Conda environment. 1. Check whether you already have Conda installed by doing `which conda`. If that doesn't print anything, [install Miniconda](https://www.anaconda.com/docs/getting-started/miniconda/install#linux). -1. Follow the instructions for setting up the `ctsm_pylib` Conda environment in Sect. :numref:`using-ctsm-pylib`. +1. Follow the instructions for setting up the `ctsm_pylib` Conda environment in Sect. {numref}`using-ctsm-pylib`. -.. _editing-text-files-wsl: +(editing-text-files-wsl)= -## Editing documentation files +### Editing documentation files If you prefer using an old-school text editor like `vim`, it's probably already installed in your Ubuntu VM, or can be installed with `sudo apt-get -y install EDITOR_NAME`. If you prefer a more user-friendly interface, there are several options. Note that **all commands in this section are to be run in your Ubuntu VM, not a Windows terminal**. -### In a Windows app (recommended) +#### In a Windows app (recommended) If you installed `wslview` in the instructions above, you can edit files by doing ```shell wslview path/to/file_i_want_to_edit.rst @@ -103,7 +110,7 @@ If you use [VS Code](https://code.visualstudio.com/), you can install the [WSL V code path/to/file-or-folder ``` -### In an Ubuntu app (not recommended) +#### In an Ubuntu app (not recommended) You can also install a user-friendly text editor in Ubuntu. This may be slower and have unexpected differences in behavior from what you expect from Windows apps, but it does work. For example: - [gedit](https://gedit-text-editor.org/): `sudo apt-get install -y gedit` @@ -112,9 +119,9 @@ You can also install a user-friendly text editor in Ubuntu. This may be slower a You can use all of those to open and edit files, but Kate and VS Code let you open entire folders, which can be convenient. In any case, you'd do `EDITOR_NAME path/to/thing/youre/editing` to open it, where `EDITOR_NAME` is `gedit`, `kate`, or `code`, respectively. -## Troubleshooting +### Troubleshooting -### "Permission denied" error +#### "Permission denied" error If you get this error, it may be a result of opening Ubuntu as an administrator (e.g., by right-clicking on its icon and choosing "Run as administrator.") Try not doing that, although this will result in you needing to get a new copy of CTSM to work in. @@ -125,6 +132,28 @@ chown -R $USER:$USER $HOME If that also gives a permission error, you may need to put `sudo` at the start of the command. -### "The host 'wsl$' was not found in the list of allowed hosts" +#### "The host 'wsl$' was not found in the list of allowed hosts" You may see this warning in a dialog box after trying to open a file with `wslview`, `explorer.exe`, or something else. Check "Permanently allow host 'wsl$'" and then press "Allow". + +## Building docs on Windows (Ubuntu VM) +Open a WSL terminal window and navigate to your CTSM checkout. Then do: + +```{include} embed-build-cmd.md +``` + +See {ref}`container-or-conda-windows` for more information on those two methods. + +## Previewing docs on Windows (Ubuntu VM) +Assuming you installed the WSL Utilities in the {ref}`windows-docs-ubuntu-utilities` setup step, you can open your build of the documentation like so: +```shell +wslview _build/html/index.html +``` +If you didn't, you can do +```shell +explorer.exe $(wslpath -w _build/html/index.html) +``` +These both do the same thing, but the `wslview` method is simpler. Either way, at least the first time you do this, it will open a window asking which app you'd like to view the HTML file in. Choose a browser like Microsoft Edge or Chrome. At the bottom of the window, you can then choose whether you always want to open HTML files using the selected app or just this once. + +```{include} embed-preview-menu.md +``` diff --git a/doc/source/users_guide/working-with-documentation/building-docs-multiple-versions.rst b/doc/source/users_guide/working-with-documentation/building-docs-multiple-versions.rst index 895dbf2a65..e8a3e2f4df 100644 --- a/doc/source/users_guide/working-with-documentation/building-docs-multiple-versions.rst +++ b/doc/source/users_guide/working-with-documentation/building-docs-multiple-versions.rst @@ -5,14 +5,14 @@ Building multiple versions of the documentation There is a menu in the lower left of the webpage that lets readers switch between different versions of the documentation. To build a website with this menu properly set up—so that all our versions appear and all the links work—you need to use ``docs/build_docs_to_publish`` instead of ``docs/build_docs``. -Note that this is not necessary in order for you to contribute an update to the documentation. GitHub will test this automatically when you open a PR. But if you'd like to try, this will generate a local site for you in ``_publish/`` and then open it: +**Note that this is not necessary in order for you to contribute an update to the documentation.** GitHub will test this automatically when you open a PR. But if you'd like to try, this will generate a local site for you in ``_publish/`` and then open it: .. literalinclude:: ../../../test/test_container_eq_ctsm_pylib.sh :start-at: ./build_docs_to_publish :end-before: VERSION LINKS WILL NOT RESOLVE :append: CMD _publish/index.html # where CMD is open for Mac or wslview for Windows (Ubuntu VM) -**Note:** This is not yet supported with Podman on Linux (including Ubuntu VM on Windows). See `doc-builder Issue #27: build_docs_to_publish fails on Linux (maybe just Ubuntu?) with Podman `_. It does work with Docker on Linux, though. +**Note:** This may run into trouble with Podman on Linux (including Ubuntu VM on Windows, but **not** including Casper builds). See `doc-builder Issue #27: build_docs_to_publish fails on Linux (maybe just Ubuntu?) with Podman `_. It should definitely work with Docker on Linux, though. How this works @@ -26,4 +26,4 @@ How this works For each member of ``VERSION_LIST``, ``build_docs_to_publish`` checks out its ``ref``, then builds the documentation in a build directory. (``LATEST_REF`` is set because some files, folders, and submodules are important for how the build works and need to stay the same for each build.) Once the build is complete, ``build_docs_to_publish`` should reset your local repo copy (CTSM clone) to how it was before you called ``build_docs_to_publish``. -Next, ``build_docs_to_publish`` moves the HTML files from the build directory to the publish directory. The publish directory has a structure that matches the paths in the version dropdown menu's links. If a member of ``VERSION_LIST`` has ``landing_version=True``, its HTML will be at the top level. That makes it simple for people to find the default version of the docs at https://escomp.github.io/CTSM, rather than having to drill down further into something like ``https://escomp.github.io/CTSM/versions/latest``. +Next, ``build_docs_to_publish`` moves the HTML files from the build directory to the publish directory. The publish directory has a structure that matches the paths in the version dropdown menu's links. If a member of ``VERSION_LIST`` has ``landing_version=True``, its HTML will be at the top level. That makes it simple for people to find the default version of the docs at https://escomp.github.io/CTSM, rather than having to search for the latest version. diff --git a/doc/source/users_guide/working-with-documentation/building-docs-original-wiki.md b/doc/source/users_guide/working-with-documentation/building-docs-original-wiki.md index 63acab53a7..cc52558b1f 100644 --- a/doc/source/users_guide/working-with-documentation/building-docs-original-wiki.md +++ b/doc/source/users_guide/working-with-documentation/building-docs-original-wiki.md @@ -1,10 +1,9 @@ -.. _building-docs-original-wiki: +(building-docs-original-wiki)= # ⚠️ Original docs documentation from the GitHub Wiki -.. warning:: - - ⚠️⚠️⚠️WARNING⚠️⚠️⚠️ - The linked page contains documentation that (a) is more complicated than you probably require and (b) has not been fully checked for accuracy with the latest documentation setup. Unless you have a very good reason, you should probably go to :ref:`docs-intro-and-recommended`. +```{warning} + The linked page contains documentation that (a) is more complicated than you probably require and (b) has not been fully checked for accuracy with the latest documentation setup. Unless you have a very good reason, you should probably go to {ref}`docs-intro`. +``` If you're really sure you want to look at the old documentation instructions, they are preserved [here](https://github.com/ESCOMP/CTSM/wiki/Directions-for-editing-CLM-documentation-on-github-and-sphinx/af29e2b37c07581a8ebacaa49e7a9b0ecf6bb7f3). diff --git a/doc/source/users_guide/working-with-documentation/common-docs-errors.md b/doc/source/users_guide/working-with-documentation/common-docs-errors.md new file mode 100644 index 0000000000..1a1410db31 --- /dev/null +++ b/doc/source/users_guide/working-with-documentation/common-docs-errors.md @@ -0,0 +1,203 @@ +(common-docs-errors)= + +# Common doc build errors and how to handle them + +```{contents} +:depth: 2 +:local: +``` + +(common-doc-builder-errors)= + +## Common docs errors: doc-builder + +### "RuntimeError: No compatible container software found: docker, podman" + +You tried to build the documentation using our container (`./build_docs ... -d`) but didn't have any software running that could handle the container. Try again after starting up container software according to the instructions for your platform: +- {ref}`bld-prev-docs-casper` **(recommended)** +- {ref}`bld-prev-docs-mac` +- {ref}`bld-prev-docs-windows` + +### "Failed to fetch object" + +This can happen if you are trying to build from within a git worktree. The simplest solution is to clone a fresh copy of your working branch somewhere else and try from there. + +(common-rst-errors)= + +## Common docs errors: reStructuredText + +(error-unexpected-unindent)= + +### "ERROR: Unexpected indentation" + +Like Python, reStructuredText is very particular about how lines are indented. Indentation is used, for example, to denote [code ("literal") blocks](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks) and [quote blocks](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#lists-and-quote-like-blocks). An error like +``` +/path/to/file.rst:102: ERROR: Unexpected indentation. [docutils] +``` +indicates that line 102 is indented but not in a way that reStructuredText expects. There are lots of potential causes. + +#### Inconsistent indentation + +reStructuredText is whitespace-sensitive. Mixed tabs and spaces, or inconsistent indentation levels within the same block, will trigger this error. Use spaces only, and keep indentation consistent throughout a block (typically 3–4 spaces for directives). + +**Incorrect** (mixed indentation levels): + +```rst +.. note:: + + This line uses 3 spaces. + This line uses 4 spaces and will cause an error. +``` + +**Correct:** + +```rst +.. note:: + + This line uses 3 spaces. + This line also uses 3 spaces. +``` + +#### Indented content with no preceding context + +If a block appears indented but there is no list item, directive, or other block element directly above it, Sphinx has no way to interpret the indentation. Either remove the indentation or add the appropriate introducing element. + +**Incorrect:** + +```rst +This is a normal paragraph. + + This indented block has no context and will cause an error. +``` + +**Correct** (remove the indentation): + +```rst +This is a normal paragraph. + +This line is at the same level and causes no error. +``` + +**Correct** (add a introducing element): + +```rst +This is a normal paragraph:: + + Now this indented block is valid as a literal block, such as you might use for code. +``` + +#### Continuation of a list item broken by a blank line + +In rST, a blank line ends a list item. If you indent content after a blank line following a list item, Sphinx may misread it. To include multi-paragraph list items, indent all continuation paragraphs to match the list item content. + +**Incorrect:** + +```rst +- First item. + + This paragraph looks like it continues the list item, but the + indentation level doesn't match, causing an error. + +- Second item. +``` + +**Correct:** + +```rst +- First item. + + This paragraph correctly continues the list item using + consistent 2-space indentation. + +- Second item. +``` + +#### Misformatted directives + +Directives require a blank line between the directive header (and any options) and the directive body. Missing or extra blank lines inside a directive block are a frequent source of this error. Double-check that your directive follows this structure: + +``` +.. directive-name:: argument + :option: value + + Body content starts here, indented consistently. +``` + +#### General Debugging Tips + +- **Check the line number** in the error message. Sphinx usually points to the exact line where the unexpected indentation was detected, but the *cause* is often one or two lines above it. +- **Simplify the block** by temporarily removing content to isolate which element is triggering the error. +- **Avoid tabs.** Configure your editor to insert spaces instead for `.rst` files, if possible. + +### "WARNING: Block quote ends without a blank line; unexpected unindent" + +This is essentially the inverse of {ref}`error-unexpected-unindent`: The above line was indented but this one isn't. reStructuredText tried to interpret the indented line as a [block quote](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#lists-and-quote-like-blocks), but block quotes require a blank line after them. + +(inline-literal-start-without-end)= + +### "WARNING: Inline literal start-string without end-string" + +An "inline literal" is when you want to mix code into a normal line of text (as opposed to in its own code block) ``like this``. This is accomplished with double-backticks: +```reStructuredText +An "inline literal" is when you want to mix code into a normal line of +text (as opposed to in its own code block) ``like this``. +``` +(A backtick is what you get if you press the key to the left of 1 on a standard US English keyboard.) + +If you have a double-backtick on a line, reStructuredText will think, "They want to start an inline literal here," then look for another double-backtick to end the literal. The "WARNING: Inline literal start-string without end-string" means it can't find one on that line. + +This might happen, for example, if you try to put a [Markdown code block](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks) in a .rst file. In that case, use the [reStructuredText code block syntax](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks) instead (optionally with [syntax highlighting](https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-highlight)). + +### "WARNING: Inline interpreted text or phrase reference start-string without end-string" + +Like {ref}`inline-literal-start-without-end`, this is probably related to having one double-backtick without another on the same line. As with that other error, it could be the result of a Markdown code block in a .rst file. + +### "ERROR: Error in "code" directive: maximum 1 argument(s) allowed, 19 supplied" + +This error might show something other than "code," like "highlight" or "sourcecode". It also will probably show a second number that's not 19. The problem is that you tried to write a [reStructuredText code block with syntax highlighting](https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-highlight) but didn't include a blank line after the first one: + +```reStructuredText +.. code:: shell + # How to list all the available grids + cd cime/scripts + ./query_config --grids +``` + +Fix this by adding a blank line: +```reStructuredText +.. code:: shell + + # How to list all the available grids + cd cime/scripts + ./query_config --grids +``` + +### 'ERROR: Error in "math" directive: invalid option block' + +You might have forgotten the empty line after an equation label. + +### "WARNING: Explicit markup ends without a blank line; unexpected unindent" + +You might have forgotten the leading spaces for every line after `.. math::`. As a reminder, you need at least one leading space on each line. + +You can also get this error if you forget to surround a {ref}`cross-reference label` with blank lines. In this case, the error message might point to lines far away from the actual problem. + +### "WARNING: Failed to create a cross reference: A title or caption not found" +This probably means you tried to `:ref:` a label that's not immediately followed by (a) a table/figure with a caption or (b) a section. + +### "WARNING: undefined label" + +If you're sure the label you referenced actually exists, this probably means you tried to ``:numref:`` a label that's not immediately followed by a table, figure, or section (see above). Alternatively, you might have tried to ``:ref:`` an {ref}`equation`; in that case, use ``:eq:`` instead. + +### "WARNING: malformed hyperlink target" + +You may have forgotten the trailing `:` on a label line. + +### "WARNING: Title underline too short" + +reStructuredText is just being difficult. It KNOWS that when you did something like this +```reStructuredText +Tips for working with reStructuredText +=================================== +``` +you meant to indicate that was a section header, but it's going to make you extend those equal signs (or hyphens or whatever) all the way out to match (or exceed) the length of the line above. diff --git a/doc/source/users_guide/working-with-documentation/converting-between-md-and-rst.md b/doc/source/users_guide/working-with-documentation/converting-between-md-and-rst.md new file mode 100644 index 0000000000..0cc7221910 --- /dev/null +++ b/doc/source/users_guide/working-with-documentation/converting-between-md-and-rst.md @@ -0,0 +1,56 @@ +(converting-between-md-and-rst)= + +# Converting between Markdown and reStructuredText + +You may find yourself wanting to convert a Markdown file to a reStructuredText file or vice versa. [`pandoc`](https://pandoc.org/) is a command-line utility that can do this for you, or at least get you something that's most of the way there. Installation instructions can be found [here](https://pandoc.org/installing.html), but it's pretty complicated. An easier alternative is to use the online demo page [here](https://pandoc.org/try/): + +1. Paste the contents of the file into the text box on the left. +1. Select the correct file types in the "from" and "to" menus (just use plain "Markdown", not one of the other flavors, unless you've copied something in one of those other flavors—e.g., if you've copied Markdown from a GitHub wiki page). +1. **Make sure "Preserve breaks" is selected, not "Auto wrap"**—see [style guide](#ctsm-docs-style-guide). +1. Click "Convert". You will be given the results of the conversion on the right side of the page. +1. Copy and paste that into a new file with the new extension. + +Note that `pandoc` doesn't support [MyST Markdown](https://mystmd.org/guide/quickstart-myst-markdown), the special flavor of Markdown we support in our docs. Thus, if you're converting a Markdown file from our docs to reStructuredText, there may be some MyST Markdown left over. E.g.: + +``` +(common-docs-errors)= + +# Common doc build errors and how to handle them + +(common-doc-builder-errors)= + +## Common docs errors: doc-builder + +### "RuntimeError: No compatible container software found: docker, podman" + +You tried to build the documentation using our container (`./build_docs ... -d`) but didn't have any software running that could handle the container. Try again after starting up container software according to the instructions for your platform: +- {ref}`bld-prev-docs-casper` **(recommended)** +- {ref}`bld-prev-docs-mac` +- {ref}`bld-prev-docs-windows` +``` + +becomes: + +```reStructuredText +(common-docs-errors)= + +Common doc build errors and how to handle them +============================================== + +(common-doc-builder-errors)= + +Common docs errors: doc-builder +------------------------------- + +"RuntimeError: No compatible container software found: docker, podman" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You tried to build the documentation using our container (``./build_docs ... -d``) but didn't have any software running that could handle the container. Try again after starting up container software according to the instructions for your platform: +- {ref}\ ``bld-prev-docs-casper`` **(recommended)** +- {ref}\ ``bld-prev-docs-mac`` +- {ref}\ ``bld-prev-docs-windows`` +``` + +The labels `(common-docs-errors)=` and `(common-doc-builder-errors)=` will need to be manually converted to their [reStructuredText equivalents](#rst-cross-references) `.. _common-docs-errors:` and `.. _common-doc-builder-errors:`, respectively. + +This can also happen when converting in the other direction, from reStructuredText to Markdown. In that case, however, there are tools that can convert from reStructuredText to MyST Markdown specifically. See the command-line tool [`rst-to-myst`](https://rst-to-myst.readthedocs.io/en/latest/) and the [MySTyc website](https://astrojuanlu.github.io/mystyc/), although at the time of writing the latter wasn't working. diff --git a/doc/source/users_guide/working-with-documentation/docs-intro-and-recommended.md b/doc/source/users_guide/working-with-documentation/docs-intro-and-recommended.md deleted file mode 100644 index bfc537f223..0000000000 --- a/doc/source/users_guide/working-with-documentation/docs-intro-and-recommended.md +++ /dev/null @@ -1,66 +0,0 @@ -.. _docs-intro-and-recommended: - -# Working with the CTSM documentation -.. _editing-the-documentation: - -## One-time setup -You will need to have some software installed on your computer in order to build and the documentation and view the results: -- :ref:`building-docs-prereqs-mac` -- :ref:`building-docs-prereqs-windows` - -## Editing the documentation -First, you will need a clone of CTSM to get all the documentation files and infrastructure. (If you're on Windows, you will make this clone in your :ref:`Ubuntu VM `.) Note that you will clone this to your own computer, not Derecho or any cluster or anything. - -The CTSM documentation is built from files in the `doc/source/tech_note/` and `doc/source/users_guide/` directories. These files are written in a mixture of what are called "markup languages." You may already be familiar—for better or for worse—with the LaTeX markup language. Fortunately, our documentation is simpler than that. It was originally written entirely in [reStructuredText](http://www.sphinx-doc.org/en/stable/rest.html), and it still mostly is, as you can tell by the predominance of .rst files. However, it's also possible to write Markdown documents (.md), which is nice because it's a much simpler and more widespread format (although see :ref:`tips-for-working-with-markdown`). If you've formatted text on GitHub, for instance, you've used Markdown. - -Editing the documentation is as simple as opening the source file for the page you want to edit, then changing text. Make sure to use either reStructuredText or Markdown syntax, depending on the file's extension (.rst or .md, respectively). Note that "opening the source file" isn't completely straightforward on Windows; see :ref:`editing-text-files-wsl`. - -If you're confident in your changes, or you're _not_ confident in your ability to preview and test the documentation (see [Building the documentation (recommended method)](#building-the-documentation) below), all you need to do is commit your changes and submit a pull request to the [CTSM GitHub repo](https://github.com/ESCOMP/CTSM). Automated testing will check the updated documentation for any errors, and a CTSM software engineer will review your PR. If everything looks good, they will merge it into the codebase and update the website. - -.. _building-the-documentation: - -## Building the documentation -We strongly suggest building the documentation on your personal computer before submitting a pull request, so that you can preview what your changes will look like. The recommended way to do this is using the `doc-builder` tool in conjunction with a "containerized" version of some required software. - -### Directories -You will need a place to build the documentation. It's fine if that doesn't exist; the build tool will make it for you. The only restriction is that, at least for the recommended method described here, **your build directory must be somewhere in your CTSM clone**. (We recommend starting the name of your build directory with `_build` because CTSM knows to ignore such directories when it comes to `git`.) The instructions here assume you want to do your build in `doc/_build/`. - -### Building the docs -All you need to do to build the docs with our recommended method is -```shell -cd doc -./build_docs -b _build -c -d -``` - -This runs a complicated series of scripts and software that culminate in something called Sphinx converting the .rst and .md files into HTML webpages. - -The `-c` means "do a clean build." If you leave it off, Sphinx will only rebuild files it thinks have changed since the last time you built the docs. It's not always right, which can lead to problems. If you get unexpected errors without `-c`, rerunning with `-c` is the first troubleshooting step. - -The `-d` means "run using the container." If you're not using the container and are instead using the `ctsm_pylib` Conda environment **(not recommended)**, leave off `-d`, and make sure you've activated `ctsm_pylib` before running the above command. See the "Container software or Conda environment" sections for :ref:`Mac ` or :ref:`Windows ` for more information on these two methods. - -(Do `./build_docs --help` for more information and options.) - -## Viewing your built docs - -Note that there is a menu in the lower left of the webpage that lets readers switch between different versions of the documentation. The links to versions in this menu will not work when using the build command given above. If you wish to preview this version switching functionality, see :ref:`building-docs-multiple-versions`. - -The process for viewing your build in a web browser differs depending on what kind of computer you have. - -### Mac - -You can open your build of the documentation in your default browser with -```shell -open _build/html/index.html -``` - -### Windows (Ubuntu VM) - -Assuming you installed the WSL Utilities in the :ref:`windows-docs-ubuntu-utilities` setup step, you can open your build of the documentation like so: -```shell -wslview _build/html/index.html -``` -If you didn't, you can do -```shell -explorer.exe $(wslpath -w _build/html/index.html) -``` -These both do the same thing, but the `wslview` method is simpler. Either way, at least the first time you do this, it will open a window asking which app you'd like to view the HTML file in. Choose a browser like Microsoft Edge or Chrome. At the bottom of the window, you can then choose whether you always want to open HTML files using the selected app or just this once. diff --git a/doc/source/users_guide/working-with-documentation/docs-intro.md b/doc/source/users_guide/working-with-documentation/docs-intro.md new file mode 100644 index 0000000000..04e6aed33b --- /dev/null +++ b/doc/source/users_guide/working-with-documentation/docs-intro.md @@ -0,0 +1,33 @@ +(docs-intro)= + +# Working with the CTSM documentation + +If you're reading this page, you're probably interested in making an improvement to this CTSM documentation website—thank you! Please read this page thoroughly before starting to make it as smooth a process as possible. + +## How the documentation works +The documentation starts life as files in the `doc/source/tech_note/` and `doc/source/users_guide/` directories. These files are written in a mixture of what are called "markup languages." You may already be familiar—for better or for worse—with the LaTeX markup language. Fortunately, our documentation is simpler than that. It was originally written entirely in [reStructuredText](http://www.sphinx-doc.org/en/stable/rest.html), and it still mostly is, as you can tell by the predominance of .rst files. However, it's also possible to write Markdown documents (.md), which is nice because it's a much simpler and more widespread format (although see {ref}`tips-for-working-with-markdown`). If you've formatted text on GitHub, for instance, you've used Markdown. + +During the "build" process, these files are converted to HTML webpages using a tool called Sphinx. This creates a directory with HTML files that can then be "previewed" to make sure they look right. When you submit a pull request (PR; see [Contribution guidelines](#docs-contribution-guidelines) below), tests will automatically run to make sure your changed documentation builds with no errors. Then, when your PR is merged to the main CTSM branch, it will be rebuilt and published automatically. + +(docs-contribution-guidelines)= + +## Contribution guidelines +We use the [CTSM GitHub repo](https://github.com/ESCOMP/CTSM) to track issues with the documentation and bring in changes. Please have a look at our ["How to contribute"](https://github.com/ESCOMP/CTSM/blob/master/CONTRIBUTING.md) readme for some general guidelines. + +If you have found a problem with the documentation but aren't able to fix it immediately, or if you're not sure whether something is truly a problem or how to fix it, please [file an issue](https://github.com/ESCOMP/CTSM/issues/new?template=03_documentation.md). + +If you've made changes that you'd like us to bring in, you can file a [pull request](https://github.com/ESCOMP/ctsm/pulls) (PR; "New pull request" button at that link). Please try to avoid filing many small documentation PRs in a short time, as it's easier for the maintenance team if you combine similar edits into one larger PR. For example, several typo fixes in a file or across files would be a good single PR. You can also mark a PR as "draft" if you think you may be adding more to it, or if you think it's otherwise not ready for review. + +Whenever you submit a documentation PR or commit new changes to one, automated testing will check the updated documentation for any errors. If you get failures, please try to diagnose and fix them; see {ref}`common-docs-errors` for tips. If you resolve the errors, add a comment on your PR saying so, and one of the CTSM software engineers will have a look. + +## Editing the documentation +First, you will need a clone of CTSM to get all the documentation files and infrastructure. Once you have that, editing the documentation is as simple as editing the source file for the page you want to edit, in `doc/source/`. You can find the exact path under that directory by appending the part of the webpage URL after `https://escomp.github.io/CTSM/` and replacing `.html` with either `.rst` (most likely) or `.md`. So if I wanted to change this page (URL `https://escomp.github.io/CTSM/users_guide/working-with-documentation/docs-intro-and-recommended.html`), I would look in the directory `doc/source/users_guide/working-with-documentation` for `docs-intro-and-recommended.rst` or `.md`. + +Make sure to use either reStructuredText or Markdown syntax, depending on the file's extension (.rst or .md, respectively). You can mix some reStructuredText into Markdown files, but generally not the other way around. For more information, see: +- {ref}`tips-for-working-with-markdown` +- {ref}`tips-for-working-with-rst` + +We strongly recommend building and previewing the docs yourself as you're editing them, or at least before requesting review on your PR. You can find instructions for doing so here: +- {ref}`bld-prev-docs-casper` +- {ref}`bld-prev-docs-mac` +- {ref}`bld-prev-docs-windows` diff --git a/doc/source/users_guide/working-with-documentation/docs-style-guide.md b/doc/source/users_guide/working-with-documentation/docs-style-guide.md new file mode 100644 index 0000000000..ae9c30c72b --- /dev/null +++ b/doc/source/users_guide/working-with-documentation/docs-style-guide.md @@ -0,0 +1,8 @@ +(ctsm-docs-style-guide)= + +# Documentation style guide + +- Please don't add manual line breaks when writing text, as this harms searchability. (Note that it's fine to do this in multi-line math blocks.) For more information, see [here](https://github.com/ESCOMP/CTSM/issues/2135#issuecomment-1764999337). +- You can write the degree symbol ° with Opt-Shift-8 on Mac or Alt+0176 on Windows, or you can copy it from here. Note that this is different from the [masculine ordinal indicator](https://en.wikipedia.org/wiki/Ordinal_indicator) (typed with Opt-0 on Mac). This is much cleaner and more searchable than using RestructuredText syntax to write a superscript-o! +- Whenever possible, please give equations meaningful labels. E.g., for [eq. 2.26.2](https://escomp.github.io/ctsm-docs/versions/release-clm5.0/html/tech_note/Crop_Irrigation/CLM50_Tech_Note_Crop_Irrigation.html#equation-25-2), `:label: gdds_for_cfts` would be better than `:label: 25.2`. Numeric labels become obsolete—as you can see in that example!—whenever new equations and/or sections are added. (Note that the equation numbering in the rendered HTML is automatic.) +- Tables defined with the [:table: directive](https://docutils.sourceforge.io/docs/ref/rst/directives.html#table) can be annoying because they're very sensitive to the cells inside them being precisely the right widths, as defined by the first `====` strings. If you don't get the widths right, you'll see "Text in column margin" errors. Instead, define your tables using the `:list-table:` directive. diff --git a/doc/source/users_guide/working-with-documentation/embed-build-cmd.md b/doc/source/users_guide/working-with-documentation/embed-build-cmd.md new file mode 100644 index 0000000000..f4ec3b295e --- /dev/null +++ b/doc/source/users_guide/working-with-documentation/embed-build-cmd.md @@ -0,0 +1,17 @@ +--- +orphan: true +--- + +% git-fleximod checkout of doc-builder shouldn't be necessary, as that should happen automatically. +```shell +cd doc +./build_docs -b _build -c -d +``` + +This runs a complicated series of scripts and software that culminate in something called Sphinx converting the .rst and .md files into HTML webpages, all within the (new, if needed) `_build` directory. + +The `-c` means "do a clean build." If you leave it off, Sphinx will only rebuild files it thinks have changed since the last time you built the docs, which is faster but can lead to problems. If you get unexpected results or errors without `-c`, rerunning with `-c` is the first troubleshooting step. + +The `-d` means "run using the container." If you're not using the container and are instead using the `ctsm_pylib` Conda environment **(not recommended)**, leave off `-d`, and make sure you've activated `ctsm_pylib` before running the above command. + +(Do `./build_docs --help` for more information and options.) diff --git a/doc/source/users_guide/working-with-documentation/embed-example-markdown.md b/doc/source/users_guide/working-with-documentation/embed-example-markdown.md new file mode 100644 index 0000000000..01b966afb0 --- /dev/null +++ b/doc/source/users_guide/working-with-documentation/embed-example-markdown.md @@ -0,0 +1,10 @@ +--- +orphan: true +--- + +Everything in this paragraph is just the contents of +`doc/source/users_guide/working-with-documentation/embed-example-markdown.md`. It's in the same directory +as the "Tips for working with Markdown" source file, so we only had to specify the +filename. If it were in a different directory, we would specify the path relative to "Tips for +working with Markdown". (Note that this file does NOT follow the "no line breaks within +paragraphs" style convention; this is purely for readability of the embedded text.) diff --git a/doc/source/users_guide/working-with-documentation/embed-example-python.py b/doc/source/users_guide/working-with-documentation/embed-example-python.py new file mode 100644 index 0000000000..68641beb85 --- /dev/null +++ b/doc/source/users_guide/working-with-documentation/embed-example-python.py @@ -0,0 +1,6 @@ +""" +This is just an example Python file that will be literalinclude'ed +""" + +print("Hello world") +my_list = ["foo", "bar"] diff --git a/doc/source/users_guide/working-with-documentation/embed-example-rst.rst b/doc/source/users_guide/working-with-documentation/embed-example-rst.rst new file mode 100644 index 0000000000..8a8de1fbcb --- /dev/null +++ b/doc/source/users_guide/working-with-documentation/embed-example-rst.rst @@ -0,0 +1,7 @@ +Everything in this paragraph is just the contents of +``doc/source/users_guide/working-with-documentation/embed-example-rst.rst``. It's in the same +directory as the "Tips for working with reStructuredText" source file, so we only had to +specify the filename. If it were in a different directory, we would specify the path +relative to "Tips for working with reStructuredText". (Note that this file does NOT follow +the "no line breaks within paragraphs" style convention; this is purely for readability of +the embedded text.) diff --git a/doc/source/users_guide/working-with-documentation/embed-preview-menu.md b/doc/source/users_guide/working-with-documentation/embed-preview-menu.md new file mode 100644 index 0000000000..eed8bd709a --- /dev/null +++ b/doc/source/users_guide/working-with-documentation/embed-preview-menu.md @@ -0,0 +1,5 @@ +--- +orphan: true +--- + +Note that there is a menu in the lower left of the webpage that lets readers switch between different versions of the documentation. The links to versions in this menu will not work when using the build command given above. If you wish to preview this version switching functionality, see {ref}`building-docs-multiple-versions`. diff --git a/doc/source/users_guide/working-with-documentation/esbonio-sphinx-buildcmd.png b/doc/source/users_guide/working-with-documentation/esbonio-sphinx-buildcmd.png new file mode 100644 index 0000000000..80a0006a1d --- /dev/null +++ b/doc/source/users_guide/working-with-documentation/esbonio-sphinx-buildcmd.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11f7d6821528a9b39a6de0a668f7b91a84ef2709d6276d68a4204258bb2b1e67 +size 15881 diff --git a/doc/source/users_guide/working-with-documentation/index.rst b/doc/source/users_guide/working-with-documentation/index.rst index 198da612d4..7bb4755bee 100644 --- a/doc/source/users_guide/working-with-documentation/index.rst +++ b/doc/source/users_guide/working-with-documentation/index.rst @@ -9,11 +9,15 @@ Working with CTSM Documentation .. toctree:: :maxdepth: 1 - docs-intro-and-recommended.md - building-docs-prereqs-mac.md - building-docs-prereqs-windows.md - building-docs-multiple-versions.rst + docs-intro.md + bld-prev-docs-casper.md + bld-prev-docs-mac.md + bld-prev-docs-windows.md + vscode-doc-editing-setup.md + docs-style-guide.md tips-for-working-with-markdown.md - tips-for-working-with-rst.md + tips-for-working-with-rst.rst + converting-between-md-and-rst.md + common-docs-errors.md + building-docs-multiple-versions.rst building-docs-original-wiki.md - diff --git a/doc/source/users_guide/working-with-documentation/tips-for-working-with-markdown.md b/doc/source/users_guide/working-with-documentation/tips-for-working-with-markdown.md index 9575092459..f22a6b68d4 100644 --- a/doc/source/users_guide/working-with-documentation/tips-for-working-with-markdown.md +++ b/doc/source/users_guide/working-with-documentation/tips-for-working-with-markdown.md @@ -1,45 +1,171 @@ -.. _tips-for-working-with-markdown: +(tips-for-working-with-markdown)= # Tips for working with Markdown -Markdown is great for very simple documentation files—it's much easier to write and read Markdown source than reStructuredText source. However, there are some compromises that you should be aware of, and you may find yourself needing to mix in some reStructuredText. +Markdown is great for very simple documentation files—it's much easier to write and read Markdown source than reStructuredText source. -.. _md-cross-references: +Note that our documentation build system uses the MyST Markdown parser. MyST is a special "flavor" of Markdown that has a lot of reStructuredText-like features added to it; see the guide to MyST Markdown syntax [here](https://myst-parser.readthedocs.io/en/v5.0.0/syntax/typography.html), although note that we don't include a lot of the referenced extensions. + +If you use VS Code, you may want to install the [MyST-Markdown extension](https://marketplace.visualstudio.com/items?itemName=ExecutableBookProject.myst-highlight) to get syntax highlighting, auto-complete, and improved rendering in the VS Code previewer. + +```{contents} +:depth: 1 +:local: +``` + +(md-cross-references)= ## Markdown: Cross-references -You can [link to section headings](#md-cross-references) with the `[link to section headings](#md-cross-references)` format, but the Sphinx compiler will complain. Instead, use the :ref:`reStructuredText cross-reference and label` syntax. -## Markdown: Math -(Note that parts of this section will be rendered incorrectly by Markdown parsers!) +You can [link to Markdown section headers](#md-cross-references) by adding a label before the header: +```markdown +(md-cross-references)= -Inline math can't be achieved with the typical Markdown syntax of just surrounding your expression with dollar signs. Instead, you need to surround THAT with backticks. So to render `$y = mx + b$`, we can't do -``` -So to render $y = mx + b$, ... -``` -because we'd just see $y = mx + b$ on the generated webpage. Instead, we do -``` -So to render `$y = mx + b$`, ... +## Markdown: Cross-references ``` -We could also use :ref:`rST's syntax` like so: + +and then referring to it like `[link to section headers](#md-cross-references)`. You can also have the display text just be the title of the relevant section—e.g., [](#md-cross-references)—by doing `[](#md-cross-references)`. + +That linking syntax also works for links to [section labels in reStructuredText files](#rst-cross-references): `[section labels in reStructuredText files](#rst-cross-references)`. + +(md-math)= + +## Markdown: Math + +Inline math can be achieved with the typical Markdown syntax of just surrounding your expression with dollar signs. E.g., $y = mx + b$: ``` -So to render :math:`y = mx + b`, ... +E.g., $y = mx + b$: ``` -You can also use Markdown's math block syntax for big equations on their own lines: +You can also use Markdown's math block syntax for big equations on their own lines, with an optional label after the second `$$` that will give it a number and make it cross-referenceable: ``` $$ y = mx + b -$$ +$$ (my-equation-label) ``` $$ y = mx + b -$$ +$$ (my-equation-label) -However, you won't get the equation numbering or labeling that you would with the :ref:`reStructuredText math format`. +Then you can get the equation number {eq}`my-equation-label` like so: +``` +Then you can get the equation number {eq}`my-equation-label` like so: +``` ## Markdown: Comments -If you want to add some text that's only visible in the documentation source file, there's not really a way to do that in Markdown. However, you can use the :ref:`reStructuredText comment syntax` in a Markdown document. +If you want to add some text that's only visible in the documentation source file, you can put a `%` at the beginning of a line. E.g.: + +```markdown +% This will not appear on the webpage. +``` + +% This will not appear on the webpage. ## Markdown: Tables -Markdown tables are supported. See [GitHub's "Organizing information with tables"](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/organizing-information-with-tables) for more info. \ No newline at end of file +Markdown tables are supported. See [GitHub's "Organizing information with tables"](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/organizing-information-with-tables) for more info. + +## Markdown: Admonitions +[Admonitions](https://myst-parser.readthedocs.io/en/v5.0.0/syntax/admonitions.html) are rendered as special "call-out" boxes. The general syntax is: +~~~ +```{admonition} This is the title of a generic admonition + It needs a title specified. Synonyms you can put in the `{}` instead of `admonition` include `note` and `seealso`; if you use one of those, you can't specify a title. In fact, `admonition` is the only type of admonition that you can specify a custom title for. +``` +~~~ +```{admonition} This is the title of a generic admonition + It needs a title specified. Synonyms you can put in the `{}` instead of `admonition` include `note` and `seealso`; if you use one of those, you can't specify a title. In fact, `admonition` is the only type of admonition that you can specify a custom title for. +``` + +There are also a number of built-in admonition types that get their own special rendering: + +~~~ +```{attention} +The reader should pay special attention to this. Synonyms you can put in the `{}` instead of `attention` include `caution` and `warning`. +``` +~~~ +```{attention} +The reader should pay special attention to this. Synonyms you can put in the `{}` instead of `attention` include `caution` and `warning`. +``` + +~~~ +```{danger} +This tells the reader about something dangerous. You can also put `error` in the `{}` instead of `danger`. +``` +~~~ +```{danger} +This tells the reader about something dangerous. You can also put `error` in the `{}` instead of `danger`. +``` + +~~~ +```{hint} +Here's a hint. Synonyms you can put in the `{}` instead of `hint` include `important` and `tip`. +``` +~~~ +```{hint} +Here's a hint. Synonyms you can put in the `{}` instead of `hint` include `important` and `tip`. +``` + +## Markdown: Embedding a different Markdown file +It can be useful to embed one Markdown file within another. This is done in this documentation documentation, for instance, to embed `doc/source/users_guide/working-with-documentation/embed-build-cmd.md` on three different pages. + +As an example, here's what an embedding looks like: +~~~ +That becomes: +```{include} embed-example-markdown.md +``` +~~~ + +That becomes: +```{include} embed-example-markdown.md +``` + +See [the MyST Markdown documentation for the "include" directive](https://mystmd.org/guide/directives#directive-include) for more information. + +You can also embed literal contents of any file without the rendering: +~~~ +That becomes the literal contents: +```{literalinclude} embed-example-markdown.md +``` +~~~ + +That becomes the literal contents: +```{literalinclude} embed-example-markdown.md +``` + +(The first three lines are to indicate to Sphinx that it's okay for that file to not be included in any Table of Contents; i.e., to suppress the `WARNING: document isn't included in any toctree [toc.not_included]` build message.) + +You can also get fancy: +~~~ +```{literalinclude} embed-example-python.py +:language: python +:linenos: +``` +~~~ + +Becomes (note syntax highlighting): + +```{literalinclude} embed-example-python.py +:language: python +:linenos: +``` + +And +~~~ +```{literalinclude} embed-example-python.py +:language: python +:linenos: +:start-at: print +:lineno-match: +``` +~~~ + +Becomes: + +```{literalinclude} embed-example-python.py +:language: python +:linenos: +:start-at: print +:lineno-match: +``` + +See [the MyST Markdown documentation for the `include` directive](https://mystmd.org/guide/directives#directive-include) for more information (all options apply to `literalinclude` as well). \ No newline at end of file diff --git a/doc/source/users_guide/working-with-documentation/tips-for-working-with-rst.md b/doc/source/users_guide/working-with-documentation/tips-for-working-with-rst.md deleted file mode 100644 index 164f24115b..0000000000 --- a/doc/source/users_guide/working-with-documentation/tips-for-working-with-rst.md +++ /dev/null @@ -1,165 +0,0 @@ -.. _tips-for-working-with-rst: - -# Tips for working with reStructuredText - -If you've never used reStructuredText before, you should be aware that its syntax is pretty different from anything you've ever used before. We recommend the following resources as references for the syntax: -- [Sphinx's reStructuredText Primer](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html) -- The [Quick reStructuredText](https://docutils.sourceforge.io/docs/user/rst/quickref.html) cheat sheet - -Some especially useful bits: -- [Section headers](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#sections) -- [Hyperlinks](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#hyperlinks) -- [Callout blocks (e.g., warning, tip)](https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#admonitions-messages-and-warnings) - -On this page, we've compiled some supplemental information that might be helpful, including a list of common errors and their causes. - -.. contents:: - :depth: 1 - :backlinks: top - :local: - -.. _rst-math: - -## reStructuredText: Math -You can write inline math like ``:math:`y = mx + b``` → :math:`y = mx + b`. You can also write bigger equations on their own line that will automatically be numbered: - -```reStructuredText -.. math:: - :label: equation for a line - - y = mx + b -``` -.. math:: - :label: equation for a line - - y = mx + b - -Note (a) the leading spaces for each line after `.. math::` and (b) the empty line after the label. If you don't include the `:label:` line, the equation will not be numbered. - -reStructuredText math largely follows LaTeX syntax. - -.. _rst-cross-references: - -## reStructuredText: Cross-references -reStructuredText lets you define labels that can be cross-referenced as links elsewhere in the documentation. A label looks like ``.. _this-is-my-label:`` or ``.. _This is my label with CAPS and spaces:``, on its own line surrounded by blank lines. The leading ``.. _`` and trailing ``:`` are what tell rST "this line is a label." E.g.: - -``` -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. - -.. _this-is-my-label: - -My cool information -^^^^^^^^^^^^^^^^^^^ -Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. -``` - -You could then refer to that section with ``:XYZ:`this-is-my-label``` (leaving off the leading `.. _`), where `XYZ` can be `ref`, `numref`, or `eq` (see examples below). This will create a link that, when clicked, takes the reader to the "My cool information" section. - -Here are some examples. Note that the displayed link text will update automatically as needed (e.g., a section number or figure caption gets changed). -- Section headings, text: ``:ref:`rst-cross-references``` → :ref:`rst-cross-references` -- Section headings, number: ``:numref:`rst-cross-references``` → :numref:`rst-cross-references`. Note that, unlike `numref` for other things mentioned here, "Section" is not automatically prepended to the section number in the link text. -- Table, text: ``:ref:`Table Crop plant functional types``` → :ref:`Table Crop plant functional types` -- Table, number: ``:numref:`Table Crop plant functional types``` → :numref:`Table Crop plant functional types` -- Figure, text (uses entire caption): ``:ref:`Figure CLM subgrid hierarchy``` → :ref:`Figure CLM subgrid hierarchy` -- Figure, number: ``:numref:`Figure CLM subgrid hierarchy``` → :numref:`Figure CLM subgrid hierarchy` -- Equation, number: ``:eq:`equation for a line``` → :eq:`equation for a line`. The parentheses in the link text seem unavoidable, and there seems to be no way to refer to have the link show the label text or anything else aside from the number. - -You can have any link (except for equations) show custom text by putting the referenced label at the end in ``. E.g., ``:ref:`Diagram of CLM subgrid hierarchy
``` → :ref:`Diagram of CLM subgrid hierarchy
`. - -Note that this is necessary for labels that aren't immediately followed by a section heading, a table with a caption, or a figure with a caption. For instance, to refer to labels in our bibliography, you could do ``:ref:`(Bonan, 1996)``` → :ref:`(Bonan, 1996)`. - -.. _rst-comments: - -## reStructuredText: Comments -If you want to add some text that's only visible in the documentation source file, you can use the reStructuredText comment syntax: - -``` -.. - This will not appear on the webpage or even anywhere in the generated HTML. - -``` - -Make sure to include at least one empty line after the comment text. - - -## reStructuredText: Tables -Tables defined with the [:table: directive](https://docutils.sourceforge.io/docs/ref/rst/directives.html#table) can be annoying because they're very sensitive to the cells inside them being precisely the right widths, as defined by the first `====` strings. If you don't get the widths right, you'll see "Text in column margin" errors. Instead, define your tables using the [list-table](https://docutils.sourceforge.io/docs/ref/rst/directives.html#list-table) directive. - -If you already have a table in some other format, like comma-separated values (CSV), you may want to check out the R package [knitr](https://cran.r-project.org/web/packages/knitr/index.html). Its [kable](https://bookdown.org/yihui/rmarkdown-cookbook/kable.html) command allows automatic conversion of R dataframes to tables in reStructuredText and other formats. - - -## reStructuredText: Common error messages and how to handle them - -.. _error-unexpected-unindent: - -### "ERROR: Unexpected indentation" - -Like Python, reStructuredText is very particular about how lines are indented. Indentation is used, for example, to denote [code ("literal") blocks](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks) and [quote blocks](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#lists-and-quote-like-blocks). An error like -``` -/path/to/file.rst:102: ERROR: Unexpected indentation. [docutils] -``` -indicates that line 102 is indented but not in a way that reStructuredText expects. - -### "WARNING: Block quote ends without a blank line; unexpected unindent" - -This is essentially the inverse of :ref:`error-unexpected-unindent`: The above line was indented but this one isn't. reStructuredText tried to interpret the indented line as a [block quote](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#lists-and-quote-like-blocks), but block quotes require a blank line after them. - -.. _inline-literal-start-without-end: - -### "WARNING: Inline literal start-string without end-string" - -An "inline literal" is when you want to mix code into a normal line of text (as opposed to in its own code block) ``like this``. This is accomplished with double-backticks: -```reStructuredText -An "inline literal" is when you want to mix code into a normal line of -text (as opposed to in its own code block) ``like this``. -``` -(A backtick is what you get if you press the key to the left of 1 on a standard US English keyboard.) - -If you have a double-backtick on a line, reStructuredText will think, "They want to start an inline literal here," then look for another double-backtick to end the literal. The "WARNING: Inline literal start-string without end-string" means it can't find one on that line. - -This might happen, for example, if you try to put a [Markdown code block](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks) in a .rst file. In that case, use the [reStructuredText code block syntax](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#literal-blocks) instead (optionally with [syntax highlighting](https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-highlight)). - -### "WARNING: Inline interpreted text or phrase reference start-string without end-string" - -Like :ref:`inline-literal-start-without-end`, this is probably related to having one double-backtick without another on the same line. As with that other error, it could be the result of a Markdown code block in a .rst file. - -### "ERROR: Error in "code" directive: maximum 1 argument(s) allowed, 19 supplied" - -This error might show something other than "code," like "highlight" or "sourcecode". It also will probably show a second number that's not 19. The problem is that you tried to write a [reStructuredText code block with syntax highlighting](https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-highlight) but didn't include a blank line after the first one: - -```reStructuredText -.. code:: shell - # How to list all the available grids - cd cime/scripts - ./query_config --grids -``` - -Fix this by adding a blank line: -```reStructuredText -.. code:: shell - - # How to list all the available grids - cd cime/scripts - ./query_config --grids -``` - -### 'ERROR: Error in "math" directive: invalid option block' - -You might have forgotten the empty line after an equation label. - -### "WARNING: Explicit markup ends without a blank line; unexpected unindent" - -You might have forgotten the leading spaces for every line after `.. math::`. As a reminder, you need at least one leading space on each line. - -You can also get this error if you forget to surround a :ref:`cross-reference label` with blank lines. In this case, the error message might point to lines far away from the actual problem. - -### "WARNING: Failed to create a cross reference: A title or caption not found" -This probably means you tried to `:ref:` a label that's not immediately followed by (a) a table/figure with a caption or (b) a section. - -### "WARNING: undefined label" - -If you're sure the label you referenced actually exists, this probably means you tried to ``:numref:`` a label that's not immediately followed by a table, figure, or section (see above). Alternatively, you might have tried to ``:ref:`` an :ref:`equation`; in that case, use ``:eq:`` instead. - -### "WARNING: malformed hyperlink target" - -You may have forgotten the trailing `:` on a label line. \ No newline at end of file diff --git a/doc/source/users_guide/working-with-documentation/tips-for-working-with-rst.rst b/doc/source/users_guide/working-with-documentation/tips-for-working-with-rst.rst new file mode 100644 index 0000000000..12dda6d1f8 --- /dev/null +++ b/doc/source/users_guide/working-with-documentation/tips-for-working-with-rst.rst @@ -0,0 +1,219 @@ +.. _tips-for-working-with-rst: + +Tips for working with reStructuredText +======================================== + +If you've never used reStructuredText before, you should be aware that its syntax is pretty different from anything you've ever used before. We recommend the following resources as references for the syntax: + +- `Sphinx's reStructuredText Primer `_ +- The `Quick reStructuredText `_ cheat sheet + +Some especially useful bits: + +- `Section headers `_ +- `Hyperlinks `_ + +On this page, we've compiled some supplemental information that might be helpful, including a list of common errors and their causes. + +.. contents:: + :depth: 1 + :backlinks: top + :local: + +.. _rst-math: + +reStructuredText: Math +---------------------- + +You can write inline math like ``:math:`y = mx + b``` → :math:`y = mx + b`. You can also write bigger equations on their own line that will automatically be numbered: + +.. code-block:: reStructuredText + + .. math:: + :label: equation for a line + + y = mx + b + +.. math:: + :label: equation for a line + + y = mx + b + +Note (a) the leading spaces for each line after ``.. math::`` and (b) the empty line after the label. If you don't include the ``:label:`` line, the equation will not be numbered. + +reStructuredText math largely follows LaTeX syntax. + +.. _rst-cross-references: + +reStructuredText: Cross-references +---------------------------------- + +reStructuredText lets you define labels that can be cross-referenced as links elsewhere in the documentation. A label looks like ``.. _this-is-my-label:`` or ``.. _This is my label with CAPS and spaces:``, on its own line surrounded by blank lines. The leading ``.. _`` and trailing ``:`` are what tell rST "this line is a label." E.g.: + +.. code-block:: reStructuredText + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + .. _this-is-my-label: + + My cool information + ^^^^^^^^^^^^^^^^^^^ + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + +You could then refer to that section with ``:XYZ:`this-is-my-label``` (leaving off the leading ``.. _``), where ``XYZ`` can be ``ref``, ``numref``, or ``eq`` (see examples below). This will create a link that, when clicked, takes the reader to the "My cool information" section. + +Here are some examples. Note that the displayed link text will update automatically as needed (e.g., a section number or figure caption gets changed). + +- Section headings, text: ``:ref:`rst-cross-references``` → :ref:`rst-cross-references` +- Section headings, number: ``:numref:`rst-cross-references``` → :numref:`rst-cross-references`. Note that, unlike ``numref`` for other things mentioned here, "Section" is not automatically prepended to the section number in the link text. +- Table, text: ``:ref:`Table Crop plant functional types``` → :ref:`Table Crop plant functional types` +- Table, number: ``:numref:`Table Crop plant functional types``` → :numref:`Table Crop plant functional types` +- Figure, text (uses entire caption): ``:ref:`Figure CLM subgrid hierarchy``` → :ref:`Figure CLM subgrid hierarchy` +- Figure, number: ``:numref:`Figure CLM subgrid hierarchy``` → :numref:`Figure CLM subgrid hierarchy` +- Equation, number: ``:eq:`equation for a line``` → :eq:`equation for a line`. The parentheses in the link text seem unavoidable, and there seems to be no way to refer to have the link show the label text or anything else aside from the number. + +You can have any link (except for equations) show custom text by putting the referenced label at the end in ````. E.g., ``:ref:`Diagram of CLM subgrid hierarchy
``` → :ref:`Diagram of CLM subgrid hierarchy
`. + +Note that this is necessary for labels that aren't immediately followed by a section heading, a table with a caption, or a figure with a caption. For instance, to refer to labels in our bibliography, you could do ``:ref:`(Bonan, 1996)``` → :ref:`(Bonan, 1996)`. + +.. _rst-comments: + +reStructuredText: Comments +-------------------------- + +If you want to add some text that's only visible in the documentation source file, you can use the reStructuredText comment syntax: + +.. code-block:: reStructuredText + + .. + This will not appear on the webpage or even anywhere in the generated HTML. + + +Make sure to include at least one empty line after the comment text. + + +reStructuredText: Tables +------------------------ + +Tables defined with the `:table: directive `_ can be annoying because they're very sensitive to the cells inside them being precisely the right widths, as defined by the first ``====`` strings. If you don't get the widths right, you'll see "Text in column margin" errors. Instead, define your tables using the `:list-table: `_ directive. + +If you already have a table in some other format, like comma-separated values (CSV), you may want to check out the R package `knitr `_. Its `kable `_ command allows automatic conversion of R dataframes to tables in reStructuredText and other formats. + +reStructuredText: Admonitions (e.g., warning, tip) +-------------------------------------------------- + +`Admonitions `_ are rendered as special "call-out" boxes. The general syntax is: + +.. code-block:: reStructuredText + + .. admonition:: This is the title of a generic admonition + + It needs a title specified. Synonyms you can put in the ``{}`` instead of ``admonition`` include ``note`` and ``seealso``; if you use one of those, you don't need to specify a title. + + +.. admonition:: This is the title of a generic admonition + + It needs a title specified. Synonyms you can put in the ``{}`` instead of ``admonition`` include ``note`` and ``seealso``; if you use one of those, you don't need to specify a title. + + +There are also a number of built-in admonition types that get their own special rendering: + +.. code-block:: reStructuredText + + .. attention:: + + The reader should pay special attention to this. Synonyms you can put in the ``{}`` instead of ``attention`` include ``caution`` and ``warning``. + +.. attention:: + + The reader should pay special attention to this. Synonyms you can put in the ``{}`` instead of ``attention`` include ``caution`` and ``warning``. + +.. code-block:: reStructuredText + + .. danger:: + + This tells the reader about something dangerous. You can also put ``error`` in the ``{}`` instead of ``danger``. + +.. danger:: + + This tells the reader about something dangerous. You can also put ``error`` in the ``{}`` instead of ``danger``. + +.. code-block:: reStructuredText + + .. hint:: + + Here's a hint. Synonyms you can put in the ``{}`` instead of ``hint`` include ``important`` and ``tip``. + +.. hint:: + + Here's a hint. Synonyms you can put in the ``{}`` instead of ``hint`` include ``important`` and ``tip``. + + + +reStructuredText: Embedding a different reStructuredText file +------------------------------------------------------------- + +.. code-block:: reStructuredText + + .. include:: embed-example-rst.rst + +Becomes: + +.. include:: embed-example-rst.rst + +You can also embed literal contents of any file without the rendering: + +.. code-block:: reStructuredText + + .. literalinclude:: embed-example-rst.rst + :language: restructuredtext + +That becomes the literal contents (note syntax highlighting): + +.. literalinclude:: embed-example-rst.rst + :language: restructuredtext + +You can also get fancy: + +.. code-block:: reStructuredText + + .. literalinclude:: embed-example-python.py + :language: python + :start-at: print + :linenos: + :lineno-match: + +Becomes: + +.. literalinclude:: embed-example-python.py + :language: python + :start-at: print + :linenos: + :lineno-match: + +See `the Sphinx documentation `_ for more options to the ``literalinclude`` directive. + + +reStructuredText: Text superscripts and subscripts +-------------------------------------------------------------- + +Note that these instructions apply to text (i.e., not in inline or block math). + +**Superscripts** + +- Incorrect: ``Fe:sup:`3+``` becomes Fe:sup:`3+` +- Incorrect: ``Fe :sup:`3+``` becomes Fe :sup:`3+` (note extraneous space) +- Correct: ``Fe\ :sup:`3+``` becomes Fe\ :sup:`3+` + +**Subscripts** + +- Incorrect: ``CO:sub:`2``` becomes CO:sub:`2` +- Incorrect: ``CO :sub:`2``` becomes CO :sub:`2` (note extraneous space) +- Correct: ``CO\ :sub:`2``` becomes CO\ :sub:`2` + + + +reStructuredText: Common error messages and how to handle them +-------------------------------------------------------------- + +See :ref:`common-rst-errors`. diff --git a/doc/source/users_guide/working-with-documentation/vscode-doc-editing-setup.md b/doc/source/users_guide/working-with-documentation/vscode-doc-editing-setup.md new file mode 100644 index 0000000000..4a531b7647 --- /dev/null +++ b/doc/source/users_guide/working-with-documentation/vscode-doc-editing-setup.md @@ -0,0 +1,92 @@ +(vscode-docs-editing-setup)= + +# Recommended setup for editing docs in VS Code + +## Set up Python +The Python packages needed for this setup are listed at `doc/ctsm-docs_container/requirements.txt`. If you recently installed [the `ctsm_pylib` conda environment](https://escomp.github.io/CTSM/users_guide/using-clm-tools/using-ctsm-pylib.html), they will already be included there. Check like so: +```shell +conda activate ctsm_pylib +pip show myst-parser +``` + +If you see `WARNING: Package(s) not found: myst-parser`, you'll need to install the doc-building Python modules. With your conda environment activated (or in whatever other environment you want to use), from the top level of a CTSM checkout, do: +```shell +pip install -r doc/ctsm-docs_container/requirements.txt +``` + +You will need to provide the path to your Python binary in various VS Code settings detailed below. You can get that with `which python` (after loading the relevant conda environment, if needed). + +## Install required [VS Code extensions](https://code.visualstudio.com/docs/getstarted/extensions) + +1. [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) +2. [MyST-Markdown](https://marketplace.visualstudio.com/items?itemName=ExecutableBookProject.myst-highlight) +3. [Esbonio](https://marketplace.visualstudio.com/items?itemName=swyddfa.esbonio) + +## Change VS Code settings for Esbonio extension +```{important} +This setup will work only if you've opened the top level of a CTSM checkout as a [VS Code workspace](https://code.visualstudio.com/docs/editing/workspaces/workspaces). +``` + +Open VS Code's settings. (To restrict the list to only settings related to this setup, you can access the Esbonio settings via the gear icon on its item in the Extensions menu.) You're going to change a few things, but note that VS Code can have up to three tabs (representing "scopes") across the top of the Settings page: User, Remote \[SSH: remotename], and Workspace. Below, we'll explain which setting should be set in which scope(s). Keep in mind that scopes going left to right get more specific, and a setting in a later (rightward) scope will always override the same setting in an earlier (leftward) scope. + +### Build command +`Esbonio > Sphinx: Build Command` in the Settings GUI: This is an annoying one. We want to tell it to use `sphinx-build doc/source ${defaultBuildDir} -c doc/doc-builder`, but each word there has to be its own element in a list. + +![](esbonio-sphinx-buildcmd.png) + +It might be easier to open your VS Code's `settings.json` file(s) for this. You'd simply add: +```json +"esbonio.sphinx.buildCommand": [ + "sphinx-build", + "doc/source", + "${defaultBuildDir}", + "-c", + "doc/doc-builder" +] +``` + +Note that it needs to be proper JSON syntax, though. So in context it looks like this if it's at the end of the file (your indentation may vary): +```json +"chat.disableAIFeatures": true, +"esbonio.sphinx.buildCommand": [ + "sphinx-build", + "doc/source", + "${defaultBuildDir}", + "-c", + "doc/doc-builder" +] +} +``` +Note the comma at the end of the preceding line, and the curly bracket on the very last line of the file. + +As far as which scope to use: If you're always or usually going to be using Esbonio to preview docs for CTSM, you should put this in the User scope. You can open your User `settings.json` by searching in the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) for `user settings json`. For other projects using Esbonio, you will be able to set a Workspace-level `esbonio.sphinx.buildCommand` to override your User default. + +### Python command +`Esbonio > Sphinx: Python Command`. Do not get this confused with `Esbonio > Sphinx: Build Command` from above, or the similar `Esbonio > Server: Python Command`. This one you're going to *have* to edit in `settings.json`: +```json +"esbonio.sphinx.pythonCommand": "/path/to/your/python", +``` +The path is what you got from `which python` above. See the note about proper JSON syntax in "Build command" above. + +Which settings scope? +- If you're working on your local machine, User: Search in the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) for `user settings json`. +- If you're working on a remote machine, Remote: Search in the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) for `remote settings json`. + +### Finishing up +Once you've made those settings changes, reload the window (search `reload window` in the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette)). + +## Previewing +This will take a while the first time you build the previews during a session. +1. (Optional but recommended, at least the first time) In the View menu, select Output. In the drop-down menu at the top right of the Output panel, select Esbonio. +2. Open a documentation source file (.rst or .md). +3. Search `Esbonio: Preview Documentation in Split Window` (or any subset of those words) in the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette). Select it and this should open a pane next to the documentation source file that is initially empty. +4. If you opened the Esbonio Output panel (or open it now), you'll see it working. This can take a while, especially if it's doing a clean build (such as the first time you do this). +5. Once it's done, the preview pane should fill in. + +When you make changes to and save a documentation source file, Esbonio will re-generate the preview for that file. This should be relatively quick, since it's not doing a clean build—just a new build of that file in particular. However, you may need to close and re-open the preview pane before you see your changes. Also, there are some types of changes you can make to one file that will affect *other* files (such as changing a section label that is cross-referenced in a different file). Esbonio will not know to rebuild those other files. To force a clean build, try the `Esbonio: Restart Language Server` command in the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette). Failing that, you can try deleting the directory referenced in the "The HTML pages are in" message printed in the Esbonio Output log. + +Some other tips: +- If you see long lines in the editor that require you to scroll far to the right, search the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) for "word wrap" and select `View: Toggle Word Wrap`. These long lines are intentional (see [style guide](#ctsm-docs-style-guide)). +- Once the preview is ready, you can scroll in either the source file or the preview and they will stay approximately in sync with each other. +- You should be able to open other source files and get their preview instantly. +- More info on features can be found on the [Esbonio VS Code Extension page](https://marketplace.visualstudio.com/items?itemName=swyddfa.esbonio) diff --git a/lilac/atm_driver/Makefile b/lilac/atm_driver/Makefile index 8a50eedb0b..3b3480ffb7 100644 --- a/lilac/atm_driver/Makefile +++ b/lilac/atm_driver/Makefile @@ -1,5 +1,5 @@ #================================================================================ -# Makefile to compile atm_driver on cheyenne +# Makefile to compile atm_driver on derecho #================================================================================ #================================================================================ diff --git a/lilac/atm_driver/cheyenne.sub b/lilac/atm_driver/derecho.sub similarity index 77% rename from lilac/atm_driver/cheyenne.sub rename to lilac/atm_driver/derecho.sub index 4733e8ae3e..6a96613493 100644 --- a/lilac/atm_driver/cheyenne.sub +++ b/lilac/atm_driver/derecho.sub @@ -2,19 +2,15 @@ #PBS -N job_name #PBS -A P93300606 #PBS -l walltime=00:10:00 -#PBS -q premium -##PBS -q share -##PBS -q regular +#PBS -q main #PBS -j oe -#PBS -l select=2:ncpus=4:mpiprocs=8 -##PBS -l select=1:ncpus=1:mpiprocs=2 -##PBS -l select=1:ncpus=1:mpiprocs=1 +#PBS -l select=1:ncpus=128:mpiprocs=128 #ml ??? ### Set TMPDIR as recommended -setenv TMPDIR /glade/scratch/$USER +setenv TMPDIR /glade/derecho/scratch/$USER mkdir -p $TMPDIR echo "hello" @@ -25,7 +21,6 @@ source /glade/u/apps/ch/opt/lmod/7.5.3/lmod/lmod/init/csh module purge module load ncarenv/1.2 intel/19.0.2 esmf_libs mkl mpt/2.19 netcdf-mpi/4.6.1 pnetcdf/1.11.0 ncarcompilers/0.4.1 setenv OMP_STACKSIZE 256M -setenv MPI_TYPE_DEPTH 16 setenv MPI_IB_CONGESTED 1 setenv MPI_USE_ARRAY None setenv ESMFMKFILE /glade/u/home/dunlap/ESMF-INSTALL/intel19/8.0.0bs32/lib/libO/Linux.intel.64.mpt.default/esmf.mk @@ -36,4 +31,4 @@ setenv UGCSFIXEDFILEPATH /glade/work/turuncu/FV3GFS/fix_am setenv UGCSADDONPATH /glade/work/turuncu/FV3GFS/addon #setenv MPI_USE_ARRAY false -mpiexec_mpt -p "%g:" ./atm_driver.exe +mpibind ./atm_driver.exe diff --git a/python/README.python_pkgs.rst b/python/README.python_pkgs.md old mode 100644 new mode 100755 similarity index 56% rename from python/README.python_pkgs.rst rename to python/README.python_pkgs.md index d1cf803509..78aeebf505 --- a/python/README.python_pkgs.rst +++ b/python/README.python_pkgs.md @@ -1,32 +1,32 @@ -.. sectnum:: +# Requirements to consider for python packages to be included for CTSM python tools -.. contents:: +Any added dependencies should be discussed and approved by the CTSM-software team. Criteria for evaluation of third-party packages include: -===================================================================================== - Requirements to consider for python packages to be included for CTSM python tools -===================================================================================== +- How much value does this package provide to us beyond what we could get without it? -Requirements for CTSM python tools: +- How difficult it is to install this package (including: how much does this complicate / slow down the creation of the conda environment)? -Any added dependencies should be discussed and approved by the CTSM-software team. Criteria for evaluation of third-party packages -include: -- How much value does this package provide to us beyond what we could get without it? -- How difficult it is to install this package (including: how much does this complicate / slow down the creation of the conda -environment)? - How stable is this package? + - How well maintained is this package? + - Are there other packages that are more stable or better maintained that would provide nearly the same level of value? -- Tools that require extra packages should be done in a "contrib" type area out of the main part of tools (this would apply for -advanced plotting capability for example) -- We need to be able to reproduce working conda environments minimally on our test machines (currently cheyenne and izumi), but also -on any machine that we run CTSM on. If there is a machine that we can run CTSM on that we can't build the conda environments or run -the tools on -- that needs to be fixed. -- We need to tell the user how long to expect the conda environment to load, and give them options if the conda load is taking too -long -- Conda environments need to build robustly even for users who don't have ctsm_pylib loaded in their conda environment + +- Tools that require extra packages should be done in a "contrib" type area out of the main part of tools (this would apply for advanced plotting capability for example) + +- We need to be able to reproduce working conda environments minimally on our test machines (currently derecho and izumi), but also on any machine that we run CTSM on. If there is a machine that we can run CTSM on that we can't build the conda environments or run the tools on, that needs to be fixed. + +- We need to tell the user how long to expect the conda environment to load, and give them options if the conda load is taking too long + +- Conda environments need to build robustly even for users who don't have `ctsm_pylib` loaded in their conda environment + - Currently we won't use conda-lock + - We specify the black version exactly so that black will function identically for all users + - We specify the pylint version exactly because pylint is finicky with version and we need it to work identically for all developers + - We might remove the need for python packages that aren't providing enough utility -Packages where specific versions seem to be required will have the version requirements in a least the >= form if not an exact +- Packages where specific versions seem to be required will have the version requirements in a least the `>=` form if not an exact version + diff --git a/python/ctsm/machine_defaults.py b/python/ctsm/machine_defaults.py index 16742da47e..84bb176d8e 100644 --- a/python/ctsm/machine_defaults.py +++ b/python/ctsm/machine_defaults.py @@ -44,30 +44,6 @@ QsubDefaults = namedtuple("QsubDefaults", ["queue", "walltime", "extra_args", "required_args"]) MACHINE_DEFAULTS = { - "cheyenne": MachineDefaults( - job_launcher_type=JOB_LAUNCHER_QSUB, - scratch_dir=os.path.join(os.path.sep, "glade", "scratch", get_user()), - baseline_dir=os.path.join( - os.path.sep, "glade", "p", "cgd", "tss", "To_Be_Safely_Deleted", "ctsm_baselines" - ), - account_required=True, - create_test_retry=0, - # NOTE(wjs, 2022-02-23) By default, use the regular queue, even for - # single-processor jobs. This is because the share queue has been really flaky, - # with lots of job failures or slow-running jobs. - create_test_queue="regular", - job_launcher_defaults={ - JOB_LAUNCHER_QSUB: QsubDefaults( - queue="regular", - walltime="11:50:00", - extra_args="", - # The following assumes a single node, with a single mpi proc; we may want - # to add more flexibility in the future, making the node / proc counts - # individually selectable - required_args="-l select=1:ncpus=36:mpiprocs=1 -V -r n -l inception=login -k oed", - ) - }, - ), "derecho": MachineDefaults( job_launcher_type=JOB_LAUNCHER_QSUB, scratch_dir=os.path.join(os.path.sep, "glade", "derecho", "scratch", get_user()), @@ -87,22 +63,6 @@ ) }, ), - "hobart": MachineDefaults( - job_launcher_type=JOB_LAUNCHER_QSUB, - scratch_dir=os.path.join(os.path.sep, "scratch", "cluster", get_user()), - baseline_dir=os.path.join(os.path.sep, "fs", "cgd", "csm", "ccsm_baselines"), - account_required=False, - create_test_retry=0, - create_test_queue=CREATE_TEST_QUEUE_UNSPECIFIED, - job_launcher_defaults={ - JOB_LAUNCHER_QSUB: QsubDefaults( - queue="medium", - walltime="04:00:00", - extra_args="", - required_args="-l nodes=1:ppn=48 -r n", - ) - }, - ), "izumi": MachineDefaults( job_launcher_type=JOB_LAUNCHER_QSUB, scratch_dir=os.path.join(os.path.sep, "scratch", "cluster", get_user()), diff --git a/python/ctsm/machine_utils.py b/python/ctsm/machine_utils.py index 593a55c75f..d280ecc4d7 100644 --- a/python/ctsm/machine_utils.py +++ b/python/ctsm/machine_utils.py @@ -38,9 +38,7 @@ def _machine_from_hostname(hostname): be extended if there are other machines with special translation rules from hostname to machine name. """ - if re.match(r"cheyenne\d+", hostname): - machine = "cheyenne" - elif re.match(r"derecho\d+", hostname): + if re.match(r"derecho\d+", hostname): machine = "derecho" else: machine = hostname diff --git a/python/ctsm/run_sys_tests.py b/python/ctsm/run_sys_tests.py index 1733b73841..e64821e63c 100644 --- a/python/ctsm/run_sys_tests.py +++ b/python/ctsm/run_sys_tests.py @@ -282,7 +282,7 @@ def _commandline_args(): This automatically detects the machine and launches the appropriate components of the aux_clm test suite on that machine. This script also implements other aspects of the typical CTSM system testing workflow, such as running create_test via qsub on - cheyenne, and setting up a directory to hold all of the tests in the test suite. A + derecho, and setting up a directory to hold all of the tests in the test suite. A symbolic link will be created in the current directory pointing to the testroot directory containing all of the test directories in the test suite. diff --git a/python/ctsm/site_and_regional/modify_singlept_site_neon.py b/python/ctsm/site_and_regional/modify_singlept_site_neon.py index f7ac7b266c..99b011da0e 100755 --- a/python/ctsm/site_and_regional/modify_singlept_site_neon.py +++ b/python/ctsm/site_and_regional/modify_singlept_site_neon.py @@ -274,7 +274,7 @@ def find_soil_structure(args, surf_file): soil_bot : array of soil layers top depths soil_top : array of soil layers bottom depths """ - # TODO: What if not cheyenne? Self-contained depth info. + # TODO: What if not derecho? Self-contained depth info. print("------------") print("surf_file : ", surf_file) diff --git a/python/ctsm/subset_data.py b/python/ctsm/subset_data.py index ed9282ef46..f38394c622 100644 --- a/python/ctsm/subset_data.py +++ b/python/ctsm/subset_data.py @@ -41,7 +41,7 @@ To run the script for a region: ./subset_data.py region -To remove NPL from your environment on Cheyenne/Casper: +To remove NPL from your environment on derecho/casper: deactivate ------------------------------------------------------------------- """ diff --git a/python/ctsm/test/README b/python/ctsm/test/README.md similarity index 64% rename from python/ctsm/test/README rename to python/ctsm/test/README.md index aa4f2e1c9b..f5e0c9c6b5 100644 --- a/python/ctsm/test/README +++ b/python/ctsm/test/README.md @@ -1,23 +1,28 @@ CTSM-specific boiler-plate needed for most unit test modules: -(1) If cime stuff is invoked by these unit tests (directly or - indirectly, then: the first ctsm import statement near the top of - the module should be: +(1) If cime stuff is invoked by these unit tests (directly or indirectly) then, the first ctsm import statement near the top of the module should be: -from ctsm import add_cime_to_path # pylint: disable=unused-import +``` +from ctsm import add_cime_to_path # pylint: disable=unused-import +``` (2) Import the ctsm-specific unit_testing module: +``` from ctsm import unit_testing +``` (3) Allow names that pylint doesn't like: - +``` # Allow names that pylint doesn't like, because otherwise I find it hard # to make readable unit test names # pylint: disable=invalid-name +``` (4) Have a 'main' block at the bottom: - +``` if __name__ == '__main__': unit_testing.setup_for_tests() unittest.main() +``` + diff --git a/python/ctsm/test/test_sys_mesh_modifier.py b/python/ctsm/test/test_sys_mesh_modifier.py index 69ec8afdac..b28a77e7a5 100755 --- a/python/ctsm/test/test_sys_mesh_modifier.py +++ b/python/ctsm/test/test_sys_mesh_modifier.py @@ -81,7 +81,7 @@ def createScripGridAndMask(self, fsurdat_in): # The mask will be idnetically 1, no matter the input grid (you can, change it, but you have to get it from a mapping file) # Since, the mask is going to be changed later, it's fine that the mask at this point is identically 1. - # This could also alturnatively be done, by using the stored SCRIP grid file for the resolution under CESM inputdata + # This could also alternatively be done, by using the stored SCRIP grid file for the resolution under CESM inputdata ncks_cmd = ( f"ncks --rgr infer --rgr scrip={self.scrip_file} {fsurdat_in} {self.metadata_file}" ) diff --git a/python/ctsm/test/test_unit_machine.py b/python/ctsm/test/test_unit_machine.py index 9fa23ea9e7..677712b652 100755 --- a/python/ctsm/test/test_unit_machine.py +++ b/python/ctsm/test/test_unit_machine.py @@ -76,7 +76,7 @@ def create_defaults(default_job_launcher=JOB_LAUNCHER_QSUB): """Creates test-specific defaults so we don't tie the tests to changes in the real defaults""" defaults = { - "cheyenne": MachineDefaults( + "derecho": MachineDefaults( job_launcher_type=default_job_launcher, scratch_dir=os.path.join(os.path.sep, "glade", "scratch", get_user()), baseline_dir=os.path.join(os.path.sep, "my", "baselines"), @@ -157,10 +157,10 @@ def test_unknownMachine_argsExplicit(self): def test_knownMachine_defaults(self): """Tests a machine known in the defaults structure, with no overriding arguments""" defaults = self.create_defaults() - machine = create_machine("cheyenne", defaults, account="a123") + machine = create_machine("derecho", defaults, account="a123") self.assertMachineInfo( machine=machine, - name="cheyenne", + name="derecho", scratch_dir=os.path.join(os.path.sep, "glade", "scratch", get_user()), baseline_dir=os.path.join(os.path.sep, "my", "baselines"), account="a123", @@ -180,7 +180,7 @@ def test_knownMachine_argsExplicit(self): """Tests a machine known in the defaults structure, with explicit arguments""" defaults = self.create_defaults(default_job_launcher=JOB_LAUNCHER_NOBATCH) machine = create_machine( - "cheyenne", + "derecho", defaults, job_launcher_type=JOB_LAUNCHER_QSUB, scratch_dir="/custom/path/to/scratch", @@ -191,7 +191,7 @@ def test_knownMachine_argsExplicit(self): ) self.assertMachineInfo( machine=machine, - name="cheyenne", + name="derecho", scratch_dir="/custom/path/to/scratch", baseline_dir=os.path.join(os.path.sep, "my", "baselines"), account="a123", @@ -214,7 +214,7 @@ def test_knownMachine_argsExplicit(self): def test_baselineDir_overridden(self): """Tests get_possibly_overridden_mach_value when baseline_dir is provided""" defaults = self.create_defaults() - machine = create_machine("cheyenne", defaults, account="a123") + machine = create_machine("derecho", defaults, account="a123") baseline_dir = get_possibly_overridden_mach_value( machine, varname="baseline_dir", value="mypath" ) @@ -223,7 +223,7 @@ def test_baselineDir_overridden(self): def test_baselineDir_default(self): """Tests get_possibly_overridden_mach_value when baseline_dir is not provided""" defaults = self.create_defaults() - machine = create_machine("cheyenne", defaults, account="a123") + machine = create_machine("derecho", defaults, account="a123") baseline_dir = get_possibly_overridden_mach_value( machine, varname="baseline_dir", value=None ) diff --git a/python/ctsm/test/testinputs/README.md b/python/ctsm/test/testinputs/README.md index ef8953d20e..f2ef8c8634 100644 --- a/python/ctsm/test/testinputs/README.md +++ b/python/ctsm/test/testinputs/README.md @@ -7,7 +7,7 @@ done once per machine, and step (2) needs to be done once per user: 1. Install the Git LFS tool: Follow the instructions on the [Git LFS page](https://git-lfs.github.com/) for installing Git LFS on your platform. - On derecho the system default version of git already has Git LFS installed. - - On cheyenne and casper, Git LFS is already available as long as you are using a git + - On derecho and casper, Git LFS is already available as long as you are using a git module rather than the default system-level git. So just make sure that you are always using git via a git module (`module load git`). - On a Mac using homebrew, this can be done with `brew install git-lfs`. diff --git a/python/ctsm/test/testinputs/mksurfdata_esmf_bld/.env_mach_specific.sh b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/.env_mach_specific.sh index da0dc4f1bd..df9c86ac33 100644 --- a/python/ctsm/test/testinputs/mksurfdata_esmf_bld/.env_mach_specific.sh +++ b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/.env_mach_specific.sh @@ -9,7 +9,6 @@ module use /glade/campaign/cesm/cesmdata/cseg/PROGS/modulefiles/esmfpkgs/intel/1 module load esmf-8.4.1b02-ncdfio-mpt-O mpt/2.25 netcdf-mpi/4.9.0 pnetcdf/1.12.3 ncarcompilers/0.5.0 pio/2.5.10 export OMP_STACKSIZE=1024M export TMPDIR=/glade/derecho/scratch/erik -export MPI_TYPE_DEPTH=16 export MPI_USE_ARRAY=None export COMPILER=intel export MPILIB=mpt diff --git a/python/ctsm/test/testinputs/mksurfdata_esmf_bld/env_mach_specific.xml b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/env_mach_specific.xml index 0284ee1952..ee0b2fbc44 100644 --- a/python/ctsm/test/testinputs/mksurfdata_esmf_bld/env_mach_specific.xml +++ b/python/ctsm/test/testinputs/mksurfdata_esmf_bld/env_mach_specific.xml @@ -208,7 +208,6 @@ 1024M /glade/derecho/scratch/$USER - 16 diff --git a/share b/share index 9aa0b449c4..f210ab4b32 160000 --- a/share +++ b/share @@ -1 +1 @@ -Subproject commit 9aa0b449c47f0f22badf27eff2e6fd37ecdd2def +Subproject commit f210ab4b326ce9da5f8b062953eef0bb023ec188 diff --git a/src/README.unit_testing b/src/README.unit_testing deleted file mode 100644 index 897e7869ce..0000000000 --- a/src/README.unit_testing +++ /dev/null @@ -1,11 +0,0 @@ -# To run all CTSM unit tests, run the following command: -# -# This reuses the existing 'unit_tests.temp' directory (if present) in -# order to do an incremental rebuild of the unit tests from the last -# time you ran them from this directory. - -# From a standalone CTSM checkout: -../cime/scripts/fortran_unit_testing/run_tests.py --build-dir unit_tests.temp - -# If you are within a full CESM checkout, you would instead do: -# ../../../cime/scripts/fortran_unit_testing/run_tests.py --build-dir unit_tests.temp diff --git a/src/README.unit_testing.md b/src/README.unit_testing.md new file mode 100644 index 0000000000..de9fa66b47 --- /dev/null +++ b/src/README.unit_testing.md @@ -0,0 +1,16 @@ +To run all CTSM unit tests, run the following command: + +This reuses the existing `unit_tests.temp` directory (if present) in +order to do an incremental rebuild of the unit tests from the last +time you ran them from this directory. + +From a standalone CTSM checkout: +``` +../cime/scripts/fortran_unit_testing/run_tests.py --build-dir unit_tests.temp +``` + +If you are within a full CESM checkout, you would instead do: +``` +../../../cime/scripts/fortran_unit_testing/run_tests.py --build-dir unit_tests.temp +``` + diff --git a/src/biogeochem/CNDriverMod.F90 b/src/biogeochem/CNDriverMod.F90 index d14e619b03..e1252b12ad 100644 --- a/src/biogeochem/CNDriverMod.F90 +++ b/src/biogeochem/CNDriverMod.F90 @@ -479,7 +479,7 @@ subroutine CNDriverNoLeaching(bounds, cnveg_carbonflux_inst,cnveg_nitrogenstate_inst,cnveg_nitrogenflux_inst, & soilbiogeochem_carbonflux_inst,& soilbiogeochem_state_inst,soilbiogeochem_nitrogenstate_inst, & - soilbiogeochem_nitrogenflux_inst,canopystate_inst) + soilbiogeochem_nitrogenflux_inst,canopystate_inst, clm_fates) call t_stopf('soilbiogeochemcompetition') ! distribute the available N between the competing patches on the basis of diff --git a/src/biogeochem/CNNDynamicsMod.F90 b/src/biogeochem/CNNDynamicsMod.F90 index 10c0f5ea38..346a407899 100644 --- a/src/biogeochem/CNNDynamicsMod.F90 +++ b/src/biogeochem/CNNDynamicsMod.F90 @@ -239,17 +239,14 @@ subroutine CNNFixation(num_soilc, filter_soilc, & if(col%is_fates(c))then s = clm_fates%f2hmap(clump_index)%hsites(c) ! %ema_npp is Smoothed [gc/m2/yr] - !npp = clm_fates%fates(clump_index)%bc_out(s)%ema_npp/(dayspyr*secspday) - ! FATES N cycling is not yet active, so runs are supplemented anyway - ! this will be added when FATES N cycling is completed. - npp = 0._r8 + npp = clm_fates%fates(clump_index)%bc_out(s)%ema_npp else - npp = col_lag_npp(c) + ! need to put npp in units of gC/m^2/year here first + npp = col_lag_npp(c) * secspday * dayspyr end if if (npp /= spval) then - ! need to put npp in units of gC/m^2/year here first - t = (1.8_r8 * (1._r8 - exp(-0.003_r8 * npp *(secspday * dayspyr))))/(secspday * dayspyr) + t = (1.8_r8 * (1._r8 - exp(-0.003_r8 * npp))) / (secspday * dayspyr) nfix_to_sminn(c) = max(0._r8,t) else nfix_to_sminn(c) = 0._r8 @@ -262,14 +259,13 @@ subroutine CNNFixation(num_soilc, filter_soilc, & if(col%is_fates(c))then s = clm_fates%f2hmap(clump_index)%hsites(c) - !npp = clm_fates%fates(clump_index)%bc_out(s)%ema_npp - ! See above regarding FATES and N fixation - npp = 0._r8 + ! %ema_npp is Smoothed [gc/m2/yr] + npp = clm_fates%fates(clump_index)%bc_out(s)%ema_npp else npp = cannsum_npp(c) end if - t = (1.8_r8 * (1._r8 - exp(-0.003_r8 * npp)))/(secspday * dayspyr) + t = (1.8_r8 * (1._r8 - exp(-0.003_r8 * npp))) / (secspday * dayspyr) nfix_to_sminn(c) = max(0._r8,t) end do endif diff --git a/src/biogeochem/ch4Mod.F90 b/src/biogeochem/ch4Mod.F90 index a5b7173b91..31d93b5d9e 100644 --- a/src/biogeochem/ch4Mod.F90 +++ b/src/biogeochem/ch4Mod.F90 @@ -385,7 +385,7 @@ subroutine InitHistory(this, bounds) ! ! !LOCAL VARIABLES: character(8) :: vr_suffix - character(10) :: active + character(10) :: active_via_hist_wrtch4diag integer :: begc,endc integer :: begg,endg real(r8), pointer :: data2dptr(:,:) ! temp. pointers for slicing larger arrays @@ -401,9 +401,9 @@ subroutine InitHistory(this, bounds) endif if (hist_wrtch4diag) then - active = "active" + active_via_hist_wrtch4diag = "active" else - active = "inactive" + active_via_hist_wrtch4diag = "inactive" end if this%finundated_col(begc:endc) = spval @@ -486,130 +486,96 @@ subroutine InitHistory(this, bounds) avgflag='A', long_name='CH4 soil Concentration for non-inundated area', & ptr_col=this%conc_ch4_unsat_col, l2g_scale_type='veg', default='inactive') - if (hist_wrtch4diag) then - this%ch4_prod_depth_sat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='CH4_PROD_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & - avgflag='A', long_name='CH4 soil production for inundated / lake area', & - ptr_col=this%ch4_prod_depth_sat_col) - end if - - if (hist_wrtch4diag) then - this%ch4_prod_depth_unsat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='CH4_PROD_DEPTH_UNSAT', units='mol/m3/s', type2d='levgrnd', & - avgflag='A', long_name='CH4 soil production for non-inundated area', & - ptr_col=this%ch4_prod_depth_unsat_col) - end if - - if (hist_wrtch4diag) then - this%ch4_oxid_depth_sat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='CH4_OXID_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & - avgflag='A', long_name='CH4 soil oxidation for inundated / lake area', & - ptr_col=this%ch4_oxid_depth_sat_col) - end if - - if (hist_wrtch4diag) then - this%ch4_oxid_depth_unsat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='CH4_OXID_DEPTH_UNSAT', units='mol/m3/s', type2d='levgrnd', & - avgflag='A', long_name='CH4 soil oxidation for non-inundated area', & - ptr_col=this%ch4_oxid_depth_unsat_col) - end if - - if (hist_wrtch4diag) then - this%ch4_aere_depth_sat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='CH4_AERE_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & - avgflag='A', long_name='CH4 soil aerenchyma loss for inundated / lake area '// & - ' (including transpiration flux if activated)', & - ptr_col=this%ch4_aere_depth_sat_col) - end if - - if (hist_wrtch4diag) then - this%ch4_aere_depth_unsat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='CH4_AERE_DEPTH_UNSAT', units='mol/m3/s', type2d='levgrnd', & - avgflag='A', long_name='CH4 soil aerenchyma loss for non-inundated area '// & - ' (including transpiration flux if activated)', & - ptr_col=this%ch4_aere_depth_unsat_col) - end if - - if (hist_wrtch4diag) then - this%o2_aere_depth_sat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='O2_AERE_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & - avgflag='A', long_name='O2 aerenchyma diffusion into soil for inundated / lake area', & - ptr_col=this%o2_aere_depth_sat_col) - end if - - if (hist_wrtch4diag) then - this%o2_aere_depth_unsat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='O2_AERE_DEPTH_UNSAT', units='mol/m3/s', type2d='levgrnd', & - avgflag='A', long_name='O2 aerenchyma diffusion into soil for non-inundated area', & - ptr_col=this%o2_aere_depth_unsat_col) - end if - - if (hist_wrtch4diag) then - call hist_addfld2d (fname='O2_DECOMP_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & - avgflag='A', long_name='O2 consumption from HR and AR for inundated / lake area', & - ptr_col=this%o2_decomp_depth_sat_col) - end if + this%ch4_prod_depth_sat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='CH4_PROD_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & + avgflag='A', long_name='CH4 soil production for inundated / lake area', & + ptr_col=this%ch4_prod_depth_sat_col, default=active_via_hist_wrtch4diag) + + this%ch4_prod_depth_unsat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='CH4_PROD_DEPTH_UNSAT', units='mol/m3/s', type2d='levgrnd', & + avgflag='A', long_name='CH4 soil production for non-inundated area', & + ptr_col=this%ch4_prod_depth_unsat_col, default=active_via_hist_wrtch4diag) + + this%ch4_oxid_depth_sat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='CH4_OXID_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & + avgflag='A', long_name='CH4 soil oxidation for inundated / lake area', & + ptr_col=this%ch4_oxid_depth_sat_col, default=active_via_hist_wrtch4diag) + + this%ch4_oxid_depth_unsat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='CH4_OXID_DEPTH_UNSAT', units='mol/m3/s', type2d='levgrnd', & + avgflag='A', long_name='CH4 soil oxidation for non-inundated area', & + ptr_col=this%ch4_oxid_depth_unsat_col, default=active_via_hist_wrtch4diag) + + this%ch4_aere_depth_sat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='CH4_AERE_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & + avgflag='A', long_name='CH4 soil aerenchyma loss for inundated / lake area '// & + ' (including transpiration flux if activated)', & + ptr_col=this%ch4_aere_depth_sat_col, default=active_via_hist_wrtch4diag) + + this%ch4_aere_depth_unsat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='CH4_AERE_DEPTH_UNSAT', units='mol/m3/s', type2d='levgrnd', & + avgflag='A', long_name='CH4 soil aerenchyma loss for non-inundated area '// & + ' (including transpiration flux if activated)', & + ptr_col=this%ch4_aere_depth_unsat_col, default=active_via_hist_wrtch4diag) + + this%o2_aere_depth_sat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='O2_AERE_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & + avgflag='A', long_name='O2 aerenchyma diffusion into soil for inundated / lake area', & + ptr_col=this%o2_aere_depth_sat_col, default=active_via_hist_wrtch4diag) + + this%o2_aere_depth_unsat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='O2_AERE_DEPTH_UNSAT', units='mol/m3/s', type2d='levgrnd', & + avgflag='A', long_name='O2 aerenchyma diffusion into soil for non-inundated area', & + ptr_col=this%o2_aere_depth_unsat_col, default=active_via_hist_wrtch4diag) + + call hist_addfld2d (fname='O2_DECOMP_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & + avgflag='A', long_name='O2 consumption from HR and AR for inundated / lake area', & + ptr_col=this%o2_decomp_depth_sat_col, default=active_via_hist_wrtch4diag) this%o2_decomp_depth_unsat_col(begc:endc,1:nlevgrnd) = spval call hist_addfld2d (fname='O2_DECOMP_DEPTH_UNSAT', units='mol/m3/s', type2d='levgrnd', & avgflag='A', long_name='O2 consumption from HR and AR for non-inundated area', & - ptr_col=this%o2_decomp_depth_unsat_col, default=active) - - if (hist_wrtch4diag) then - this%ch4_tran_depth_sat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='CH4_TRAN_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & - avgflag='A', long_name='CH4 soil loss from transpiration for inundated / lake area', & - ptr_col=this%ch4_tran_depth_sat_col) - end if - - if (hist_wrtch4diag) then - this%ch4_tran_depth_unsat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='CH4_TRAN_DEPTH_UNSAT', units='mol/m3/s', type2d='levgrnd', & - avgflag='A', long_name='CH4 soil loss from transpiration for non-inundated area', & - ptr_col=this%ch4_tran_depth_unsat_col) - end if - - if (hist_wrtch4diag) then - this%ch4_ebul_depth_sat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='CH4_EBUL_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & - avgflag='A', long_name='CH4 soil ebullition for inundated / lake area', & - ptr_col=this%ch4_ebul_depth_sat_col) - end if - - if (hist_wrtch4diag) then - this%ch4_ebul_depth_unsat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='CH4_EBUL_DEPTH_UNSAT', units='mol/m3/s', type2d='levgrnd', & - avgflag='A', long_name='CH4 soil ebullition for non-inundated area', & - ptr_col=this%ch4_ebul_depth_unsat_col) - end if - - if (hist_wrtch4diag) then - this%o2stress_sat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='O2STRESS_SAT', units='unitless', type2d='levgrnd', & - avgflag='A', long_name='Ratio of oxygen available to demanded for non-inundated area', & - ptr_col=this%o2stress_sat_col) - end if - - if (hist_wrtch4diag) then - this%o2stress_unsat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='O2STRESS_UNSAT', units='unitless', type2d='levgrnd', & - avgflag='A', long_name='Ratio of oxygen available to demanded for inundated / lake area', & - ptr_col=this%o2stress_unsat_col) - end if - - if (hist_wrtch4diag) then - this%ch4stress_unsat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='CH4STRESS_UNSAT', units='unitless', type2d='levgrnd', & - avgflag='A', long_name='Ratio of methane available to total potential sink for inundated / lake area', & - ptr_col=this%ch4stress_unsat_col) - end if - - if (hist_wrtch4diag) then - this%ch4stress_sat_col(begc:endc,1:nlevgrnd) = spval - call hist_addfld2d (fname='CH4STRESS_SAT', units='unitless', type2d='levgrnd', & - avgflag='A', long_name='Ratio of methane available to total potential sink for non-inundated area', & - ptr_col=this%ch4stress_sat_col) - end if + ptr_col=this%o2_decomp_depth_unsat_col, default=active_via_hist_wrtch4diag) + + this%ch4_tran_depth_sat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='CH4_TRAN_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & + avgflag='A', long_name='CH4 soil loss from transpiration for inundated / lake area', & + ptr_col=this%ch4_tran_depth_sat_col, default=active_via_hist_wrtch4diag) + + this%ch4_tran_depth_unsat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='CH4_TRAN_DEPTH_UNSAT', units='mol/m3/s', type2d='levgrnd', & + avgflag='A', long_name='CH4 soil loss from transpiration for non-inundated area', & + ptr_col=this%ch4_tran_depth_unsat_col, default=active_via_hist_wrtch4diag) + + this%ch4_ebul_depth_sat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='CH4_EBUL_DEPTH_SAT', units='mol/m3/s', type2d='levgrnd', & + avgflag='A', long_name='CH4 soil ebullition for inundated / lake area', & + ptr_col=this%ch4_ebul_depth_sat_col, default=active_via_hist_wrtch4diag) + + this%ch4_ebul_depth_unsat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='CH4_EBUL_DEPTH_UNSAT', units='mol/m3/s', type2d='levgrnd', & + avgflag='A', long_name='CH4 soil ebullition for non-inundated area', & + ptr_col=this%ch4_ebul_depth_unsat_col, default=active_via_hist_wrtch4diag) + + this%o2stress_sat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='O2STRESS_SAT', units='unitless', type2d='levgrnd', & + avgflag='A', long_name='Ratio of oxygen available to demanded for non-inundated area', & + ptr_col=this%o2stress_sat_col, default=active_via_hist_wrtch4diag) + + this%o2stress_unsat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='O2STRESS_UNSAT', units='unitless', type2d='levgrnd', & + avgflag='A', long_name='Ratio of oxygen available to demanded for inundated / lake area', & + ptr_col=this%o2stress_unsat_col, default=active_via_hist_wrtch4diag) + + this%ch4stress_unsat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='CH4STRESS_UNSAT', units='unitless', type2d='levgrnd', & + avgflag='A', long_name='Ratio of methane available to total potential sink for inundated / lake area', & + ptr_col=this%ch4stress_unsat_col, default=active_via_hist_wrtch4diag) + + this%ch4stress_sat_col(begc:endc,1:nlevgrnd) = spval + call hist_addfld2d (fname='CH4STRESS_SAT', units='unitless', type2d='levgrnd', & + avgflag='A', long_name='Ratio of methane available to total potential sink for non-inundated area', & + ptr_col=this%ch4stress_sat_col, default=active_via_hist_wrtch4diag) if (hist_wrtch4diag) then this%ch4_prod_tot_col(begc:endc) = spval @@ -625,71 +591,65 @@ subroutine InitHistory(this, bounds) ptr_col=this%ch4_oxid_tot_col) endif - if (hist_wrtch4diag .and. allowlakeprod) then + if (allowlakeprod) then this%ch4_prod_depth_sat_col(begc:endc,1:nlevgrnd) = spval call hist_addfld2d (fname='CH4_PROD_DEPTH_LAKE', units='mol/m3/s', type2d='levgrnd', & avgflag='A', long_name='CH4 production in each soil layer, lake col. only', & - ptr_col=this%ch4_prod_depth_sat_col) + ptr_col=this%ch4_prod_depth_sat_col, default=active_via_hist_wrtch4diag) end if - if (hist_wrtch4diag .and. allowlakeprod) then + if (allowlakeprod) then this%conc_ch4_sat_col(begc:endc,1:nlevgrnd) = spval call hist_addfld2d (fname='CONC_CH4_LAKE', units='mol/m3', type2d='levgrnd', & avgflag='A', long_name='CH4 Concentration each soil layer, lake col. only', & - ptr_col=this%conc_ch4_sat_col) + ptr_col=this%conc_ch4_sat_col, default=active_via_hist_wrtch4diag) end if - if (hist_wrtch4diag .and. allowlakeprod) then + if (allowlakeprod) then this%conc_o2_sat_col(begc:endc,1:nlevgrnd) = spval call hist_addfld2d (fname='CONC_O2_LAKE', units='mol/m3', type2d='levgrnd', & avgflag='A', long_name='O2 Concentration each soil layer, lake col. only', & - ptr_col=this%conc_o2_sat_col) + ptr_col=this%conc_o2_sat_col, default=active_via_hist_wrtch4diag) end if - if (hist_wrtch4diag .and. allowlakeprod) then + if (allowlakeprod) then this%ch4_surf_diff_sat_col(begc:endc) = spval call hist_addfld1d (fname='CH4_SURF_DIFF_LAKE', units='mol/m2/s', & avgflag='A', long_name='diffusive surface CH4 flux, lake col. only (+ to atm)', & - ptr_col=this%ch4_surf_diff_sat_col) + ptr_col=this%ch4_surf_diff_sat_col, default=active_via_hist_wrtch4diag) end if - if (hist_wrtch4diag .and. allowlakeprod) then + if (allowlakeprod) then this%ch4_surf_ebul_sat_col(begc:endc) = spval call hist_addfld1d (fname='CH4_SURF_EBUL_LAKE', units='mol/m2/s', & avgflag='A', long_name='ebullition surface CH4 flux, lake col. only (+ to atm)', & - ptr_col=this%ch4_surf_ebul_sat_col) + ptr_col=this%ch4_surf_ebul_sat_col, default=active_via_hist_wrtch4diag) end if - if (hist_wrtch4diag .and. allowlakeprod) then + if (allowlakeprod) then this%ch4_oxid_depth_sat_col(begc:endc,1:nlevgrnd) = spval call hist_addfld2d (fname='CH4_OXID_DEPTH_LAKE', units='mol/m2/s', type2d='levgrnd', & avgflag='A', long_name='CH4 oxidation in each soil layer, lake col. only', & - ptr_col=this%ch4_oxid_depth_sat_col) - end if - - if (hist_wrtch4diag) then - this%layer_sat_lag_col(begc:endc,1:nlevgrnd) = spval - ! Using l2g_scale_type='veg' to exclude mass in special landunits, which can arise - ! from dynamic column adjustments. (We also exclude lakes here, because they don't - ! have any unsaturated area.) - call hist_addfld2d (fname='LAYER_SAT_LAG', units='unitless', type2d='levgrnd', & - avgflag='A', long_name='lagged saturation status of layer in unsat. zone', & - ptr_col=this%layer_sat_lag_col, l2g_scale_type='veg') + ptr_col=this%ch4_oxid_depth_sat_col, default=active_via_hist_wrtch4diag) end if - if (hist_wrtch4diag) then - this%annavg_finrw_col(begc:endc) = spval - call hist_addfld1d (fname='ANNAVG_FINRW', units='unitless', & - avgflag='A', long_name='annual average respiration-weighted FINUNDATED', & - ptr_col=this%annavg_finrw_col) - end if - - if (hist_wrtch4diag) then - this%sif_col(begc:endc) = spval - call hist_addfld1d (fname='SIF', units='unitless', & - avgflag='A', long_name='seasonal inundation factor calculated for sat. CH4 prod. (non-lake)', & - ptr_col=this%sif_col) - end if + this%layer_sat_lag_col(begc:endc,1:nlevgrnd) = spval + ! Using l2g_scale_type='veg' to exclude mass in special landunits, which can arise + ! from dynamic column adjustments. (We also exclude lakes here, because they don't + ! have any unsaturated area.) + call hist_addfld2d (fname='LAYER_SAT_LAG', units='unitless', type2d='levgrnd', & + avgflag='A', long_name='lagged saturation status of layer in unsat. zone', & + ptr_col=this%layer_sat_lag_col, l2g_scale_type='veg', default=active_via_hist_wrtch4diag) + + this%annavg_finrw_col(begc:endc) = spval + call hist_addfld1d (fname='ANNAVG_FINRW', units='unitless', & + avgflag='A', long_name='annual average respiration-weighted FINUNDATED', & + ptr_col=this%annavg_finrw_col, default=active_via_hist_wrtch4diag) + + this%sif_col(begc:endc) = spval + call hist_addfld1d (fname='SIF', units='unitless', & + avgflag='A', long_name='seasonal inundation factor calculated for sat. CH4 prod. (non-lake)', & + ptr_col=this%sif_col, default=active_via_hist_wrtch4diag) this%conc_o2_sat_col(begc:endc,1:nlevgrnd) = spval ! Using l2g_scale_type='veg_plus_lake' to exclude mass in non-lake special landunits, diff --git a/src/fates b/src/fates index e027a4030d..37c28ce7e9 160000 --- a/src/fates +++ b/src/fates @@ -1 +1 @@ -Subproject commit e027a4030d2a0f09039fb337ad67ced7461dd4f0 +Subproject commit 37c28ce7e94751905542cb29c096c74cc250d7eb diff --git a/src/main/clm_driver.F90 b/src/main/clm_driver.F90 index 38d13a71f8..05fa6145ba 100644 --- a/src/main/clm_driver.F90 +++ b/src/main/clm_driver.F90 @@ -120,6 +120,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro use FATESFireFactoryMod , only : scalar_lightning use FatesInterfaceTypesMod, only : fates_dispersal_cadence_none use CIsoAtmTimeseriesMod, only : C14BombSpike, C13TimeSeries + use shr_log_mod, only : errMsg => shr_log_errMsg ! ! !ARGUMENTS: implicit none @@ -822,6 +823,12 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro if (irrigate) then + if (use_fates) then + call endrun(msg=' ERROR: Can not have ' // & + 'use_fates = .true. and irrigate = .true. ' // & + 'Set one of them to .false. in your user_nl_clm. ' // & + errMsg(sourcefile, __LINE__)) + endif ! ============================================================================ ! Determine irrigation needed for future time steps ! ============================================================================ diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index 83133acf2b..9e42c3ff21 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -6,6 +6,7 @@ module clm_varctl ! ! !USES: use shr_kind_mod, only: r8 => shr_kind_r8, SHR_KIND_CX + use shr_kind_mod, only: CS => SHR_KIND_CS use shr_sys_mod , only: shr_sys_abort ! cannot use endrun here due to circular dependency ! ! !PUBLIC MEMBER FUNCTIONS: @@ -324,14 +325,22 @@ module clm_varctl integer, public :: fates_seeddisp_cadence = iundef ! 0 => no seed dispersal ! 1, 2, 3 => daily, monthly, or yearly dispersal - integer, public :: fates_parteh_mode = -9 ! 1 => carbon only - ! 2 => C+N+P (not enabled yet) - ! no others enabled + character(len=CS), public :: fates_parteh_mode = '' ! FATES Plant Allocation Reactions and Transport Hypotheses + ! = carbon_only : Cycle carbon in FATES only + ! = carbon_nitrogen: Cycle both carbon and nitrogen + ! in FATES. FATES will cycle phosphorus as well, + ! to do this, FATES will generate synthetic uptake + ! conditions to make sure that phosphorus is saturated + ! in the plant stores + ! so clm needs fates_cnp_prescribed_puptake > 1 + ! (recommended value 10) in the fates paramfile + integer, public :: fates_spitfire_mode = 0 ! 0 for no fire; 1 for constant ignitions; ! > 1 for external data (lightning and/or anthropogenic ignitions) ! see bld/namelist_files/namelist_definition_clm4_5.xml for details logical, public :: use_fates_managed_fire = .false. ! true => turn on managed fire + integer, public :: fates_lu_transition_logic = -9 ! controls logic around transition between land use classes logical, public :: use_fates_tree_damage = .false. ! true => turn on tree damage module character(len=256), public :: fates_harvest_mode = '' ! five different harvest modes; see namelist definition character(len=256), public :: fates_stomatal_model = '' ! stomatal conductance model, Ball-berry or Medlyn @@ -348,6 +357,7 @@ module clm_varctl logical, public :: use_fates_ed_st3 = .false. ! true => static stand structure logical, public :: use_fates_ed_prescribed_phys = .false. ! true => prescribed physiology logical, public :: use_fates_inventory_init = .false. ! true => initialize fates from inventory + logical, public :: use_fates_dbh_init = .false. ! true => initialize cohorts with dbh instead of density (nocomp only) logical, public :: use_fates_fixed_biogeog = .false. ! true => use fixed biogeography mode logical, public :: use_fates_nocomp = .false. ! true => use no comopetition mode logical, public :: use_fates_daylength_factor = .false. ! true => enable fates to use host land model daylength factor diff --git a/src/main/clm_varpar.F90 b/src/main/clm_varpar.F90 index 9ac4b197a0..12f3fbf6e8 100644 --- a/src/main/clm_varpar.F90 +++ b/src/main/clm_varpar.F90 @@ -6,6 +6,7 @@ module clm_varpar ! ! !USES: use shr_kind_mod , only: r8 => shr_kind_r8 + use shr_kind_mod , only: CS => SHR_KIND_CS use shr_sys_mod , only: shr_sys_abort use spmdMod , only: masterproc use clm_varctl , only: use_extralakelayers @@ -53,8 +54,16 @@ module clm_varpar integer, public, parameter :: mxpft = 78 ! maximum number of PFT's for any mode; integer, public, parameter :: mxsowings = 1 ! maximum number of crop growing seasons to begin in any year; integer, public :: mxharvests ! maximum number of crop harvests in any year - ! (allows for multiple harvests in a calendar year in case harvest occurs near + ! (allows for multiple harvests in a calendar + ! year in case harvest occurs near ! beginning/end of year); + + ! These strings define the clm-fates coupling, i.e. which chemical species + ! are cycled between the two, see corresponding values for fates_parteh_mode: + ! bld/namelist_files/namelist_definition_ctsm.xml + character(len=CS), public, parameter :: clmfates_carbon_only = 'carbon_only' + character(len=CS), public, parameter :: clmfates_carbon_nitrogen = 'carbon_nitrogen' + ! FIX(RF,032414) might we set some of these automatically from reading pft-physiology? integer, public, parameter :: nlayer = 3 ! number of VIC soil layer --Added by AWang integer, public :: nlayert ! number of VIC soil layer + 3 lower thermal layers diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index 082e3bb710..70cf132dc7 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -20,6 +20,8 @@ module controlMod use decompInitMod , only: clump_pproc use clm_varcon , only: h2osno_max use clm_varpar , only: maxpatch_glc, numrad, nlevsno + use clm_varpar , only: clmfates_carbon_only + use clm_varpar , only: clmfates_carbon_nitrogen use fileutils , only: getavu, relavu, get_filename use histFileMod , only: max_tapes, max_namlen use histFileMod , only: hist_empty_htapes, hist_all_fields, hist_dov2xy, hist_avgflag_pertape, hist_type1d_pertape @@ -42,7 +44,7 @@ module controlMod use CNSharedParamsMod , only: use_fun, use_matrixcn use CIsoAtmTimeseriesMod , only: use_c14_bombspike, atm_c14_filename, use_c13_timeseries, atm_c13_filename use SoilBiogeochemDecompCascadeConType, only : use_soil_matrixcn - use SoilBiogeochemCompetitionMod , only: suplnitro, suplnNon + use SoilBiogeochemCompetitionMod , only: suplnitro, suplnNon, suplnAll use SoilBiogeochemLittVertTranspMod , only: som_adv_flux, max_depth_cryoturb use SoilBiogeochemVerticalProfileMod , only: surfprof_exp use SoilBiogeochemNitrifDenitrifMod , only: no_frozen_nitrif_denitrif @@ -51,6 +53,7 @@ module controlMod use CanopyFluxesMod , only: CanopyFluxesReadNML use shr_drydep_mod , only: n_drydep use clm_varctl + ! ! !PUBLIC TYPES: implicit none @@ -236,6 +239,7 @@ subroutine control_init(dtime) use_fates_cohort_age_tracking, & use_fates_ed_prescribed_phys, & use_fates_inventory_init, & + use_fates_dbh_init, & use_fates_fixed_biogeog, & use_fates_nocomp, & use_fates_sp, & @@ -258,8 +262,9 @@ subroutine control_init(dtime) use_fates_tree_damage, & use_fates_daylength_factor, & fates_photosynth_acclimation, & - fates_history_dimlevel, & - use_fates_managed_fire + use_fates_managed_fire, & + fates_lu_transition_logic, & + fates_history_dimlevel ! Ozone vegetation stress method namelist / clm_inparm / o3_veg_stress_method @@ -492,12 +497,19 @@ subroutine control_init(dtime) use_fates_bgc = .true. end if - if (fates_parteh_mode == 1 .and. suplnitro == suplnNon .and. use_fates_bgc )then - write(iulog,*) ' When FATES with fates_parteh_mode == 1 (ie carbon only mode),' + if (trim(fates_parteh_mode) == trim(clmfates_carbon_only) .and. suplnitro == suplnNon)then + write(iulog,*) ' When fates_parteh_mode == carbon_only,' write(iulog,*) ' you must have supplemental nitrogen turned on, there will be' write(iulog,*) ' no nitrogen dynamics with the plants, and therefore no' write(iulog,*) ' meaningful limitations to nitrogen.' - call endrun(msg=' ERROR: fates_parteh_mode=1 must have suplnitro set to suplnAll.'//& + call endrun(msg=' ERROR: fates_parteh_mode=carbon_only must have suplnitro set to suplnAll.'//& + errMsg(sourcefile, __LINE__)) + end if + if (trim(fates_parteh_mode) == trim(clmfates_carbon_nitrogen) .and. use_fates_sp )then + write(iulog,*) ' When fates_parteh_mode == carbon_nirogen,' + write(iulog,*) ' you must have use_fates_bgc and not use_fates_sp.' + write(iulog,*) ' When you have use_fates_sp, then fates_parteh_mode should equal carbon_only.' + call endrun(msg=' ERROR: fates_parteh_mode=carbon_nitrogen and use_fates_sp are inconsistent.'//& errMsg(sourcefile, __LINE__)) end if @@ -818,6 +830,7 @@ subroutine control_spmd() call mpi_bcast (for_testing_allow_interp_non_ciso_to_ciso, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (fates_spitfire_mode, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (fates_lu_transition_logic, 1, MPI_INTEGER, 0, mpicom, ier) call mpi_bcast (fates_harvest_mode, len(fates_harvest_mode) , MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (fates_stomatal_model, len(fates_stomatal_model) , MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (fates_stomatal_assimilation, len(fates_stomatal_assimilation) , MPI_CHARACTER, 0, mpicom, ier) @@ -833,6 +846,7 @@ subroutine control_spmd() call mpi_bcast (use_fates_ed_st3, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_fates_ed_prescribed_phys, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_fates_inventory_init, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (use_fates_dbh_init, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_fates_fixed_biogeog, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_fates_nocomp, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_fates_sp, 1, MPI_LOGICAL, 0, mpicom, ier) @@ -848,7 +862,7 @@ subroutine control_spmd() call mpi_bcast (flandusepftdat, len(flandusepftdat) , MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (use_fates_managed_fire, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (fates_parteh_mode, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (fates_parteh_mode, len(fates_parteh_mode), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (fates_seeddisp_cadence, 1, MPI_INTEGER, 0, mpicom, ier) call mpi_bcast (fates_history_dimlevel, 2, MPI_INTEGER, 0, mpicom, ier) @@ -1235,6 +1249,7 @@ subroutine control_print () if (use_fates) then write(iulog, *) ' fates_spitfire_mode = ', fates_spitfire_mode write(iulog, *) ' fates_harvest_mode = ', fates_harvest_mode + write(iulog, *) ' fates_lu_transition_logic = ', fates_lu_transition_logic write(iulog, *) ' fates_stomatal_model = ', fates_stomatal_model write(iulog, *) ' fates_stomatal_assimilation = ', fates_stomatal_assimilation write(iulog, *) ' fates_leafresp_model = ', fates_leafresp_model @@ -1253,6 +1268,7 @@ subroutine control_print () write(iulog, *) ' use_fates_ed_st3 = ',use_fates_ed_st3 write(iulog, *) ' use_fates_ed_prescribed_phys = ',use_fates_ed_prescribed_phys write(iulog, *) ' use_fates_inventory_init = ',use_fates_inventory_init + write(iulog, *) ' use_fates_dbh_init = ',use_fates_dbh_init write(iulog, *) ' use_fates_fixed_biogeog = ', use_fates_fixed_biogeog write(iulog, *) ' use_fates_nocomp = ', use_fates_nocomp write(iulog, *) ' use_fates_sp = ', use_fates_sp diff --git a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 index 23f24e44d5..a86cc69c3c 100644 --- a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 @@ -30,7 +30,9 @@ module SoilBiogeochemCarbonFluxType ! decomposition fluxes real(r8), pointer :: decomp_cpools_sourcesink_col (:,:,:) ! change in decomposing c pools. Used to update concentrations concurrently with vertical transport (gC/m3/timestep) - real(r8), pointer :: c_overflow_vr (:,:,:) ! vertically-resolved C rejected by microbes that cannot process it (gC/m3/s) + real(r8), pointer :: c_overflow_hr_vr (:,:,:) ! vertically-resolved C rejected by microbes that cannot process it (gC/m3/s) (included in the heterotrophic respiration) + real(r8), pointer :: c_overflow_hr (:,:) ! vertically-integrated C rejected by microbes that cannot process it (gC/m2/s) (included in the heterotrophic respiration) + real(r8), pointer :: c_overflow_hr_sum (:) ! vertically-integrated and summed over all transitions, C rejected by microbes that cannot process it (gC/m2/s) (included in the heterotrophic respiration) real(r8), pointer :: decomp_cascade_hr_vr_col (:,:,:) ! vertically-resolved het. resp. from decomposing C pools (gC/m3/s) real(r8), pointer :: decomp_cascade_hr_col (:,:) ! vertically-integrated (diagnostic) het. resp. from decomposing C pools (gC/m2/s) real(r8), pointer :: decomp_cascade_ctransfer_vr_col (:,:,:) ! vertically-resolved C transferred along deomposition cascade (gC/m3/s) @@ -139,8 +141,14 @@ subroutine InitAllocate(this, bounds) allocate(this%decomp_cpools_sourcesink_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools)) this%decomp_cpools_sourcesink_col(:,:,:)= nan - allocate(this%c_overflow_vr(begc:endc,1:nlevdecomp_full,1:ndecomp_cascade_transitions)) - this%c_overflow_vr(:,:,:) = nan + allocate(this%c_overflow_hr_vr(begc:endc,1:nlevdecomp_full,1:ndecomp_cascade_transitions)) + this%c_overflow_hr_vr(:,:,:) = nan + + allocate(this%c_overflow_hr(begc:endc,1:ndecomp_cascade_transitions)) + this%c_overflow_hr(:,:) = nan + + allocate(this%c_overflow_hr_sum(begc:endc)) + this%c_overflow_hr_sum(:) = nan allocate(this%decomp_cascade_hr_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_cascade_transitions)) this%decomp_cascade_hr_vr_col(:,:,:)= spval @@ -264,6 +272,11 @@ subroutine InitHistory(this, bounds, carbon_type) ptr_col=this%hr_col) if (decomp_method == mimics_decomp) then + this%c_overflow_hr_sum(begc:endc) = spval + call hist_addfld1d (fname='COVERFLOW_HR_SUM', units='gC/m^2/s', & + avgflag='A', long_name='C overflow (already included in the heterotrophic respiration)', & + ptr_col=this%c_overflow_hr_sum, default='inactive') + this%michr_col(begc:endc) = spval call hist_addfld1d (fname='MICC_HR', units='gC/m^2/s', & avgflag='A', long_name='microbial C heterotrophic respiration: donor-pool based, so expect zero with MIMICS', & @@ -307,6 +320,8 @@ subroutine InitHistory(this, bounds, carbon_type) ptr_col=data2dptr, default='inactive') end do + this%c_overflow_hr(begc:endc,:) = spval + this%c_overflow_hr_vr(begc:endc,:,:) = spval this%decomp_cascade_hr_col(begc:endc,:) = spval this%decomp_cascade_hr_vr_col(begc:endc,:,:) = spval this%decomp_cascade_ctransfer_col(begc:endc,:) = spval @@ -316,6 +331,29 @@ subroutine InitHistory(this, bounds, carbon_type) do l = 1, ndecomp_cascade_transitions ! output the vertically integrated fluxes only as default + !-- C overflow (ONLY c12 FOR NOW) + if (decomp_method == mimics_decomp) then + data1dptr => this%c_overflow_hr(:,l) + ! check to see if there are multiple pathways that include respiration, and if so, note that in the history file + ii = 0 + do jj = 1, ndecomp_cascade_transitions + if ( decomp_cascade_con%cascade_donor_pool(jj) == decomp_cascade_con%cascade_donor_pool(l) ) ii = ii+1 + end do + if ( ii == 1 ) then + fieldname = & + trim(decomp_cascade_con%decomp_pool_name_history(decomp_cascade_con%cascade_donor_pool(l)))//'_COVERFLOW' + else + fieldname = & + trim(decomp_cascade_con%decomp_pool_name_history(decomp_cascade_con%cascade_donor_pool(l)))//'_COVERFLOW_'//& + trim(decomp_cascade_con%decomp_pool_name_short(decomp_cascade_con%cascade_receiver_pool(l))) + endif + longname = 'C overflow (already included in HR) from '//& + trim(decomp_cascade_con%decomp_pool_name_long(decomp_cascade_con%cascade_donor_pool(l))) + call hist_addfld1d (fname=fieldname, units='gC/m^2/s', & + avgflag='A', long_name=longname, & + ptr_col=data1dptr, default='inactive') + end if + !-- HR fluxes data1dptr => this%decomp_cascade_hr_col(:,l) ! check to see if there are multiple pathways that include respiration, and if so, note that in the history file @@ -352,6 +390,31 @@ subroutine InitHistory(this, bounds, carbon_type) ! output the vertically resolved fluxes if ( nlevdecomp_full > 1 ) then + !-- C overflow (ONLY c12 FOR NOW) + if (decomp_method == mimics_decomp) then + data2dptr => this%c_overflow_hr_vr(:,:,l) + ! check to see if there are multiple pathways that include respiration, and if so, note that in the history file + ii = 0 + do jj = 1, ndecomp_cascade_transitions + if ( decomp_cascade_con%cascade_donor_pool(jj) == decomp_cascade_con%cascade_donor_pool(l) ) ii = ii+1 + end do + if ( ii == 1 ) then + fieldname = & + trim(decomp_cascade_con%decomp_pool_name_history(decomp_cascade_con%cascade_donor_pool(l)))& + //'_COVERFLOW'//trim(vr_suffix) + else + fieldname = & + trim(decomp_cascade_con%decomp_pool_name_history(decomp_cascade_con%cascade_donor_pool(l)))//'_COVERFLOW_'//& + trim(decomp_cascade_con%decomp_pool_name_short(decomp_cascade_con%cascade_receiver_pool(l)))& + //trim(vr_suffix) + endif + longname = 'C overflow (already included in HR) from '//& + trim(decomp_cascade_con%decomp_pool_name_long(decomp_cascade_con%cascade_donor_pool(l))) + call hist_addfld_decomp (fname=fieldname, units='gC/m^3/s', type2d='levdcmp', & + avgflag='A', long_name=longname, & + ptr_col=data2dptr, default='inactive') + end if + !-- HR fluxes data2dptr => this%decomp_cascade_hr_vr_col(:,:,l) ! check to see if there are multiple pathways that include respiration, and if so, note that in the history file @@ -731,8 +794,10 @@ subroutine SetValues ( this, num_column, filter_column, value_column) do j = 1, nlevdecomp_full do fi = 1,num_column i = filter_column(fi) + this%c_overflow_hr_sum(i) = value_column + this%c_overflow_hr(i,l) = value_column + this%c_overflow_hr_vr(i,j,l) = value_column this%decomp_cascade_hr_col(i,l) = value_column - this%c_overflow_vr(i,j,l) = value_column this%decomp_cascade_hr_vr_col(i,j,l) = value_column this%decomp_cascade_ctransfer_col(i,l) = value_column this%decomp_cascade_ctransfer_vr_col(i,j,l) = value_column @@ -850,6 +915,10 @@ subroutine Summary(this, bounds, & do j = 1,nlevdecomp do fc = 1,num_bgc_soilc c = filter_bgc_soilc(fc) + this%c_overflow_hr(c,k) = & + this%c_overflow_hr(c,k) + & + this%c_overflow_hr_vr(c,j,k) * dzsoi_decomp(j) + this%decomp_cascade_hr_col(c,k) = & this%decomp_cascade_hr_col(c,k) + & this%decomp_cascade_hr_vr_col(c,j,k) * dzsoi_decomp(j) @@ -898,13 +967,14 @@ subroutine Summary(this, bounds, & end do end do - ! soil organic matter heterotrophic respiration + ! soil organic matter heterotrophic respiration associate(is_soil => decomp_cascade_con%is_soil) ! TRUE => pool is a soil pool do k = 1, ndecomp_cascade_transitions if ( is_soil(decomp_cascade_con%cascade_donor_pool(k)) ) then do fc = 1,num_bgc_soilc c = filter_bgc_soilc(fc) this%somhr_col(c) = this%somhr_col(c) + this%decomp_cascade_hr_col(c,k) + this%c_overflow_hr_sum(c) = this%c_overflow_hr_sum(c) + this%c_overflow_hr(c,k) end do end if end do @@ -917,6 +987,7 @@ subroutine Summary(this, bounds, & do fc = 1,num_bgc_soilc c = filter_bgc_soilc(fc) this%lithr_col(c) = this%lithr_col(c) + this%decomp_cascade_hr_col(c,k) + this%c_overflow_hr_sum(c) = this%c_overflow_hr_sum(c) + this%c_overflow_hr(c,k) end do end if end do @@ -929,6 +1000,7 @@ subroutine Summary(this, bounds, & do fc = 1,num_bgc_soilc c = filter_bgc_soilc(fc) this%cwdhr_col(c) = this%cwdhr_col(c) + this%decomp_cascade_hr_col(c,k) + this%c_overflow_hr_sum(c) = this%c_overflow_hr_sum(c) + this%c_overflow_hr(c,k) end do end if end do @@ -941,6 +1013,7 @@ subroutine Summary(this, bounds, & do fc = 1,num_bgc_soilc c = filter_bgc_soilc(fc) this%michr_col(c) = this%michr_col(c) + this%decomp_cascade_hr_col(c,k) + this%c_overflow_hr_sum(c) = this%c_overflow_hr_sum(c) + this%c_overflow_hr(c,k) end do end if end do diff --git a/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 b/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 index 041f6ee740..d3cb1fb474 100644 --- a/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 @@ -30,6 +30,7 @@ module SoilBiogeochemCompetitionMod use TemperatureType , only : temperature_type use SoilStateType , only : soilstate_type use CanopyStateType , only : CanopyState_type + use CLMFatesInterfaceMod, only : hlm_fates_interface_type ! implicit none private @@ -172,10 +173,11 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu cnveg_carbonflux_inst,cnveg_nitrogenstate_inst,cnveg_nitrogenflux_inst, & soilbiogeochem_carbonflux_inst, & soilbiogeochem_state_inst, soilbiogeochem_nitrogenstate_inst, & - soilbiogeochem_nitrogenflux_inst,canopystate_inst) + soilbiogeochem_nitrogenflux_inst,canopystate_inst, clm_fates) ! ! !USES: - use clm_varctl , only: allocate_carbon_only, iulog + use clm_varctl , only: fates_parteh_mode, allocate_carbon_only, iulog + use clm_varpar , only: clmfates_carbon_only,clmfates_carbon_nitrogen use clm_varpar , only: nlevdecomp, ndecomp_cascade_transitions use clm_varpar , only: i_cop_mic, i_oli_mic use clm_varcon , only: nitrif_n2o_loss_frac @@ -207,11 +209,16 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu type(soilbiogeochem_nitrogenstate_type) , intent(inout) :: soilbiogeochem_nitrogenstate_inst type(soilbiogeochem_nitrogenflux_type) , intent(inout) :: soilbiogeochem_nitrogenflux_inst type(canopystate_type) , intent(inout) :: canopystate_inst + type(hlm_fates_interface_type), intent(inout) :: clm_fates ! ! ! !LOCAL VARIABLES: integer :: c,p,l,pi,j,k ! indices integer :: fc ! filter column index + integer :: ft ! FATES functional type index + integer :: f ! loop index for FATES plant competitors + integer :: n_pcomp ! number of FATES plant competitors + integer :: ci, s ! used for FATES BC (clump index, site index) logical :: local_use_fun ! local version of use_fun real(r8) :: amnf_immob_vr ! actual mineral N flux from immobilization (gN/m3/s) real(r8) :: n_deficit_vr ! microbial N deficit, vertically resolved (gN/m3/s) @@ -221,6 +228,7 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu real(r8) :: compet_decomp_nh4 ! (unitless) relative competitiveness of immobilizers for NH4 real(r8) :: compet_denit ! (unitless) relative competitiveness of denitrifiers for NO3 real(r8) :: compet_nit ! (unitless) relative competitiveness of nitrifiers for NH4 + real(r8) :: ndemand ! (gN/m2/s) nitrogen demand per FATES plant competitor f (see local variable f above) real(r8) :: fpi_no3_vr(bounds%begc:bounds%endc,1:nlevdecomp) ! fraction of potential immobilization supplied by no3(no units) real(r8) :: fpi_nh4_vr(bounds%begc:bounds%endc,1:nlevdecomp) ! fraction of potential immobilization supplied by nh4 (no units) real(r8) :: sum_nh4_demand(bounds%begc:bounds%endc,1:nlevdecomp) @@ -228,6 +236,7 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu real(r8) :: sum_no3_demand(bounds%begc:bounds%endc,1:nlevdecomp) real(r8) :: sum_no3_demand_scaled(bounds%begc:bounds%endc,1:nlevdecomp) real(r8) :: sum_ndemand_vr(bounds%begc:bounds%endc, 1:nlevdecomp) !total column N demand (gN/m3/s) at a given level + real(r8) :: plant_ndemand_vr(bounds%begc:bounds%endc, 1:nlevdecomp) !plant column N demand (gN/m3/s) at a given level real(r8) :: nuptake_prof(bounds%begc:bounds%endc, 1:nlevdecomp) real(r8) :: sminn_tot(bounds%begc:bounds%endc) integer :: nlimit(bounds%begc:bounds%endc,0:nlevdecomp) !flag for N limitation @@ -253,8 +262,6 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu sminn_vr => soilbiogeochem_nitrogenstate_inst%sminn_vr_col , & ! Input: [real(r8) (:,:) ] (gN/m3) soil mineral N smin_nh4_vr => soilbiogeochem_nitrogenstate_inst%smin_nh4_vr_col , & ! Input: [real(r8) (:,:) ] (gN/m3) soil mineral NH4 smin_no3_vr => soilbiogeochem_nitrogenstate_inst%smin_no3_vr_col , & ! Input: [real(r8) (:,:) ] (gN/m3) soil mineral NO3 - - c_overflow_vr => soilbiogeochem_carbonflux_inst%c_overflow_vr , & ! Output: [real(r8) (:,:,:)] (gC/m3/s) vertically-resolved C rejected by microbes that cannot process it cascade_receiver_pool => decomp_cascade_con%cascade_receiver_pool , & ! Input: [integer (:) ] which pool is C added to for a given decomposition step pot_f_nit_vr => soilbiogeochem_nitrogenflux_inst%pot_f_nit_vr_col , & ! Input: [real(r8) (:,:) ] (gN/m3/s) potential soil nitrification flux @@ -319,12 +326,55 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu end do end do - do j = 1, nlevdecomp - do fc=1,num_bgc_soilc - c = filter_bgc_soilc(fc) - sum_ndemand_vr(c,j) = plant_ndemand(c) * nuptake_prof(c,j) + potential_immob_vr(c,j) + ! This loop repeats here in the ".not. use_nitrif_denitrif" + ! section of the if-statement and later in the else section + bgc_soilc_loop1: do fc = 1, num_bgc_soilc + c = filter_bgc_soilc(fc) + + fates1: if (col%is_fates(c)) then + ci = bounds%clump_index + s = clm_fates%f2hmap(ci)%hsites(c) + n_pcomp = clm_fates%fates(ci)%bc_out(s)%num_plant_comps + + ! Overwrite the column level demands, since fates plants are all sharing + ! the same space, in units per the same square meter, we just add demand + ! to scale up to column + plant_ndemand(c) = 0._r8 + + ! We fill the vertically resolved array to simplify some jointly used code + do j = 1, nlevdecomp + plant_ndemand_vr(c,j) = 0._r8 + + if (trim(fates_parteh_mode) == trim(clmfates_carbon_nitrogen)) then + do f = 1, n_pcomp + ft = clm_fates%fates(ci)%bc_out(s)%ft_index(f) + + ! [gN/m3/s] = [gC/m3] * [gN/gC/s] + plant_ndemand_vr(c,j) = plant_ndemand_vr(c,j) + & + clm_fates%fates(ci)%bc_out(s)%veg_rootc(f,j) * & + (clm_fates%fates(ci)%bc_pconst%vmax_nh4(ft) + & + clm_fates%fates(ci)%bc_pconst%vmax_no3(ft)) + end do + end if + + ! [gN/m2/s] + plant_ndemand(c) = plant_ndemand(c) + plant_ndemand_vr(c,j) * dzsoi_decomp(j) + + end do + + else ! not is_fates + + do j = 1, nlevdecomp + plant_ndemand_vr(c,j) = plant_ndemand(c) * nuptake_prof(c,j) + end do + + end if fates1 + + do j = 1, nlevdecomp + sum_ndemand_vr(c,j) = plant_ndemand_vr(c,j) + potential_immob_vr(c,j) end do - end do + + end do bgc_soilc_loop1 do j = 1, nlevdecomp do fc=1,num_bgc_soilc @@ -337,7 +387,7 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu nlimit(c,j) = 0 fpi_vr(c,j) = 1.0_r8 actual_immob_vr(c,j) = potential_immob_vr(c,j) - sminn_to_plant_vr(c,j) = plant_ndemand(c) * nuptake_prof(c,j) + sminn_to_plant_vr(c,j) = plant_ndemand_vr(c,j) else if ( allocate_carbon_only()) then !.or. & ! this code block controls the addition of N to sminn pool ! to eliminate any N limitation, when Carbon_Only is set. This lets the @@ -349,7 +399,7 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu nlimit(c,j) = 1 fpi_vr(c,j) = 1.0_r8 actual_immob_vr(c,j) = potential_immob_vr(c,j) - sminn_to_plant_vr(c,j) = plant_ndemand(c) * nuptake_prof(c,j) + sminn_to_plant_vr(c,j) = plant_ndemand_vr(c,j) supplement_to_sminn_vr(c,j) = sum_ndemand_vr(c,j) - (sminn_vr(c,j)/dt) else ! N availability can not satisfy the sum of immobilization and @@ -545,6 +595,53 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu end do end do + ! This loop repeats here in the "use_nitrif_denitrif" section + ! of the if-statement and earlier in the + ! ".not. use_nitrif_denitrif" section + bgc_soilc_loop2: do fc = 1, num_bgc_soilc + c = filter_bgc_soilc(fc) + + fates2: if (col%is_fates(c)) then + ci = bounds%clump_index + s = clm_fates%f2hmap(ci)%hsites(c) + n_pcomp = clm_fates%fates(ci)%bc_out(s)%num_plant_comps + + ! Overwrite the column level demands, since fates plants are all sharing + ! the same space, in units per the same square meter, we just add demand + ! to scale up to column + plant_ndemand(c) = 0._r8 + + ! We fill the vertically resolved array to simplify some jointly used code + do j = 1, nlevdecomp + plant_ndemand_vr(c,j) = 0._r8 + + if (trim(fates_parteh_mode) == trim(clmfates_carbon_nitrogen))then + do f = 1, n_pcomp + ft = clm_fates%fates(ci)%bc_out(s)%ft_index(f) + + ! [gN/m3/s] = [gC/m3] * [gN/gC/s] + plant_ndemand_vr(c,j) = plant_ndemand_vr(c,j) + & + clm_fates%fates(ci)%bc_out(s)%veg_rootc(f,j) * & + (clm_fates%fates(ci)%bc_pconst%vmax_nh4(ft) + & + clm_fates%fates(ci)%bc_pconst%vmax_no3(ft)) + end do + end if + + ! [gN/m2/s] + plant_ndemand(c) = plant_ndemand(c) + plant_ndemand_vr(c,j) * dzsoi_decomp(j) + + end do + + else ! not is_fates + + do j = 1, nlevdecomp + plant_ndemand_vr(c,j) = plant_ndemand(c) * nuptake_prof(c,j) + end do + + end if fates2 + + end do bgc_soilc_loop2 + ! main column/vertical loop do j = 1, nlevdecomp do fc=1,num_bgc_soilc @@ -552,8 +649,8 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu l = col%landunit(c) ! first compete for nh4 - sum_nh4_demand(c,j) = plant_ndemand(c) * nuptake_prof(c,j) + potential_immob_vr(c,j) + pot_f_nit_vr(c,j) - sum_nh4_demand_scaled(c,j) = plant_ndemand(c)* nuptake_prof(c,j) * compet_plant_nh4 + & + sum_nh4_demand(c,j) = plant_ndemand_vr(c,j) + potential_immob_vr(c,j) + pot_f_nit_vr(c,j) + sum_nh4_demand_scaled(c,j) = plant_ndemand_vr(c,j) * compet_plant_nh4 + & potential_immob_vr(c,j)*compet_decomp_nh4 + pot_f_nit_vr(c,j)*compet_nit if (sum_nh4_demand(c,j)*dt < smin_nh4_vr(c,j)) then @@ -568,7 +665,7 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu f_nit_vr(c,j) = pot_f_nit_vr(c,j) if ( .not. local_use_fun ) then - smin_nh4_to_plant_vr(c,j) = plant_ndemand(c) * nuptake_prof(c,j) + smin_nh4_to_plant_vr(c,j) = plant_ndemand_vr(c,j) else smin_nh4_to_plant_vr(c,j) = smin_nh4_vr(c,j)/dt - actual_immob_nh4_vr(c,j) - f_nit_vr(c,j) end if @@ -588,8 +685,8 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu sum_nh4_demand_scaled(c,j)), pot_f_nit_vr(c,j)) if ( .not. local_use_fun ) then - smin_nh4_to_plant_vr(c,j) = min((smin_nh4_vr(c,j)/dt)*(plant_ndemand(c)* & - nuptake_prof(c,j)*compet_plant_nh4 / sum_nh4_demand_scaled(c,j)), plant_ndemand(c)*nuptake_prof(c,j)) + smin_nh4_to_plant_vr(c,j) = min((smin_nh4_vr(c,j)/dt) * (plant_ndemand_vr(c,j) * & + compet_plant_nh4 / sum_nh4_demand_scaled(c,j)), plant_ndemand_vr(c,j)) else ! RF added new term. send rest of N to plant - which decides whether it should pay or not? @@ -619,15 +716,15 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu end if if(.not.local_use_fun)then - sum_no3_demand(c,j) = (plant_ndemand(c)*nuptake_prof(c,j)-smin_nh4_to_plant_vr(c,j)) + & + sum_no3_demand(c,j) = (plant_ndemand_vr(c,j) - smin_nh4_to_plant_vr(c,j)) + & (potential_immob_vr(c,j)-actual_immob_nh4_vr(c,j)) + pot_f_denit_vr(c,j) - sum_no3_demand_scaled(c,j) = (plant_ndemand(c)*nuptake_prof(c,j) & + sum_no3_demand_scaled(c,j) = (plant_ndemand_vr(c,j) & -smin_nh4_to_plant_vr(c,j))*compet_plant_no3 + & (potential_immob_vr(c,j)-actual_immob_nh4_vr(c,j))*compet_decomp_no3 + pot_f_denit_vr(c,j)*compet_denit else - sum_no3_demand(c,j) = plant_ndemand(c)*nuptake_prof(c,j) + & + sum_no3_demand(c,j) = plant_ndemand_vr(c,j) + & (potential_immob_vr(c,j)-actual_immob_nh4_vr(c,j)) + pot_f_denit_vr(c,j) - sum_no3_demand_scaled(c,j) = (plant_ndemand(c)*nuptake_prof(c,j))*compet_plant_no3 + & + sum_no3_demand_scaled(c,j) = (plant_ndemand_vr(c,j)) * compet_plant_no3 + & (potential_immob_vr(c,j)-actual_immob_nh4_vr(c,j))*compet_decomp_no3 + pot_f_denit_vr(c,j)*compet_denit endif @@ -642,12 +739,12 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu f_denit_vr(c,j) = pot_f_denit_vr(c,j) if(.not.local_use_fun)then - smin_no3_to_plant_vr(c,j) = (plant_ndemand(c)*nuptake_prof(c,j)-smin_nh4_to_plant_vr(c,j)) + smin_no3_to_plant_vr(c,j) = (plant_ndemand_vr(c,j) - smin_nh4_to_plant_vr(c,j)) else ! This restricts the N uptake of a single layer to the value determined from the total demands and the ! hypothetical uptake profile above. Which is a strange thing to do, since that is independent of FUN ! do we need this at all? - smin_no3_to_plant_vr(c,j) = plant_ndemand(c)*nuptake_prof(c,j) + smin_no3_to_plant_vr(c,j) = plant_ndemand_vr(c,j) ! RF added new term. send rest of N to plant - which decides whether it should pay or not? if ( local_use_fun ) then smin_no3_to_plant_vr(c,j) = smin_no3_vr(c,j)/dt - actual_immob_no3_vr(c,j) - f_denit_vr(c,j) @@ -667,9 +764,9 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu actual_immob_nh4_vr(c,j))*compet_decomp_no3 / sum_no3_demand_scaled(c,j)), & potential_immob_vr(c,j)-actual_immob_nh4_vr(c,j)) - smin_no3_to_plant_vr(c,j) = min((smin_no3_vr(c,j)/dt)*((plant_ndemand(c)* & - nuptake_prof(c,j)-smin_nh4_to_plant_vr(c,j))*compet_plant_no3 / sum_no3_demand_scaled(c,j)), & - plant_ndemand(c)*nuptake_prof(c,j)-smin_nh4_to_plant_vr(c,j)) + smin_no3_to_plant_vr(c,j) = min((smin_no3_vr(c,j)/dt) * ((plant_ndemand_vr(c,j) - & + smin_nh4_to_plant_vr(c,j)) * compet_plant_no3 / sum_no3_demand_scaled(c,j)), & + plant_ndemand_vr(c,j) - smin_nh4_to_plant_vr(c,j)) f_denit_vr(c,j) = min((smin_no3_vr(c,j)/dt)*(pot_f_denit_vr(c,j)*compet_denit / & sum_no3_demand_scaled(c,j)), pot_f_denit_vr(c,j)) @@ -681,8 +778,8 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu f_denit_vr(c,j) = min((smin_no3_vr(c,j)/dt)*(pot_f_denit_vr(c,j)*compet_denit / & sum_no3_demand_scaled(c,j)), pot_f_denit_vr(c,j)) - smin_no3_to_plant_vr(c,j) = (smin_no3_vr(c,j)/dt)*((plant_ndemand(c)* & - nuptake_prof(c,j)-smin_nh4_to_plant_vr(c,j))*compet_plant_no3 / sum_no3_demand_scaled(c,j)) + smin_no3_to_plant_vr(c,j) = (smin_no3_vr(c,j)/dt) * ((plant_ndemand_vr(c,j) - & + smin_nh4_to_plant_vr(c,j)) * compet_plant_no3 / sum_no3_demand_scaled(c,j)) ! RF added new term. send rest of N to plant - which decides whether it should pay or not? smin_no3_to_plant_vr(c,j) = (smin_no3_vr(c,j) / dt) - actual_immob_no3_vr(c,j) - f_denit_vr(c,j) @@ -737,10 +834,10 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu ! update to new values that satisfy demand actual_immob_nh4_vr(c,j) = potential_immob_vr(c,j) - actual_immob_no3_vr(c,j) end if - if ( smin_no3_to_plant_vr(c,j) + smin_nh4_to_plant_vr(c,j) < plant_ndemand(c)*nuptake_prof(c,j) ) then + if ( smin_no3_to_plant_vr(c,j) + smin_nh4_to_plant_vr(c,j) < plant_ndemand_vr(c,j) ) then supplement_to_sminn_vr(c,j) = supplement_to_sminn_vr(c,j) + & - (plant_ndemand(c)*nuptake_prof(c,j) - smin_no3_to_plant_vr(c,j)) - smin_nh4_to_plant_vr(c,j) ! use old values - smin_nh4_to_plant_vr(c,j) = plant_ndemand(c)*nuptake_prof(c,j) - smin_no3_to_plant_vr(c,j) + (plant_ndemand_vr(c,j) - smin_no3_to_plant_vr(c,j)) - smin_nh4_to_plant_vr(c,j) ! use old values + smin_nh4_to_plant_vr(c,j) = plant_ndemand_vr(c,j) - smin_no3_to_plant_vr(c,j) end if sminn_to_plant_vr(c,j) = smin_no3_to_plant_vr(c,j) + smin_nh4_to_plant_vr(c,j) end if @@ -821,6 +918,7 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu cascade_receiver_pool(k) == i_oli_mic) then sum_ndemand_vr(c,j) = sum_no3_demand_scaled(c,j) + & sum_nh4_demand_scaled(c,j) + ! WW effectively turn this off now, since pmnf_decomp_cascade < 0 for mineralization if (pmnf_decomp_cascade(c,j,k) > 0.0_r8 .and. & sum_ndemand_vr(c,j) > 0.0_r8) then amnf_immob_vr = (sminn_vr(c,j) / dt) * & @@ -828,19 +926,11 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu sum_ndemand_vr(c,j)) n_deficit_vr = pmnf_decomp_cascade(c,j,k) - & amnf_immob_vr - c_overflow_vr(c,j,k) = & - n_deficit_vr * p_decomp_cn_gain(c,j,cascade_receiver_pool(k)) - else ! not pmnf and sum_ndemand > 0 - c_overflow_vr(c,j,k) = 0.0_r8 end if - else ! not microbes receiving - c_overflow_vr(c,j,k) = 0.0_r8 end if end do end do end do - else ! not mimics_decomp - c_overflow_vr(:,:,:) = 0.0_r8 end if if(.not.local_use_fun)then @@ -991,6 +1081,46 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu end if end do ! end of column loops + ! Set the FATES N uptake fluxes + + if (col%is_fates(c)) then + do fc=1, num_bgc_soilc + c = filter_bgc_soilc(fc) + ci = bounds%clump_index + s = clm_fates%f2hmap(ci)%hsites(c) + n_pcomp = clm_fates%fates(ci)%bc_out(s)%num_plant_comps + + ! if fates_parteh_mode /= clmfates_carbon_nitrogen then + ! plant_ndemand = 0 and this if-statement gets skipped + if ( plant_ndemand(c) > tiny(plant_ndemand(c)) ) then + do f = 1, n_pcomp + ft = clm_fates%fates(ci)%bc_out(s)%ft_index(f) + + ! [gN/m2/s] + ndemand = 0._r8 + + do j = 1, nlevdecomp + ndemand = ndemand + clm_fates%fates(ci)%bc_out(s)%veg_rootc(f,j) * & + (clm_fates%fates(ci)%bc_pconst%vmax_nh4(ft) + & + clm_fates%fates(ci)%bc_pconst%vmax_no3(ft)) * dzsoi_decomp(j) + end do + + do j = 1, nlevdecomp + clm_fates%fates(ci)%bc_in(s)%plant_nh4_uptake_flux(f,1) = & + clm_fates%fates(ci)%bc_in(s)%plant_nh4_uptake_flux(f,1) + & + smin_nh4_to_plant_vr(c,j) * dt * dzsoi_decomp(j) * & + (ndemand / plant_ndemand(c)) + + clm_fates%fates(ci)%bc_in(s)%plant_no3_uptake_flux(f,1) = & + clm_fates%fates(ci)%bc_in(s)%plant_no3_uptake_flux(f,1) + & + smin_no3_to_plant_vr(c,j) * dt * dzsoi_decomp(j) * & + (ndemand / plant_ndemand(c)) + end do + end do + end if + end do + end if + end if if_nitrif !end of if_not_use_nitrif_denitrif end associate diff --git a/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 index 6be924bcf5..b63ac49837 100644 --- a/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 @@ -127,7 +127,7 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc, net_nmin => soilbiogeochem_nitrogenflux_inst%net_nmin_col , & ! Output: [real(r8) (:) ] net rate of N mineralization (gN/m2/s) w_scalar => soilbiogeochem_carbonflux_inst%w_scalar_col , & ! Input: [real(r8) (:,:) ] fraction by which decomposition is limited by moisture availability - c_overflow_vr => soilbiogeochem_carbonflux_inst%c_overflow_vr , & ! Input: [real(r8) (:,:,:) ] vertically-resolved C rejected by microbes that cannot process it (gC/m3/s) + c_overflow_hr_vr => soilbiogeochem_carbonflux_inst%c_overflow_hr_vr , & ! Input: [real(r8) (:,:,:) ] vertically-resolved C rejected by microbes that cannot process it (gC/m3/s) decomp_cascade_hr_vr => soilbiogeochem_carbonflux_inst%decomp_cascade_hr_vr_col , & ! Output: [real(r8) (:,:,:) ] vertically-resolved het. resp. from decomposing C pools (gC/m3/s) decomp_cascade_ctransfer_vr => soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_vr_col , & ! Output: [real(r8) (:,:,:) ] vertically-resolved het. resp. from decomposing C pools (gC/m3/s) phr_vr => soilbiogeochem_carbonflux_inst%phr_vr_col , & ! Input: [real(r8) (:,:) ] potential HR (gC/m3/s) @@ -194,7 +194,7 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc, if (decomp_method == mimics_decomp) then decomp_cascade_hr_vr(c,j,k) = min( & p_decomp_cpool_loss(c,j,k), & - decomp_cascade_hr_vr(c,j,k) + c_overflow_vr(c,j,k)) + decomp_cascade_hr_vr(c,j,k) + c_overflow_hr_vr(c,j,k)) decomp_cascade_ctransfer_vr(c,j,k) = max(0.0_r8, p_decomp_cpool_loss(c,j,k) - decomp_cascade_hr_vr(c,j,k)) end if if (decomp_npools_vr(c,j,cascade_donor_pool(k)) > 0._r8 .and. cascade_receiver_pool(k) /= i_atm) then diff --git a/src/soilbiogeochem/SoilBiogeochemPotentialMod.F90 b/src/soilbiogeochem/SoilBiogeochemPotentialMod.F90 index deb9bdbf78..044cad9115 100644 --- a/src/soilbiogeochem/SoilBiogeochemPotentialMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemPotentialMod.F90 @@ -104,6 +104,7 @@ subroutine SoilBiogeochemPotential (bounds, num_bgc_soilc, filter_bgc_soilc, & real(r8):: p_decomp_npool_gain_sum(1:ndecomp_pools) ! total potential N gain by receiver pool (only microbial pools) real(r8):: decomp_nc_loss_donor ! N:C ratio of donor pool real(r8):: p_decomp_cn_diff_ratio ! relative change in receiver pool C:N + real(r8):: adjusted_c_to_mic ! relative change in receiver pool C:N real(r8):: p_decomp_npool_loss ! potential N flux out of donor pool real(r8):: ratio !temporary variable !----------------------------------------------------------------------- @@ -129,6 +130,7 @@ subroutine SoilBiogeochemPotential (bounds, num_bgc_soilc, filter_bgc_soilc, & decomp_npools_vr => soilbiogeochem_nitrogenstate_inst%decomp_npools_vr_col , & ! Input: [real(r8) (:,:,:) ] (gC/m3) vertically-resolved decomposing (litter, cwd, soil) N pools decomp_cpools_vr => soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col , & ! Input: [real(r8) (:,:,:) ] (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools + c_overflow_hr_vr => soilbiogeochem_carbonflux_inst%c_overflow_hr_vr , & ! Output: [real(r8) (:,:,:)] (gC/m3/s) vertically-resolved C rejected by microbes that cannot process it potential_immob_vr => soilbiogeochem_nitrogenflux_inst%potential_immob_vr_col , & ! Output: [real(r8) (:,:) ] gross_nmin_vr => soilbiogeochem_nitrogenflux_inst%gross_nmin_vr_col , & ! Output: [real(r8) (:,:) ] @@ -198,6 +200,7 @@ subroutine SoilBiogeochemPotential (bounds, num_bgc_soilc, filter_bgc_soilc, & endif else ! CWD -> litter OR mimics_decomp is true pmnf_decomp_cascade(c,j,k) = 0._r8 + c_overflow_hr_vr(c,j,k) = 0._r8 if (decomp_method == mimics_decomp) then ! N:C ratio of donor pools (N:C instead of C:N because @@ -271,18 +274,33 @@ subroutine SoilBiogeochemPotential (bounds, num_bgc_soilc, filter_bgc_soilc, & cascade_receiver_pool(k) == i_oli_mic) then if (decomp_cpools_vr(c,j,cascade_donor_pool(k)) > 0._r8 .and. & decomp_k(c,j,cascade_donor_pool(k)) > 0._r8 ) then - ! if p_decomp_cn_diff < 0 N mineralization - ! > 0 immobilization - ! "min" in next line turns off immobilization flux - p_decomp_cn_diff_ratio = min(0.0_r8, & + ! if p_decomp_cn_diff_ratio < 0 N mineralization + ! > 0 immobilization + !! Easier here if p_decomp_cn_diff_ratio < 0 + !! then calculate C supply for each N flux to meet cn_col demands + !! and extra C goes to overflow respiration + !! This approcah this would be on a per flux basis + !! Alternatively could sum all C and N fluxes into microbes and then balance stoich + !! but this would have to take place outside of k loop + p_decomp_cn_diff_ratio = & (p_decomp_cn_gain(c,j,cascade_receiver_pool(k)) - & - cn_col(c,cascade_receiver_pool(k))) / cn_col(c,cascade_receiver_pool(k))) - ! Actual amount of N that's mineralized or that would - ! need to be immobilized - ! negative=mineralization: add to the DIN pool - ! positive=immobilizaiton: compete for N with plants to - ! see how much we get - pmnf_decomp_cascade(c,j,k) = p_decomp_cn_diff_ratio * p_decomp_npool_gain(c,j,k) + cn_col(c,cascade_receiver_pool(k))) / cn_col(c,cascade_receiver_pool(k)) + + ! Actual amount of N that's mineralized or that would be need to be immobilized + ! negative=mineralization: add to the DIN pool + ! positive=immobilizaiton: compete for N with plants to see how much we get + ! WW Overflow respiration calculation requires positive ratio to be active + ! TODO may need to think about how we track actual immobilization fluxes too? + if (p_decomp_cn_diff_ratio <= 0._r8) then + pmnf_decomp_cascade(c,j,k) = p_decomp_cn_diff_ratio * p_decomp_npool_gain(c,j,k) + c_overflow_hr_vr(c,j,k) = 0.0_r8 + else + ! Assumes each flux into MIC must be in stoichiometric ballance + ! Could also sum at all C fluxes into MIC and then maintain stoichiometry + pmnf_decomp_cascade(c,j,k) = 0._r8 + adjusted_c_to_mic = p_decomp_npool_gain(c,j,k) * cn_col(c,cascade_receiver_pool(k)) + c_overflow_hr_vr(c,j,k) = p_decomp_cpool_gain(c,j,k) - adjusted_c_to_mic + end if end if ! donors donating (decomp_cpools_vr & decomp_k > 0) end if ! microbes receiving end do ! transitions loop diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index 9038b6dbca..04ad683517 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -22,7 +22,6 @@ list(APPEND clm_sources SparseMatrixMultiplyMod.F90 IssueFixedMetadataHandler.F90 NumericsMod.F90 - spmdMod.F90 ) sourcelist_to_parent(clm_sources) diff --git a/src/utils/clmfates_interfaceMod.F90 b/src/utils/clmfates_interfaceMod.F90 index 19b247218e..ae2a409f7c 100644 --- a/src/utils/clmfates_interfaceMod.F90 +++ b/src/utils/clmfates_interfaceMod.F90 @@ -46,7 +46,7 @@ module CLMFatesInterfaceMod use CNProductsMod , only : cn_products_type use clm_varctl , only : iulog use clm_varctl , only : fates_parteh_mode - use PRTGenericMod , only : prt_cnp_flex_allom_hyp + use PRTGenericMod , only : carbon_only,carbon_nitrogen_phosphorus use clm_varctl , only : use_fates use clm_varctl , only : fates_spitfire_mode use clm_varctl , only : use_fates_managed_fire @@ -58,6 +58,7 @@ module CLMFatesInterfaceMod use clm_varctl , only : use_fates_ed_st3 use clm_varctl , only : use_fates_ed_prescribed_phys use clm_varctl , only : fates_harvest_mode + use clm_varctl , only : fates_lu_transition_logic use clm_varctl , only : fates_stomatal_model use clm_varctl , only : fates_stomatal_assimilation use clm_varctl , only : fates_leafresp_model @@ -67,6 +68,7 @@ module CLMFatesInterfaceMod use clm_varctl , only : fates_radiation_model use clm_varctl , only : fates_electron_transport_model use clm_varctl , only : use_fates_inventory_init + use clm_varctl , only : use_fates_dbh_init use clm_varctl , only : use_fates_fixed_biogeog use clm_varctl , only : use_fates_nocomp use clm_varctl , only : use_fates_sp @@ -93,6 +95,8 @@ module CLMFatesInterfaceMod use clm_varpar , only : nlevdecomp use clm_varpar , only : nlevdecomp_full use clm_varpar , only : nlevsoi + use clm_varpar , only : clmfates_carbon_only + use clm_varpar , only : clmfates_carbon_nitrogen use PhotosynthesisMod , only : photosyns_type use atm2lndType , only : atm2lnd_type use SurfaceAlbedoType , only : surfalb_type @@ -314,6 +318,7 @@ subroutine CLMFatesGlobals1(surf_numpft,surf_numcft,maxsoil_patches) integer :: pass_use_sp integer :: pass_masterproc integer :: pass_use_luh2 + integer :: pass_parteh_mode logical :: verbose_output call t_startf('fates_globals1') @@ -364,8 +369,24 @@ subroutine CLMFatesGlobals1(surf_numpft,surf_numcft,maxsoil_patches) end if call set_fates_ctrlparms('use_luh2',ival=pass_use_luh2) - - call set_fates_ctrlparms('parteh_mode',ival=fates_parteh_mode) + if(trim(fates_parteh_mode)==trim(clmfates_carbon_only))then + pass_parteh_mode = carbon_only + elseif(trim(fates_parteh_mode)==trim(clmfates_carbon_nitrogen))then + ! FATES has NO carbon_nitrogen mode. It cycles + ! either carbon alone, or carbon with both nutrients + ! If we want to couple nitrogen, we tell FATES + ! to use synthetic uptake conditions for phosphorus, which + ! most likely will be ample so that P stores in plants + ! are saturated and non-limiting + pass_parteh_mode = carbon_nitrogen_phosphorus + else + write(iulog,*) 'FATES coupling mode must be either' + write(iulog,*) trim(clmfates_carbon_only),' or ' + write(iulog,*) trim(clmfates_carbon_nitrogen) + write(iulog,*) 'you specified: ',trim(fates_parteh_mode) + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + call set_fates_ctrlparms('parteh_mode',ival=pass_parteh_mode) end if @@ -403,7 +424,6 @@ subroutine CLMFatesGlobals2() integer :: pass_vertsoilc integer :: pass_ch4 - integer :: pass_spitfire integer :: pass_ed_st3 integer :: pass_num_lu_harvest_cats integer :: pass_lu_harvest @@ -411,6 +431,7 @@ subroutine CLMFatesGlobals2() integer :: pass_ed_prescribed_phys integer :: pass_planthydro integer :: pass_inventory_init + integer :: pass_dbh_init integer :: pass_is_restart integer :: pass_cohort_age_tracking integer :: pass_tree_damage @@ -637,6 +658,7 @@ subroutine CLMFatesGlobals2() end if call set_fates_ctrlparms('num_luh2_states',ival=pass_num_luh_states) call set_fates_ctrlparms('num_luh2_transitions',ival=pass_num_luh_transitions) + call set_fates_ctrlparms('fates_lu_transition_logic',ival=fates_lu_transition_logic) if ( use_fates_potentialveg ) then pass_use_potentialveg = 1 @@ -654,6 +676,12 @@ subroutine CLMFatesGlobals2() call set_fates_ctrlparms('inventory_ctrl_file',cval=fates_inventory_ctrl_filename) + if(use_fates_dbh_init) then + pass_dbh_init = 1 + else + pass_dbh_init = 0 + end if + call set_fates_ctrlparms('use_dbh_init',ival=pass_dbh_init) ! Check through FATES parameters to see if all have been set call set_fates_ctrlparms('check_allset') @@ -1403,25 +1431,25 @@ subroutine UpdateNLitterFluxes(this,soilbiogeochem_nitrogenflux_inst,ci,c) nf_soil%decomp_npools_sourcesink_col(c,:,:) = 0._r8 if ( .not. use_fates_sp ) then - + ! (gC/m3/timestep) - !nf_soil%decomp_npools_sourcesink_col(c,1:nlevdecomp,i_met_lit) = & - ! nf_soil%decomp_npools_sourcesink_col(c,1:nlevdecomp,i_met_lit) + & - ! this%fates(ci)%bc_out(s)%litt_flux_lab_n_si(1:nlevdecomp)*dtime + nf_soil%decomp_npools_sourcesink_col(c,1:nlevdecomp,i_met_lit) = & + nf_soil%decomp_npools_sourcesink_col(c,1:nlevdecomp,i_met_lit) + & + this%fates(ci)%bc_out(s)%litt_flux_lab_n_si(1:nlevdecomp)*dtime ! Used for mass balance checking (gC/m2/s) - !nf_soil%fates_litter_flux(c) = sum(this%fates(ci)%bc_out(s)%litt_flux_lab_n_si(1:nlevdecomp) * & - ! this%fates(ci)%bc_in(s)%dz_decomp_sisl(1:nlevdecomp)) + nf_soil%fates_litter_flux(c) = sum(this%fates(ci)%bc_out(s)%litt_flux_lab_n_si(1:nlevdecomp) * & + this%fates(ci)%bc_in(s)%dz_decomp_sisl(1:nlevdecomp)) - i_cel_lit = i_met_lit + 1 + i_cel_lit = i_met_lit + 1 ! slevis note: in mimics i_cel_lit = i_str_lit = i_met_lit + 1 - !nf_soil%decomp_npools_sourcesink_col(c,1:nlevdecomp,i_cel_lit) = & - ! nf_soil%decomp_npools_sourcesink_col(c,1:nlevdecomp,i_cel_lit) + & - ! this%fates(ci)%bc_out(s)%litt_flux_cel_n_si(1:nlevdecomp)*dtime + nf_soil%decomp_npools_sourcesink_col(c,1:nlevdecomp,i_cel_lit) = & + nf_soil%decomp_npools_sourcesink_col(c,1:nlevdecomp,i_cel_lit) + & + this%fates(ci)%bc_out(s)%litt_flux_cel_n_si(1:nlevdecomp)*dtime - !nf_soil%fates_litter_flux(c) = nf_soil%fates_litter_flux(c) + & - ! sum(this%fates(ci)%bc_out(s)%litt_flux_cel_n_si(1:nlevdecomp) * & - ! this%fates(ci)%bc_in(s)%dz_decomp_sisl(1:nlevdecomp)) + nf_soil%fates_litter_flux(c) = nf_soil%fates_litter_flux(c) + & + sum(this%fates(ci)%bc_out(s)%litt_flux_cel_n_si(1:nlevdecomp) * & + this%fates(ci)%bc_in(s)%dz_decomp_sisl(1:nlevdecomp)) if (decomp_method == mimics_decomp) then ! Mimics has a structural pool, which is cellulose and lignan @@ -1431,16 +1459,14 @@ subroutine UpdateNLitterFluxes(this,soilbiogeochem_nitrogenflux_inst,ci,c) i_lig_lit = i_cel_lit + 1 end if - !nf_soil%decomp_npools_sourcesink_col(c,1:nlevdecomp,i_lig_lit) = & - ! nf_soil%decomp_npools_sourcesink_col(c,1:nlevdecomp,i_lig_lit) + & - ! this%fates(ci)%bc_out(s)%litt_flux_lig_n_si(1:nlevdecomp)*dtime + nf_soil%decomp_npools_sourcesink_col(c,1:nlevdecomp,i_lig_lit) = & + nf_soil%decomp_npools_sourcesink_col(c,1:nlevdecomp,i_lig_lit) + & + this%fates(ci)%bc_out(s)%litt_flux_lig_n_si(1:nlevdecomp)*dtime - !nf_soil%fates_litter_flux(c) = nf_soil%fates_litter_flux(c) + & - ! sum(this%fates(ci)%bc_out(s)%litt_flux_lig_n_si(1:nlevdecomp) * & - ! this%fates(ci)%bc_in(s)%dz_decomp_sisl(1:nlevdecomp)) + nf_soil%fates_litter_flux(c) = nf_soil%fates_litter_flux(c) + & + sum(this%fates(ci)%bc_out(s)%litt_flux_lig_n_si(1:nlevdecomp) * & + this%fates(ci)%bc_in(s)%dz_decomp_sisl(1:nlevdecomp)) - nf_soil%fates_litter_flux = 0._r8 - else ! In SP mode their is no mass flux between the two @@ -1849,9 +1875,6 @@ subroutine restart( this, bounds_proc, ncid, flag, waterdiagnosticbulk_inst, & ! I think that is it... ! --------------------------------------------------------------------------------- - ! Set the FATES global time and date variables - call GetAndSetTime - if(.not.initialized) then initialized=.true. @@ -1916,7 +1939,7 @@ subroutine restart( this, bounds_proc, ncid, flag, waterdiagnosticbulk_inst, & do nc = 1, nclumps if (this%fates(nc)%nsites>0) then call this%fates_restart%set_restart_vectors(nc,this%fates(nc)%nsites, & - this%fates(nc)%sites) + this%fates(nc)%sites,this%fates(nc)%bc_in) end if end do !$OMP END PARALLEL DO @@ -1984,6 +2007,11 @@ subroutine restart( this, bounds_proc, ncid, flag, waterdiagnosticbulk_inst, & ! --------------------------------------------------------------------------------- if(flag=='read')then + ! pass time to FATES internal variables + ! since this routine is called on 'define','write','read' + ! and the first two can be called whenever, calling this outside 'read' + ! will change the time that has been previously set in dynamics_driver + call GetAndSetTime !$OMP PARALLEL DO PRIVATE (nc,bounds_clump,s) do nc = 1, nclumps @@ -1999,7 +2027,7 @@ subroutine restart( this, bounds_proc, ncid, flag, waterdiagnosticbulk_inst, & this%fates(nc)%bc_out) call this%fates_restart%get_restart_vectors(nc, this%fates(nc)%nsites, & - this%fates(nc)%sites ) + this%fates(nc)%sites,this%fates(nc)%bc_in ) ! I think ed_update_site and update_hlmfates_dyn are doing some similar ! update type stuff, should consolidate (rgk 11-2016) @@ -2811,15 +2839,15 @@ subroutine wrap_WoodProducts(this, bounds_clump, num_soilc, filter_soilc, & this%fates(ci)%bc_out(s)%hrv_deadstemc_to_prod100c ! If N cycling is on - if(fates_parteh_mode == prt_cnp_flex_allom_hyp ) then + if ( trim(fates_parteh_mode)==trim(clmfates_carbon_nitrogen) ) then - !n_products_inst%hrv_deadstem_to_prod10_grc(g) = & - ! n_products_inst%hrv_deadstem_to_prod10_grc(g) + & - ! this%fates(ci)%bc_out(s)%hrv_deadstemc_to_prod10c + n_products_inst%hrv_deadstem_to_prod10_grc(g) = & + n_products_inst%hrv_deadstem_to_prod10_grc(g) + & + this%fates(ci)%bc_out(s)%hrv_deadstemc_to_prod10c - !n_products_inst%hrv_deadstem_to_prod100_grc(g) = & - ! n_products_inst%hrv_deadstem_to_prod100_grc(g) + & - ! this%fates(ci)%bc_out(s)%hrv_deadstemc_to_prod100c + n_products_inst%hrv_deadstem_to_prod100_grc(g) = & + n_products_inst%hrv_deadstem_to_prod100_grc(g) + & + this%fates(ci)%bc_out(s)%hrv_deadstemc_to_prod100c end if @@ -3938,7 +3966,7 @@ subroutine GetLandusePFTData(bounds, landuse_pft_file, landuse_pft_map, landuse_ ! Land use name arrays character(len=10), parameter :: landuse_pft_map_varnames(num_landuse_pft_vars) = & - [character(len=10) :: 'frac_primr','frac_secnd','frac_pastr','frac_range'] !need to move 'frac_surf' to a different variable + [character(len=10) :: 'frac_primr','frac_secnd','frac_range','frac_pastr'] !need to move 'frac_surf' to a different variable character(len=*), parameter :: subname = 'GetLandusePFTData' diff --git a/tools/README.md b/tools/README.md index 3e74fd6f3e..29c8ce48f6 100644 --- a/tools/README.md +++ b/tools/README.md @@ -1,5 +1,5 @@ # CTSM Tools for Preprocessing of Input Datasets or Postprocessing of History Output -#### $CTSMROOT/tools/README +#### $CTSMROOT/tools/README.md CTSM tools for analysis of CTSM history files -- or for creation or modification of CTSM input files. @@ -11,8 +11,6 @@ I. General directory structure: crop_calendars --- Regrid and process GGCMI sowing and harvest date files for use in CTSM. - mkmapgrids ------- Create regular lat/lon SCRIP grid files - site_and_regional Scripts for handling input datasets for site and regional cases. These scripts both help with creation of datasets using the standard process as well as subsetting existing datasets and overwriting @@ -37,7 +35,7 @@ II. Notes on building/running for each of the above tools: mkmapgrids and site_and_regional only contain scripts that do not need build files. - Some tools have copies of files from other directories -- see the README.filecopies + Some tools have copies of files from other directories -- see the README.filecopies.md file for more information on this. Tools may also have files with the directory name followed by namelist to provide sample namelists. @@ -45,7 +43,7 @@ II. Notes on building/running for each of the above tools: .namelist ------ Namelist to create a global file. These files are also used by the test scripts to test the tools (see the - README.testing) file. + README.testing.md) file. > [!NOTE] > Be sure to change the path of the datasets referenced by these namelists to diff --git a/tools/contrib/README.md b/tools/contrib/README.md index c53f807ffe..d7a4c55ebb 100644 --- a/tools/contrib/README.md +++ b/tools/contrib/README.md @@ -21,8 +21,6 @@ abm_raw.ncl add_tillage_to_paramsfile.py Add tillage data to the parameter file Can this be deleted since we have modify paramfile scripts? EBK 3/12/2026 -create_scrip_file.ncl - Create a SCRIP grid file needed for running with WRF CRUJRA_antarctica.ipynb Jupyter notebook to add forcing data over Antarctica for the CRUJRA forcing CRUJRA_greenland.ipynb diff --git a/tools/contrib/create_scrip_file.ncl b/tools/contrib/create_scrip_file.ncl deleted file mode 100644 index c2d911743b..0000000000 --- a/tools/contrib/create_scrip_file.ncl +++ /dev/null @@ -1,58 +0,0 @@ -load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" -load "$NCARG_ROOT/lib/ncarg/nclscripts/esmf/ESMF_regridding.ncl" -begin - -nums = (/"00","01","02","03","04","05","06","07","08","09", \ - "10","11","12","13","14","15","16","17","18","19", \ - "20","21","22","23","24","25","26","27","28","29", \ - "30","31","32","33","34","35","36","37","38","39"/) - -;************************************************ -; get WRF fields -;************************************************ - -;change this to point to the relevant geo_em file. -wrf_file = addfile("geo_em.d01.nc", "r") - - -lat2d = wrf_file->XLAT_M(0,:,:) -lon2d = wrf_file->XLONG_M(0,:,:) -lon2d = where(lon2d.lt.0, lon2d+360.0, lon2d) -landmask = wrf_file->LANDMASK(0,:,:) - -ns_corner_lat = wrf_file->XLAT_V(0,:,:) -ns_corner_lon = wrf_file->XLONG_U(0,:,:) -ew_corner_lat = wrf_file->XLAT_U(0,:,:) -ew_corner_lon = wrf_file->XLONG_U(0,:,:) - -print(lat2d(0,0)) -print(lon2d(0,0)) - -print(ns_corner_lat(0:1,0:1)) -print(ns_corner_lon(0:1,0:1)) -print(ew_corner_lat(0:1,0:1)) -print(ew_corner_lon(0:1,0:1)) - -opt = True -opt@GridMask = landmask -opt@ForceOverwrite = True - -curvilinear_to_SCRIP("wrf2clm_land.nc",lat2d,lon2d,opt) - -opt@GridMask = where(landmask.eq.0,1,0) -curvilinear_to_SCRIP("wrf2clm_ocean.nc",lat2d,lon2d,opt) - -infile = addfile("wrf2clm_land.nc","r") - -lat1d = infile->grid_center_lat -lon1d = infile->grid_center_lon - -lat1dc = infile->grid_corner_lat -lon1dc = infile->grid_corner_lon - -print(lat1d(0)) -print(lon1d(0)) -print(lat1dc(0,:)) -print(lon1dc(0,:)) - -end diff --git a/tools/contrib/prep_co2_wiemip_files.m b/tools/contrib/prep_co2_wiemip_files.m new file mode 100644 index 0000000000..38b7fe25a9 --- /dev/null +++ b/tools/contrib/prep_co2_wiemip_files.m @@ -0,0 +1,48 @@ +% prep_co2_wiemip_files.m +% +% Reminder: MODIFY file_raw and file_wiemip below for each individual case +% +% Workflow: +% - Before running this matlab script, I renamed the TRENDY2025 co2 file (fco2_datm_global_simyr_1700-2024_TRENDY_c250625.nc) to the name of the wiemip co2 file (used below) +% - The script, extends CO2 and time vars in the file from 2024 (TRENDY2025) to 2300 (wiemip) +% - and brings in wiemip co2 to the file +% - After running the matlab script, I used nco to append to each file's history, for example: +% ncatted -h -a history,global,o,c,"06/25/2025 21:30: converted by TRENDY2024_Data_Prep.ipynb; 06/04/2026: slevis used matlab script tools/contrib/prep_co2_wiemip_files.m to extend the co2 and time variables from 2024 to 2300 and to append the co2 from WIEMIP_hl_co2_ann_2024_2300.txt" WIEMIP_hl_co2_ann_2024_2300_copied_to_fco2_datm_global_simyr_1700-2024_TRENDY_c250625.nc +% +% More information appears in issues +% github.com/ESCOMP/CTSM/issues/4072 +% github.com/ESCOMP/CTSM/issues/3936 +% +% slevis 2026/06/03 + +clear + +% get trendy CO2, time, time_bnds +file_trendy = 'fco2_datm_global_simyr_1700-2024_TRENDY_c250625.nc'; +co2_trendy = ncread(file_trendy, 'CO2'); +time_trendy = ncread(file_trendy, 'time'); +time_bnds_trendy = ncread(file_trendy, 'time_bnds'); + +% extend CO2, time, time_bnds +co2_wiemip = co2_trendy; % orig. to 2024 +time_wiemip = time_trendy; % orig. to 2024 +time_bnds_wiemip = time_bnds_trendy; % orig. to 2024 +for yr = 1:276 % out to 2300 + co2_wiemip(:,:,end+1) = co2_wiemip(:,:,end); % dims (lon, lat, time) + time_wiemip(end+1) = time_wiemip(end) + 365; % dims (time) + time_bnds_wiemip(:,end+1) = time_bnds_wiemip(:,end); % dims (bnds, time) +end +% Fix time_bnds preexisting glitch in 2021 +time_bnds_wiemip(:,322) = time_bnds_wiemip(:,321); % dims (bnds, time) + +% get wiemip co2 for the years 2024-2300 +file_raw = '/glade/derecho/scratch/swensosc/WIEMIP/co2/WIEMIP_m_co2_ann_2024_2300.txt'; +co2 = readmatrix(file_raw); +co2_wiemip(1,1,325:end) = squeeze(co2(:,2)); + +% write modified time, time_bnds, and CO2 to the renamed trendy file +file_wiemip = 'WIEMIP_m_co2_ann_2024_2300_copied_to_fco2_datm_global_simyr_1700-2024_TRENDY_c250625.nc'; +ncwrite(file_wiemip, 'time', time_wiemip); +ncwrite(file_wiemip, 'time_bnds', time_bnds_wiemip); +ncwrite(file_wiemip, 'CO2', co2_wiemip); + diff --git a/tools/contrib/preview_docs_pr b/tools/contrib/preview_docs_pr new file mode 100755 index 0000000000..038951293b --- /dev/null +++ b/tools/contrib/preview_docs_pr @@ -0,0 +1,377 @@ +#!/usr/bin/env python +"""Given a GitHub PR URL, download the code as if it had been merged and then build the docs""" + +import urllib.request +import urllib.error +import json +import re +import os +import sys +import argparse +import subprocess +import time +import zipfile +import stat +import shutil + +# Get default location in which to clone the code +SCRATCH = os.getenv("SCRATCH") +DEFAULT_EXTRACTION_DIR_BASENAME = ( + "preview_docs_pr.{}.{}.pr-{}" # repo owner, repo name, PR number +) +DEFAULT_EXTRACTION_DIR = os.path.join( + SCRATCH if SCRATCH else "", + DEFAULT_EXTRACTION_DIR_BASENAME, +) + +INDENT = 4 * " " + + +def parse_pr_url(url): + """Extract owner, repo, and PR number from a GitHub PR URL.""" + pattern = r"https://github\.com/([^/]+)/([^/]+)/pull/(\d+)" + match = re.match(pattern, url.strip()) + if not match: + raise ValueError(f"Invalid GitHub PR URL: {url}") + owner, repo, pr_number = match.groups() + return owner, repo, int(pr_number) + + +def make_api_call(url, token): + """Helper function to make a GitHub API call""" + headers = { + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + } + if token: + headers["Authorization"] = f"Bearer {token}" + + req = urllib.request.Request(url, headers=headers) + with urllib.request.urlopen(req) as resp: + return json.loads(resp.read().decode()) + + +def fetch_pr_info(owner, repo, pr_number, token=None): + """Fetch PR metadata from the GitHub API.""" + + # Get overall PR info + pr_url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}" + pr_info = make_api_call(pr_url, token) + + # Get files touched by PR + files_url = pr_url + "/files" + pr_files = make_api_call(files_url, token) + + return pr_info, pr_files + + +def fetch_pr_info_with_mergeability(owner, repo, pr_number, token=None, retries=5): + """Fetch the PR info, retrying as needed if mergeability hasn't yet been computed""" + wait_time = 10 # seconds + for attempt in range(retries): + pr, files = fetch_pr_info(owner, repo, pr_number, token) + if pr["state"] != "open" or pr.get("mergeable") is not None: + return pr, files + print( + f" Mergeability not yet computed, waiting {wait_time} seconds and retrying" + f"({attempt + 1}/{retries})..." + ) + time.sleep(wait_time) + raise RuntimeError(f"Mergeability still unknown after {retries} retries.") + + +def pick_ref(pr): + """ + Choose the best ref to download, with explanation. + """ + state = pr["state"] + merge_commit_sha = pr.get("merge_commit_sha") + mergeable = pr.get("mergeable") + + # If the PR can't be merged, we can't preview what it'd look like after merge. + # Note that "mergeable" only refers to whether there are Git conflicts; it doesn't "know" + # anything about PR tests that are passing or failing. + if not mergeable: + print( + "PR branch has merge conflicts, so merged docs can't be previewed. Exiting." + ) + sys.exit(1) + + # If PR was closed without merging, GitHub supposedly nulls out merge_commit_sha, so that + # situation would require special handling. + if state == "closed" and not pr.get("merged_at"): + raise NotImplementedError("PR closed without merge") + + if not merge_commit_sha: + raise RuntimeError("How is this possible?") + + return merge_commit_sha + + +def download_zip(extraction_dir, token, pr_info, merge_commit_sha): + """Download the code as of the merge commit from GitHub""" + print("Downloading zip from GitHub...") + owner, repo, pr_number = pr_info + zip_url = f"https://api.github.com/repos/{owner}/{repo}/zipball/{merge_commit_sha}" + headers = { + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + } + if token: + headers["Authorization"] = f"Bearer {token}" + req = urllib.request.Request(zip_url, headers=headers) + pr_number = pr_info[2] + zip_path = os.path.join(extraction_dir, f"pr-{pr_number}.zip") + try: + with urllib.request.urlopen(req) as resp, open(zip_path, "wb") as f: + f.write(resp.read()) + except urllib.error.HTTPError as e: + raise RuntimeError(f"Failed to download zip from {zip_url}: {e}") from e + return zip_path + + +def extract_zip(extraction_dir, zip_path, overwrite): + """Unzip the code""" + try: + with zipfile.ZipFile(zip_path, "r") as zf: + # GitHub zips have a single top-level folder like "owner-repo-/" + top_level = zf.namelist()[0].split("/")[0] + extracted_path = os.path.join(extraction_dir, top_level) + + # If it already exists, it would be nice to skip re-extracting. But we would want to do + # a git reset to make sure it's actually at the right commit, and unfortunately the + # downloaded ZIP file doesn't include the git history. So instead, we delete the + # existing one first. + if os.path.exists(extracted_path): + if not overwrite: + raise FileExistsError( + "Clone directory exists; add -o/--overwrite to overwrite:" + f"'{extracted_path}'" + ) + print(f"Deleting existing clone dir: '{extracted_path}'") + shutil.rmtree(extracted_path) + + # Unzip + print("Unzipping...") + zf.extractall(extraction_dir) + os.remove(zip_path) + except: + os.remove(zip_path) + raise + + print(f"Code downloaded to: '{extracted_path}'") + return extracted_path + + +def download_pr_code(pr_url, extraction_dir, overwrite, token=None): + """Download code as if the pull request had been merged""" + # Fetch PR information via GitHub API + pr_info = parse_pr_url(pr_url) + pr, files = fetch_pr_info_with_mergeability(*pr_info, token) + + # Get the ref to download + merge_commit_sha = pick_ref(pr) + + if not os.path.exists(extraction_dir): + os.makedirs(extraction_dir) + + # Download the zip (follows redirects automatically) + zip_path = download_zip(extraction_dir, token, pr_info, merge_commit_sha) + + # Unzip + code_dir = extract_zip(extraction_dir, zip_path, overwrite) + + return code_dir, files, pr_info + + +def build_docs(code_dir, files, verbose, pr_info): + """Build the documentation""" + os.chdir(code_dir) + + # Handle verbosity for subprocess calls + if verbose: + stdout = None + else: + stdout = subprocess.DEVNULL + + # Set up so that git lfs works + set_up_git(pr_info, stdout) + + print("Getting submodules...") + os.chmod(path := "bin/git-fleximod", os.stat(path).st_mode | stat.S_IXUSR) + subprocess.check_call([path, "update"], stdout=stdout) + + print("Building docs...") + os.chdir("doc") + os.chmod(path := "./build_docs", os.stat(path).st_mode | stat.S_IXUSR) + output = [] + cmd = [path, "-b", "_build", "-d", "-c"] + if verbose: + cmd.append("--verbose") + with subprocess.Popen( + cmd, + cwd=os.path.join(code_dir, "doc"), + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, # Merge stderr into stdout + text=True, + bufsize=1, # Line buffering + env={**os.environ, "PYTHONUNBUFFERED": "1"}, # Force unbuffered output + ) as process: + for line in process.stdout: + print(line, end="") # Print to screen + output.append(line) # Save for later + output = "".join(output) + if output and os.path.exists(os.path.join("_build", "html", "index.html")): + print_files_msg(code_dir, files) + + +def set_up_git(pr_info, stdout): + """Initialize a git repo in the downloaded code so that git lfs works right""" + + owner, repo, _ = pr_info + remote_url = f"https://github.com/{owner}/{repo}.git" + subprocess.check_call(["git", "init", "-b", "preview-docs"], stdout=stdout) + subprocess.check_call(["git", "remote", "add", "origin", remote_url], stdout=stdout) + subprocess.check_call(["git", "add", "-A"], stdout=stdout) + subprocess.check_call( + [ + "git", + "commit", + "-m", + "PR snapshot for docs preview", + ], + stdout=stdout, + ) + + +def print_files_msg(code_dir, files): + """Print a message about the directly-affected files""" + build_dir = os.path.join(code_dir, "doc", "_build") + html_dir = os.path.join(build_dir, "html") + print(f"\nThe updated files are in {html_dir}") + print("Doc source files directly touched (not deleted) by PR:") + for f_dict in files: + f = f_dict["filename"] + # Slashes here are platform-independent, because f is returned from GitHub API call + # Skip deleted or otherwise nonexistent files + full_path = os.path.join(code_dir, f) + if f_dict["status"] == "removed" or not os.path.exists(full_path): + continue + + # Skip files not in doc source + if not f.startswith("doc/source/"): + continue + + # Get string to print + f_print = "/".join(f.split("/")[2:]) # Remove leading doc/source/ + root, extension = os.path.splitext(f_print) + basename = f.split("/")[-1] # pylint: disable=use-maxsplit-arg + if extension in [".rst", ".md"]: + # These types get converted to HTML + f_print = root + ".html" + assert os.path.exists(os.path.join(html_dir, f_print)) + elif os.path.exists(os.path.join(html_dir, "_images", basename)): + # Image files get put in _build/html/_images/ + f_print = os.path.join("_images", basename) + else: + f_print = "[NOT SURE WHERE THIS IS BUILT TO] " + f_print + print(INDENT + f_print) + print( + "Note that changes to these or other files may indirectly affect other doc files!" + " For example, if one of these files is a new/changed image, or a new/changed text" + " file that's `include`d somewhere, or a text file with an updated label that's cross-" + "referenced elsewhere. Or if a file outside doc/source/ that's `include`d in a doc file" + " got changed." + ) + + +def parse_args(): + """Parse arguments""" + parser = argparse.ArgumentParser( + description="Given a GitHub PR URL, download the merged version and build the docs." + ) + + parser.add_argument( + "pr_url", + help="GitHub pull request URL", + type=str, + ) + + extraction_dir_help_default = DEFAULT_EXTRACTION_DIR.format( + "REPO_OWNER", "REPO", "PR_NUM" + ) + parser.add_argument( + "--dir", + "--extraction-dir", + dest="extraction_dir", + help=( + "Directory to download and extract code versions to." + f" Default: {extraction_dir_help_default}" + ), + type=str, + default=None, + ) + + parser.add_argument( + "-o", + "--overwrite", + help="Overwrite existing clone dir, if any.", + action="store_true", + ) + + parser.add_argument( + "-v", + "--verbose", + help="Verbose output, including for build_docs command.", + action="store_true", + ) + + args = parser.parse_args(sys.argv[1:]) + + # Get clone dir, if not provided + pr_info = parse_pr_url(args.pr_url) + if not args.extraction_dir: + args.extraction_dir = DEFAULT_EXTRACTION_DIR.format(*pr_info) + elif os.path.abspath(args.extraction_dir) == os.getcwd(): + args.extraction_dir = os.path.join( + os.getcwd(), DEFAULT_EXTRACTION_DIR_BASENAME.format(*pr_info) + ) + print(f"Will clone to '{args.extraction_dir}'") + + # Check that clone dir parent exists + args.extraction_dir = os.path.abspath(args.extraction_dir) + clone_parent = os.path.dirname(args.extraction_dir) + if not os.path.exists(clone_parent): + raise NotImplementedError( + f"Clone parent directory does not exist: '{clone_parent}'" + ) + + # Check that clone dir parent is not (in) a git repo + result = subprocess.run( + ["git", "-C", clone_parent, "rev-parse", "--is-inside-work-tree"], + check=False, + capture_output=True, + ) + if not result.returncode: + raise RuntimeError( + "Clone parent directory is (in) a git repo, which would cause git-fleximod problems: " + f"'{clone_parent}'" + ) + + return args + + +def main(): + """Main function""" + args = parse_args() + # GitHub personal access tokens are currently not supported, but the code is all there. Just + # need to think about how to implement them in a way that will prevent people from putting their + # secrets into their shell history. + code_dir, files, pr_info = download_pr_code( + args.pr_url, args.extraction_dir, args.overwrite, token=None + ) + build_docs(code_dir, files, args.verbose, pr_info) + + +if __name__ == "__main__": + main() diff --git a/tools/mkmapgrids/README b/tools/mkmapgrids/README deleted file mode 100644 index cc6d2cb644..0000000000 --- a/tools/mkmapgrids/README +++ /dev/null @@ -1,22 +0,0 @@ -$CTSMROOT/tools/mkmapgrids/README June08/2018 - -NCL script to create a SCRIP grid file for a regular lat/lon grid. - -To use the script, set the following environment variables - -Required (or defaults to a single point over Boulder Colorado) - -PTNAME ! name of your grid -S_LAT ! Southern latitude corner -N_LAT ! Northern latitude corner -E_LON ! Eastern longitude corner -W_LON ! Western longitude corner - -Optional: - -NX ! Number of grid points along longitude (default 1) -NY ! Number of grid points along latitude (default 1) -IMASK ! 0 or 1, mask to use if all points are active or not (default active) -PRINT ! TRUE/FALSE do extra verbose printing or not (default FALSE) -GRIDFILE ! Output filename - diff --git a/tools/mkmapgrids/mkscripgrid.ncl b/tools/mkmapgrids/mkscripgrid.ncl deleted file mode 100644 index 0cbd1a8960..0000000000 --- a/tools/mkmapgrids/mkscripgrid.ncl +++ /dev/null @@ -1,188 +0,0 @@ -; -; mkscripgrid.ncl -; -; Create SCRIP grid and mapping file for a land-only point or region. -; Requires NCL 6.1.0 or later for the ESMF regridding functions -; -; Erik Kluzek -; Dec/07/2011 -; -load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" -load "$NCARG_ROOT/lib/ncarg/nclscripts/esmf/ESMF_regridding.ncl" -begin - ; =========================================================================================================== - ; Set a few constants needed later - cdate = systemfunc( "date +%y%m%d" ); - ldate = systemfunc( "date" ); - ; - ; IMPORTANT NOTE: EDIT THE FOLLOWING TO CUSTOMIZE or use ENV VARIABLE SETTINGS - ; Edit the following as needed to interpolate to a new resolution. - ; - ; Input resolution and position - ; - name = getenv("PTNAME"); ; Get name of this point - - latS = stringtodouble( getenv("S_LAT") ); ; Get south latitude from env variable - latN = stringtodouble( getenv("N_LAT") ); ; Get north latitude from env variable - lonE = stringtodouble( getenv("E_LON") ); ; Get east longitude from env variable - lonW = stringtodouble( getenv("W_LON") ); ; Get west longitude from env variable - - nx = stringtointeger( getenv("NX" ) ); ; Get number of grids along longitude lines - ny = stringtointeger( getenv("NY" ) ); ; Get number of grids along latitude lines - - imask = stringtointeger( getenv("IMASK") ); ; Get imask to use from env variable - - print_str = getenv("PRINT"); ; Do Extra printing for debugging - - outfilename = getenv("GRIDFILE"); ; Get filename from env variable - - gitdescribe = getenv("GITDES"); ; Git describe from the source clone - - if ( ismissing(nx) )then - nx = 1; - end if - if ( ismissing(ny) )then - ny = 1; - end if - if ( ismissing(imask) )then - imask = 1; - end if - if ( ismissing(name) )then - name = nx+"x"+ny+"pt_US-UMB"; - end if - if ( ismissing(latS) )then - latS = 45.5098; - end if - if ( ismissing(latN) )then - latN = 45.6098; - end if - if ( ismissing(lonW) )then - lonW = 275.2362; - end if - if ( ismissing(lonE) )then - lonE = 275.3362; - end if - if ( ismissing(print_str) )then - printn = False; - else - if ( print_str .eq. "TRUE" )then - printn = True; - else - printn = False; - end if - end if - - if ( ismissing(outfilename) )then - if ( imask .eq. 1 )then - outfilename = "SCRIPgrid_"+name+"_nomask_c"+cdate+".nc"; - else - if ( imask .eq. 0 )then - outfilename = "SCRIPgrid_"+name+"_noocean_c"+cdate+".nc"; - else - outfilename = "SCRIPgrid_"+name+"_mask_c"+cdate+".nc"; - end if - end if - end if - - if ( ismissing(gitdescribe) )then - gitdescribe = systemfunc( "git describe" ) - end if - - system( "/bin/rm -f "+outfilename ); - if ( printn )then - print( "output file: "+outfilename ); - end if - -function fspan1up( fbegin [*]:double, fend [*]:double, number:integer ) -; -; An "fspan" that can handle size of 1 and up. -; Do fspan for arrays of two or more, or average of end points for array of one. -; -local farray; -begin - if ( number .eq. 1) then - farray = (/ (fbegin + fend) / 2.0d00 /); - else - farray = fspan( fbegin, fend, number ); - end if - return( farray ); -end - - ; - ; Compute derived quantities - ; - - delX = (lonE - lonW) / int2dble(nx); - delY = (latN - latS) / int2dble(ny); - - lonCenters = fspan1up( (lonW + delX/2.d0), (lonE - delX/2.d0), nx) - latCenters = fspan1up( (latS + delY/2.d0), (latN - delY/2.d0), ny) - lon = new( (/ny, nx/), "double" ); - lat = new( (/ny, nx/), "double" ); - if ( (nx .eq. 1) .or. (ny .eq. 1) )then - if ( printn )then - print( "Calculate corners" ) - end if - lonCorners = new( (/ny, nx, 4/), "double" ); - latCorners = new( (/ny, nx, 4/), "double" ); - else - if ( printn )then - print( "Have NCL calculate corners" ) - end if - end if - do i = 0, nx-1 - lat(:,i) = latCenters; - if ( (nx .eq. 1) .or. (ny .eq. 1) )then - latCorners(:,i,0) = latCenters - delY/2.d0; - latCorners(:,i,1) = latCenters - delY/2.d0; - latCorners(:,i,2) = latCenters + delY/2.d0; - latCorners(:,i,3) = latCenters + delY/2.d0; - end if - end do - do j = 0, ny-1 - lon(j,:) = lonCenters; - if ( (nx .eq. 1) .or. (ny .eq. 1) )then - lonCorners(j,:,0) = lonCenters - delX/2.d0; - lonCorners(j,:,1) = lonCenters + delX/2.d0; - lonCorners(j,:,2) = lonCenters + delX/2.d0; - lonCorners(j,:,3) = lonCenters - delX/2.d0; - end if - end do - - ; for some reason, "No_FillValue" isn't working in the case where imask=1 - Mask2D = new( (/ny,nx/), "integer", "No_FillValue" ) - Mask2D(:,:) = imask - gridSize = delX+"x"+delY - - ; - ; Create SCRIP grid file - ; - - Opt = True - Opt@Mask2D = Mask2D - if ( (nx .eq. 1) .or. (ny .eq. 1) )then - Opt@GridCornerLat = latCorners - Opt@GridCornerLon = lonCorners - end if - Opt@Title = "SCRIP grid file for "+name - if (printn) then - Opt@Debug = True - end if - curvilinear_to_SCRIP(outfilename, lat, lon, Opt) - - ; - ; Add global attributes to file - ; - - nc = addfile( outfilename, "w" ); - nc@history = ldate+": create using mkscripgrid.ncl"; - nc@comment = "Ocean is assumed to be non-existant in this region"; - nc@Version = gitdescribe; - if ( printn )then - print( "================================================================================================" ); - print( "Successfully created SCRIP grid file: "+outfilename); - end if - - ; =========================================================================================================== - -end diff --git a/tools/mksurfdata_esmf/README.filecopies b/tools/mksurfdata_esmf/README.filecopies.md similarity index 86% rename from tools/mksurfdata_esmf/README.filecopies rename to tools/mksurfdata_esmf/README.filecopies.md index 44c9ef6918..64542cd5d8 100644 --- a/tools/mksurfdata_esmf/README.filecopies +++ b/tools/mksurfdata_esmf/README.filecopies.md @@ -9,19 +9,23 @@ directories as well. I. Files that are IDENTICAL: 1. cesm_share files copied that should be identical to share/src: - +``` shr_kind_mod.F90 shr_const_mod.F90 shr_string_mod.F90 shr_file_mod.F90 - +``` II. Files with differences 1. cesm_share files copied with differences: - shr_sys_mod.F90 - Remove mpi abort and reference to shr_mpi_mod.F90. +``` + shr_sys_mod.F90 # Remove mpi abort and reference to shr_mpi_mod.F90 +``` 2. Files in mksurfdata_esmf - +``` mkvarpar.F90 nanMod.F90 +``` + diff --git a/tools/mksurfdata_esmf/README.md b/tools/mksurfdata_esmf/README.md index 95064a9839..5182f03b2d 100644 --- a/tools/mksurfdata_esmf/README.md +++ b/tools/mksurfdata_esmf/README.md @@ -1,89 +1,13 @@ # Instructions for Using mksurfdata_esmf to Create Surface Datasets +#### $CTSMROOT/tools/mksurfdata_esmf/README.md ## Table of contents -1. [Purpose](#purpose) -1. [Building](#building) -1. [Running a Single Submission](#running-for-a-single-submission) -1. [Running for Multiple Datasets](#running-for-the-generation-of-multiple-datasets) -1. [Notes](#notes) - - -## Purpose - -This tool is intended to generate fsurdat files (surface datasets) for the -CTSM. It can generate global, regional, and single-point fsurdat files, as long -as a mesh file is available for the grid. - -The subset_data tool allows users to make fsurdat files from existing fsurdat -files when a mesh file is unavailable. Generally, users should consider the -subset_data tool for generating regional and single-point fsurdat files. - - -## Building - - - -### Build Requirements - - -mksurfdata_esmf is a distributed memory parallel program (using Message Passing -Interface -- MPI) that utilizes both ESMF (Earth System Modelling Framework) -for regridding as well as PIO (Parallel I/O) and NetCDF output. As -such, libraries must be built for the following: - -1. MPI -2. NetCDF -3. PIO -4. ESMF - -In addition for the build: python, bash-shell, CMake and GNU-Make are required - -These libraries need to be built such that they can all work together in the -same executable. Hence, the above order may be required in building them. - -CTSM submodules that are required are: cime and ccs_config. See [Building](#building-the-executable) on getting -those. A python environment that includes particular packages is also required -we demonstrate how to use the ctsm_pylib environment that we support in CTSM. - -Note, PNETCDF is an optional library that can be used, but is NOT required. - -#### Use cime to manage the build requirements - -See [IMPORTANT NOTE](important note-only-working-on-derecho-currently) - -For users working on cime machines you can use the build script to build the -tool. On other machines you'll need to do a port to cime and tell how to build -for that machine. That's talked about in the cime documentation. -And you'll have to make some modifications to the build script. - -https://github.com/ESMCI/cime/wiki/Porting-Overview - -Machines that already run CTSM or CESM have been ported to cime. So if you can -run the model on your machine, you will be able to build the tool there. - -To get a list of the machines that have been ported to cime: - -``` shell -# Assuming pwd is the tools/mksurfdata_esmf directory -cd ../../cime/scripts # or ../../../../cime/scripts for a CESM checkout -./query_config --machines -``` - -#### NOTE: -In addition to having a port to cime, the machine also needs to have PIO built -and able to be referenced with the env variable PIO which will need to be in -the porting instructions for the machine. An independent PIO library -is available on supported CESM machines. - - -#### IMPORTANT NOTE: ONLY WORKING ON DERECHO CURRENTLY - - - -> [!IMPORTANT] -> Currently we have run and tested mksurfdata_esmf on Derecho. Please see this github issue about mksurfdata_esmf on other CESM machines: - -https://github.com/ESCOMP/CTSM/issues/2341 +1. Purpose NOW IN THE USER'S GUIDE https://escomp.github.io/CTSM/users_guide/using-clm-tools/creating-surface-datasets.html#mksurfdata-esmf-purpose +2. Build Requirements NOW IN THE USER'S GUIDE https://escomp.github.io/CTSM/users_guide/using-clm-tools/creating-surface-datasets.html#build-requirements +3. [Building the executable](#building-the-executable) +4. [Running a Single Submission](#running-for-a-single-submission) +5. [Running for Multiple Datasets](#running-for-the-generation-of-multiple-datasets) +6. [Notes](#notes) ### Building the executable @@ -217,4 +141,3 @@ ncks --mk_rec_dmn time file_with_time_equals_12.nc -o file_with_time_unlimited.n In general we recommend using subset_data and/or fsurdat_modifier for regional grids. - diff --git a/tools/mksurfdata_esmf/gen_mksurfdata_build b/tools/mksurfdata_esmf/gen_mksurfdata_build index 864b5915b9..c657a3c27b 100755 --- a/tools/mksurfdata_esmf/gen_mksurfdata_build +++ b/tools/mksurfdata_esmf/gen_mksurfdata_build @@ -44,10 +44,6 @@ case $hostname in export MACH="izumi" pio_iotype=2 ;; - hobart*) - export MACH="hobart" - pio_iotype=2 - ;; ## Other machines ## Assumption: pnetcdf is off; therefore, pio_iotype = 2 *) diff --git a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 index df4bfd43ba..a6251bb23c 100644 --- a/tools/mksurfdata_esmf/src/mkurbanparMod.F90 +++ b/tools/mksurfdata_esmf/src/mkurbanparMod.F90 @@ -302,7 +302,7 @@ subroutine mkurban(file_mesh_i, file_data_i, mesh_o, pcturb_o, & ! Regrid data_i to data_o if (allocated(data_o)) deallocate(data_o) allocate(data_o(max_regions, ns_o), stat=ier) - if (ier/=0) call shr_sys_abort('error allocating data_i(max_regions, ns_o)') + if (ier/=0) call shr_sys_abort('error allocating data_o(max_regions, ns_o)') ! This regridding could be done either with or without fracarea normalization, ! because we just use it to find a dominant value. We use nonorm because we already ! have a nonorm mapper for the sake of PCTURB and this way we don't need to make a diff --git a/tools/modify_input_files/README.fsurdat_modifier b/tools/modify_input_files/README.fsurdat_modifier.md similarity index 55% rename from tools/modify_input_files/README.fsurdat_modifier rename to tools/modify_input_files/README.fsurdat_modifier.md index 885227c928..ca0decf9cf 100644 --- a/tools/modify_input_files/README.fsurdat_modifier +++ b/tools/modify_input_files/README.fsurdat_modifier.md @@ -5,7 +5,7 @@ Current applications are limited to the simplest CTSM(SP) mode, so bgc, fire, urban, vic, lake, transient, and crop-related variables in the fsurdat file remain unchanged. -It differs from modify_singlept_site_neon.py in that the latter specifically +It differs from `modify_singlept_site_neon.py` in that the latter specifically modifies soil properties of single-point surface datasets. It also differs from the subset_data tool in that the latter subsets fsurdat @@ -13,38 +13,51 @@ files to regional or single-point domains; subset_data does include some "modify" functionality when subsetting, but such functionality is more prescriptive in subset_data. In particular: -fsurdat_modifier options subset_data options ------------------------------------ ------------------- -std_elev (user sets STD_ELEV value) uniform-snowpack (sets STD_ELEV to 20) -max_sat_area (user sets FMAX value) cap-saturation (sets FMAX to zero) +|fsurdat_modifier options | subset_data options | +|----------------------------------- | ------------------- | +|std_elev (user sets STD_ELEV value) | uniform-snowpack (sets STD_ELEV to 20)| +|max_sat_area (user sets FMAX value) | cap-saturation (sets FMAX to zero) | Files involved --------------- +``` python/ctsm/modify_input_files/fsurdat_modifier.py python/ctsm/modify_input_files/modify_fsurdat.py tools/modify_input_files/fsurdat_modifier tools/modify_input_files/modify_fsurdat_template.cfg - +``` Instructions ------------ To run on various machines: 1) (Un)load, execute, and activate the following: + 1a) First step to activate conda on your system -1a) Casper: + +- Casper: +``` module unload python module load conda -1a) Izumi: +``` +- Izumi: +``` module load python -1a) Derecho (nothing needs to be done for this step) -1a) Elsewhere (do what's needed to activate conda) -1b) On all systems +``` +- Derecho (nothing needs to be done for this step) +- Elsewhere (do what's needed to activate conda) + +1b) On all systems: +``` ./py_env_create conda activate ctsm_pylib +``` (Use "deactivate" to reverse the latter.) -2) Copy, then modify the configure file named modify_fsurdat_template.cfg, which -contains all the arguments needed by the script. -3) Run the script ./fsurdat_modifier pointing to the copied/modified .cfg file, -e.g. modify_users_copy.cfg + +2) Copy, then modify the configure file named `modify_fsurdat_template.cfg`, which contains all the arguments needed by the script. + +3) Run the script `./fsurdat_modifier` pointing to the copied/modified `.cfg` file, e.g. `modify_users_copy.cfg` +``` ./fsurdat_modifier modify_users_copy.cfg -See modify_fsurdat_template.cfg for required and optional settings. -4) Use the --verbose option to see progress output on your screen +``` +See `modify_fsurdat_template.cfg` for required and optional settings. + +4) Use the `--verbose option` to see progress output on your screen. + diff --git a/tools/modify_input_files/README.mesh_mask_modifier b/tools/modify_input_files/README.mesh_mask_modifier.md similarity index 50% rename from tools/modify_input_files/README.mesh_mask_modifier rename to tools/modify_input_files/README.mesh_mask_modifier.md index b667ebf22f..91404de201 100644 --- a/tools/modify_input_files/README.mesh_mask_modifier +++ b/tools/modify_input_files/README.mesh_mask_modifier.md @@ -1,36 +1,45 @@ mesh_mask_modifier is a tool that modifies mesh_mask files. It reads a mesh_mask file and outputs a modified copy of the same file. -Files involved --------------- +# Files involved +``` python/ctsm/modify_input_files/mesh_mask_modifier.py python/ctsm/modify_input_files/modify_mesh_mask.py tools/modify_input_files/mesh_mask_modifier tools/modify_input_files/modify_mesh_template.cfg +``` +# Instructions -Instructions ------------- To run on various machines: 1) (Un)load, execute, and activate the following: + 1a) First step to activate conda on your system -1a) Casper: + +- Casper: +``` module unload python module load conda -1a) Izumi: +``` +- Izumi: +``` module load python -1a) Derecho (nothing needs to be done -1a) Elsewhere (do what's needed to activate conda) -1b) On all systems +``` +- Derecho (nothing needs to be done) +- Elsewhere (do what's needed to activate conda) + +1b) On all systems: +``` ./py_env_create conda activate ctsm_py +``` (Use "deactivate" to reverse the latter.) -2) Copy, then modify the configure file named modify_mesh_template.cfg, which -contains all the arguments needed by the script. -3) Run the script ./mesh_mask_modifier pointing to the copied/modified -.cfg file, e.g. modify_users_copy.cfg -Example use-case ----------------- +2) Copy, then modify the configure file named `modify_mesh_template.cfg`, which contains all the arguments needed by the script. + +3) Run the script .`/mesh_mask_modifier` pointing to the copied/modified `.cfg` file, e.g. `modify_users_copy.cfg` + +# Example use-case + F-Case, modifying the continental geometry User wants to make the Indian Ocean into grassland. They specify their @@ -38,30 +47,31 @@ own land fraction mask on the CESM 1-degree grid, as well as the area to be specified as grassland in a netcdf file. This has been obtained by modifying the default land fraction of CESM. The file contains two arrays: -- landmask = the new landmask -- mod_lnd_props = set to 1 where the new land surface has been specified -(i.e., where grassland needs to be specified) and zero elsewhere - -This use-case requires modification to the fsurdat and mesh files. To -modify the former, use the modify_fsurdat tool. See that tool for -instructions. Here are the steps to modify the mesh file: - -In your copy of the CTSM (say, ~user/ctsm), go to the appropriate tool: ->>> cd tools/modify_input_files ->>> cp modify_mesh_template.cfg modify_fill_indianocean.cfg +- `landmask` = the new landmask +- `mod_lnd_props` = set to 1 where the new land surface has been specified (i.e., where grassland needs to be specified) and zero elsewhere -Enter the following (or similar) selections in modify_fill_indianocean.cfg: +This use-case requires modification to the fsurdat and mesh files. To modify the former, use the `modify_fsurdat` tool. See that tool for instructions. Here are the steps to modify the mesh file: +In your copy of the CTSM (say, `~user/ctsm`), go to the appropriate tool: +``` +cd tools/modify_input_files +cp modify_mesh_template.cfg modify_fill_indianocean.cfg +``` +Enter the following (or similar) selections in `modify_fill_indianocean.cfg`: +``` mesh_mask_in = /glade/campaign/cesm/cesmdata/cseg/inputdata/share/meshes/fv0.9x1.25_141008_polemod_ESMFmesh.nc mesh_mask_out = fv0.9x1.25_141008_polemod_ESMFmesh_modified.nc landmask_file = .../path_to_your_copy_of/fill_indianocean.nc - +``` Run the tool ->>> ./mesh_mask_modifier modify_fill_indianocean.cfg +``` +./mesh_mask_modifier modify_fill_indianocean.cfg +``` A modified mesh file should appear in the directory where you ran. -Point to this file in your case's env_run.xml in the line that sets -MASK_MESH. If for some reason this fails, hardwire the ocean domain mesh -file name in ~user/ctsm/ccs_config/component_grids_nuopc.xml before +Point to this file in your case's `env_run.xml` in the line that sets +`MASK_MESH`. If for some reason this fails, hardwire the ocean domain mesh +file name in `~user/ctsm/ccs_config/component_grids_nuopc.xml` before starting your CTSM or CESM simulation. In the specific example shown -here, hardwire the mesh file name for domain name gx1v7. +here, hardwire the mesh file name for domain name `gx1v7`. + diff --git a/tools/site_and_regional/README.md b/tools/site_and_regional/README.md index e2ec7cda95..56f0ff451c 100644 --- a/tools/site_and_regional/README.md +++ b/tools/site_and_regional/README.md @@ -51,14 +51,3 @@ neon_gcs_upload Script to rename and upload NEON site finidat files to NEON server for use in transient startup cases -## DEPRECATED SCRIPTS: - -mknoocnmap.pl - Script to create unity mapping dataset for single-point - or regional studies over land-only (no ocean). - -NCL Scripts available: - -mkunitymap.ncl - NCL script to create a unity map -- ran by above script (mknoocnmap.pl) - diff --git a/tools/site_and_regional/mknoocnmap.pl b/tools/site_and_regional/mknoocnmap.pl deleted file mode 100755 index 5438c8bcd3..0000000000 --- a/tools/site_and_regional/mknoocnmap.pl +++ /dev/null @@ -1,302 +0,0 @@ -#!/usr/bin/env perl -# -# mknoocnmap.pl Erik Kluzek -# Dec/07/2011 -# -# Create SCRIP grid and mapping files for a single-point or region -# that is assumed to be a land land-only region. -# -use Cwd; -use strict; -use English; -use IO::File; -use Getopt::Long; - -# -# Global constants -# -my $degsiz = 0.1; - -#----------------------------------------------------------------------------------------------- -# Set the directory that contains this scripts. If the command was issued using a -# relative or absolute path, that path is in $ProgDir. Otherwise assume the -# command was issued from the current working directory. - -(my $ProgName = $0) =~ s!(.*)/!!; # name of this script -my $ProgDir = $1; # name of directory containing this script -- may be a - # relative or absolute path, or null if the script - # is in - # the user's PATH -my $cmdline = "@ARGV"; # Command line arguments to script -my $cwd = getcwd(); # current working directory -my $scrdir; # absolute pathname of directory that contains this script -my $nm = "${ProgName}::"; # name to use if script dies -if ($ProgDir) { - $scrdir = absolute_path($ProgDir); -} else { - $scrdir = $cwd; -} - - -#----------------------------------------------------------------------------------------------- - -sub usage { - die < Center latitude,longitude of the grid to create. - -name [-or -n] Name to use to describe point - -OPTIONS - -dx Size of total grid in degrees in longitude direction - (default is $degsiz) - -dy Size of total grid in degrees in latitude direction - (default is $degsiz) - -silent [or -s] Make output silent - -help [or -h] Print usage to STDOUT. - -verbose [or -v] Make output more verbose. - -nx Number of longitudes (default is 1) - -ny Number of latitudes (default is 1) -EOF -} - -#----------------------------------------------------------------------------------------------- - -sub get_latlon { -# -# Return the latitude and longitude of the input string and validate it -# - my $string = shift; - my $desc = shift; - my $dx = shift; - my $dy = shift; - - my $lat = undef; - my $lon = undef; - my $valreal1 = "[+-]?[0-9]*\.?[0-9]*[EedDqQ]?[0-9+-]*"; - - if ( $string =~ /^($valreal1)\s*,\s*($valreal1)$/ ) { - $lat = $1; - $lon = $2; - } else { - die <<"EOF"; -** $ProgName - Error in entering latitude/longitude for $desc ** -EOF - } - if ( $dx <= 0.0 || $dx > 360. ) { - die <<"EOF"; -** $ProgName - Bad value for dx (=$dx) for $desc ** - } - if ( $dy <= 0.0 || $dy > 180. ) { - die <<"EOF"; -** $ProgName - Bad value for dy (=$dy) for $desc ** - } - if ( ($lat < -90.+$dy/2.0) || ($lat > 90.0-$dy/2.0) ) { - die <<"EOF"; -** $ProgName - Bad value for latitude (=$lat) for $desc ** -EOF - } - if ( ($lon < $dx/2.0) || ($lon > 360.0-$dx/2.0) ) { - die <<"EOF"; -** $ProgName - Bad value for longitude (=$lat) for $desc ** -EOF - } - return( $lat, $lon ); - -} - -#------------------------------------------------------------------------------- - -sub absolute_path { -# -# Convert a pathname into an absolute pathname, expanding any . or .. characters. -# Assumes pathnames refer to a local filesystem. -# Assumes the directory separator is "/". -# - my $path = shift; - my $cwd = getcwd(); # current working directory - my $abspath; # resulting absolute pathname - -# Strip off any leading or trailing whitespace. (This pattern won't match if -# there's embedded whitespace. - $path =~ s!^\s*(\S*)\s*$!$1!; - -# Convert relative to absolute path. - - if ($path =~ m!^\.$!) { # path is "." - return $cwd; - } elsif ($path =~ m!^\./!) { # path starts with "./" - $path =~ s!^\.!$cwd!; - } elsif ($path =~ m!^\.\.$!) { # path is ".." - $path = "$cwd/.."; - } elsif ($path =~ m!^\.\./!) { # path starts with "../" - $path = "$cwd/$path"; - } elsif ($path =~ m!^[^/]!) { # path starts with non-slash character - $path = "$cwd/$path"; - } - - my ($dir, @dirs2); - my @dirs = split "/", $path, -1; # The -1 prevents split from stripping trailing nulls - # This enables correct processing of the input "/". - - # Remove any "" that are not leading. - for (my $i=0; $i<=$#dirs; ++$i) { - if ($i == 0 or $dirs[$i] ne "") { - push @dirs2, $dirs[$i]; - } - } - @dirs = (); - - # Remove any "." - foreach $dir (@dirs2) { - unless ($dir eq ".") { - push @dirs, $dir; - } - } - @dirs2 = (); - - # Remove the "subdir/.." parts. - foreach $dir (@dirs) { - if ( $dir !~ /^\.\.$/ ) { - push @dirs2, $dir; - } else { - pop @dirs2; # remove previous dir when current dir is .. - } - } - if ($#dirs2 == 0 and $dirs2[0] eq "") { return "/"; } - $abspath = join '/', @dirs2; - return( $abspath ); -} - -#------------------------------------------------------------------------------- - -# Process command-line options - -my %opts = ( - ctr => undef, - help => undef, - name => undef, - nx => 1, - ny => 1, - dx => $degsiz, - dy => $degsiz, - silent => 0, - verbose => 0, - ); - -GetOptions( - "p|centerpoint=s" => \$opts{'ctr'}, - "n|name=s" => \$opts{'name'}, - "nx=i" => \$opts{'nx'}, - "ny=i" => \$opts{'ny'}, - "dx=f" => \$opts{'dx'}, - "dy=f" => \$opts{'dy'}, - "h|help" => \$opts{'help'}, - "s|silent" => \$opts{'silent'}, - "v|verbose" => \$opts{'verbose'}, -) or usage(); - -# Check for unparsed arguments -if (@ARGV) { - print "ERROR: unrecognized arguments: @ARGV\n"; - usage(); -} - -if ( $opts{'verbose'} && $opts{'silent'} ) { - print "ERROR: Can NOT set both silent and verbose at once!\n"; - usage(); -} -my $printlev; -if ( $opts{'verbose'} ) { - $printlev = 2; -} elsif ( $opts{'silent'} ) { - $printlev = 0; -} else { - $printlev = 1; -} - -if ( ! defined($opts{'ctr'}) ) { - print "ERROR: MUST set the center point\n"; - usage(); -} -if ( ! defined($opts{'name'}) ) { - print "ERROR: MUST set the name of the point\n"; - usage(); -} -my $name = $opts{'name'}; - -my ($lat,$lon) = get_latlon( $opts{'ctr'}, $name, $opts{'dx'}, $opts{'dy'} ); -my $S_lat = $lat - $opts{'dy'}/2.0; -my $N_lat = $lat + $opts{'dy'}/2.0; -my $W_lon = $lon - $opts{'dx'}/2.0; -my $E_lon = $lon + $opts{'dx'}/2.0; - -my $nx = $opts{'nx'}; -my $ny = $opts{'ny'}; -if ( $opts{'nx'} < 1 ) { - print "ERROR: nx MUST be greater than or equal to 1\n"; - usage(); -} -if ( $opts{'ny'} < 1 ) { - print "ERROR: ny MUST be greater than or equal to 1\n"; - usage(); -} - -#----------------------------------------------------------------------------------------------- -my $print; -if ( $printlev > 1 ) { - $print = "PRINT=TRUE"; -} - -# Creation date -my $cdate = `date +%y%m%d`; chomp( $cdate ); - -if ( $printlev > 0 ) { - print "\n\nCreate SCRIP grid and mapping files for a single-point\n"; -} -# land grid... -my $GITDES = `cd $scrdir; git describe; cd -`; -$GITDES =~ s/\n//g; -my $grddir = absolute_path( "$scrdir/../mkmapgrids" ); -my $cwd = getcwd(); -my $datdir = $grddir; -if ( $cwd ne $scrdir ) { - $datdir = $cwd; -} -my $grid1 = "$datdir/SCRIPgrid_${name}_nomask_c${cdate}.nc"; -my $cmdenv = "env S_LAT=$S_lat W_LON=$W_lon N_LAT=$N_lat E_LON=$E_lon " . - "NX=$nx NY=$ny PTNAME=$name GITDES=$GITDES $print "; - -my $cmd = "$cmdenv GRIDFILE=$grid1 ncl $scrdir/../mkmapgrids/mkscripgrid.ncl"; -if ( $printlev > 0 ) { - print "Create land SCRIP gridfile\n"; - print "Execute: $cmd\n"; -} -system( $cmd ); - -# ocean grid... -my $grid2 = "$datdir/SCRIPgrid_${name}_noocean_c${cdate}.nc"; -my $cmd = "$cmdenv GRIDFILE=$grid2 IMASK=0 ncl $scrdir/../mkmapgrids/mkscripgrid.ncl"; -if ( $printlev > 0 ) { - print "Create ocean SCRIP gridfile\n"; - print "Execute: $cmd\n"; -} -system( $cmd ); - -# Now create a unity mapping between the two... -# Note reversal of grid1 & grid2, because we want an ocean -> land -# mapping file -my $mapfile = "$datdir/map_${name}_noocean_to_${name}_nomask_aave_da_${cdate}.nc"; -my $cmd = "env GRIDFILE1=$grid2 GRIDFILE2=$grid1 MAPFILE=$mapfile " . - "GITDES=$GITDES $print ncl $scrdir/mkunitymap.ncl"; - -if ( $printlev > 0 ) { - print "Create unity mapping file between the two gridfile\n"; - print "Execute: $cmd\n"; -} -system( $cmd ); - -if ( $printlev > 0 ) { - print "\n\nSuccessfully created grid/mapping files for single-point\n"; -} diff --git a/tools/site_and_regional/mkunitymap.ncl b/tools/site_and_regional/mkunitymap.ncl deleted file mode 100644 index 7570f7eedd..0000000000 --- a/tools/site_and_regional/mkunitymap.ncl +++ /dev/null @@ -1,166 +0,0 @@ -; -; mkunitymap.ncl -; -; Create a unity map file either between two identical grids or between two -; grids that do NOT intersect at all. -; -; Erik Kluzek -; Dec/07/2011 -; -load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl" -begin - ; Set a few constants needed later - cdate = systemfunc( "date +%y%m%d" ); - ldate = systemfunc( "date" ); - ; =========================================================================================================== - ; - ; IMPORTANT NOTE: EDIT THE FOLLOWING TO CUSTOMIZE or use ENV VARIABLE SETTINGS - ; Edit the following as needed to interpolate to a new resolution. - gridfile1 = getenv("GRIDFILE1"); ; Get name of the first SCRIP grid file - gridfile2 = getenv("GRIDFILE2"); ; Get name of the second SCRIP grid file - - outfilename = getenv("MAPFILE"); ; Get name of the output mapping file - - print_str = getenv("PRINT"); ; Do Extra printing for debugging - - gitdescribe = getenv("GITDES"); ; Git describe from the source clone - - if ( ismissing(gridfile1) )then - print( "ERROR: GRIDFILE1 is missing!" ); - exit - end if - if ( ismissing(gridfile2) )then - print( "ERROR: GRIDFILE2 is missing!" ); - exit - end if - if ( ismissing(outfilename) )then - print( "ERROR: MAPFILE is missing!" ); - exit - end if - if ( ismissing(print_str) )then - printn = False; - else - if ( print_str .eq. "TRUE" )then - printn = True; - else - printn = False; - end if - end if - - if ( ismissing(gitdescribe) )then - gitdescribe = systemfunc( "git describe" ) - end if - - ; - ; Open up the input grid files - ; - nca = addfile( gridfile1, "r" ); - ncb = addfile( gridfile2, "r" ); - - system( "/bin/rm -f "+outfilename ); - if ( printn )then - print( "output mapping file to create: "+outfilename ); - end if - nc = addfile( outfilename, "c" ); - ; - ; Define dimensions - ; - n_a = dimsizes( nca->grid_center_lat ); - n_b = dimsizes( ncb->grid_center_lat ); - if ( n_a .ne. n_b )then - print( "ERROR: dimensions of input SCRIP grid files is NOT the same!" ); - exit - end if - if ( any(ncb->grid_imask .ne. 1.0d00) )then - print( "ERROR: the mask of the second file isn't identically 1!" ); - print( "(second file should be land grid file)"); - exit - end if - chkvars = (/ "grid_center_lat", "grid_center_lon", "grid_corner_lat", "grid_corner_lon" /); - do i = 1, dimsizes(chkvars)-1 - if ( any(nca->$chkvars(i)$ .ne. ncb->$chkvars(i)$) )then - print( "ERROR: the grid variables are different between the two files!: "+chkvars(i) ); - exit - end if - end do - n_s = n_a; - dimnames = (/ "n_a", "n_b", "n_s", "nv_a", "nv_b", "num_wgts", "src_grid_rank", "dst_grid_rank" /); - dsizes = (/ n_a, n_b, n_a, 4, 4, 1, 2, 2/); - is_unlim = (/ False, False, False, False, False, False, False, False /); - filedimdef( nc, dimnames, dsizes, is_unlim ); - - ; - ; Define grid dimensions - ; - filevardef( nc, "src_grid_dims", "integer", (/ "src_grid_rank" /)) - nc->src_grid_dims = (/nca->grid_dims/) - filevardef( nc, "dst_grid_dims", "integer", (/ "dst_grid_rank" /)) - nc->dst_grid_dims = (/ncb->grid_dims/) - - ; - ; Define variables - ; - cvars = (/ "yc", "xc", "yv", "xv", "mask" /); - gvars = (/ "grid_center_lat", "grid_center_lon", "grid_corner_lat", "grid_corner_lon", "grid_imask" /); - - do i = 0, dimsizes(cvars)-1 - var = cvars(i)+"_a"; - if ( cvars(i) .eq. "yv" .or. cvars(i) .eq. "xv" )then - dnamesa = (/ "n_a", "nv_a" /); - dnamesb = (/ "n_b", "nv_b" /); - else - dnamesa = (/ "n_a" /); - dnamesb = (/ "n_b" /); - end if - filevardef ( nc, var, typeof(nca->$gvars(i)$), dnamesa ); - filevarattdef ( nc, var, nca->$gvars(i)$ ); - nc->$var$ = (/ nca->$gvars(i)$ /); - var = cvars(i)+"_b"; - filevardef ( nc, var, typeof(nca->$gvars(i)$), dnamesb ); - filevarattdef ( nc, var, ncb->$gvars(i)$ ); - nc->$var$ = (/ ncb->$gvars(i)$ /); - delete( dnamesa ); - delete( dnamesb ); - end do - filevardef ( nc, "area_a", "double", (/ "n_a" /) ); - filevardef ( nc, "area_b", "double", (/ "n_b" /) ); - filevardef ( nc, "frac_a", "double", (/ "n_a" /) ); - filevardef ( nc, "frac_b", "double", (/ "n_b" /) ); - ; - ; Attributes - ; - nc->area_a@units = "square radians"; - nc->frac_a@units = "unitless"; - nc->area_b@units = nc->area_a@units; - nc->frac_b@units = nc->frac_a@units; - nc@conventions = "NCAR-CESM"; - nc@domain_a = gridfile1; - nc@domain_b = gridfile2; - nc@grid_file_src = gridfile1; - nc@grid_file_dst = gridfile2; - nc@title = "SCRIP mapping file between identical grids without ocean"; - nc@history = ldate+": create using mkunitymap.ncl"; - nc@Version = gitdescribe; - - ; - ; Fraction - ; - nc->frac_a = int2dble( (/nc->mask_a/) ); - nc->frac_b = int2dble( (/nc->mask_b/) ); - ; - ; Area - ; - nc->area_a = gc_qarea( nc->yv_a(:,:), nc->xv_a(:,:) ); - nc->area_b = gc_qarea( nc->yv_b(:,:), nc->xv_b(:,:) ); - ; - ; Weights - ; - filevardef ( nc, "col", "integer", (/ "n_s" /) ); - filevardef ( nc, "row", "integer", (/ "n_s" /) ); - filevardef ( nc, "S", "double", (/ "n_s" /) ); - - nc->col = ispan( 1, n_s, 1 ); - nc->row = nc->col; - nc->S = 1.0d00; - -end