diff --git a/.circleci/config.yml b/.circleci/config.yml
index 5b107ce77773..fcb61785c368 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -2,7 +2,7 @@ version: 2.1
jobs:
build:
machine:
- image: ubuntu-2004:202010-01
+ image: ubuntu-2004:2024.01.1
steps:
- checkout
- run: bash .circleci/setup.sh
diff --git a/.circleci/setup.sh b/.circleci/setup.sh
index 498d9c6441ec..db0657f26158 100755
--- a/.circleci/setup.sh
+++ b/.circleci/setup.sh
@@ -11,6 +11,10 @@ function download
return $?
}
+# Install Singularity deps:
+
+sudo apt-get update && sudo apt-get -y install uuid-dev
+
# Install Singularity
download && \
tar -xzf singularity-${VERSION}.tar.gz && \
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 8b6ddf3e51f5..4fb88c2dc67b 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -11,3 +11,5 @@ updates:
reviewers:
- "mahf708"
- "bartgol"
+ labels:
+ - "AT: Integrate Without Testing"
diff --git a/.github/workflows/e3sm-gh-ci-cime-tests.yml b/.github/workflows/e3sm-gh-ci-cime-tests.yml
index 7963e6bf1fff..366fef018f20 100644
--- a/.github/workflows/e3sm-gh-ci-cime-tests.yml
+++ b/.github/workflows/e3sm-gh-ci-cime-tests.yml
@@ -3,12 +3,25 @@ name: gh
on:
pull_request:
branches: [ master ]
+ paths:
+ # first, yes to these
+ - 'cime_config/**'
+ - 'components/eam/**'
+ - 'components/elm/**'
+ - 'driver-moab/**'
+ - 'driver-mct/**'
+ # second, no to these
+ - '!components/eam/docs/**'
+ - '!components/eam/mkdocs.yml'
+ - '!components/elm/docs/**'
+ - '!components/elm/mkdocs.yml'
workflow_dispatch:
jobs:
ci:
+ if: ${{ github.event.repository.name == 'e3sm' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -18,6 +31,7 @@ jobs:
- SMS_P4.ne4pg2_oQU480.F2010.singularity_gnu
- REP_P4.ne4pg2_oQU480.F2010.singularity_gnu
- ERS_P4.ne4pg2_oQU480.F2010.singularity_gnu
+ - ERS_P4.ne4pg2_oQU480.F2010.singularity_gnu.eam-wcprod_F2010
- ERP_P4.ne4pg2_oQU480.F2010.singularity_gnu
- PET_P4.ne4pg2_oQU480.F2010.singularity_gnu
- PEM_P4.ne4pg2_oQU480.F2010.singularity_gnu
diff --git a/.github/workflows/e3sm-gh-ci-w-cime-tests.yml b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml
new file mode 100644
index 000000000000..595518c326d7
--- /dev/null
+++ b/.github/workflows/e3sm-gh-ci-w-cime-tests.yml
@@ -0,0 +1,59 @@
+name: gh
+
+on:
+ pull_request:
+ branches: [ master ]
+ paths-ignore:
+ - 'mkdocs.yaml'
+ - 'docs/**'
+ - 'components/*/docs/**'
+ - 'components/*/mkdocs.yml'
+
+ workflow_dispatch:
+
+jobs:
+
+ ci-w:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ test:
+ - SMS_D_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu
+ - SMS_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu
+ - REP_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu
+ - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu
+ - ERS_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu.allactive-wcprod_1850
+ - ERP_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu
+ - PET_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu
+ - PEM_P8.ne4pg2_oQU480.WCYCL2010NS.singularity_gnu
+ container:
+ image: ghcr.io/mahf708/e3sm-imgs:v0.0.6
+
+ steps:
+ -
+ name: Checkout
+ uses: actions/checkout@v4
+ with:
+ show-progress: false
+ submodules: recursive
+ -
+ name: CIME
+ working-directory: cime/scripts
+ run: |
+ mkdir -p $HOME/projects/e3sm/cesm-inputdata/atm/cam/physprops/
+ wget https://web.lcrc.anl.gov/public/e3sm/inputdata/atm/cam/physprops/p3_lookup_table_1.dat-v4.1.2
+ mv p3_lookup_table_1.dat-v4.1.2 $HOME/projects/e3sm/cesm-inputdata/atm/cam/physprops/
+ export USER=test
+ ./create_test ${{ matrix.test }} --wait --debug
+ -
+ name: Artifacts
+ uses: actions/upload-artifact@v4
+ if: ${{ always() }}
+ with:
+ name: ${{ matrix.test }}
+ path: |
+ ~/projects/e3sm/scratch/${{ matrix.test }}*/TestStatus.log
+ ~/projects/e3sm/scratch/${{ matrix.test }}*/bld/*.bldlog.*
+ ~/projects/e3sm/scratch/${{ matrix.test }}*/run/*.log.*
+ ~/projects/e3sm/scratch/${{ matrix.test }}*/run/*.cprnc.out
diff --git a/.github/workflows/e3sm-gh-md-linter.yml b/.github/workflows/e3sm-gh-md-linter.yml
new file mode 100644
index 000000000000..6484335213dd
--- /dev/null
+++ b/.github/workflows/e3sm-gh-md-linter.yml
@@ -0,0 +1,28 @@
+name: markdown
+
+# if .md files are touched in a PR, lint them!
+
+on:
+ pull_request:
+ branches: ["master"]
+ paths:
+ - '**/*.md'
+
+jobs:
+ linter:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - uses: tj-actions/changed-files@v44
+ id: changed-files
+ with:
+ files: '**/*.md'
+ separator: ","
+ - uses: DavidAnson/markdownlint-cli2-action@v16
+ if: steps.changed-files.outputs.any_changed == 'true'
+ with:
+ config: 'docs/.markdownlint.json'
+ globs: ${{ steps.changed-files.outputs.all_changed_files }}
+ separator: ","
diff --git a/.github/workflows/e3sm-gh-pages.yml b/.github/workflows/e3sm-gh-pages.yml
index 8b8da284c76f..ccca0c479f26 100644
--- a/.github/workflows/e3sm-gh-pages.yml
+++ b/.github/workflows/e3sm-gh-pages.yml
@@ -15,7 +15,7 @@ concurrency:
jobs:
Build-and-Deploy-docs:
- if: ${{ github.event.repository.name != 'scream' }}
+ if: ${{ github.event.repository.name == 'e3sm' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -31,7 +31,7 @@ jobs:
- name: Show action trigger
run: echo "= The job was automatically triggered by a ${{github.event_name}} event on repo ${{github.event.repository.name}}."
- name: Set up Python 3.10
- uses: actions/setup-python@v5.0.0
+ uses: actions/setup-python@v5.1.0
with:
python-version: "3.10"
- name: Install python deps
@@ -53,7 +53,7 @@ jobs:
folder: ./site/
# If it's a PR from within the same repo, deploy to a preview page
# For security reasons, PRs from forks cannot write into gh-pages for now
- - if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository }}
+ - if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' }}
name: Preview docs
uses: rossjrw/pr-preview-action@v1
with:
diff --git a/.github/workflows/eamxx-gh-pages.yml b/.github/workflows/eamxx-gh-pages.yml
index 0144f2abb7c7..91f591a32ba6 100644
--- a/.github/workflows/eamxx-gh-pages.yml
+++ b/.github/workflows/eamxx-gh-pages.yml
@@ -54,7 +54,7 @@ jobs:
echo "= The job was automatically triggered by a ${{github.event_name}} event."
- name: Set up Python 3.10
- uses: actions/setup-python@v5.0.0
+ uses: actions/setup-python@v5.1.0
with:
python-version: "3.10"
diff --git a/.github/workflows/eamxx_default_files.yml b/.github/workflows/eamxx_default_files.yml
new file mode 100644
index 000000000000..5ecdf6dec00c
--- /dev/null
+++ b/.github/workflows/eamxx_default_files.yml
@@ -0,0 +1,62 @@
+name: inputdata
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+ schedule:
+ - cron: '00 00 * * *'
+ workflow_dispatch:
+
+jobs:
+ scream-defaults:
+ runs-on: ubuntu-latest
+ outputs:
+ event_name: ${{ github.event_name }}
+ steps:
+ - name: Check out the repository
+ uses: actions/checkout@v4
+ with:
+ show-progress: false
+ submodules: false
+ - name: Set up Python 3.11
+ uses: actions/setup-python@v5.1.0
+ with:
+ python-version: "3.11"
+ - name: Run unit tests
+ working-directory: components/eamxx/cime_config/
+ run: |
+ python -m unittest tests/eamxx_default_files.py -v
+
+ notify-scream-defaults:
+ needs: scream-defaults
+ if: ${{ failure() && needs.scream-defaults.outputs.event_name != 'pull_request' }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: Create issue
+ run: |
+ previous_issue_number=$(gh issue list \
+ --label "$LABELS" \
+ --json number \
+ --jq '.[0].number')
+ if [[ -n $previous_issue_number ]]; then
+ gh issue comment "$previous_issue_number" \
+ --body "$BODY"
+ else
+ gh issue create \
+ --title "$TITLE" \
+ --assignee "$ASSIGNEES" \
+ --label "$LABELS" \
+ --body "$BODY"
+ fi
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_REPO: ${{ github.repository }}
+ TITLE: Inputdata server file missing
+ ASSIGNEES: mahf708,bartgol
+ LABELS: bug,input file,notify-file-gh-action
+ BODY: |
+ Workflow failed! There's likely a missing file specified in the configs! For more information, please see:
+ - Workflow URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (number ${{ github.run_number }}, attempt ${{ github.run_attempt }})
+ - Workflow SHA: ${{ github.sha }}
diff --git a/.gitignore b/.gitignore
index c4d2a64bc994..8c1fa12b87ca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,6 +30,13 @@ site
# Ignore emacs backup files
*~
+#Ignore Mac folder files
+.DS_Store
+
+#Ignore vscode dir
+.vscode
+
+
# Ignore mkdocs site-generated files in eamxx
components/eamxx/site/*
# Ignore auto-generated eamxx_params.md file
diff --git a/CITATION.cff b/CITATION.cff
index bf980f74f6d3..9542a7d01ef4 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -8,8 +8,8 @@ type: software
authors:
- given-names: E3SM
family-names: Project
-version: 2.1.0
-doi: 10.11578/E3SM/dc.20230110.5
+version: 3.0.0
+doi: 10.11578/E3SM/dc.20240301.3
repository-code: 'https://github.com/E3SM-Project/E3SM'
url: 'https://e3sm.org'
license: BSD-3-Clause
diff --git a/README.md b/README.md
index 84eb15d8e186..192c288d78e1 100644
--- a/README.md
+++ b/README.md
@@ -9,12 +9,14 @@ the most challenging and demanding climate-change research problems and
Department of Energy mission needs while efficiently using DOE Leadership
Computing Facilities.
-DOI: [10.11578/E3SM/dc.20230110.5](http://dx.doi.org/10.11578/E3SM/dc.20230110.5)
+DOI: [10.11578/E3SM/dc.20240301.3](http://dx.doi.org/10.11578/E3SM/dc.20240301.3)
Please visit the [project website](https://e3sm.org) or our [Confluence site](https://acme-climate.atlassian.net/wiki/spaces/DOC/overview)
for further details.
-For questions about the model, use [Github Discussions](https://github.com/E3SM-Project/E3SM/discussions)
+For questions about the model, use [Github Discussions](https://github.com/E3SM-Project/E3SM/discussions).
+
+See our Github-hosted documentation at [https://e3sm-project.github.io/E3SM/](https://e3sm-project.github.io/E3SM/).
Table of Contents
--------------------------------------------------------------------------------
@@ -27,7 +29,7 @@ Table of Contents
Quick Start
--------------------------------------------------------------------------------
-The [Quick Start](https://e3sm.org/model/running-e3sm/e3sm-quick-start/) page
+The [Quick Start](https://e3sm.org/model/running-e3sm/e3sm-quick-start/) page
includes instructions on obtaining the necessary code and input data for model
setup and execution on a supported machine.
@@ -42,7 +44,7 @@ To run E3SM, it is recommended that you obtain time on a
Running
--------------------------------------------------------------------------------
-Please refer to [Running E3SM](https://e3sm.org/model/running-e3sm/)
+Please refer to [Running E3SM](https://e3sm.org/model/running-e3sm/)
for instructions on running the model.
Contributing
@@ -64,11 +66,11 @@ the following BibTeX entry is provided.
author = {{E3SM Project}},
abstractNote = {{E3SM} is a state-of-the-art fully coupled model of the {E}arth's
climate including important biogeochemical and cryospheric processes.},
- howpublished = {[Computer Software] \url{https://dx.doi.org/10.11578/E3SM/dc.20230110.5}},
- url = {https://dx.doi.org/10.11578/E3SM/dc.20230110.5},
- doi = {10.11578/E3SM/dc.20230110.5},
- year = 2023,
- month = jan,
+ howpublished = {[Computer Software] \url{https://dx.doi.org/10.11578/E3SM/dc.20240301.3}},
+ url = {https://dx.doi.org/10.11578/E3SM/dc.20240301.3},
+ doi = {10.11578/E3SM/dc.20240301.3},
+ year = 2024,
+ month = mar,
}
```
diff --git a/cime b/cime
index 12142ee0c003..4388509869bd 160000
--- a/cime
+++ b/cime
@@ -1 +1 @@
-Subproject commit 12142ee0c003c135e66265528247518339c0b067
+Subproject commit 4388509869bd5988d6315e2da65b1a2fbfa604fa
diff --git a/cime_config/allactive/config_compsets.xml b/cime_config/allactive/config_compsets.xml
index b0587d3f7ae8..66edcf617c0d 100755
--- a/cime_config/allactive/config_compsets.xml
+++ b/cime_config/allactive/config_compsets.xml
@@ -70,9 +70,15 @@
1850_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV
+
+
+ WCYCL2010NS
+ 2010_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV
+
+
WCYCL1950
- 1950SOI_EAM%CMIP6_ELM%SPBC_MPASSI_MPASO_MOSART_SGLC_SWAV
+ 1950SOI_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV
@@ -113,12 +119,17 @@
WCYCLSSP585
- SSP585SOI_EAM%CMIP6_ELM%SPBC_MPASSI_MPASO_MOSART_SGLC_SWAV
+ SSP585SOI_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV
WCYCLSSP370
- SSP370SOI_EAM%CMIP6_ELM%SPBC_MPASSI_MPASO_MOSART_SGLC_SWAV
+ SSP370SOI_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV
+
+
+
+ WCYCLSSP245
+ SSP245SOI_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI_MPASO_MOSART_SGLC_SWAV
@@ -393,7 +404,7 @@
BGWCYCL1850
- 1850_EAM%CMIP6_ELM%SPBC_MPASSI_MPASO_MOSART_MALI%STATIC_SWAV
+ 1850_EAM%CMIP6_ELM%SPBC_MPASSI_MPASO_MOSART_MALI_SWAV
@@ -443,6 +454,7 @@
1850-01-01
2015-01-01
2015-01-01
+ 2015-01-01
diff --git a/cime_config/allactive/config_pesall.xml b/cime_config/allactive/config_pesall.xml
index 67a74a3f60c0..0db40bd57982 100644
--- a/cime_config/allactive/config_pesall.xml
+++ b/cime_config/allactive/config_pesall.xml
@@ -325,7 +325,7 @@
-
+
"anvil, GPMPAS-JRA compset, 6 nodes"
-6
@@ -338,7 +338,7 @@
-
+
"crusher, GPMPAS-JRA compset, 2 nodes"
-4
@@ -351,7 +351,7 @@
-
+
summit|ascent: GPMPAS-JRA compset on ne30np4 grid
-4
@@ -468,7 +468,7 @@
-
+
-compset A_WCYCL* -res ne30_oEC* on 27 nodes pure-MPI
900
@@ -487,7 +487,7 @@
0
-
+
-compset A_WCYCL* -res ne30_oEC* on 40 nodes pure-MPI
1350
@@ -506,7 +506,7 @@
0
-
+
-compset A_WCYCL* -res ne30_oEC* on 80 nodes pure-MPI
2700
@@ -525,7 +525,7 @@
0
-
+
-compset A_WCYCL* -res ne30_oEC* on 160 nodes pure-MPI
5400
@@ -548,7 +548,7 @@
-
+
ne120-wcycl on 42 nodes 128x1 ~0.7 sypd
128
@@ -584,7 +584,7 @@
-
+
ne120-wcycl on 145 nodes, MPI-only
64
64
@@ -609,7 +609,7 @@
0
-
+
ne120-wcycl on 145 nodes, threaded
256
64
@@ -644,7 +644,7 @@
0
-
+
ne120 coupled-compset on 466 nodes
64
64
@@ -669,7 +669,7 @@
0
-
+
ne120-wcycl on 863 nodes, MPI-only
64
64
@@ -694,7 +694,7 @@
0
-
+
ne120-wcycl on 863 nodes, threaded
128
64
@@ -729,7 +729,7 @@
0
-
+
ne120-wcycl on 825 nodes, threaded, 32 tasks/node
128
32
@@ -764,7 +764,7 @@
0
-
+
ne120-wcycl on 800 nodes, threaded, 32 tasks/node
128
32
@@ -801,7 +801,7 @@
-
+
compy ne120 W-cycle on 310 nodes, 40x1, sypd=1.2
9600
@@ -824,7 +824,7 @@
-
+
--compset WCYCL* --res ne30pg2_EC30to60E2r2 on 25 nodes pure-MPI, ~5.4 sypd
675
@@ -843,7 +843,7 @@
0
-
+
--compset WCYCL* --res ne30pg2_EC30to60E2r2 on 48 nodes pure-MPI, ~9.4 sypd
1350
@@ -862,7 +862,7 @@
0
-
+
--compset WCYCL* --res ne30pg2_EC30to60E2r2 on 90 nodes pure-MPI, ~12 sypd
2700
@@ -917,7 +917,7 @@
-
+
-compset A_WCYCL* -res ne30pg2_EC30to60* on 27 nodes pure-MPI, ~15.5 sypd
2700
@@ -936,7 +936,7 @@
0
-
+
-compset A_WCYCL* -res ne30pg2_EC30to60* on 54 nodes pure-MPI, ~25.5 sypd
5400
@@ -957,7 +957,7 @@
-
+
-compset A_WCYCL* -res ne30pg2_EC30to60* on 11 nodes pure-MPI, ~2.8 sypd
320
@@ -976,7 +976,7 @@
0
-
+
-compset A_WCYCL* -res ne30pg2_EC30to60* on 21 nodes pure-MPI, ~5.5 sypd
600
@@ -995,7 +995,7 @@
0
-
+
-compset A_WCYCL* -res ne30pg2_EC30to60* on 46 nodes pure-MPI, ~11 sypd
1350
@@ -1014,7 +1014,7 @@
0
-
+
-compset A_WCYCL* -res ne30pg2_EC30to60* on 90 nodes pure-MPI, ~18 sypd
2700
@@ -1037,7 +1037,7 @@
-
+
-compset WCYCL*/CRYO* -res SOwISC12to60E2r4* on 75 nodes pure-MPI, ~5 sypd
900
@@ -1058,7 +1058,7 @@
-
+
-compset WCYCL*/CRYO* -res ne30pg*SOwISC12to60E2r4* on 105 nodes pure-MPI, ~18.5 sypd
64
@@ -1078,7 +1078,7 @@
0
-
+
-compset WCYCL*/CRYO* -res ne30pg*SOwISC12to60E2r4* on 54 nodes pure-MPI, ~11 sypd
64
@@ -1102,7 +1102,7 @@
-
+
-compset WCYCL*/CRYO* -res ECwISC30to60E2r1* on 48 nodes pure-MPI, ~8.5 sypd
1350
@@ -1123,7 +1123,7 @@
-
+
-compset WCYCL*/CRYO* -res ne30pg*ECwISC30to60E2r1* on 105 nodes pure-MPI, ~40 sypd
64
@@ -1143,7 +1143,7 @@
0
-
+
-compset WCYCL*/CRYO* -res ne30pg*ECwISC30to60E2r1* on 55 nodes pure-MPI, ~25 sypd
64
@@ -1163,7 +1163,7 @@
0
-
+
-compset WCYCL*/CRYO* -res ne30pg*ECwISC30to60E2r1* on 28 nodes pure-MPI, ~15 sypd
64
@@ -1187,7 +1187,7 @@
-
+
gcp12 -compset A_WCYCL* -res ne30pg2_oECv3 with MPASO on 7 nodes
280
@@ -1216,7 +1216,7 @@
-
+
gcp10 -compset A_WCYCL* -res ne30pg2_oECv3 with MPASO on 11 nodes
240
@@ -1245,7 +1245,7 @@
-
+
-compset A_WCYCL* -res ne30pg2_oECv3 with MPASO on 7 nodes, 128x1
128
@@ -1273,7 +1273,7 @@
0
-
+
-compset A_WCYCL* -res ne30pg2_oECv3 with MPASO on 58 nodes, 128x1, ~20 sypd
128
@@ -1379,10 +1379,38 @@
+
+
+ improv: any compset on ne30np4 grid
+
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+
+
+
+ improv: BGC compset on ne30np4 grid
+
+ -8
+ -8
+ -8
+ -8
+ -8
+ -8
+ -8
+ -8
+
+
+
-
+
-compset A_WCYCL* -res ne30pg2_oECv3 on 11 nodes pure-MPI, ~2.8 sypd
320
@@ -1401,7 +1429,7 @@
0
-
+
-compset A_WCYCL* -res ne30pg2_oECv3 on 21 nodes pure-MPI, ~5.5 sypd
600
@@ -1420,7 +1448,7 @@
0
-
+
-compset A_WCYCL* -res ne30pg2_oECv3 on 46 nodes pure-MPI, ~11 sypd
1350
@@ -1439,7 +1467,7 @@
0
-
+
-compset A_WCYCL* -res ne30pg2_oECv3 on 90 nodes pure-MPI, ~18 sypd
2700
@@ -1531,10 +1559,97 @@
+
+
+ gcp12 --compset WCYCL* --res ne30pg2_r05_IcoswISC30E3r5 on 4 nodes
+
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+
+
+
+
+
+ pm-cpu --compset WCYCL* --res ne30pg2_r05_IcoswISC30E3r5 on 4 nodes
+
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+
+
+
+
+
+
+
+ --compset WCYCL* --res ne30pg2_r05_IcosXISC30E3r7 on 20 nodes pure-MPI, ~7.25 sypd
+
+ 1024
+ 1024
+ 256
+ 640
+ 384
+ 385
+
+
+ 0
+ 0
+ 1024
+ 0
+ 640
+ 640
+
+
+
+ --compset WCYCL* --res ne30pg2_r05_IcosXISC30E3r7 on 54 nodes pure-MPI, ~17.5 sypd
+
+ 2752
+ 2752
+ 704
+ 2048
+ 704
+ 704
+
+
+ 0
+ 0
+ 2752
+ 0
+ 2048
+ 2048
+
+
+
+ --compset WCYCL* --res ne30pg2_r05_IcosXISC30E3r7 on 105 nodes pure-MPI, ~27.7 sypd
+
+ 5440
+ 5440
+ 1280
+ 4352
+ 1088
+ 1088
+
+
+ 0
+ 0
+ 5440
+ 0
+ 4352
+ 4352
+
+
+
-
+
-compset WCYCL* -res ne30pg2_EC30to60E2r2 on 14 nodes pure-MPI, ~6 sypd
704
@@ -1553,7 +1668,7 @@
0
-
+
-compset WCYCL* -res ne30pg2_EC30to60E2r2 on 27 nodes pure-MPI, ~12 sypd
1408
@@ -1572,7 +1687,7 @@
0
-
+
-compset WCYCL* -res ne30pg2_EC30to60E2r2 on 53 nodes pure-MPI, ~21 sypd
2752
@@ -1591,7 +1706,7 @@
0
-
+
-compset WCYCL* -res ne30pg2_EC30to60E2r2 on 70 nodes pure-MPI, ~24 sypd
3648
@@ -1610,7 +1725,7 @@
0
-
+
-compset WCYCL* -res ne30pg2EC30to60E2r2 on 100 nodes pure-MPI, ~30 sypd
5440
@@ -1631,7 +1746,7 @@
-
+
-compset A_WCYCL* -res ne30pg*EC30to60* on 8 debug Q nodes threaded, 0.8 sypd
384
@@ -1658,7 +1773,7 @@
0
-
+
-compset A_WCYCL* -res ne30pg*EC30to60* on 128 default Q nodes pure-MPI, 3.8 sypd
5400
@@ -1681,7 +1796,7 @@
-
+
-compset WCYCL* -res ne30pg*WCAtl* on 80 nodes pure-MPI, ~8.5 sypd
2700
@@ -1879,7 +1994,7 @@
-
+
rmod025a
40
40
@@ -1900,7 +2015,7 @@
0
-
+
rmod077a
40
40
@@ -1921,7 +2036,7 @@
0
-
+
rmod111a
40
40
@@ -1942,7 +2057,7 @@
0
-
+
rmod037a
20
40
@@ -1963,7 +2078,7 @@
2
-
+
rmod074a
20
40
@@ -1992,7 +2107,7 @@
0
-
+
rmod115b
20
40
@@ -2023,7 +2138,7 @@
-
+
RRM-WCYCL: 64 nodes 2.133 sypd
1800
@@ -2044,7 +2159,7 @@
-
+
cmod016b64x1 s=2.4
64
128
@@ -2065,7 +2180,7 @@
0
-
+
cmod040c64x1 s=5.6
64
128
@@ -2086,7 +2201,7 @@
0
-
+
cmod060d64x1 s=8.0
64
128
@@ -2107,7 +2222,7 @@
0
-
+
cmod080c64x1 s=10.1
64
128
@@ -2128,7 +2243,7 @@
0
-
+
cmod100b64x1 s=12.3
64
128
@@ -2151,7 +2266,7 @@
-
+
8 nodes, 128x1
640
@@ -2204,7 +2319,7 @@
-
+
--compset WCYCL* --res ne30pg2_EC30to60E2r2_wQU225EC30to60E2r2 on 48 nodes pure-MPI, ~8.8 sypd
1350
@@ -2238,7 +2353,7 @@
-
+
none
924
@@ -2275,7 +2390,7 @@
-
+
none
2768
@@ -2450,5 +2565,102 @@
+
+
+ pm-cpu, conus 2 nodes
+
+ -2
+ -2
+ -2
+ -2
+ -2
+ -2
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+ GIS 1-to-10km (high-res) baseline config
+ 128
+ 128
+
+ 1350
+ 960
+ 960
+ 1350
+ 320
+ 960
+ 2310
+ 2310
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 1350
+ 1350
+ 0
+ 2310
+ 1350
+ 0
+ 0
+
+
+
+
+
+ GIS 1-to-10km (high-res) baseline config
+ 64
+ 64
+
+ 1350
+ 960
+ 960
+ 1408
+ 384
+ 960
+ 1
+ 2368
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+
+
+ 0
+ 1408
+ 1408
+ 0
+ 2368
+ 1408
+ 0
+ 0
+
+
+
diff --git a/cime_config/config_archive.xml b/cime_config/config_archive.xml
index 028a11e84393..84de6e0f171a 100644
--- a/cime_config/config_archive.xml
+++ b/cime_config/config_archive.xml
@@ -119,7 +119,6 @@
rst
- rst.am.timeSeriesStatsMonthly
hist
unset
@@ -129,9 +128,8 @@
rpointer.glc
casename.mali.rst.1976-01-01_00000.nc
- casename.mali.rst.am.timeSeriesStatsMonthly.1976-01-01_00000.nc
- casename.mali.hist.am.globalStats.1976-01-01.nc
- casename.mali.hist.am.highFrequencyOutput.1976-01-01_00.00.00.nc
+ casename.mali.hist.1976-01-01_00000.nc
+ casename.mali.hist.am.1976-01-01.nc
diff --git a/cime_config/config_files.xml b/cime_config/config_files.xml
index 97d73759ac4d..71de51964426 100644
--- a/cime_config/config_files.xml
+++ b/cime_config/config_files.xml
@@ -98,6 +98,7 @@
char
$CIMEROOT/CIME/data/config/config_tests.xml
+ $COMP_ROOT_DIR_OCN/cime_config/config_tests.xml
test
env_test.xml
@@ -321,6 +322,7 @@
char
$CIMEROOT/CIME/SystemTests
+ $COMP_ROOT_DIR_OCN/cime_config/SystemTests
test
env_test.xml
diff --git a/cime_config/config_grids.xml b/cime_config/config_grids.xml
index 1894ef66fa5d..ccfb3d908d86 100755
--- a/cime_config/config_grids.xml
+++ b/cime_config/config_grids.xml
@@ -38,9 +38,6 @@
r05
r05
null
- gland5UM
- gland4
- gland4
null
null
null
@@ -489,6 +486,36 @@
WC14to60E2r3
+
+ TL319
+ r05
+ WC14to60E2r3
+ r05
+ null
+ null
+ WC14to60E2r3
+
+
+
+ TL319
+ r05
+ EC30to60E2r2
+ r05
+ null
+ null
+ EC30to60E2r2
+
+
+
+ TL319
+ r05
+ ARRM10to60E2r1
+ r05
+ null
+ null
+ ARRM10to60E2r1
+
+
TL319
TL319
@@ -509,6 +536,46 @@
SOwISC12to60E2r4
+
+ TL319
+ TL319
+ FRISwISC08to60E3r1
+ JRA025
+ null
+ null
+ FRISwISC08to60E3r1
+
+
+
+ TL319
+ TL319
+ FRISwISC04to60E3r1
+ JRA025
+ null
+ null
+ FRISwISC04to60E3r1
+
+
+
+ TL319
+ TL319
+ FRISwISC02to60E3r1
+ JRA025
+ null
+ null
+ FRISwISC02to60E3r1
+
+
+
+ TL319
+ TL319
+ FRISwISC01to60E3r1
+ JRA025
+ null
+ null
+ FRISwISC01to60E3r1
+
+
TL319
TL319
@@ -529,6 +596,16 @@
IcoswISC30E3r5
+
+ TL319
+ TL319
+ IcosXISC30E3r7
+ JRA025
+ null
+ null
+ IcosXISC30E3r7
+
+
TL319
TL319
@@ -681,6 +758,16 @@
oEC60to30v3
+
+ r025
+ r025
+ r025
+ r025
+ null
+ null
+ oEC60to30v3
+
+
r0125
r0125
@@ -711,6 +798,16 @@
oRRS18to6v3
+
+ r025
+ r025
+ IcoswISC30E3r5
+ null
+ null
+ null
+ IcoswISC30E3r5
+
+
@@ -963,6 +1060,16 @@
oEC60to30v3
+
+ ne0np4_conus_x4v1_lowcon.pg2
+ r05
+ IcoswISC30E3r5
+ r05
+ null
+ null
+ IcoswISC30E3r5
+
+
ne0np4_northamericax4v1
r0125
@@ -973,6 +1080,16 @@
oRRS15to5
+
+ ne0np4_northamericax4v1.pg2
+ r025
+ IcoswISC30E3r5
+ r025
+ null
+ null
+ IcoswISC30E3r5
+
+
ne0np4_northamericax4v1.pg2
r0125
@@ -1376,6 +1493,26 @@
oRRS18to6v3
+
+ ne120np4.pg2
+ r025
+ IcoswISC30E3r5
+ null
+ null
+ null
+ IcoswISC30E3r5
+
+
+
+ ne30np4.pg2
+ r025
+ IcoswISC30E3r5
+ null
+ null
+ null
+ IcoswISC30E3r5
+
+
ne60np4
ne60np4
@@ -1658,6 +1795,36 @@
oEC60to30v3
+
+ ne30np4.pg2
+ r05
+ EC30to60E2r2
+ r05
+ mpas.gis20km
+ null
+ EC30to60E2r2
+
+
+
+ ne30np4.pg2
+ r05
+ IcoswISC30E3r5
+ r05
+ mpas.gis20km
+ null
+ IcoswISC30E3r5
+
+
+
+ TL319
+ TL319
+ IcoswISC30E3r5
+ JRA025
+ mpas.gis20km
+ null
+ IcoswISC30E3r5
+
+
ne30np4.pg2
r05
@@ -1678,6 +1845,16 @@
oEC60to30v3
+
+ ne30np4.pg2
+ r05
+ EC30to60E2r2
+ r05
+ mpas.gis1to10km
+ null
+ EC30to60E2r2
+
+
ne30np4.pg2
r0125
@@ -1688,6 +1865,36 @@
EC30to60E2r2
+
+ ne30np4.pg2
+ r05
+ EC30to60E2r2
+ r05
+ mpas.gis1to10kmR2
+ null
+ EC30to60E2r2
+
+
+
+ ne30np4.pg2
+ r05
+ IcoswISC30E3r5
+ r05
+ mpas.gis1to10kmR2
+ null
+ IcoswISC30E3r5
+
+
+
+ TL319
+ TL319
+ IcoswISC30E3r5
+ JRA025
+ mpas.gis1to10kmR2
+ null
+ IcoswISC30E3r5
+
+
ne120np4.pg2
r0125
@@ -2054,6 +2261,16 @@
IcoswISC30E3r5
+
+ ne30np4.pg2
+ r05
+ IcosXISC30E3r7
+ r05
+ null
+ null
+ IcosXISC30E3r7
+
+
ne30np4.pg2
r05
@@ -2404,10 +2621,20 @@
$DIN_LOC_ROOT/share/domains/domain.ocn.TL319_WCAtl12to45E2r4.210318.nc
$DIN_LOC_ROOT/share/domains/domain.lnd.TL319_SOwISC12to60E2r4.210119.nc
$DIN_LOC_ROOT/share/domains/domain.ocn.TL319_SOwISC12to60E2r4.210119.nc
+ $DIN_LOC_ROOT/share/domains/domain.lnd.TL319_FRISwISC08to60E3r1.240214.nc
+ $DIN_LOC_ROOT/share/domains/domain.ocn.TL319_FRISwISC08to60E3r1.240214.nc
+ $DIN_LOC_ROOT/share/domains/domain.lnd.TL319_FRISwISC04to60E3r1.240214.nc
+ $DIN_LOC_ROOT/share/domains/domain.ocn.TL319_FRISwISC04to60E3r1.240214.nc
+ $DIN_LOC_ROOT/share/domains/domain.lnd.TL319_FRISwISC02to60E3r1.240214.nc
+ $DIN_LOC_ROOT/share/domains/domain.ocn.TL319_FRISwISC02to60E3r1.240214.nc
+ $DIN_LOC_ROOT/share/domains/domain.lnd.TL319_FRISwISC01to60E3r1.240216.nc
+ $DIN_LOC_ROOT/share/domains/domain.ocn.TL319_FRISwISC01to60E3r1.240216.nc
$DIN_LOC_ROOT/share/domains/domain.lnd.TL319_ECwISC30to60E2r1.201007.nc
$DIN_LOC_ROOT/share/domains/domain.ocn.TL319_ECwISC30to60E2r1.201007.nc
$DIN_LOC_ROOT/share/domains/domain.lnd.TL319_IcoswISC30E3r5.231121.nc
$DIN_LOC_ROOT/share/domains/domain.ocn.TL319_IcoswISC30E3r5.231121.nc
+ $DIN_LOC_ROOT/share/domains/domain.lnd.TL319_IcosXISC30E3r7.240326.nc
+ $DIN_LOC_ROOT/share/domains/domain.ocn.TL319_IcosXISC30E3r7.240326.nc
$DIN_LOC_ROOT/share/domains/domain.lnd.TL319_oRRS18to6v3.220124.nc
$DIN_LOC_ROOT/share/domains/domain.ocn.TL319_oRRS18to6v3.220124.nc
TL319 is JRA lat/lon grid:
@@ -2517,6 +2744,8 @@
$DIN_LOC_ROOT/share/domains/domain.ocn.ne30pg2_oRRS18to6v3.211101.nc
$DIN_LOC_ROOT/share/domains/domain.lnd.ne30pg2_IcoswISC30E3r5.231121.nc
$DIN_LOC_ROOT/share/domains/domain.ocn.ne30pg2_IcoswISC30E3r5.231121.nc
+ $DIN_LOC_ROOT/share/domains/domain.lnd.ne30pg2_IcosXISC30E3r7.240326.nc
+ $DIN_LOC_ROOT/share/domains/domain.ocn.ne30pg2_IcosXISC30E3r7.240326.nc
$DIN_LOC_ROOT/share/domains/domain.lnd.ne30pg2_gx1v6.190806.nc
$DIN_LOC_ROOT/share/domains/domain.ocn.ne30pg2_gx1v6.190806.nc
ne30np4.pg2 is Spectral Elem 1-deg grid w/ 2x2 FV physics grid per element:
@@ -2777,6 +3006,34 @@
SOwISC12to60E2r4 is a MPAS ice/ocean grid with enhanced resolution of 12km in the Southern Ocean around Antarctica. The high resolution regions smoothly transition to the background resolution of the standard low resolution 60to30km grid:
+
+ 605169
+ 1
+ $DIN_LOC_ROOT/share/domains/domain.ocn.FRISwISC08to60E3r1.240214.nc
+ FRISwISC08to60E3r1 is a MPAS ice/ocean grid with enhanced resolution of 12km in the Southern Ocean around Antarctica and 4 km beneath the Filchner-Ronne Ice Shelf. The high resolution regions smoothly transition to the background resolution of the standard low resolution 60to30km grid:
+
+
+
+ 718054
+ 1
+ $DIN_LOC_ROOT/share/domains/domain.ocn.FRISwISC04to60E3r1.240214.nc
+ FRISwISC04to60E3r1 is a MPAS ice/ocean grid with enhanced resolution of 12km in the Southern Ocean around Antarctica and 4 km beneath the Filchner-Ronne Ice Shelf. The high resolution regions smoothly transition to the background resolution of the standard low resolution 60to30km grid:
+
+
+
+ 1055045
+ 1
+ $DIN_LOC_ROOT/share/domains/domain.ocn.FRISwISC02to60E3r1.240214.nc
+ FRISwISC02to60E3r1 is a MPAS ice/ocean grid with enhanced resolution of 12km in the Southern Ocean around Antarctica and 4 km beneath the Filchner-Ronne Ice Shelf. The high resolution regions smoothly transition to the background resolution of the standard low resolution 60to30km grid:
+
+
+
+ 2162616
+ 1
+ $DIN_LOC_ROOT/share/domains/domain.ocn.FRISwISC01to60E3r1.240216.nc
+ FRISwISC01to60E3r1 is a MPAS ice/ocean grid with enhanced resolution of 12km in the Southern Ocean around Antarctica and 4 km beneath the Filchner-Ronne Ice Shelf. The high resolution regions smoothly transition to the background resolution of the standard low resolution 60to30km grid:
+
+
237984
1
@@ -2791,6 +3048,13 @@
IcoswISC30E3r5 is a MPAS ocean grid generated with the jigsaw/compass process using a dual mesh that is a subdivided icosahedron, resulting in a nearly uniform resolution of 30 km. Additionally, it has ocean in ice-shelf cavities:
+
+ 463013
+ 1
+ $DIN_LOC_ROOT/share/domains/domain.ocn.IcosXISC30E3r7.240326.nc
+ IcosXISC30E3r7 is a MPAS ocean grid generated with the jigsaw/compass process using a dual mesh that is a subdivided icosahedron, resulting in a nearly uniform resolution of 30 km.:
+
+
@@ -2823,6 +3087,8 @@
$DIN_LOC_ROOT/share/domains/domain.lnd.r05_WC14to60E2r3.200929.nc
$DIN_LOC_ROOT/share/domains/domain.lnd.r05_IcoswISC30E3r5.231121.nc
$DIN_LOC_ROOT/share/domains/domain.lnd.r05_IcoswISC30E3r5.231121.nc
+ $DIN_LOC_ROOT/share/domains/domain.lnd.r05_IcosXISC30E3r7.240326.nc
+ $DIN_LOC_ROOT/share/domains/domain.lnd.r05_IcosXISC30E3r7.240326.nc
$DIN_LOC_ROOT/share/domains/domain.lnd.r05_gx1v6.191014.nc
r05 is 1/2 degree river routing grid:
@@ -2852,6 +3118,12 @@
r0125 is 1/8 degree river routing grid:
+
+ 1440
+ 720
+ $DIN_LOC_ROOT/share/domains/domain.lnd.r025_IcoswISC30E3r5.240129.nc
+
+
28993
1
@@ -2885,6 +3157,12 @@
mpas.gis1to10km is a variable-resolution, from 1- to 10-km, MALI grid of the Greenland Ice Sheet.
+
+ 427386
+ 1
+ mpas.gis1to10kmR2 is an updated (fewer grid cells; improved optimization) variable-resolution, from 1- to 10-km, MALI grid of the Greenland Ice Sheet.
+
+
45675
1
@@ -2950,6 +3228,8 @@
1
$DIN_LOC_ROOT/share/domains/domain.lnd.conusx4v1pg2_oEC60to30v3.200518.nc
$DIN_LOC_ROOT/share/domains/domain.ocn.conusx4v1pg2_oEC60to30v3.200518.nc
+ $DIN_LOC_ROOT/share/domains/domain.lnd.conusx4v1pg2_IcoswISC30E3r5.240205.nc
+ $DIN_LOC_ROOT/share/domains/domain.ocn.conusx4v1pg2_IcoswISC30E3r5.240205.nc
1-deg with 1/4-deg over CONUS (version 1):
@@ -2972,6 +3252,8 @@
$DIN_LOC_ROOT/share/domains/domain.ocn.northamericax4v1pg2_WC14to60E2r3.200929.nc
$DIN_LOC_ROOT/share/domains/domain.lnd.northamericax4v1pg2_EC30to60E2r2.220428.nc
$DIN_LOC_ROOT/share/domains/domain.ocn.northamericax4v1pg2_EC30to60E2r2.220428.nc
+ $DIN_LOC_ROOT/share/domains/domain.lnd.northamericax4v1pg2_IcoswISC30E3r5.240416.nc
+ $DIN_LOC_ROOT/share/domains/domain.ocn.northamericax4v1pg2_IcoswISC30E3r5.240416.nc
1-deg with 1/4-deg over North America (version 1) pg2:
@@ -3283,6 +3565,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -3340,6 +3634,7 @@
+
@@ -3458,6 +3753,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -3674,15 +3985,22 @@
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
@@ -3747,6 +4065,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -3754,6 +4082,14 @@
+
+
+
+
+
+
+
+
@@ -3764,6 +4100,12 @@
+
+
+
+
+
+
@@ -4084,6 +4426,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -4100,6 +4474,14 @@
+
+
+
+
+
+
+
+
@@ -4108,6 +4490,13 @@
+
+
+
+
+
+
+
@@ -4184,7 +4573,8 @@
-
+
+
@@ -4222,6 +4612,11 @@
+
+
+
+
+
@@ -4287,6 +4682,11 @@
+
+
+
+
+
@@ -4454,10 +4854,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -4610,6 +5022,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -4620,6 +5052,11 @@
+
+
+
+
+
@@ -4705,6 +5142,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -4823,6 +5270,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -4870,6 +5360,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cime_config/customize/case_post_run_io.py b/cime_config/customize/case_post_run_io.py
index bb44477ebb57..83419aa81348 100755
--- a/cime_config/customize/case_post_run_io.py
+++ b/cime_config/customize/case_post_run_io.py
@@ -74,6 +74,12 @@ def _convert_adios_to_nc(case):
# Load the environment
case.load_env(reset=True)
+ # Reset MPICH/MPI GPU support, if enabled
+ is_mpich_gpu_enabled = os.environ.get('MPICH_GPU_SUPPORT_ENABLED')
+ if int(0 if is_mpich_gpu_enabled is None else is_mpich_gpu_enabled) == 1:
+ logger.info("Resetting support for GPU in MPICH/MPI library (since its not used by the tool)")
+ os.environ['MPICH_GPU_SUPPORT_ENABLED'] = str(0);
+
run_func = lambda: run_cmd(cmd, from_dir=rundir)[0]
# Run the modified case
diff --git a/cime_config/machines/Depends.chicoma-cpu.gnu.cmake b/cime_config/machines/Depends.chicoma-cpu.gnu.cmake
new file mode 100644
index 000000000000..9ebd88ff8762
--- /dev/null
+++ b/cime_config/machines/Depends.chicoma-cpu.gnu.cmake
@@ -0,0 +1,13 @@
+# For this file, fixes non-BFB behavior of stealth feature on pm-cpu with -O2
+set(NOOPT
+ eam/src/physics/cam/zm_conv.F90)
+
+if (NOT DEBUG)
+ foreach(ITEM IN LISTS NOOPT)
+ e3sm_deoptimize_file("${ITEM}")
+ endforeach()
+endif()
+
+
+
+
diff --git a/cime_config/machines/Depends.chicoma-gpu.nvidia.cmake b/cime_config/machines/Depends.chicoma-gpu.nvidia.cmake
new file mode 100644
index 000000000000..89235ac5efd1
--- /dev/null
+++ b/cime_config/machines/Depends.chicoma-gpu.nvidia.cmake
@@ -0,0 +1,10 @@
+list(APPEND REDUCE_OPT_LIST
+ homme/src/share/derivative_mod_base.F90
+)
+
+# Can use this flag to avoid internal compiler error for this file (with nvidia/21.11)
+if (NOT DEBUG)
+ foreach(ITEM IN LISTS REDUCE_OPT_LIST)
+ e3sm_add_flags("${ITEM}" " -Mnovect")
+ endforeach()
+endif()
diff --git a/cime_config/machines/Depends.chicoma-gpu.nvidiagpu.cmake b/cime_config/machines/Depends.chicoma-gpu.nvidiagpu.cmake
new file mode 100644
index 000000000000..89235ac5efd1
--- /dev/null
+++ b/cime_config/machines/Depends.chicoma-gpu.nvidiagpu.cmake
@@ -0,0 +1,10 @@
+list(APPEND REDUCE_OPT_LIST
+ homme/src/share/derivative_mod_base.F90
+)
+
+# Can use this flag to avoid internal compiler error for this file (with nvidia/21.11)
+if (NOT DEBUG)
+ foreach(ITEM IN LISTS REDUCE_OPT_LIST)
+ e3sm_add_flags("${ITEM}" " -Mnovect")
+ endforeach()
+endif()
diff --git a/cime_config/machines/Depends.oneapi-ifx.cmake b/cime_config/machines/Depends.oneapi-ifx.cmake
index 8b51086df4a9..5a958df26eba 100644
--- a/cime_config/machines/Depends.oneapi-ifx.cmake
+++ b/cime_config/machines/Depends.oneapi-ifx.cmake
@@ -1,3 +1,5 @@
# compile mpas_seaice_core_interface.f90 with ifort, not ifx
-e3sm_add_flags("${CMAKE_BINARY_DIR}/core_seaice/model_forward/mpas_seaice_core_interface.f90" "-fc=ifort")
+if (NOT MPILIB STREQUAL "openmpi")
+ e3sm_add_flags("${CMAKE_BINARY_DIR}/core_seaice/model_forward/mpas_seaice_core_interface.f90" "-fc=ifort")
+endif()
diff --git a/cime_config/machines/Depends.pm-cpu.nvidia.cmake b/cime_config/machines/Depends.pm-cpu.nvidia.cmake
index 2947c73aacc4..f3514d118804 100644
--- a/cime_config/machines/Depends.pm-cpu.nvidia.cmake
+++ b/cime_config/machines/Depends.pm-cpu.nvidia.cmake
@@ -10,6 +10,17 @@ if (NOT DEBUG)
endforeach()
endif()
+list(APPEND NO_STACK_ARRAY_LIST
+ eam/src/physics/cam/phys_grid_ctem.F90
+)
+
+# Remove -Mstack_arrays for this one file to avoid error (likely compiler bug)
+# As we can't remove flag, try adding -Mnostack_arrays https://github.com/E3SM-Project/E3SM/issues/6350
+# Tried with nvidia/22.7 and 23.9 on pm-cpu
+foreach(ITEM IN LISTS NO_STACK_ARRAY_LIST)
+ e3sm_add_flags("${ITEM}" " -Mnostack_arrays")
+endforeach()
+
# Use -O2 for a few files already found to benefit from increased optimization in Intel Depends file
set(PERFOBJS
homme/src/share/prim_advection_base.F90
diff --git a/cime_config/machines/cmake_macros/crayclang-scream_frontier-scream-gpu.cmake b/cime_config/machines/cmake_macros/crayclang-scream_frontier-scream-gpu.cmake
index 8cc85b92cc6a..afcca8f479e5 100644
--- a/cime_config/machines/cmake_macros/crayclang-scream_frontier-scream-gpu.cmake
+++ b/cime_config/machines/cmake_macros/crayclang-scream_frontier-scream-gpu.cmake
@@ -34,5 +34,5 @@ if (COMP_NAME STREQUAL gptl)
endif()
set(PIO_FILESYSTEM_HINTS "lustre")
-string(APPEND KOKKOS_OPTIONS " -DKokkos_ENABLE_HIP=On -DKokkos_ARCH_VEGA90A=On -DCMAKE_CXX_FLAGS='-std=gnu++14'")
+string(APPEND KOKKOS_OPTIONS " -DKokkos_ENABLE_HIP=On -DKokkos_ARCH_VEGA90A=On -DCMAKE_CXX_FLAGS='-std=gnu++14' -DKokkos_ENABLE_OPENMP=OFF")
set(USE_HIP "TRUE")
diff --git a/cime_config/machines/cmake_macros/crayclang_frontier.cmake b/cime_config/machines/cmake_macros/crayclang_frontier.cmake
index 6bda90a4187c..6c8d4164cb28 100644
--- a/cime_config/machines/cmake_macros/crayclang_frontier.cmake
+++ b/cime_config/machines/cmake_macros/crayclang_frontier.cmake
@@ -15,3 +15,6 @@ string(APPEND CMAKE_Fortran_FLAGS " -hipa0 -hzero")
# -em -ef generates modulename.mod (lowercase files) to support
# Scorpio installs
string(APPEND CMAKE_Fortran_FLAGS " -em -ef")
+
+# to support Fortran specific compiler intrinsic functions
+set(E3SM_LINK_WITH_FORTRAN "TRUE")
diff --git a/cime_config/machines/cmake_macros/gnu9.cmake b/cime_config/machines/cmake_macros/gnu9.cmake
deleted file mode 100644
index 02662c7d4c77..000000000000
--- a/cime_config/machines/cmake_macros/gnu9.cmake
+++ /dev/null
@@ -1,34 +0,0 @@
-string(APPEND CMAKE_C_FLAGS " -mcmodel=medium")
-if (compile_threaded)
- string(APPEND CMAKE_C_FLAGS " -fopenmp")
-endif()
-string(APPEND CMAKE_C_FLAGS_DEBUG " -g -Wall -fbacktrace -fcheck=bounds -ffpe-trap=invalid,zero,overflow")
-string(APPEND CMAKE_C_FLAGS_RELEASE " -O")
-if (COMP_NAME STREQUAL csm_share)
- string(APPEND CMAKE_C_FLAGS " -std=c99")
-endif()
-string(APPEND CMAKE_CXX_FLAGS " -std=c++14")
-if (compile_threaded)
- string(APPEND CMAKE_CXX_FLAGS " -fopenmp")
-endif()
-string(APPEND CMAKE_CXX_FLAGS_DEBUG " -g -Wall -fbacktrace")
-string(APPEND CMAKE_CXX_FLAGS_RELEASE " -O")
-string(APPEND CPPDEFS " -DFORTRANUNDERSCORE -DNO_R16 -DCPRGNU")
-string(APPEND CPPDEFS_DEBUG " -DYAKL_DEBUG")
-string(APPEND CMAKE_Fortran_FLAGS " -mcmodel=medium -fconvert=big-endian -ffree-line-length-none -ffixed-line-length-none")
-if (compile_threaded)
- string(APPEND CMAKE_Fortran_FLAGS " -fopenmp")
-endif()
-string(APPEND CMAKE_Fortran_FLAGS_DEBUG " -g -Wall -fbacktrace -fcheck=bounds -ffpe-trap=zero,overflow")
-string(APPEND CMAKE_Fortran_FLAGS_RELEASE " -O")
-string(APPEND CMAKE_Fortran_FORMAT_FIXED_FLAG " -ffixed-form")
-string(APPEND CMAKE_Fortran_FORMAT_FREE_FLAG " -ffree-form")
-if (compile_threaded)
- string(APPEND CMAKE_EXE_LINKER_FLAGS " -fopenmp")
-endif()
-set(MPICC "mpicc")
-set(MPICXX "mpicxx")
-set(MPIFC "mpif90")
-set(SCC "gcc")
-set(SCXX "g++")
-set(SFC "gfortran")
diff --git a/cime_config/machines/cmake_macros/gnu9_mappy.cmake b/cime_config/machines/cmake_macros/gnu9_mappy.cmake
deleted file mode 100644
index 945113b5dc84..000000000000
--- a/cime_config/machines/cmake_macros/gnu9_mappy.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-if (COMP_NAME STREQUAL gptl)
- string(APPEND CPPDEFS " -DHAVE_SLASHPROC")
-endif()
-string(APPEND CMAKE_C_FLAGS_RELEASE " -O2")
-string(APPEND CMAKE_Fortran_FLAGS_RELEASE " -O2")
-if (MPILIB STREQUAL mpi-serial AND NOT compile_threaded)
- set(PFUNIT_PATH "$ENV{SEMS_PFUNIT_ROOT}")
-endif()
diff --git a/cime_config/machines/cmake_macros/gnu_chicoma-gpu.cmake b/cime_config/machines/cmake_macros/gnu_chicoma-gpu.cmake
new file mode 100644
index 000000000000..807c7d0211eb
--- /dev/null
+++ b/cime_config/machines/cmake_macros/gnu_chicoma-gpu.cmake
@@ -0,0 +1,19 @@
+string(APPEND CONFIG_ARGS " --host=cray")
+if (COMP_NAME STREQUAL gptl)
+ string(APPEND CPPDEFS " -DHAVE_NANOTIME -DBIT64 -DHAVE_SLASHPROC -DHAVE_GETTIMEOFDAY")
+endif()
+string(APPEND SLIBS " -lblas -llapack")
+set(CXX_LINKER "FORTRAN")
+if (NOT DEBUG)
+ string(APPEND CFLAGS " -O2 -g")
+endif()
+if (NOT DEBUG)
+ string(APPEND FFLAGS " -O2 -g")
+endif()
+string(APPEND CXX_LIBS " -lstdc++")
+set(MPICC "cc")
+set(MPICXX "CC")
+set(MPIFC "ftn")
+set(SCC "gcc")
+set(SCXX "g++")
+set(SFC "gfortran")
diff --git a/cime_config/machines/cmake_macros/gnu_chrysalis.cmake b/cime_config/machines/cmake_macros/gnu_chrysalis.cmake
index d18626a3ef24..d3f99e211552 100644
--- a/cime_config/machines/cmake_macros/gnu_chrysalis.cmake
+++ b/cime_config/machines/cmake_macros/gnu_chrysalis.cmake
@@ -2,4 +2,3 @@ if (COMP_NAME STREQUAL gptl)
string(APPEND CPPDEFS " -DHAVE_NANOTIME -DBIT64 -DHAVE_SLASHPROC -DHAVE_GETTIMEOFDAY")
endif()
set(PIO_FILESYSTEM_HINTS "gpfs")
-set(MOAB_PATH "/lcrc/soft/climate/moab/chrysalis/gnu")
diff --git a/cime_config/machines/cmake_macros/gnu_improv.cmake b/cime_config/machines/cmake_macros/gnu_improv.cmake
new file mode 100644
index 000000000000..3dd45bc09c10
--- /dev/null
+++ b/cime_config/machines/cmake_macros/gnu_improv.cmake
@@ -0,0 +1,8 @@
+if (COMP_NAME STREQUAL gptl)
+ string(APPEND CPPDEFS " -DHAVE_SLASHPROC")
+endif()
+string(APPEND CMAKE_C_FLAGS_RELEASE " -O2")
+string(APPEND CMAKE_Fortran_FLAGS_RELEASE " -O2")
+set(PIO_FILESYSTEM_HINTS "gpfs")
+string(APPEND SLIBS " /lcrc/group/e3sm/soft/improv/netlib-lapack/3.12.0/gcc-12.3.0/liblapack.a /lcrc/group/e3sm/soft/improv/netlib-lapack/3.12.0/gcc-12.3.0/libblas.a")
+
diff --git a/cime_config/machines/cmake_macros/gnugpu_chicoma-gpu.cmake b/cime_config/machines/cmake_macros/gnugpu_chicoma-gpu.cmake
new file mode 100644
index 000000000000..b696962159cf
--- /dev/null
+++ b/cime_config/machines/cmake_macros/gnugpu_chicoma-gpu.cmake
@@ -0,0 +1,20 @@
+string(APPEND CONFIG_ARGS " --host=cray")
+set(USE_CUDA "TRUE")
+string(APPEND CPPDEFS " -DGPU")
+if (COMP_NAME STREQUAL gptl)
+ string(APPEND CPPDEFS " -DHAVE_NANOTIME -DBIT64 -DHAVE_SLASHPROC -DHAVE_GETTIMEOFDAY")
+endif()
+string(APPEND CPPDEFS " -DTHRUST_IGNORE_CUB_VERSION_CHECK")
+string(APPEND SLIBS " -lblas -llapack")
+string(APPEND CUDA_FLAGS " -ccbin CC -O2 -arch sm_80 --use_fast_math")
+string(APPEND KOKKOS_OPTIONS " -DKokkos_ARCH_AMPERE80=On -DKokkos_ENABLE_CUDA=On -DKokkos_ENABLE_CUDA_LAMBDA=On -DKokkos_ENABLE_SERIAL=ON -DKokkos_ENABLE_OPENMP=Off")
+if (NOT DEBUG)
+ string(APPEND CFLAGS " -O2")
+ string(APPEND FFLAGS " -O2")
+endif()
+set(MPICC "cc")
+set(MPICXX "CC")
+set(MPIFC "ftn")
+set(SCC "cc")
+set(SCXX "CC")
+set(SFC "ftn")
diff --git a/cime_config/machines/cmake_macros/gnugpu_frontier.cmake b/cime_config/machines/cmake_macros/gnugpu_frontier.cmake
index dbbe7ba2b2e9..174f8207d0d0 100644
--- a/cime_config/machines/cmake_macros/gnugpu_frontier.cmake
+++ b/cime_config/machines/cmake_macros/gnugpu_frontier.cmake
@@ -18,7 +18,7 @@ string(APPEND SPIO_CMAKE_OPTS " -DPIO_ENABLE_TOOLS:BOOL=OFF")
set(E3SM_LINK_WITH_FORTRAN "TRUE")
string(APPEND CMAKE_CXX_FLAGS " -I$ENV{MPICH_DIR}/include --offload-arch=gfx90a")
-string(APPEND CMAKE_EXE_LINKER_FLAGS " -L/opt/cray/pe/gcc-libs -lgfortran -L$ENV{MPICH_DIR}/lib -lmpi -L$ENV{CRAY_MPICH_ROOTDIR}/gtl/lib -lmpi_gtl_hsa ")
+string(APPEND CMAKE_EXE_LINKER_FLAGS " -L/opt/cray/pe/gcc/11.2.0/snos/lib64/ -lgfortran -L/opt/rocm-5.4.0/lib -lhsa-runtime64 -L$ENV{MPICH_DIR}/lib -lmpi -L$ENV{CRAY_MPICH_ROOTDIR}/gtl/lib -lmpi_gtl_hsa ")
string(APPEND KOKKOS_OPTIONS " -DKokkos_ENABLE_HIP=On -DKokkos_ARCH_ZEN3=On -DKokkos_ARCH_VEGA90A=On -DKokkos_ENABLE_OPENMP=Off")
diff --git a/cime_config/machines/cmake_macros/intel_chrysalis.cmake b/cime_config/machines/cmake_macros/intel_chrysalis.cmake
index a38fe5226cdc..fa68bc6075df 100644
--- a/cime_config/machines/cmake_macros/intel_chrysalis.cmake
+++ b/cime_config/machines/cmake_macros/intel_chrysalis.cmake
@@ -12,7 +12,6 @@ string(APPEND CMAKE_Fortran_FLAGS " -axCORE-AVX2")
string(APPEND CMAKE_Fortran_FLAGS_RELEASE " -O3 -qno-opt-dynamic-align")
set(PIO_FILESYSTEM_HINTS "gpfs")
string(APPEND CMAKE_EXE_LINKER_FLAGS " -static-intel")
-set(MOAB_PATH "/lcrc/soft/climate/moab/chrysalis/intel")
if (MPILIB STREQUAL impi)
set(MPICC "mpiicc")
set(MPICXX "mpiicpc")
diff --git a/cime_config/machines/cmake_macros/nvidia_chicoma-gpu.cmake b/cime_config/machines/cmake_macros/nvidia_chicoma-gpu.cmake
new file mode 100644
index 000000000000..5c55dc6bb2f4
--- /dev/null
+++ b/cime_config/machines/cmake_macros/nvidia_chicoma-gpu.cmake
@@ -0,0 +1,24 @@
+string(APPEND CONFIG_ARGS " --host=cray")
+if (COMP_NAME STREQUAL gptl)
+ string(APPEND CPPDEFS " -DHAVE_NANOTIME -DBIT64 -DHAVE_SLASHPROC -DHAVE_GETTIMEOFDAY")
+endif()
+string(APPEND SLIBS " -lblas -llapack")
+set(CXX_LINKER "FORTRAN")
+if (NOT DEBUG)
+ string(APPEND CFLAGS " -O2")
+endif()
+if (NOT DEBUG)
+ string(APPEND CXXFLAGS " -O2")
+endif()
+if (NOT DEBUG)
+ string(APPEND FFLAGS " -O2")
+endif()
+if (compile_threaded)
+ string(APPEND KOKKOS_OPTIONS " -DKokkos_ENABLE_OPENMP=Off") # work-around for nvidia as kokkos is not passing "-mp" for threaded build
+endif()
+set(MPICC "cc")
+set(MPICXX "CC")
+set(MPIFC "ftn")
+set(SCC "cc")
+set(SCXX "CC")
+set(SFC "ftn")
diff --git a/cime_config/machines/cmake_macros/nvidiagpu_chicoma-gpu.cmake b/cime_config/machines/cmake_macros/nvidiagpu_chicoma-gpu.cmake
new file mode 100644
index 000000000000..e9606e066060
--- /dev/null
+++ b/cime_config/machines/cmake_macros/nvidiagpu_chicoma-gpu.cmake
@@ -0,0 +1,13 @@
+string(APPEND CONFIG_ARGS " --host=cray")
+set(USE_CUDA "TRUE")
+string(APPEND CPPDEFS " -DGPU")
+if (COMP_NAME STREQUAL gptl)
+ string(APPEND CPPDEFS " -DHAVE_NANOTIME -DBIT64 -DHAVE_SLASHPROC -DHAVE_GETTIMEOFDAY")
+endif()
+string(APPEND CPPDEFS " -DTHRUST_IGNORE_CUB_VERSION_CHECK")
+string(APPEND CUDA_FLAGS " -ccbin CC -O2 -arch sm_80 --use_fast_math")
+string(APPEND SLIBS " -lblas -llapack")
+set(CXX_LINKER "FORTRAN")
+set(SCC "cc")
+set(SCXX "CC")
+set(SFC "ftn")
diff --git a/cime_config/machines/config_batch.xml b/cime_config/machines/config_batch.xml
index 61d2cd364a69..5ba8e38f2e79 100644
--- a/cime_config/machines/config_batch.xml
+++ b/cime_config/machines/config_batch.xml
@@ -291,7 +291,6 @@
--job-name={{ job_id }}
--nodes={{ num_nodes }}
--output={{ job_id }}.%j
- --exclusive
@@ -423,6 +422,16 @@
+
+
+ -l select={{ num_nodes }}:mpiprocs={{ tasks_per_node }}
+
+
+ debug
+ compute
+
+
+
collaboration
@@ -433,17 +442,16 @@
--constraint=gpu
-
- --gpus-per-task=1
-
+ --gpus-per-node=4
--gpu-bind=none
+ --gpus-per-task=1
--gpu-bind=map_gpu:0,1,2,3
- --gpus-per-task=1
+ --gpus-per-node=4
--gpu-bind=none
@@ -475,17 +483,16 @@
--constraint=gpu
-
- --gpus-per-task=1
-
+ --gpus-per-node=4
--gpu-bind=none
+ --gpus-per-task=1
--gpu-bind=map_gpu:0,1,2,3
- --gpus-per-task=1
+ --gpus-per-node=4
--gpu-bind=none
@@ -645,35 +652,40 @@
-
-
- --nodes={{ num_nodes }}
- --ntasks-per-node={{ tasks_per_node }}
- --qos=standard
-
-
- standard
-
-
-
-
-
- --nodes={{ num_nodes }}
- --ntasks-per-node={{ tasks_per_node }}
- --qos=standard
-
-
- standard
-
-
-
--partition=standard
--qos=standard
- standard
+ standard
+
+
+
+
+
+ --partition=gpu
+
+
+ --gpu-bind=none
+
+
+ --gpu-bind=none
+
+
+ --gpu-bind=map_gpu:0,1,2,3
+
+
+ --gpu-bind=none
+
+
+ -G 0
+
+
+ -G 0
+
+
+ gpu
diff --git a/cime_config/machines/config_machines.xml b/cime_config/machines/config_machines.xml
index f3aa5cfa6149..f13901830891 100644
--- a/cime_config/machines/config_machines.xml
+++ b/cime_config/machines/config_machines.xml
@@ -206,6 +206,7 @@
aocc
cudatoolkit
climate-utils
+ matlab
craype-accel-nvidia80
craype-accel-host
perftools-base
@@ -263,8 +264,6 @@
/global/cfs/cdirs/e3sm/perl/lib/perl5-only-switch
software
MPI_Bcast
- $SHELL{if [ -z "$Albany_ROOT" ]; then echo /global/common/software/e3sm/mali_tpls/albany-e3sm-serial-release-gcc; else echo "$Albany_ROOT"; fi}
- $SHELL{if [ -z "$Trilinos_ROOT" ]; then echo /global/common/software/e3sm/mali_tpls/trilinos-e3sm-serial-release-gcc; else echo "$Trilinos_ROOT"; fi}
$ENV{CRAY_NETCDF_HDF5PARALLEL_PREFIX}
$ENV{CRAY_PARALLEL_NETCDF_PREFIX}
4000MB
@@ -275,6 +274,9 @@
$SHELL{if [ -z "$ADIOS2_ROOT" ]; then echo /global/cfs/cdirs/e3sm/3rdparty/adios2/2.9.1/cray-mpich-8.1.25/gcc-11.2.0; else echo "$ADIOS2_ROOT"; fi}
Generic
+ $SHELL{if [ -z "$Albany_ROOT" ]; then echo /global/common/software/e3sm/mali_tpls/albany-e3sm-serial-release-gcc-cmake-fix; else echo "$Albany_ROOT"; fi}
+ $SHELL{if [ -z "$Trilinos_ROOT" ]; then echo /global/common/software/e3sm/mali_tpls/trilinos-e3sm-serial-release-gcc; else echo "$Trilinos_ROOT"; fi}
+ $SHELL{if [ -z "$Kokkos_ROOT" ]; then echo /global/common/software/e3sm/mali_tpls/trilinos-e3sm-serial-release-gcc; else echo "$Kokkos_ROOT"; fi}
$SHELL{if [ -z "$ADIOS2_ROOT" ]; then echo /global/cfs/cdirs/e3sm/3rdparty/adios2/2.9.1/cray-mpich-8.1.25/nvidia-22.7; else echo "$ADIOS2_ROOT"; fi}
@@ -290,6 +292,12 @@
$SHELL{if [ -z "$ADIOS2_ROOT" ]; then echo /global/cfs/cdirs/e3sm/3rdparty/adios2/2.9.1/cray-mpich-8.1.25/aocc-4.0.0; else echo "$ADIOS2_ROOT"; fi}
+
+ $SHELL{if [ -z "$MOAB_ROOT" ]; then echo /global/cfs/cdirs/e3sm/software/moab/intel; else echo "$MOAB_ROOT"; fi}
+
+
+ $SHELL{if [ -z "$MOAB_ROOT" ]; then echo /global/cfs/cdirs/e3sm/software/moab/gnu; else echo "$MOAB_ROOT"; fi}
+
-1
@@ -361,6 +369,7 @@
aocc
cudatoolkit
climate-utils
+ matlab
craype-accel-nvidia80
craype-accel-host
perftools-base
@@ -504,6 +513,7 @@
aocc
cudatoolkit
climate-utils
+ matlab
craype-accel-nvidia80
craype-accel-host
perftools-base
@@ -666,6 +676,7 @@
aocc
cudatoolkit
climate-utils
+ matlab
craype-accel-nvidia80
craype-accel-host
perftools-base
@@ -817,6 +828,7 @@
aocc
cudatoolkit
climate-utils
+ matlab
craype-accel-nvidia80
craype-accel-host
perftools-base
@@ -1773,7 +1785,7 @@
mappy
LINUX
proxy.sandia.gov:80
- gnu,gnu9,intel
+ gnu
openmpi
/sems-data-store/ACME/mappy/timings
.*
@@ -1812,21 +1824,12 @@
acme-cmake/3.26.3
- acme-gcc/8.1.0
-
-
- sems-archive-gcc/9.2.0
-
-
- sems-archive-intel/19.0.5
+ acme-gcc/11.2.0
-
+
acme-netcdf/4.4.1/exo_acme
acme-pfunit/3.2.8/base
-
- sems-archive-netcdf/4.7.3/base
-
acme-openmpi/4.1.4
acme-netcdf/4.7.4/acme
@@ -1843,6 +1846,7 @@
spread
threads
Generic
+ 4000MB
@@ -2066,7 +2070,7 @@
ANL CELS General Computing Environment (Linux) workstation (Ubuntu 22.04)
- compute-386-01|compute-386-02
+ compute-386-(01|02|03|05|07|08)|compute-240-(15)
LINUX
gnu
mpich,openmpi
@@ -2127,6 +2131,7 @@
/nfs/gce/projects/climate/software/linux-ubuntu22.04-x86_64/hdf5/1.12.2/mpich-4.1.2/gcc-12.1.0
/nfs/gce/projects/climate/software/linux-ubuntu22.04-x86_64/netcdf/4.8.0c-4.3.1cxx-4.5.3f-parallel/mpich-4.1.2/gcc-12.1.0
/nfs/gce/projects/climate/software/linux-ubuntu22.04-x86_64/pnetcdf/1.12.3/mpich-4.1.2/gcc-12.1.0
+ $SHELL{if [ -z "$MOAB_ROOT" ]; then echo /nfs/gce/projects/climate/software/moab/devel/mpich-4.1.2/gcc-12.1.0; else echo "$MOAB_ROOT"; fi}
@@ -2136,6 +2141,7 @@
/nfs/gce/projects/climate/software/linux-ubuntu22.04-x86_64/hdf5/1.12.2/openmpi-4.1.6/gcc-12.1.0
/nfs/gce/projects/climate/software/linux-ubuntu22.04-x86_64/netcdf/4.8.0c-4.3.1cxx-4.5.3f-parallel/openmpi-4.1.6/gcc-12.1.0
/nfs/gce/projects/climate/software/linux-ubuntu22.04-x86_64/pnetcdf/1.12.3/openmpi-4.1.6/gcc-12.1.0
+ $SHELL{if [ -z "$MOAB_ROOT" ]; then echo /nfs/gce/projects/climate/software/moab/devel/openmpi-4.1.6/gcc-12.1.0; else echo "$MOAB_ROOT"; fi}
64M
@@ -2218,7 +2224,6 @@
/nfs/gce/projects/climate/software/linux-ubuntu20.04-x86_64/netcdf/4.8.0c-4.3.1cxx-4.5.3f-parallel/mpich-4.0/gcc-11.1.0
/nfs/gce/projects/climate/software/linux-ubuntu20.04-x86_64/pnetcdf/1.12.2/mpich-4.0/gcc-11.1.0
$SHELL{if [ -z "$MOAB_ROOT" ]; then echo /nfs/gce/projects/climate/software/moab/devel/mpich-4.0/gcc-11.1.0; else echo "$MOAB_ROOT"; fi}
- /nfs/gce/projects/climate/software/moab/devel/mpich-4.0/gcc-11.1.0
@@ -2565,12 +2570,12 @@
intel-mkl/2020.4.304-g2qaxzf
- openmpi/4.1.3-pin4k7o
- hdf5/1.10.7-eewgp6v
- netcdf-c/4.4.1-ihoo4zq
- netcdf-cxx/4.2-soitsxm
- netcdf-fortran/4.4.4-tplolxh
- parallel-netcdf/1.11.0-gvcfihh
+ openmpi/4.1.6-2mm63n2
+ hdf5/1.10.7-4cghwvq
+ netcdf-c/4.4.1-a4hji6e
+ netcdf-cxx/4.2-ldoxr43
+ netcdf-fortran/4.4.4-husened
+ parallel-netcdf/1.11.0-icrpxty
intel-mpi/2019.9.304-tkzvizk
@@ -2616,12 +2621,14 @@
$CIME_OUTPUT_ROOT/$CASE/bld
0.05
0.05
- 1000
+ 0
/lcrc/group/e3sm/soft/perl/chrys/lib/perl5
$SHELL{dirname $(dirname $(which nc-config))}
$SHELL{dirname $(dirname $(which nf-config))}
$SHELL{dirname $(dirname $(which pnetcdf_version))}
+ ^lockedfile,individual
+ ^xpmem
128M
@@ -2641,6 +2648,11 @@
$SHELL{if [ -z "$MOAB_ROOT" ]; then echo /lcrc/soft/climate/moab/chrysalis/gnu; else echo "$MOAB_ROOT"; fi}
+
+ $SHELL{if [ -z "$Albany_ROOT" ]; then echo /lcrc/group/e3sm/ac.jwatkins/LandIce/AlbanyBuilds/build-gcc-sfad12-e3sm/install; else echo "$Albany_ROOT"; fi}
+ $SHELL{if [ -z "$Trilinos_ROOT" ]; then echo /lcrc/group/e3sm/ac.jwatkins/LandIce/TrilinosBuilds/build-gcc-e3sm/install; else echo "$Trilinos_ROOT"; fi}
+ $SHELL{if [ -z "$Kokkos_ROOT" ]; then echo /lcrc/group/e3sm/ac.jwatkins/LandIce/TrilinosBuilds/build-gcc-e3sm/install; else echo "$Kokkos_ROOT"; fi}
+
@@ -2698,7 +2710,7 @@
$CIME_OUTPUT_ROOT/$CASE/run
$CIME_OUTPUT_ROOT/$CASE/bld
0.1
- 1000
+ 0
$SHELL{dirname $(dirname $(which nc-config))}
$SHELL{dirname $(dirname $(which nf-config))}
@@ -2777,7 +2789,7 @@
$CIME_OUTPUT_ROOT/$CASE/run
$CIME_OUTPUT_ROOT/$CASE/bld
0.1
- 1000
+ 0
$SHELL{dirname $(dirname $(which nc-config))}
$SHELL{dirname $(dirname $(which nf-config))}
@@ -2897,80 +2909,65 @@
-
- LLNL Linux Cluster, Linux, 4 V100 GPUs/node, 44 IBM P9 cpu cores/node
- lassen.*
+
+ ANL LCRC cluster 825-node AMD 7713 2-sockets 128-cores per node
+ ilogin(1|2|3|4).lcrc.anl.gov
LINUX
- gnugpu
- spectrum-mpi
- cbronze
- /usr/workspace/$USER/e3sm_scratch
- /usr/gdata/climdat/ccsm3data/inputdata
- /usr/gdata/climdat/ccsm3data/inputdata/atm/datm7
- /usr/workspace/$USER/archive/$CASE
- /usr/gdata/climdat/baselines/$COMPILER
- 16
- lsf
- donahue5 -at- llnl.gov
- 40
- 40
-
-
-
-
- jsrun
+ gnu
+ openmpi
+ e3sm
+ /lcrc/group/e3sm/$USER/scratch/improv
+ /lcrc/group/e3sm/data/inputdata
+ /lcrc/group/e3sm/data/inputdata/atm/datm7
+ /lcrc/group/e3sm/$USER/scratch/improv/archive/$CASE
+ /lcrc/group/e3sm/baselines/improv/$COMPILER
+ /lcrc/group/e3sm/tools/cprnc/cprnc.improv
+ 8
+ e3sm_integration
+ 8
+ pbspro
+ E3SM
+ 128
+ 128
+ FALSE
+
+ mpirun
- -X 1
- $SHELL{if [ {{ total_tasks }} -eq 1 ];then echo --nrs 1 --rs_per_host 1;else echo --nrs $NUM_RS --rs_per_host $RS_PER_NODE;fi}
- --tasks_per_rs $SHELL{echo "({{ tasks_per_node }} + $RS_PER_NODE - 1)/$RS_PER_NODE"|bc}
- -d plane:$SHELL{echo "({{ tasks_per_node }} + $RS_PER_NODE - 1)/$RS_PER_NODE"|bc}
- --cpu_per_rs $ENV{CPU_PER_RS}
- --gpu_per_rs $ENV{GPU_PER_RS}
- --bind packed:smt:$ENV{OMP_NUM_THREADS}
- --latency_priority $ENV{LTC_PRT}
- --stdio_mode prepended
- $ENV{JSRUN_THREAD_VARS}
- $ENV{SMPIARGS}
+ --tag-output -n {{ total_tasks }}
+ --map-by ppr:1:core:PE=$ENV{OMP_NUM_THREADS} --bind-to core --oversubscribe
- /usr/share/lmod/lmod/init/env_modules_python.py
- /usr/share/lmod/lmod/init/perl
- /usr/share/lmod/lmod/init/sh
- /usr/share/lmod/lmod/init/csh
- module
+ /gpfs/fs1/soft/chrysalis/spack/opt/spack/linux-centos8-x86_64/gcc-9.3.0/lmod-8.3-5be73rg/lmod/lmod/init/sh
+ /gpfs/fs1/soft/chrysalis/spack/opt/spack/linux-centos8-x86_64/gcc-9.3.0/lmod-8.3-5be73rg/lmod/lmod/init/csh
+ /gpfs/fs1/soft/chrysalis/spack/opt/spack/linux-centos8-x86_64/gcc-9.3.0/lmod-8.3-5be73rg/lmod/lmod/init/env_modules_python.py
+ /gpfs/fs1/soft/chrysalis/spack/opt/spack/linux-centos8-x86_64/gcc-9.3.0/lmod-8.3-5be73rg/lmod/lmod/libexec/lmod python
module
- /usr/share/lmod/lmod/libexec/lmod python
- /usr/share/lmod/lmod/libexec/lmod perl
-
-
- git
- gcc/8.3.1
- cuda/11.8.0
- cmake/3.16.8
- spectrum-mpi
- python/3.7.2
+ module
+
+
+ cmake/3.27.4
+
+
+ gcc/12.3.0
- /p/gpfs1/$USER/e3sm_scratch/$CASE/run
+ $CIME_OUTPUT_ROOT/$CASE/run
$CIME_OUTPUT_ROOT/$CASE/bld
-
-
+ 0.05
+ 0
+
+ /lcrc/group/e3sm/soft/improv/netcdf-c/4.9.2b/gcc-12.3.0/openmpi-4.1.6
+ /lcrc/group/e3sm/soft/improv/netcdf-fortran/4.6.1b/gcc-12.3.0/openmpi-4.1.6
+ /lcrc/group/e3sm/soft/improv/pnetcdf/1.12.3/gcc-12.3.0/openmpi-4.1.6
+ /lcrc/group/e3sm/soft/improv/pnetcdf/1.12.3/gcc-12.3.0/openmpi-4.1.6/bin:/lcrc/group/e3sm/soft/improv/netcdf-fortran/4.6.1b/gcc-12.3.0/openmpi-4.1.6/bin:/lcrc/group/e3sm/soft/improv/netcdf-c/4.9.2b/gcc-12.3.0/openmpi-4.1.6/bin:/lcrc/group/e3sm/soft/improv/openmpi/4.1.6/gcc-12.3.0/bin:/lcrc/group/e3sm/soft/perl/improv/bin:$ENV{PATH}
+ $SHELL{lp=/lcrc/group/e3sm/soft/improv/netlib-lapack/3.12.0/gcc-12.3.0:/lcrc/group/e3sm/soft/improv/pnetcdf/1.12.3/gcc-12.3.0/openmpi-4.1.6/lib:/lcrc/group/e3sm/soft/improv/netcdf-fortran/4.6.1b/gcc-12.3.0/openmpi-4.1.6/lib:/lcrc/group/e3sm/soft/improv/netcdf-c/4.9.2b/gcc-12.3.0/openmpi-4.1.6/lib:/opt/pbs/lib:/lcrc/group/e3sm/soft/improv/openmpi/4.1.6/gcc-12.3.0/lib; if [ -z "$LD_LIBRARY_PATH" ]; then echo $lp; else echo "$lp:$LD_LIBRARY_PATH"; fi}
- -E OMP_NUM_THREADS=$ENV{OMP_NUM_THREADS} -E OMP_PROC_BIND=spread -E OMP_PLACES=threads -E OMP_STACKSIZE=256M
+ 128M
-
- y
- /usr/gdata/climdat/netcdf/bin:$ENV{PATH}
- /usr/gdata/climdat/netcdf/lib:$ENV{LD_LIBRARY_PATH}
- /usr/gdata/climdat/netcdf
- 2
- 20
- 2
- gpu-cpu
- $SHELL{echo "2*((`./xmlquery --value TOTAL_TASKS` + `./xmlquery --value TASKS_PER_NODE` - 1)/`./xmlquery --value TASKS_PER_NODE`)"|bc}
- --smpiargs="-gpu"
+
+ cores
@@ -2981,11 +2978,11 @@
mpich
cbronze
/p/lustre2/$USER/e3sm_scratch/ruby
- /usr/gdata/climdat/ccsm3data/inputdata
- /usr/gdata/climdat/ccsm3data/inputdata/atm/datm7
+ /usr/gdata/e3sm/ccsm3data/inputdata
+ /usr/gdata/e3sm/ccsm3data/inputdata/atm/datm7
/p/lustre2/$USER/archive/$CASE
/p/lustre2/$USER/ccsm_baselines/$COMPILER
- /usr/gdata/climdat/tools/cprnc
+ /usr/gdata/e3sm/tools/cprnc
8
lc_slurm
donahue5 -at- llnl.gov
@@ -3013,18 +3010,19 @@
intel-classic/2021.6.0-magic
mvapich2/2.3.7
cmake/3.19.2
- /usr/gdata/climdat/install/quartz/modulefiles
+ /usr/gdata/e3sm/install/quartz/modulefiles
hdf5/1.12.2
netcdf-c/4.9.0
netcdf-fortran/4.6.0
parallel-netcdf/1.12.3
screamML-venv/0.0.1
+ subversion
$CIME_OUTPUT_ROOT/$CASE/run
$CIME_OUTPUT_ROOT/$CASE/bld
- /usr/gdata/climdat/install/quartz/netcdf-fortran/
+ /usr/gdata/e3sm/install/quartz/netcdf-fortran/
/usr/tce/packages/parallel-netcdf/parallel-netcdf-1.12.3-mvapich2-2.3.7-intel-classic-2021.6.0
@@ -3036,11 +3034,11 @@
mpich
cbronze
/p/lustre2/$USER/e3sm_scratch/quartz
- /usr/gdata/climdat/ccsm3data/inputdata
- /usr/gdata/climdat/ccsm3data/inputdata/atm/datm7
+ /usr/gdata/e3sm/ccsm3data/inputdata
+ /usr/gdata/e3sm/ccsm3data/inputdata/atm/datm7
/p/lustre2/$USER/archive/$CASE
/p/lustre2/$USER/ccsm_baselines/$COMPILER
- /usr/gdata/climdat/tools/cprnc
+ /usr/gdata/e3sm/tools/cprnc
8
lc_slurm
donahue5 -at- llnl.gov
@@ -3068,18 +3066,19 @@
intel-classic/2021.6.0-magic
mvapich2/2.3.7
cmake/3.19.2
- /usr/gdata/climdat/install/quartz/modulefiles
+ /usr/gdata/e3sm/install/quartz/modulefiles
hdf5/1.12.2
netcdf-c/4.9.0
netcdf-fortran/4.6.0
parallel-netcdf/1.12.3
screamML-venv/0.0.1
+ subversion
$CIME_OUTPUT_ROOT/$CASE/run
$CIME_OUTPUT_ROOT/$CASE/bld
- /usr/gdata/climdat/install/quartz/netcdf-fortran/
+ /usr/gdata/e3sm/install/quartz/netcdf-fortran/
/usr/tce/packages/parallel-netcdf/parallel-netcdf-1.12.3-mvapich2-2.3.7-intel-classic-2021.6.0
@@ -4213,181 +4212,153 @@
-
- LANL Linux Cluster, 36 pes/node, batch system slurm
- gr-fe.*.lanl.gov
- LINUX
- intel,gnu
- openmpi,impi,mvapich
- climateacme
- /lustre/scratch4/turquoise/$ENV{USER}/E3SM/scratch
- /lustre/scratch4/turquoise/$ENV{USER}/E3SM/input_data
- /lustre/scratch4/turquoise/$ENV{USER}/E3SM/input_data/atm/datm7
- /lustre/scratch4/turquoise/$ENV{USER}/E3SM/archive/$CASE
- /lustre/scratch4/turquoise/$ENV{USER}/E3SM/input_data/ccsm_baselines/$COMPILER
- /turquoise/usr/projects/climate/SHARED_CLIMATE/software/wolf/cprnc/v0.40/cprnc
- 4
- e3sm_developer
- slurm
- luke.vanroekel @ gmail.com
- 36
- 32
- TRUE
-
- srun
-
- -n {{ total_tasks }}
-
-
-
-
-
-
- /usr/share/Modules/init/perl.pm
- /usr/share/Modules/init/python.py
- /etc/profile.d/z00_lmod.sh
- /etc/profile.d/z00_lmod.csh
- /usr/share/lmod/lmod/libexec/lmod perl
- /usr/share/lmod/lmod/libexec/lmod python
- module
- module
-
-
- cmake/3.16.2
-
-
- gcc/6.4.0
- openmpi/2.1.2
-
-
- gcc/6.4.0
- mvapich2/2.3
-
-
- intel/19.0.4
- intel-mpi/2019.4
-
-
- intel/18.0.2
- mvapich2/2.2
-
-
- intel/19.0.4
- openmpi/2.1.2
-
-
- friendly-testing
- hdf5-parallel/1.8.16
- pnetcdf/1.11.2
- netcdf-h5parallel/4.7.3
- mkl/2019.0.4
-
-
- $CIME_OUTPUT_ROOT/$CASE/run
- $CIME_OUTPUT_ROOT/$CASE/bld
-
- $ENV{MKLROOT}
- romio_ds_write=disable;romio_ds_read=disable;romio_cb_write=enable;romio_cb_read=enable
-
-
-
-
- LANL Linux Cluster, 36 pes/node, batch system slurm
- ba-fe.*.lanl.gov
- LINUX
- intel,gnu
- openmpi,impi,mvapich
- climateacme
- /lustre/scratch4/turquoise/$ENV{USER}/E3SM/scratch
- /lustre/scratch4/turquoise/$ENV{USER}/E3SM/input_data
- /lustre/scratch4/turquoise/$ENV{USER}/E3SM/input_data/atm/datm7
- /lustre/scratch4/turquoise/$ENV{USER}/E3SM/archive/$CASE
- /lustre/scratch4/turquoise/$ENV{USER}/E3SM/input_data/ccsm_baselines/$COMPILER
- /turquoise/usr/projects/climate/SHARED_CLIMATE/software/wolf/cprnc/v0.40/cprnc
- 4
+
+ Chicoma CPU-only nodes at LANL IC. Each node has 2 AMD EPYC 7H12 64-Core (Milan) 512GB
+ ch-fe*
+ Linux
+ gnu,intel,nvidia,amdclang
+ mpich
+ /lustre/scratch5/$ENV{USER}/E3SM/scratch/chicoma-cpu
+ /usr/projects/e3sm/inputdata
+ /usr/projects/e3sm/inputdata/atm/datm7
+ /lustre/scratch5/$ENV{USER}/E3SM/archive/$CASE
+ /lustre/scratch5/$ENV{USER}/E3SM/input_data/ccsm_baselines/$COMPILER
+ /usr/projects/climate/SHARED_CLIMATE/software/badger/cprnc
+ 10
e3sm_developer
+ 4
slurm
e3sm
- 36
- 32
+ 256
+ 128
TRUE
srun
- -n {{ total_tasks }}
-
-
-
-
+ --label
+ -n {{ total_tasks }} -N {{ num_nodes }}
+ -c $SHELL{echo 256/`./xmlquery --value MAX_MPITASKS_PER_NODE`|bc}
+ $SHELL{if [ 128 -ge `./xmlquery --value MAX_MPITASKS_PER_NODE` ]; then echo "--cpu_bind=cores"; else echo "--cpu_bind=threads";fi;}
+ -m plane=$SHELL{echo `./xmlquery --value MAX_MPITASKS_PER_NODE`}
+
-
- /usr/share/Modules/init/perl.pm
- /usr/share/Modules/init/python.py
- /etc/profile.d/z00_lmod.sh
- /etc/profile.d/z00_lmod.csh
+
+ /usr/share/lmod/8.3.1/init/perl
+
+ /usr/share/lmod/8.3.1/init/python
+ /usr/share/lmod/8.3.1/init/sh
+ /usr/share/lmod/8.3.1/init/csh
/usr/share/lmod/lmod/libexec/lmod perl
/usr/share/lmod/lmod/libexec/lmod python
module
module
+
-
- cmake/3.16.2
-
-
- gcc/6.4.0
- openmpi/2.1.2
+ cray-hdf5-parallel
+ cray-netcdf-hdf5parallel
+ cray-parallel-netcdf
+ cray-netcdf
+ cray-hdf5
+ PrgEnv-gnu
+ PrgEnv-intel
+ PrgEnv-nvidia
+ PrgEnv-cray
+ PrgEnv-aocc
+ intel
+ intel-oneapi
+ nvidia
+ aocc
+ cudatoolkit
+ climate-utils
+ craype-accel-nvidia80
+ craype-accel-host
+ perftools-base
+ perftools
+ darshan
-
- gcc/6.4.0
- mvapich2/2.3
+
+
+ PrgEnv-gnu/8.4.0
+ gcc/12.2.0
+ cray-libsci/23.05.1.4
-
- intel/19.0.4
- intel-mpi/2019.4
+
+
+ PrgEnv-nvidia/8.4.0
+ nvidia/22.7
+ cray-libsci/23.05.1.4
-
- intel/18.0.2
- mvapich2/2.2
+
+
+ PrgEnv-intel/8.4.0
+ intel-classic/2023.2.0
-
- intel/19.0.4
- openmpi/2.1.2
+
+
+ PrgEnv-aocc/8.4.0
+ aocc/3.2.0
+ cray-libsci/23.05.1.4
+
- friendly-testing
- hdf5-parallel/1.8.16
- pnetcdf/1.11.2
- netcdf-h5parallel/4.7.3
- mkl/2019.0.4
+ craype-accel-host
+ craype/2.7.21
+ cray-mpich/8.1.26
+ libfabric/1.15.2.0
+ cray-hdf5-parallel/1.12.2.3
+ cray-netcdf-hdf5parallel/4.9.0.3
+ cray-parallel-netcdf/1.12.3.3
+ cmake/3.25.1
+
$CIME_OUTPUT_ROOT/$CASE/run
$CIME_OUTPUT_ROOT/$CASE/bld
+ 0.1
+
- $ENV{MKLROOT}
+ 1
+ 1
+ 128M
+ spread
+ threads
+ FALSE
+ /usr/projects/climate/SHARED_CLIMATE/software/chicoma-cpu/perl5-only-switch/lib/perl5
romio_ds_write=disable;romio_ds_read=disable;romio_cb_write=enable;romio_cb_read=enable
+ software
+ MPI_Bcast
+ $ENV{CRAY_NETCDF_HDF5PARALLEL_PREFIX}
+ $ENV{CRAY_PARALLEL_NETCDF_PREFIX}
+
+ -1
+
-
- Chicoma CPU-only nodes at LANL IC. Each node has 2 AMD EPYC 7H12 64-Core (Milan) 512GB
+
+ Chicoma GPU nodes at LANL IC. Each GPU node has single
+AMD EPYC 7713 64-Core (Milan) (256GB) and 4 nvidia A100'
ch-fe*
Linux
- gnu,nvidia,intel,aocc,amdclang
+ gnugpu,gnu,nvidiagpu,nvidia
mpich
- /lustre/scratch4/turquoise/$ENV{USER}/E3SM/scratch/chicoma-cpu
+ /lustre/scratch5/$ENV{USER}/E3SM/scratch/chicoma-gpu
/usr/projects/e3sm/inputdata
/usr/projects/e3sm/inputdata/atm/datm7
- /lustre/scratch4/turquoise/$ENV{USER}/E3SM/archive/$CASE
- /lustre/scratch4/turquoise/$ENV{USER}/E3SM/input_data/ccsm_baselines/$COMPILER
+ /lustre/scratch5/$ENV{USER}/E3SM/archive/$CASE
+ /lustre/scratch5/$ENV{USER}/E3SM/input_data/ccsm_baselines/$COMPILER
/usr/projects/climate/SHARED_CLIMATE/software/badger/cprnc
10
e3sm_developer
4
slurm
e3sm
- 256
- 64
+ 128
+ 256
+ 256
+ 4
+ 64
+ 64
TRUE
srun
@@ -4395,7 +4366,7 @@
--label
-n {{ total_tasks }} -N {{ num_nodes }}
-c $ENV{OMP_NUM_THREADS}
- $SHELL{if [ 128 -ge `./xmlquery --value MAX_MPITASKS_PER_NODE` ]; then echo "--cpu_bind=cores"; else echo "--cpu_bind=threads";fi;}
+ $SHELL{if [ 128 -ge `./xmlquery --value MAX_MPITASKS_PER_NODE` ]; then echo "--cpu_bind=cores"; else echo "--cpu_bind=threads";fi;}
-m plane=$SHELL{echo `./xmlquery --value MAX_MPITASKS_PER_NODE`}
@@ -4414,50 +4385,64 @@
cray-hdf5-parallel
cray-netcdf-hdf5parallel
cray-parallel-netcdf
+ cray-netcdf
+ cray-hdf5
PrgEnv-gnu
+ PrgEnv-intel
PrgEnv-nvidia
PrgEnv-cray
PrgEnv-aocc
+ intel
+ intel-oneapi
+ nvidia
+ aocc
+ cudatoolkit
+ climate-utils
craype-accel-nvidia80
craype-accel-host
- cce
+ perftools-base
+ perftools
+ darshan
-
+
PrgEnv-gnu/8.4.0
- gcc/12.2.0
+ gcc/11.2.0
-
+
PrgEnv-nvidia/8.4.0
nvidia/22.7
-
- PrgEnv-intel/8.4.0
- intel-classic/2023.2.0
+
+ cudatoolkit/22.7_11.7
+ craype-accel-nvidia80
-
- PrgEnv-aocc/8.4.0
- aocc/3.2.0
+
+ cudatoolkit/22.7_11.7
+ craype-accel-nvidia80
+ gcc-mixed/11.2.0
-
- PrgEnv-aocc/8.4.0
- aocc/3.2.0
+
+ craype-accel-host
-
+
craype-accel-host
- cray-libsci
- craype
+
+
+
+ cray-libsci/23.05.1.4
+ craype/2.7.21
cray-mpich/8.1.26
libfabric/1.15.2.0
cray-hdf5-parallel/1.12.2.3
cray-netcdf-hdf5parallel/4.9.0.3
cray-parallel-netcdf/1.12.3.3
- cmake/3.22.3
+ cmake/3.25.1
@@ -4478,6 +4463,7 @@
MPI_Bcast
$ENV{CRAY_NETCDF_HDF5PARALLEL_PREFIX}
$ENV{CRAY_PARALLEL_NETCDF_PREFIX}
+ /usr/projects/e3sm/cudatoolkit:$ENV{PKG_CONFIG_PATH}
-1
@@ -4828,12 +4814,12 @@
cli115
/gpfs/alpine/proj-shared/cli115
.*
- /gpfs/alpine/$PROJECT/proj-shared/$ENV{USER}/e3sm_scratch
- /gpfs/alpine/cli115/world-shared/e3sm/inputdata
- /gpfs/alpine/cli115/world-shared/e3sm/inputdata/atm/datm7
+ /gpfs/alpine2/$PROJECT/proj-shared/$ENV{USER}/e3sm_scratch
+ /gpfs/alpine2/atm146/world-shared/e3sm/inputdata
+ /gpfs/alpine2/atm146/world-shared/e3sm/inputdata/atm/datm7
/gpfs/alpine/$PROJECT/proj-shared/$ENV{USER}/archive/$CASE
- /gpfs/alpine/cli115/world-shared/e3sm/baselines/$COMPILER
- /gpfs/alpine/cli115/world-shared/e3sm/tools/cprnc.summit/cprnc
+ /gpfs/alpine2/atm146/world-shared/e3sm/baselines/$COMPILER
+ /gpfs/alpine2/atm146/world-shared/e3sm/tools/cprnc.summit/cprnc
8
e3sm_developer
4
@@ -4843,7 +4829,7 @@
18
42
42
-
+
84
18
@@ -4877,7 +4863,7 @@
module
- DefApps
+ DefApps-2023
python/3.7-anaconda3
subversion/1.14.0
git/2.31.1
@@ -4925,6 +4911,7 @@
$ENV{OLCF_PARALLEL_NETCDF_ROOT}
0
+ True
@@ -4988,15 +4975,6 @@
mlx5_3:1,mlx5_0:1
mlx5_0:1,mlx5_3:1
-
- $SHELL{if [ -z "$ADIOS2_ROOT" ]; then echo /gpfs/alpine/cli115/world-shared/3rdparty/adios2/2.9.1/spectrum-mpi-10.4.0.3/xl-16.1.1-10; else echo "$ADIOS2_ROOT"; fi}
-
-
- $SHELL{if [ -z "$ADIOS2_ROOT" ]; then echo /gpfs/alpine/cli115/world-shared/3rdparty/adios2/2.9.1/spectrum-mpi-10.4.0.3/nvhpc-21.11; else echo "$ADIOS2_ROOT"; fi}
-
-
- $SHELL{if [ -z "$ADIOS2_ROOT" ]; then echo /gpfs/alpine/cli115/world-shared/3rdparty/adios2/2.9.1/spectrum-mpi-10.4.0.3/gcc-9.1.0; else echo "$ADIOS2_ROOT"; fi}
-
diff --git a/cime_config/machines/config_pio.xml b/cime_config/machines/config_pio.xml
index e1784b1618d1..742e82bd7ef7 100644
--- a/cime_config/machines/config_pio.xml
+++ b/cime_config/machines/config_pio.xml
@@ -63,9 +63,8 @@
netcdf
netcdf
netcdf
- netcdf
- netcdf
netcdf
+ netcdf
netcdf
netcdf
diff --git a/cime_config/testmods_dirs/allactive/nlmaps/shell_commands b/cime_config/testmods_dirs/allactive/nlmaps/shell_commands
index 1d90d0938a66..637b4f3099b6 100644
--- a/cime_config/testmods_dirs/allactive/nlmaps/shell_commands
+++ b/cime_config/testmods_dirs/allactive/nlmaps/shell_commands
@@ -1,19 +1,15 @@
alg=trfvnp2
-# This line is separate from the nonlinear maps. It corrects an oversight in the
-# existing default trigrid grid configuration.
-./xmlchange ATM2ROF_SMAPNAME=cpl/gridmaps/ne30pg2/map_ne30pg2_to_r05_bilin.200220.nc
-
# We want these in v3.
a2l=cpl/gridmaps/ne30pg2/map_ne30pg2_to_r05_trfvnp2.230516.nc
-a2o=cpl/gridmaps/ne30pg2/map_ne30pg2_to_EC30to60E2r2_trfvnp2.230516.nc
+a2o=cpl/gridmaps/ne30pg2/map_ne30pg2_to_IcoswISC30E3r5_trfvnp2.20231121.nc
./xmlchange ATM2LND_FMAPNAME_NONLINEAR=$a2l
./xmlchange ATM2ROF_FMAPNAME_NONLINEAR=$a2l
./xmlchange ATM2OCN_FMAPNAME_NONLINEAR=$a2o
-# These surface->atm maps are not needed, but we want to test the capability.
+# These surface->atm maps are not needed in v3, but we want to test the capability.
l2a=cpl/gridmaps/ne30pg2/map_r05_to_ne30pg2_${alg}.230516.nc
-o2a=cpl/gridmaps/EC30to60E2r2/map_EC30to60E2r2_to_ne30pg2_trfvnp2.230516.nc
+o2a=cpl/gridmaps/IcoswISC30E3r5/map_IcoswISC30E3r5_to_ne30pg2_trfv2.20240222.nc
./xmlchange LND2ATM_FMAPNAME_NONLINEAR=$l2a
./xmlchange LND2ATM_SMAPNAME_NONLINEAR=$l2a
./xmlchange OCN2ATM_FMAPNAME_NONLINEAR=$o2a
diff --git a/cime_config/testmods_dirs/allactive/wcprod/README b/cime_config/testmods_dirs/allactive/wcprod/README
index 020bbf93e9f2..329e3e6ea7ab 100644
--- a/cime_config/testmods_dirs/allactive/wcprod/README
+++ b/cime_config/testmods_dirs/allactive/wcprod/README
@@ -3,4 +3,3 @@ water cycle production sims
Run these for at least 1 day to see all output.
Also use the CMIP6 compsets.
-If running longer, change the nhtfrq for the first history file.
diff --git a/cime_config/testmods_dirs/allactive/wcprod/user_nl_eam b/cime_config/testmods_dirs/allactive/wcprod/user_nl_eam
index eeac1d647b1d..095c6946f5de 100644
--- a/cime_config/testmods_dirs/allactive/wcprod/user_nl_eam
+++ b/cime_config/testmods_dirs/allactive/wcprod/user_nl_eam
@@ -1,11 +1,59 @@
- nhtfrq = -24,-24,-6,-6,-3,-24,-24
- mfilt = 1,30,120,120,240,30,1
- avgflag_pertape = 'A','A','I','A','A','A','I'
- fexcl1 = 'CFAD_SR532_CAL', 'LINOZ_DO3', 'LINOZ_DO3_PSC', 'LINOZ_O3CLIM', 'LINOZ_O3COL', 'LINOZ_SSO3', 'hstobie_linoz'
- fincl1 = 'extinct_sw_inp','extinct_lw_bnd7','extinct_lw_inp','CLD_CAL', 'TREFMNAV', 'TREFMXAV'
- fincl2 = 'FLUT','PRECT','U200','V200','U850','V850','Z500','OMEGA500','UBOT','VBOT','TREFHT','TREFHTMN:M','TREFHTMX:X','QREFHT','TS','PS','TMQ','TUQ','TVQ','TOZ', 'FLDS', 'FLNS', 'FSDS', 'FSNS', 'SHFLX', 'LHFLX', 'TGCLDCWP', 'TGCLDIWP', 'TGCLDLWP', 'CLDTOT', 'T250', 'T200', 'T150', 'T100', 'T050', 'T025', 'T010', 'T005', 'T002', 'T001', 'TTOP', 'U250', 'U150', 'U100', 'U050', 'U025', 'U010', 'U005', 'U002', 'U001', 'UTOP', 'FSNT', 'FLNT'
- fincl3 = 'PSL','T200','T500','U850','V850','UBOT','VBOT','TREFHT', 'Z700', 'TBOT:M'
- fincl4 = 'FLUT','U200','U850','PRECT','OMEGA500'
- fincl5 = 'PRECT','PRECC','TUQ','TVQ','QFLX','SHFLX','U90M','V90M'
- fincl6 = 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANTAU_ISCCP','MEANPTOP_ISCCP','MEANTB_ISCCP','CLDTOT_CAL','CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN','CLDHGH_CAL','CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN','CLDMED_CAL','CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN','CLDLOW_CAL','CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN'
- fincl7 = 'O3', 'PS', 'TROP_P'
+cosp_lite = .true.
+
+empty_htapes = .true.
+
+avgflag_pertape = 'A','A','A','A','I','I'
+nhtfrq = -24,-24,-6,-3,-1,-24
+mfilt = 1,30,120,240,720,1
+
+fincl1 = 'AODALL','AODBC','AODDUST','AODPOM','AODSO4','AODSOA','AODSS','AODVIS',
+ 'CLDLOW','CLDMED','CLDHGH','CLDTOT',
+ 'CLDHGH_CAL','CLDLOW_CAL','CLDMED_CAL','CLD_MISR','CLDTOT_CAL',
+ 'CLMODIS','FISCCP1_COSP','FLDS','FLNS','FLNSC','FLNT','FLUT',
+ 'FLUTC','FSDS','FSDSC','FSNS','FSNSC','FSNT','FSNTOA','FSNTOAC','FSNTC',
+ 'ICEFRAC','LANDFRAC','LWCF','OCNFRAC','OMEGA','PRECC','PRECL','PRECSC','PRECSL','PS','PSL','Q',
+ 'QFLX','QREFHT','RELHUM','SCO','SHFLX','SOLIN','SWCF','T','TAUX','TAUY','TCO',
+ 'TGCLDLWP','TMQ','TREFHT','TREFMNAV','TREFMXAV','TS','U','U10','V','Z3',
+ 'dst_a1DDF','dst_a3DDF','dst_c1DDF','dst_c3DDF','dst_a1SFWET','dst_a3SFWET','dst_c1SFWET','dst_c3SFWET',
+ 'O3','LHFLX',
+ 'O3_2DTDA_trop','O3_2DTDB_trop','O3_2DTDD_trop','O3_2DTDE_trop','O3_2DTDI_trop','O3_2DTDL_trop',
+ 'O3_2DTDN_trop','O3_2DTDO_trop','O3_2DTDS_trop','O3_2DTDU_trop','O3_2DTRE_trop','O3_2DTRI_trop',
+ 'O3_SRF','NO_2DTDS','NO_TDLgt','NO2_2DTDD','NO2_2DTDS','NO2_TDAcf','CO_SRF','TROPE3D_P','TROP_P',
+ 'CDNUMC','SFDMS','so4_a1_sfgaex1','so4_a2_sfgaex1','so4_a3_sfgaex1','so4_a5_sfgaex1','soa_a1_sfgaex1',
+ 'soa_a2_sfgaex1','soa_a3_sfgaex1','GS_soa_a1','GS_soa_a2','GS_soa_a3','AQSO4_H2O2','AQSO4_O3',
+ 'SFSO2','SO2_CLXF','SO2','DF_SO2','AQ_SO2','GS_SO2','WD_SO2','ABURDENSO4_STR','ABURDENSO4_TRO',
+ 'ABURDENSO4','ABURDENBC','ABURDENDUST','ABURDENMOM','ABURDENPOM','ABURDENSEASALT',
+ 'ABURDENSOA','AODSO4_STR','AODSO4_TRO',
+ 'EXTINCT','AODABS','AODABSBC','CLDICE','CLDLIQ','CLD_CAL_TMPLIQ','CLD_CAL_TMPICE','Mass_bc_srf',
+ 'Mass_dst_srf','Mass_mom_srf','Mass_ncl_srf','Mass_pom_srf','Mass_so4_srf','Mass_soa_srf','Mass_bc_850',
+ 'Mass_dst_850','Mass_mom_850','Mass_ncl_850','Mass_pom_850','Mass_so4_850','Mass_soa_850','Mass_bc_500',
+ 'Mass_dst_500','Mass_mom_500','Mass_ncl_500','Mass_pom_500','Mass_so4_500','Mass_soa_500','Mass_bc_330',
+ 'Mass_dst_330','Mass_mom_330','Mass_ncl_330','Mass_pom_330','Mass_so4_330','Mass_soa_330','Mass_bc_200',
+ 'Mass_dst_200','Mass_mom_200','Mass_ncl_200','Mass_pom_200','Mass_so4_200','Mass_soa_200',
+ 'O3_2DTDD','O3_2DCIP','O3_2DCIL','CO_2DTDS','CO_2DTDD','CO_2DCEP','CO_2DCEL','NO_2DTDD',
+ 'FLNTC','SAODVIS',
+ 'H2OLNZ',
+ 'dst_a1SF','dst_a3SF',
+ 'PHIS','CLOUD','TGCLDIWP','TGCLDCWP','AREL',
+ 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANPTOP_ISCCP','CLD_CAL',
+ 'CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN',
+ 'CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN',
+ 'CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN',
+ 'CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN',
+ 'CLWMODIS','CLIMODIS'
+
+fincl2 = 'PS', 'FLUT','PRECT','U200','V200','U850','V850',
+ 'TCO','SCO','TREFHTMN','TREFHTMX','TREFHT','QREFHT'
+fincl3 = 'PS', 'PSL','PRECT','TUQ','TVQ','UBOT','VBOT','TREFHT','FLUT','OMEGA500','TBOT','U850','V850','U200','V200','T200','T500','Z700'
+fincl4 = 'PRECT'
+fincl5 = 'O3_SRF'
+fincl6 = 'CO_2DMSD','NO2_2DMSD','NO_2DMSD','O3_2DMSD','O3_2DMSD_trop'
+
+! -- chemUCI settings ------------------
+history_chemdyg_summary = .true.
+history_gaschmbudget_2D = .false.
+history_gaschmbudget_2D_levels = .false.
+history_gaschmbudget_num = 6 !! no impact if history_gaschmbudget_2D = .false.
+
+! -- MAM5 settings ------------------
+is_output_interactive_volc = .true.
diff --git a/cime_config/testmods_dirs/allactive/wcprod/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprod/user_nl_elm
index a93edc10b690..cd1adab77404 100644
--- a/cime_config/testmods_dirs/allactive/wcprod/user_nl_elm
+++ b/cime_config/testmods_dirs/allactive/wcprod/user_nl_elm
@@ -1,6 +1,40 @@
- finidat = ' '
- hist_dov2xy = .true.,.true.
- hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
- hist_mfilt = 1,365
- hist_nhtfrq = -24,-24
- hist_avgflag_pertape = 'A','A'
+hist_dov2xy = .true.,.true.
+hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP',
+ 'BAF_PEATF','BIOCHEM_PMIN_TO_PLANT','CH4_SURF_AERE_SAT','CH4_SURF_AERE_UNSAT','CH4_SURF_DIFF_SAT',
+ 'CH4_SURF_DIFF_UNSAT','CH4_SURF_EBUL_SAT','CH4_SURF_EBUL_UNSAT','CMASS_BALANCE_ERROR','cn_scalar',
+ 'COL_PTRUNC','CONC_CH4_SAT','CONC_CH4_UNSAT','CONC_O2_SAT','CONC_O2_UNSAT',
+ 'cp_scalar','CWDC_HR','CWDC_LOSS','CWDC_TO_LITR2C','CWDC_TO_LITR3C',
+ 'CWDC_vr','CWDN_TO_LITR2N','CWDN_TO_LITR3N','CWDN_vr','CWDP_TO_LITR2P',
+ 'CWDP_TO_LITR3P','CWDP_vr','DWT_CONV_CFLUX_DRIBBLED','F_CO2_SOIL','F_CO2_SOIL_vr',
+ 'F_DENIT_vr','F_N2O_DENIT','F_N2O_NIT','F_NIT_vr','FCH4_DFSAT',
+ 'FINUNDATED_LAG','FPI_P_vr','FPI_vr','FROOTC_LOSS','HR_vr',
+ 'LABILEP_TO_SECONDP','LABILEP_vr','LAND_UPTAKE','LEAF_MR','leaf_npimbalance',
+ 'LEAFC_LOSS','LEAFC_TO_LITTER','LFC2','LITR1_HR','LITR1C_TO_SOIL1C',
+ 'LITR1C_vr','LITR1N_TNDNCY_VERT_TRANS','LITR1N_TO_SOIL1N','LITR1N_vr','LITR1P_TNDNCY_VERT_TRANS',
+ 'LITR1P_TO_SOIL1P','LITR1P_vr','LITR2_HR','LITR2C_TO_SOIL2C','LITR2C_vr',
+ 'LITR2N_TNDNCY_VERT_TRANS','LITR2N_TO_SOIL2N','LITR2N_vr','LITR2P_TNDNCY_VERT_TRANS','LITR2P_TO_SOIL2P',
+ 'LITR2P_vr','LITR3_HR','LITR3C_TO_SOIL3C','LITR3C_vr','LITR3N_TNDNCY_VERT_TRANS',
+ 'LITR3N_TO_SOIL3N','LITR3N_vr','LITR3P_TNDNCY_VERT_TRANS','LITR3P_TO_SOIL3P','LITR3P_vr',
+ 'M_LITR1C_TO_LEACHING','M_LITR2C_TO_LEACHING','M_LITR3C_TO_LEACHING','M_SOIL1C_TO_LEACHING','M_SOIL2C_TO_LEACHING',
+ 'M_SOIL3C_TO_LEACHING','M_SOIL4C_TO_LEACHING','NDEPLOY','NEM','nlim_m',
+ 'o2_decomp_depth_unsat','OCCLP_vr','PDEPLOY','PLANT_CALLOC','PLANT_NDEMAND',
+ 'PLANT_NDEMAND_COL','PLANT_PALLOC','PLANT_PDEMAND','PLANT_PDEMAND_COL','plim_m',
+ 'POT_F_DENIT','POT_F_NIT','POTENTIAL_IMMOB','POTENTIAL_IMMOB_P','PRIMP_TO_LABILEP',
+ 'PRIMP_vr','PROD1P_LOSS','QOVER_LAG','RETRANSN_TO_NPOOL','RETRANSP_TO_PPOOL',
+ 'SCALARAVG_vr','SECONDP_TO_LABILEP','SECONDP_TO_OCCLP','SECONDP_vr','SMIN_NH4_vr',
+ 'SMIN_NO3_vr','SMINN_TO_SOIL1N_L1','SMINN_TO_SOIL2N_L2','SMINN_TO_SOIL2N_S1','SMINN_TO_SOIL3N_L3',
+ 'SMINN_TO_SOIL3N_S2','SMINN_TO_SOIL4N_S3','SMINP_TO_SOIL1P_L1','SMINP_TO_SOIL2P_L2','SMINP_TO_SOIL2P_S1',
+ 'SMINP_TO_SOIL3P_L3','SMINP_TO_SOIL3P_S2','SMINP_TO_SOIL4P_S3','SMINP_vr','SOIL1_HR','SOIL1C_TO_SOIL2C','SOIL1C_vr','SOIL1N_TNDNCY_VERT_TRANS','SOIL1N_TO_SOIL2N','SOIL1N_vr',
+ 'SOIL1P_TNDNCY_VERT_TRANS','SOIL1P_TO_SOIL2P','SOIL1P_vr','SOIL2_HR','SOIL2C_TO_SOIL3C',
+ 'SOIL2C_vr','SOIL2N_TNDNCY_VERT_TRANS','SOIL2N_TO_SOIL3N','SOIL2N_vr','SOIL2P_TNDNCY_VERT_TRANS',
+ 'SOIL2P_TO_SOIL3P','SOIL2P_vr','SOIL3_HR','SOIL3C_TO_SOIL4C','SOIL3C_vr',
+ 'SOIL3N_TNDNCY_VERT_TRANS','SOIL3N_TO_SOIL4N','SOIL3N_vr','SOIL3P_TNDNCY_VERT_TRANS','SOIL3P_TO_SOIL4P',
+ 'SOIL3P_vr','SOIL4_HR','SOIL4C_vr','SOIL4N_TNDNCY_VERT_TRANS','SOIL4N_TO_SMINN',
+ 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr',
+ 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF',
+ 'wlim_m','WOODC_LOSS','WTGQ'
+hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC'
+hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
+hist_mfilt = 1,365
+hist_nhtfrq = -24,-24
+hist_avgflag_pertape = 'A','A'
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850/README b/cime_config/testmods_dirs/allactive/wcprod_1850/README
index 020bbf93e9f2..329e3e6ea7ab 100644
--- a/cime_config/testmods_dirs/allactive/wcprod_1850/README
+++ b/cime_config/testmods_dirs/allactive/wcprod_1850/README
@@ -3,4 +3,3 @@ water cycle production sims
Run these for at least 1 day to see all output.
Also use the CMIP6 compsets.
-If running longer, change the nhtfrq for the first history file.
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850/user_nl_eam b/cime_config/testmods_dirs/allactive/wcprod_1850/user_nl_eam
index eeac1d647b1d..095c6946f5de 100644
--- a/cime_config/testmods_dirs/allactive/wcprod_1850/user_nl_eam
+++ b/cime_config/testmods_dirs/allactive/wcprod_1850/user_nl_eam
@@ -1,11 +1,59 @@
- nhtfrq = -24,-24,-6,-6,-3,-24,-24
- mfilt = 1,30,120,120,240,30,1
- avgflag_pertape = 'A','A','I','A','A','A','I'
- fexcl1 = 'CFAD_SR532_CAL', 'LINOZ_DO3', 'LINOZ_DO3_PSC', 'LINOZ_O3CLIM', 'LINOZ_O3COL', 'LINOZ_SSO3', 'hstobie_linoz'
- fincl1 = 'extinct_sw_inp','extinct_lw_bnd7','extinct_lw_inp','CLD_CAL', 'TREFMNAV', 'TREFMXAV'
- fincl2 = 'FLUT','PRECT','U200','V200','U850','V850','Z500','OMEGA500','UBOT','VBOT','TREFHT','TREFHTMN:M','TREFHTMX:X','QREFHT','TS','PS','TMQ','TUQ','TVQ','TOZ', 'FLDS', 'FLNS', 'FSDS', 'FSNS', 'SHFLX', 'LHFLX', 'TGCLDCWP', 'TGCLDIWP', 'TGCLDLWP', 'CLDTOT', 'T250', 'T200', 'T150', 'T100', 'T050', 'T025', 'T010', 'T005', 'T002', 'T001', 'TTOP', 'U250', 'U150', 'U100', 'U050', 'U025', 'U010', 'U005', 'U002', 'U001', 'UTOP', 'FSNT', 'FLNT'
- fincl3 = 'PSL','T200','T500','U850','V850','UBOT','VBOT','TREFHT', 'Z700', 'TBOT:M'
- fincl4 = 'FLUT','U200','U850','PRECT','OMEGA500'
- fincl5 = 'PRECT','PRECC','TUQ','TVQ','QFLX','SHFLX','U90M','V90M'
- fincl6 = 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANTAU_ISCCP','MEANPTOP_ISCCP','MEANTB_ISCCP','CLDTOT_CAL','CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN','CLDHGH_CAL','CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN','CLDMED_CAL','CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN','CLDLOW_CAL','CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN'
- fincl7 = 'O3', 'PS', 'TROP_P'
+cosp_lite = .true.
+
+empty_htapes = .true.
+
+avgflag_pertape = 'A','A','A','A','I','I'
+nhtfrq = -24,-24,-6,-3,-1,-24
+mfilt = 1,30,120,240,720,1
+
+fincl1 = 'AODALL','AODBC','AODDUST','AODPOM','AODSO4','AODSOA','AODSS','AODVIS',
+ 'CLDLOW','CLDMED','CLDHGH','CLDTOT',
+ 'CLDHGH_CAL','CLDLOW_CAL','CLDMED_CAL','CLD_MISR','CLDTOT_CAL',
+ 'CLMODIS','FISCCP1_COSP','FLDS','FLNS','FLNSC','FLNT','FLUT',
+ 'FLUTC','FSDS','FSDSC','FSNS','FSNSC','FSNT','FSNTOA','FSNTOAC','FSNTC',
+ 'ICEFRAC','LANDFRAC','LWCF','OCNFRAC','OMEGA','PRECC','PRECL','PRECSC','PRECSL','PS','PSL','Q',
+ 'QFLX','QREFHT','RELHUM','SCO','SHFLX','SOLIN','SWCF','T','TAUX','TAUY','TCO',
+ 'TGCLDLWP','TMQ','TREFHT','TREFMNAV','TREFMXAV','TS','U','U10','V','Z3',
+ 'dst_a1DDF','dst_a3DDF','dst_c1DDF','dst_c3DDF','dst_a1SFWET','dst_a3SFWET','dst_c1SFWET','dst_c3SFWET',
+ 'O3','LHFLX',
+ 'O3_2DTDA_trop','O3_2DTDB_trop','O3_2DTDD_trop','O3_2DTDE_trop','O3_2DTDI_trop','O3_2DTDL_trop',
+ 'O3_2DTDN_trop','O3_2DTDO_trop','O3_2DTDS_trop','O3_2DTDU_trop','O3_2DTRE_trop','O3_2DTRI_trop',
+ 'O3_SRF','NO_2DTDS','NO_TDLgt','NO2_2DTDD','NO2_2DTDS','NO2_TDAcf','CO_SRF','TROPE3D_P','TROP_P',
+ 'CDNUMC','SFDMS','so4_a1_sfgaex1','so4_a2_sfgaex1','so4_a3_sfgaex1','so4_a5_sfgaex1','soa_a1_sfgaex1',
+ 'soa_a2_sfgaex1','soa_a3_sfgaex1','GS_soa_a1','GS_soa_a2','GS_soa_a3','AQSO4_H2O2','AQSO4_O3',
+ 'SFSO2','SO2_CLXF','SO2','DF_SO2','AQ_SO2','GS_SO2','WD_SO2','ABURDENSO4_STR','ABURDENSO4_TRO',
+ 'ABURDENSO4','ABURDENBC','ABURDENDUST','ABURDENMOM','ABURDENPOM','ABURDENSEASALT',
+ 'ABURDENSOA','AODSO4_STR','AODSO4_TRO',
+ 'EXTINCT','AODABS','AODABSBC','CLDICE','CLDLIQ','CLD_CAL_TMPLIQ','CLD_CAL_TMPICE','Mass_bc_srf',
+ 'Mass_dst_srf','Mass_mom_srf','Mass_ncl_srf','Mass_pom_srf','Mass_so4_srf','Mass_soa_srf','Mass_bc_850',
+ 'Mass_dst_850','Mass_mom_850','Mass_ncl_850','Mass_pom_850','Mass_so4_850','Mass_soa_850','Mass_bc_500',
+ 'Mass_dst_500','Mass_mom_500','Mass_ncl_500','Mass_pom_500','Mass_so4_500','Mass_soa_500','Mass_bc_330',
+ 'Mass_dst_330','Mass_mom_330','Mass_ncl_330','Mass_pom_330','Mass_so4_330','Mass_soa_330','Mass_bc_200',
+ 'Mass_dst_200','Mass_mom_200','Mass_ncl_200','Mass_pom_200','Mass_so4_200','Mass_soa_200',
+ 'O3_2DTDD','O3_2DCIP','O3_2DCIL','CO_2DTDS','CO_2DTDD','CO_2DCEP','CO_2DCEL','NO_2DTDD',
+ 'FLNTC','SAODVIS',
+ 'H2OLNZ',
+ 'dst_a1SF','dst_a3SF',
+ 'PHIS','CLOUD','TGCLDIWP','TGCLDCWP','AREL',
+ 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANPTOP_ISCCP','CLD_CAL',
+ 'CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN',
+ 'CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN',
+ 'CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN',
+ 'CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN',
+ 'CLWMODIS','CLIMODIS'
+
+fincl2 = 'PS', 'FLUT','PRECT','U200','V200','U850','V850',
+ 'TCO','SCO','TREFHTMN','TREFHTMX','TREFHT','QREFHT'
+fincl3 = 'PS', 'PSL','PRECT','TUQ','TVQ','UBOT','VBOT','TREFHT','FLUT','OMEGA500','TBOT','U850','V850','U200','V200','T200','T500','Z700'
+fincl4 = 'PRECT'
+fincl5 = 'O3_SRF'
+fincl6 = 'CO_2DMSD','NO2_2DMSD','NO_2DMSD','O3_2DMSD','O3_2DMSD_trop'
+
+! -- chemUCI settings ------------------
+history_chemdyg_summary = .true.
+history_gaschmbudget_2D = .false.
+history_gaschmbudget_2D_levels = .false.
+history_gaschmbudget_num = 6 !! no impact if history_gaschmbudget_2D = .false.
+
+! -- MAM5 settings ------------------
+is_output_interactive_volc = .true.
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprod_1850/user_nl_elm
index 0bbfbeea61bc..cd1adab77404 100644
--- a/cime_config/testmods_dirs/allactive/wcprod_1850/user_nl_elm
+++ b/cime_config/testmods_dirs/allactive/wcprod_1850/user_nl_elm
@@ -1,7 +1,40 @@
-! Finidat to be updated, The one below not compatible with v3 lnd config (with TOP and BGC mode, new grid)
-! finidat = '$DIN_LOC_ROOT/lnd/clm2/initdata_map/clmi.WCYCL1850.ne30pg2_EC30to60E2r2.SMS_Ld1.c20230213.nc'
- hist_dov2xy = .true.,.true.
- hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
- hist_mfilt = 1,365
- hist_nhtfrq = -24,-24
- hist_avgflag_pertape = 'A','A'
+hist_dov2xy = .true.,.true.
+hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP',
+ 'BAF_PEATF','BIOCHEM_PMIN_TO_PLANT','CH4_SURF_AERE_SAT','CH4_SURF_AERE_UNSAT','CH4_SURF_DIFF_SAT',
+ 'CH4_SURF_DIFF_UNSAT','CH4_SURF_EBUL_SAT','CH4_SURF_EBUL_UNSAT','CMASS_BALANCE_ERROR','cn_scalar',
+ 'COL_PTRUNC','CONC_CH4_SAT','CONC_CH4_UNSAT','CONC_O2_SAT','CONC_O2_UNSAT',
+ 'cp_scalar','CWDC_HR','CWDC_LOSS','CWDC_TO_LITR2C','CWDC_TO_LITR3C',
+ 'CWDC_vr','CWDN_TO_LITR2N','CWDN_TO_LITR3N','CWDN_vr','CWDP_TO_LITR2P',
+ 'CWDP_TO_LITR3P','CWDP_vr','DWT_CONV_CFLUX_DRIBBLED','F_CO2_SOIL','F_CO2_SOIL_vr',
+ 'F_DENIT_vr','F_N2O_DENIT','F_N2O_NIT','F_NIT_vr','FCH4_DFSAT',
+ 'FINUNDATED_LAG','FPI_P_vr','FPI_vr','FROOTC_LOSS','HR_vr',
+ 'LABILEP_TO_SECONDP','LABILEP_vr','LAND_UPTAKE','LEAF_MR','leaf_npimbalance',
+ 'LEAFC_LOSS','LEAFC_TO_LITTER','LFC2','LITR1_HR','LITR1C_TO_SOIL1C',
+ 'LITR1C_vr','LITR1N_TNDNCY_VERT_TRANS','LITR1N_TO_SOIL1N','LITR1N_vr','LITR1P_TNDNCY_VERT_TRANS',
+ 'LITR1P_TO_SOIL1P','LITR1P_vr','LITR2_HR','LITR2C_TO_SOIL2C','LITR2C_vr',
+ 'LITR2N_TNDNCY_VERT_TRANS','LITR2N_TO_SOIL2N','LITR2N_vr','LITR2P_TNDNCY_VERT_TRANS','LITR2P_TO_SOIL2P',
+ 'LITR2P_vr','LITR3_HR','LITR3C_TO_SOIL3C','LITR3C_vr','LITR3N_TNDNCY_VERT_TRANS',
+ 'LITR3N_TO_SOIL3N','LITR3N_vr','LITR3P_TNDNCY_VERT_TRANS','LITR3P_TO_SOIL3P','LITR3P_vr',
+ 'M_LITR1C_TO_LEACHING','M_LITR2C_TO_LEACHING','M_LITR3C_TO_LEACHING','M_SOIL1C_TO_LEACHING','M_SOIL2C_TO_LEACHING',
+ 'M_SOIL3C_TO_LEACHING','M_SOIL4C_TO_LEACHING','NDEPLOY','NEM','nlim_m',
+ 'o2_decomp_depth_unsat','OCCLP_vr','PDEPLOY','PLANT_CALLOC','PLANT_NDEMAND',
+ 'PLANT_NDEMAND_COL','PLANT_PALLOC','PLANT_PDEMAND','PLANT_PDEMAND_COL','plim_m',
+ 'POT_F_DENIT','POT_F_NIT','POTENTIAL_IMMOB','POTENTIAL_IMMOB_P','PRIMP_TO_LABILEP',
+ 'PRIMP_vr','PROD1P_LOSS','QOVER_LAG','RETRANSN_TO_NPOOL','RETRANSP_TO_PPOOL',
+ 'SCALARAVG_vr','SECONDP_TO_LABILEP','SECONDP_TO_OCCLP','SECONDP_vr','SMIN_NH4_vr',
+ 'SMIN_NO3_vr','SMINN_TO_SOIL1N_L1','SMINN_TO_SOIL2N_L2','SMINN_TO_SOIL2N_S1','SMINN_TO_SOIL3N_L3',
+ 'SMINN_TO_SOIL3N_S2','SMINN_TO_SOIL4N_S3','SMINP_TO_SOIL1P_L1','SMINP_TO_SOIL2P_L2','SMINP_TO_SOIL2P_S1',
+ 'SMINP_TO_SOIL3P_L3','SMINP_TO_SOIL3P_S2','SMINP_TO_SOIL4P_S3','SMINP_vr','SOIL1_HR','SOIL1C_TO_SOIL2C','SOIL1C_vr','SOIL1N_TNDNCY_VERT_TRANS','SOIL1N_TO_SOIL2N','SOIL1N_vr',
+ 'SOIL1P_TNDNCY_VERT_TRANS','SOIL1P_TO_SOIL2P','SOIL1P_vr','SOIL2_HR','SOIL2C_TO_SOIL3C',
+ 'SOIL2C_vr','SOIL2N_TNDNCY_VERT_TRANS','SOIL2N_TO_SOIL3N','SOIL2N_vr','SOIL2P_TNDNCY_VERT_TRANS',
+ 'SOIL2P_TO_SOIL3P','SOIL2P_vr','SOIL3_HR','SOIL3C_TO_SOIL4C','SOIL3C_vr',
+ 'SOIL3N_TNDNCY_VERT_TRANS','SOIL3N_TO_SOIL4N','SOIL3N_vr','SOIL3P_TNDNCY_VERT_TRANS','SOIL3P_TO_SOIL4P',
+ 'SOIL3P_vr','SOIL4_HR','SOIL4C_vr','SOIL4N_TNDNCY_VERT_TRANS','SOIL4N_TO_SMINN',
+ 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr',
+ 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF',
+ 'wlim_m','WOODC_LOSS','WTGQ'
+hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC'
+hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
+hist_mfilt = 1,365
+hist_nhtfrq = -24,-24
+hist_avgflag_pertape = 'A','A'
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/README b/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/README
index 020bbf93e9f2..329e3e6ea7ab 100644
--- a/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/README
+++ b/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/README
@@ -3,4 +3,3 @@ water cycle production sims
Run these for at least 1 day to see all output.
Also use the CMIP6 compsets.
-If running longer, change the nhtfrq for the first history file.
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/user_nl_eam b/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/user_nl_eam
index eeac1d647b1d..095c6946f5de 100644
--- a/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/user_nl_eam
+++ b/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/user_nl_eam
@@ -1,11 +1,59 @@
- nhtfrq = -24,-24,-6,-6,-3,-24,-24
- mfilt = 1,30,120,120,240,30,1
- avgflag_pertape = 'A','A','I','A','A','A','I'
- fexcl1 = 'CFAD_SR532_CAL', 'LINOZ_DO3', 'LINOZ_DO3_PSC', 'LINOZ_O3CLIM', 'LINOZ_O3COL', 'LINOZ_SSO3', 'hstobie_linoz'
- fincl1 = 'extinct_sw_inp','extinct_lw_bnd7','extinct_lw_inp','CLD_CAL', 'TREFMNAV', 'TREFMXAV'
- fincl2 = 'FLUT','PRECT','U200','V200','U850','V850','Z500','OMEGA500','UBOT','VBOT','TREFHT','TREFHTMN:M','TREFHTMX:X','QREFHT','TS','PS','TMQ','TUQ','TVQ','TOZ', 'FLDS', 'FLNS', 'FSDS', 'FSNS', 'SHFLX', 'LHFLX', 'TGCLDCWP', 'TGCLDIWP', 'TGCLDLWP', 'CLDTOT', 'T250', 'T200', 'T150', 'T100', 'T050', 'T025', 'T010', 'T005', 'T002', 'T001', 'TTOP', 'U250', 'U150', 'U100', 'U050', 'U025', 'U010', 'U005', 'U002', 'U001', 'UTOP', 'FSNT', 'FLNT'
- fincl3 = 'PSL','T200','T500','U850','V850','UBOT','VBOT','TREFHT', 'Z700', 'TBOT:M'
- fincl4 = 'FLUT','U200','U850','PRECT','OMEGA500'
- fincl5 = 'PRECT','PRECC','TUQ','TVQ','QFLX','SHFLX','U90M','V90M'
- fincl6 = 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANTAU_ISCCP','MEANPTOP_ISCCP','MEANTB_ISCCP','CLDTOT_CAL','CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN','CLDHGH_CAL','CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN','CLDMED_CAL','CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN','CLDLOW_CAL','CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN'
- fincl7 = 'O3', 'PS', 'TROP_P'
+cosp_lite = .true.
+
+empty_htapes = .true.
+
+avgflag_pertape = 'A','A','A','A','I','I'
+nhtfrq = -24,-24,-6,-3,-1,-24
+mfilt = 1,30,120,240,720,1
+
+fincl1 = 'AODALL','AODBC','AODDUST','AODPOM','AODSO4','AODSOA','AODSS','AODVIS',
+ 'CLDLOW','CLDMED','CLDHGH','CLDTOT',
+ 'CLDHGH_CAL','CLDLOW_CAL','CLDMED_CAL','CLD_MISR','CLDTOT_CAL',
+ 'CLMODIS','FISCCP1_COSP','FLDS','FLNS','FLNSC','FLNT','FLUT',
+ 'FLUTC','FSDS','FSDSC','FSNS','FSNSC','FSNT','FSNTOA','FSNTOAC','FSNTC',
+ 'ICEFRAC','LANDFRAC','LWCF','OCNFRAC','OMEGA','PRECC','PRECL','PRECSC','PRECSL','PS','PSL','Q',
+ 'QFLX','QREFHT','RELHUM','SCO','SHFLX','SOLIN','SWCF','T','TAUX','TAUY','TCO',
+ 'TGCLDLWP','TMQ','TREFHT','TREFMNAV','TREFMXAV','TS','U','U10','V','Z3',
+ 'dst_a1DDF','dst_a3DDF','dst_c1DDF','dst_c3DDF','dst_a1SFWET','dst_a3SFWET','dst_c1SFWET','dst_c3SFWET',
+ 'O3','LHFLX',
+ 'O3_2DTDA_trop','O3_2DTDB_trop','O3_2DTDD_trop','O3_2DTDE_trop','O3_2DTDI_trop','O3_2DTDL_trop',
+ 'O3_2DTDN_trop','O3_2DTDO_trop','O3_2DTDS_trop','O3_2DTDU_trop','O3_2DTRE_trop','O3_2DTRI_trop',
+ 'O3_SRF','NO_2DTDS','NO_TDLgt','NO2_2DTDD','NO2_2DTDS','NO2_TDAcf','CO_SRF','TROPE3D_P','TROP_P',
+ 'CDNUMC','SFDMS','so4_a1_sfgaex1','so4_a2_sfgaex1','so4_a3_sfgaex1','so4_a5_sfgaex1','soa_a1_sfgaex1',
+ 'soa_a2_sfgaex1','soa_a3_sfgaex1','GS_soa_a1','GS_soa_a2','GS_soa_a3','AQSO4_H2O2','AQSO4_O3',
+ 'SFSO2','SO2_CLXF','SO2','DF_SO2','AQ_SO2','GS_SO2','WD_SO2','ABURDENSO4_STR','ABURDENSO4_TRO',
+ 'ABURDENSO4','ABURDENBC','ABURDENDUST','ABURDENMOM','ABURDENPOM','ABURDENSEASALT',
+ 'ABURDENSOA','AODSO4_STR','AODSO4_TRO',
+ 'EXTINCT','AODABS','AODABSBC','CLDICE','CLDLIQ','CLD_CAL_TMPLIQ','CLD_CAL_TMPICE','Mass_bc_srf',
+ 'Mass_dst_srf','Mass_mom_srf','Mass_ncl_srf','Mass_pom_srf','Mass_so4_srf','Mass_soa_srf','Mass_bc_850',
+ 'Mass_dst_850','Mass_mom_850','Mass_ncl_850','Mass_pom_850','Mass_so4_850','Mass_soa_850','Mass_bc_500',
+ 'Mass_dst_500','Mass_mom_500','Mass_ncl_500','Mass_pom_500','Mass_so4_500','Mass_soa_500','Mass_bc_330',
+ 'Mass_dst_330','Mass_mom_330','Mass_ncl_330','Mass_pom_330','Mass_so4_330','Mass_soa_330','Mass_bc_200',
+ 'Mass_dst_200','Mass_mom_200','Mass_ncl_200','Mass_pom_200','Mass_so4_200','Mass_soa_200',
+ 'O3_2DTDD','O3_2DCIP','O3_2DCIL','CO_2DTDS','CO_2DTDD','CO_2DCEP','CO_2DCEL','NO_2DTDD',
+ 'FLNTC','SAODVIS',
+ 'H2OLNZ',
+ 'dst_a1SF','dst_a3SF',
+ 'PHIS','CLOUD','TGCLDIWP','TGCLDCWP','AREL',
+ 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANPTOP_ISCCP','CLD_CAL',
+ 'CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN',
+ 'CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN',
+ 'CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN',
+ 'CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN',
+ 'CLWMODIS','CLIMODIS'
+
+fincl2 = 'PS', 'FLUT','PRECT','U200','V200','U850','V850',
+ 'TCO','SCO','TREFHTMN','TREFHTMX','TREFHT','QREFHT'
+fincl3 = 'PS', 'PSL','PRECT','TUQ','TVQ','UBOT','VBOT','TREFHT','FLUT','OMEGA500','TBOT','U850','V850','U200','V200','T200','T500','Z700'
+fincl4 = 'PRECT'
+fincl5 = 'O3_SRF'
+fincl6 = 'CO_2DMSD','NO2_2DMSD','NO_2DMSD','O3_2DMSD','O3_2DMSD_trop'
+
+! -- chemUCI settings ------------------
+history_chemdyg_summary = .true.
+history_gaschmbudget_2D = .false.
+history_gaschmbudget_2D_levels = .false.
+history_gaschmbudget_num = 6 !! no impact if history_gaschmbudget_2D = .false.
+
+! -- MAM5 settings ------------------
+is_output_interactive_volc = .true.
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/user_nl_elm
index c8d35999c0a5..cd1adab77404 100644
--- a/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/user_nl_elm
+++ b/cime_config/testmods_dirs/allactive/wcprod_1850_1pctCO2/user_nl_elm
@@ -1,7 +1,40 @@
-! Finidat to be updated, The one below not compatible with v3 lnd config (with TOP and BGC mode, new grid)
-! finidat = '$DIN_LOC_ROOT/lnd/clm2/initdata_map/clmi.WCYCL1850-1pctCO2.ne30pg2_EC30to60E2r2.SMS_Ld1.c20230213.nc'
- hist_dov2xy = .true.,.true.
- hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
- hist_mfilt = 1,365
- hist_nhtfrq = -24,-24
- hist_avgflag_pertape = 'A','A'
+hist_dov2xy = .true.,.true.
+hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP',
+ 'BAF_PEATF','BIOCHEM_PMIN_TO_PLANT','CH4_SURF_AERE_SAT','CH4_SURF_AERE_UNSAT','CH4_SURF_DIFF_SAT',
+ 'CH4_SURF_DIFF_UNSAT','CH4_SURF_EBUL_SAT','CH4_SURF_EBUL_UNSAT','CMASS_BALANCE_ERROR','cn_scalar',
+ 'COL_PTRUNC','CONC_CH4_SAT','CONC_CH4_UNSAT','CONC_O2_SAT','CONC_O2_UNSAT',
+ 'cp_scalar','CWDC_HR','CWDC_LOSS','CWDC_TO_LITR2C','CWDC_TO_LITR3C',
+ 'CWDC_vr','CWDN_TO_LITR2N','CWDN_TO_LITR3N','CWDN_vr','CWDP_TO_LITR2P',
+ 'CWDP_TO_LITR3P','CWDP_vr','DWT_CONV_CFLUX_DRIBBLED','F_CO2_SOIL','F_CO2_SOIL_vr',
+ 'F_DENIT_vr','F_N2O_DENIT','F_N2O_NIT','F_NIT_vr','FCH4_DFSAT',
+ 'FINUNDATED_LAG','FPI_P_vr','FPI_vr','FROOTC_LOSS','HR_vr',
+ 'LABILEP_TO_SECONDP','LABILEP_vr','LAND_UPTAKE','LEAF_MR','leaf_npimbalance',
+ 'LEAFC_LOSS','LEAFC_TO_LITTER','LFC2','LITR1_HR','LITR1C_TO_SOIL1C',
+ 'LITR1C_vr','LITR1N_TNDNCY_VERT_TRANS','LITR1N_TO_SOIL1N','LITR1N_vr','LITR1P_TNDNCY_VERT_TRANS',
+ 'LITR1P_TO_SOIL1P','LITR1P_vr','LITR2_HR','LITR2C_TO_SOIL2C','LITR2C_vr',
+ 'LITR2N_TNDNCY_VERT_TRANS','LITR2N_TO_SOIL2N','LITR2N_vr','LITR2P_TNDNCY_VERT_TRANS','LITR2P_TO_SOIL2P',
+ 'LITR2P_vr','LITR3_HR','LITR3C_TO_SOIL3C','LITR3C_vr','LITR3N_TNDNCY_VERT_TRANS',
+ 'LITR3N_TO_SOIL3N','LITR3N_vr','LITR3P_TNDNCY_VERT_TRANS','LITR3P_TO_SOIL3P','LITR3P_vr',
+ 'M_LITR1C_TO_LEACHING','M_LITR2C_TO_LEACHING','M_LITR3C_TO_LEACHING','M_SOIL1C_TO_LEACHING','M_SOIL2C_TO_LEACHING',
+ 'M_SOIL3C_TO_LEACHING','M_SOIL4C_TO_LEACHING','NDEPLOY','NEM','nlim_m',
+ 'o2_decomp_depth_unsat','OCCLP_vr','PDEPLOY','PLANT_CALLOC','PLANT_NDEMAND',
+ 'PLANT_NDEMAND_COL','PLANT_PALLOC','PLANT_PDEMAND','PLANT_PDEMAND_COL','plim_m',
+ 'POT_F_DENIT','POT_F_NIT','POTENTIAL_IMMOB','POTENTIAL_IMMOB_P','PRIMP_TO_LABILEP',
+ 'PRIMP_vr','PROD1P_LOSS','QOVER_LAG','RETRANSN_TO_NPOOL','RETRANSP_TO_PPOOL',
+ 'SCALARAVG_vr','SECONDP_TO_LABILEP','SECONDP_TO_OCCLP','SECONDP_vr','SMIN_NH4_vr',
+ 'SMIN_NO3_vr','SMINN_TO_SOIL1N_L1','SMINN_TO_SOIL2N_L2','SMINN_TO_SOIL2N_S1','SMINN_TO_SOIL3N_L3',
+ 'SMINN_TO_SOIL3N_S2','SMINN_TO_SOIL4N_S3','SMINP_TO_SOIL1P_L1','SMINP_TO_SOIL2P_L2','SMINP_TO_SOIL2P_S1',
+ 'SMINP_TO_SOIL3P_L3','SMINP_TO_SOIL3P_S2','SMINP_TO_SOIL4P_S3','SMINP_vr','SOIL1_HR','SOIL1C_TO_SOIL2C','SOIL1C_vr','SOIL1N_TNDNCY_VERT_TRANS','SOIL1N_TO_SOIL2N','SOIL1N_vr',
+ 'SOIL1P_TNDNCY_VERT_TRANS','SOIL1P_TO_SOIL2P','SOIL1P_vr','SOIL2_HR','SOIL2C_TO_SOIL3C',
+ 'SOIL2C_vr','SOIL2N_TNDNCY_VERT_TRANS','SOIL2N_TO_SOIL3N','SOIL2N_vr','SOIL2P_TNDNCY_VERT_TRANS',
+ 'SOIL2P_TO_SOIL3P','SOIL2P_vr','SOIL3_HR','SOIL3C_TO_SOIL4C','SOIL3C_vr',
+ 'SOIL3N_TNDNCY_VERT_TRANS','SOIL3N_TO_SOIL4N','SOIL3N_vr','SOIL3P_TNDNCY_VERT_TRANS','SOIL3P_TO_SOIL4P',
+ 'SOIL3P_vr','SOIL4_HR','SOIL4C_vr','SOIL4N_TNDNCY_VERT_TRANS','SOIL4N_TO_SMINN',
+ 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr',
+ 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF',
+ 'wlim_m','WOODC_LOSS','WTGQ'
+hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC'
+hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
+hist_mfilt = 1,365
+hist_nhtfrq = -24,-24
+hist_avgflag_pertape = 'A','A'
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/README b/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/README
index 020bbf93e9f2..329e3e6ea7ab 100644
--- a/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/README
+++ b/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/README
@@ -3,4 +3,3 @@ water cycle production sims
Run these for at least 1 day to see all output.
Also use the CMIP6 compsets.
-If running longer, change the nhtfrq for the first history file.
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/user_nl_eam b/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/user_nl_eam
index eeac1d647b1d..095c6946f5de 100644
--- a/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/user_nl_eam
+++ b/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/user_nl_eam
@@ -1,11 +1,59 @@
- nhtfrq = -24,-24,-6,-6,-3,-24,-24
- mfilt = 1,30,120,120,240,30,1
- avgflag_pertape = 'A','A','I','A','A','A','I'
- fexcl1 = 'CFAD_SR532_CAL', 'LINOZ_DO3', 'LINOZ_DO3_PSC', 'LINOZ_O3CLIM', 'LINOZ_O3COL', 'LINOZ_SSO3', 'hstobie_linoz'
- fincl1 = 'extinct_sw_inp','extinct_lw_bnd7','extinct_lw_inp','CLD_CAL', 'TREFMNAV', 'TREFMXAV'
- fincl2 = 'FLUT','PRECT','U200','V200','U850','V850','Z500','OMEGA500','UBOT','VBOT','TREFHT','TREFHTMN:M','TREFHTMX:X','QREFHT','TS','PS','TMQ','TUQ','TVQ','TOZ', 'FLDS', 'FLNS', 'FSDS', 'FSNS', 'SHFLX', 'LHFLX', 'TGCLDCWP', 'TGCLDIWP', 'TGCLDLWP', 'CLDTOT', 'T250', 'T200', 'T150', 'T100', 'T050', 'T025', 'T010', 'T005', 'T002', 'T001', 'TTOP', 'U250', 'U150', 'U100', 'U050', 'U025', 'U010', 'U005', 'U002', 'U001', 'UTOP', 'FSNT', 'FLNT'
- fincl3 = 'PSL','T200','T500','U850','V850','UBOT','VBOT','TREFHT', 'Z700', 'TBOT:M'
- fincl4 = 'FLUT','U200','U850','PRECT','OMEGA500'
- fincl5 = 'PRECT','PRECC','TUQ','TVQ','QFLX','SHFLX','U90M','V90M'
- fincl6 = 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANTAU_ISCCP','MEANPTOP_ISCCP','MEANTB_ISCCP','CLDTOT_CAL','CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN','CLDHGH_CAL','CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN','CLDMED_CAL','CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN','CLDLOW_CAL','CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN'
- fincl7 = 'O3', 'PS', 'TROP_P'
+cosp_lite = .true.
+
+empty_htapes = .true.
+
+avgflag_pertape = 'A','A','A','A','I','I'
+nhtfrq = -24,-24,-6,-3,-1,-24
+mfilt = 1,30,120,240,720,1
+
+fincl1 = 'AODALL','AODBC','AODDUST','AODPOM','AODSO4','AODSOA','AODSS','AODVIS',
+ 'CLDLOW','CLDMED','CLDHGH','CLDTOT',
+ 'CLDHGH_CAL','CLDLOW_CAL','CLDMED_CAL','CLD_MISR','CLDTOT_CAL',
+ 'CLMODIS','FISCCP1_COSP','FLDS','FLNS','FLNSC','FLNT','FLUT',
+ 'FLUTC','FSDS','FSDSC','FSNS','FSNSC','FSNT','FSNTOA','FSNTOAC','FSNTC',
+ 'ICEFRAC','LANDFRAC','LWCF','OCNFRAC','OMEGA','PRECC','PRECL','PRECSC','PRECSL','PS','PSL','Q',
+ 'QFLX','QREFHT','RELHUM','SCO','SHFLX','SOLIN','SWCF','T','TAUX','TAUY','TCO',
+ 'TGCLDLWP','TMQ','TREFHT','TREFMNAV','TREFMXAV','TS','U','U10','V','Z3',
+ 'dst_a1DDF','dst_a3DDF','dst_c1DDF','dst_c3DDF','dst_a1SFWET','dst_a3SFWET','dst_c1SFWET','dst_c3SFWET',
+ 'O3','LHFLX',
+ 'O3_2DTDA_trop','O3_2DTDB_trop','O3_2DTDD_trop','O3_2DTDE_trop','O3_2DTDI_trop','O3_2DTDL_trop',
+ 'O3_2DTDN_trop','O3_2DTDO_trop','O3_2DTDS_trop','O3_2DTDU_trop','O3_2DTRE_trop','O3_2DTRI_trop',
+ 'O3_SRF','NO_2DTDS','NO_TDLgt','NO2_2DTDD','NO2_2DTDS','NO2_TDAcf','CO_SRF','TROPE3D_P','TROP_P',
+ 'CDNUMC','SFDMS','so4_a1_sfgaex1','so4_a2_sfgaex1','so4_a3_sfgaex1','so4_a5_sfgaex1','soa_a1_sfgaex1',
+ 'soa_a2_sfgaex1','soa_a3_sfgaex1','GS_soa_a1','GS_soa_a2','GS_soa_a3','AQSO4_H2O2','AQSO4_O3',
+ 'SFSO2','SO2_CLXF','SO2','DF_SO2','AQ_SO2','GS_SO2','WD_SO2','ABURDENSO4_STR','ABURDENSO4_TRO',
+ 'ABURDENSO4','ABURDENBC','ABURDENDUST','ABURDENMOM','ABURDENPOM','ABURDENSEASALT',
+ 'ABURDENSOA','AODSO4_STR','AODSO4_TRO',
+ 'EXTINCT','AODABS','AODABSBC','CLDICE','CLDLIQ','CLD_CAL_TMPLIQ','CLD_CAL_TMPICE','Mass_bc_srf',
+ 'Mass_dst_srf','Mass_mom_srf','Mass_ncl_srf','Mass_pom_srf','Mass_so4_srf','Mass_soa_srf','Mass_bc_850',
+ 'Mass_dst_850','Mass_mom_850','Mass_ncl_850','Mass_pom_850','Mass_so4_850','Mass_soa_850','Mass_bc_500',
+ 'Mass_dst_500','Mass_mom_500','Mass_ncl_500','Mass_pom_500','Mass_so4_500','Mass_soa_500','Mass_bc_330',
+ 'Mass_dst_330','Mass_mom_330','Mass_ncl_330','Mass_pom_330','Mass_so4_330','Mass_soa_330','Mass_bc_200',
+ 'Mass_dst_200','Mass_mom_200','Mass_ncl_200','Mass_pom_200','Mass_so4_200','Mass_soa_200',
+ 'O3_2DTDD','O3_2DCIP','O3_2DCIL','CO_2DTDS','CO_2DTDD','CO_2DCEP','CO_2DCEL','NO_2DTDD',
+ 'FLNTC','SAODVIS',
+ 'H2OLNZ',
+ 'dst_a1SF','dst_a3SF',
+ 'PHIS','CLOUD','TGCLDIWP','TGCLDCWP','AREL',
+ 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANPTOP_ISCCP','CLD_CAL',
+ 'CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN',
+ 'CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN',
+ 'CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN',
+ 'CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN',
+ 'CLWMODIS','CLIMODIS'
+
+fincl2 = 'PS', 'FLUT','PRECT','U200','V200','U850','V850',
+ 'TCO','SCO','TREFHTMN','TREFHTMX','TREFHT','QREFHT'
+fincl3 = 'PS', 'PSL','PRECT','TUQ','TVQ','UBOT','VBOT','TREFHT','FLUT','OMEGA500','TBOT','U850','V850','U200','V200','T200','T500','Z700'
+fincl4 = 'PRECT'
+fincl5 = 'O3_SRF'
+fincl6 = 'CO_2DMSD','NO2_2DMSD','NO_2DMSD','O3_2DMSD','O3_2DMSD_trop'
+
+! -- chemUCI settings ------------------
+history_chemdyg_summary = .true.
+history_gaschmbudget_2D = .false.
+history_gaschmbudget_2D_levels = .false.
+history_gaschmbudget_num = 6 !! no impact if history_gaschmbudget_2D = .false.
+
+! -- MAM5 settings ------------------
+is_output_interactive_volc = .true.
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/user_nl_elm
index 4379fd5e4fe1..cd1adab77404 100644
--- a/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/user_nl_elm
+++ b/cime_config/testmods_dirs/allactive/wcprod_1850_4xCO2/user_nl_elm
@@ -1,7 +1,40 @@
-! Finidat to be updated, The one below not compatible with v3 lnd config (with TOP and BGC mode, new grid)
-! finidat = '$DIN_LOC_ROOT/lnd/clm2/initdata_map/clmi.WCYCL1850-4xCO2.ne30pg2_EC30to60E2r2.SMS_Ld1.c20230213.nc'
- hist_dov2xy = .true.,.true.
- hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
- hist_mfilt = 1,365
- hist_nhtfrq = -24,-24
- hist_avgflag_pertape = 'A','A'
+hist_dov2xy = .true.,.true.
+hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP',
+ 'BAF_PEATF','BIOCHEM_PMIN_TO_PLANT','CH4_SURF_AERE_SAT','CH4_SURF_AERE_UNSAT','CH4_SURF_DIFF_SAT',
+ 'CH4_SURF_DIFF_UNSAT','CH4_SURF_EBUL_SAT','CH4_SURF_EBUL_UNSAT','CMASS_BALANCE_ERROR','cn_scalar',
+ 'COL_PTRUNC','CONC_CH4_SAT','CONC_CH4_UNSAT','CONC_O2_SAT','CONC_O2_UNSAT',
+ 'cp_scalar','CWDC_HR','CWDC_LOSS','CWDC_TO_LITR2C','CWDC_TO_LITR3C',
+ 'CWDC_vr','CWDN_TO_LITR2N','CWDN_TO_LITR3N','CWDN_vr','CWDP_TO_LITR2P',
+ 'CWDP_TO_LITR3P','CWDP_vr','DWT_CONV_CFLUX_DRIBBLED','F_CO2_SOIL','F_CO2_SOIL_vr',
+ 'F_DENIT_vr','F_N2O_DENIT','F_N2O_NIT','F_NIT_vr','FCH4_DFSAT',
+ 'FINUNDATED_LAG','FPI_P_vr','FPI_vr','FROOTC_LOSS','HR_vr',
+ 'LABILEP_TO_SECONDP','LABILEP_vr','LAND_UPTAKE','LEAF_MR','leaf_npimbalance',
+ 'LEAFC_LOSS','LEAFC_TO_LITTER','LFC2','LITR1_HR','LITR1C_TO_SOIL1C',
+ 'LITR1C_vr','LITR1N_TNDNCY_VERT_TRANS','LITR1N_TO_SOIL1N','LITR1N_vr','LITR1P_TNDNCY_VERT_TRANS',
+ 'LITR1P_TO_SOIL1P','LITR1P_vr','LITR2_HR','LITR2C_TO_SOIL2C','LITR2C_vr',
+ 'LITR2N_TNDNCY_VERT_TRANS','LITR2N_TO_SOIL2N','LITR2N_vr','LITR2P_TNDNCY_VERT_TRANS','LITR2P_TO_SOIL2P',
+ 'LITR2P_vr','LITR3_HR','LITR3C_TO_SOIL3C','LITR3C_vr','LITR3N_TNDNCY_VERT_TRANS',
+ 'LITR3N_TO_SOIL3N','LITR3N_vr','LITR3P_TNDNCY_VERT_TRANS','LITR3P_TO_SOIL3P','LITR3P_vr',
+ 'M_LITR1C_TO_LEACHING','M_LITR2C_TO_LEACHING','M_LITR3C_TO_LEACHING','M_SOIL1C_TO_LEACHING','M_SOIL2C_TO_LEACHING',
+ 'M_SOIL3C_TO_LEACHING','M_SOIL4C_TO_LEACHING','NDEPLOY','NEM','nlim_m',
+ 'o2_decomp_depth_unsat','OCCLP_vr','PDEPLOY','PLANT_CALLOC','PLANT_NDEMAND',
+ 'PLANT_NDEMAND_COL','PLANT_PALLOC','PLANT_PDEMAND','PLANT_PDEMAND_COL','plim_m',
+ 'POT_F_DENIT','POT_F_NIT','POTENTIAL_IMMOB','POTENTIAL_IMMOB_P','PRIMP_TO_LABILEP',
+ 'PRIMP_vr','PROD1P_LOSS','QOVER_LAG','RETRANSN_TO_NPOOL','RETRANSP_TO_PPOOL',
+ 'SCALARAVG_vr','SECONDP_TO_LABILEP','SECONDP_TO_OCCLP','SECONDP_vr','SMIN_NH4_vr',
+ 'SMIN_NO3_vr','SMINN_TO_SOIL1N_L1','SMINN_TO_SOIL2N_L2','SMINN_TO_SOIL2N_S1','SMINN_TO_SOIL3N_L3',
+ 'SMINN_TO_SOIL3N_S2','SMINN_TO_SOIL4N_S3','SMINP_TO_SOIL1P_L1','SMINP_TO_SOIL2P_L2','SMINP_TO_SOIL2P_S1',
+ 'SMINP_TO_SOIL3P_L3','SMINP_TO_SOIL3P_S2','SMINP_TO_SOIL4P_S3','SMINP_vr','SOIL1_HR','SOIL1C_TO_SOIL2C','SOIL1C_vr','SOIL1N_TNDNCY_VERT_TRANS','SOIL1N_TO_SOIL2N','SOIL1N_vr',
+ 'SOIL1P_TNDNCY_VERT_TRANS','SOIL1P_TO_SOIL2P','SOIL1P_vr','SOIL2_HR','SOIL2C_TO_SOIL3C',
+ 'SOIL2C_vr','SOIL2N_TNDNCY_VERT_TRANS','SOIL2N_TO_SOIL3N','SOIL2N_vr','SOIL2P_TNDNCY_VERT_TRANS',
+ 'SOIL2P_TO_SOIL3P','SOIL2P_vr','SOIL3_HR','SOIL3C_TO_SOIL4C','SOIL3C_vr',
+ 'SOIL3N_TNDNCY_VERT_TRANS','SOIL3N_TO_SOIL4N','SOIL3N_vr','SOIL3P_TNDNCY_VERT_TRANS','SOIL3P_TO_SOIL4P',
+ 'SOIL3P_vr','SOIL4_HR','SOIL4C_vr','SOIL4N_TNDNCY_VERT_TRANS','SOIL4N_TO_SMINN',
+ 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr',
+ 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF',
+ 'wlim_m','WOODC_LOSS','WTGQ'
+hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC'
+hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
+hist_mfilt = 1,365
+hist_nhtfrq = -24,-24
+hist_avgflag_pertape = 'A','A'
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850_r05/README b/cime_config/testmods_dirs/allactive/wcprod_1850_r05/README
deleted file mode 100644
index 020bbf93e9f2..000000000000
--- a/cime_config/testmods_dirs/allactive/wcprod_1850_r05/README
+++ /dev/null
@@ -1,6 +0,0 @@
-These modifications should result in a case that has the same namelist settings as the
-water cycle production sims
-
-Run these for at least 1 day to see all output.
-Also use the CMIP6 compsets.
-If running longer, change the nhtfrq for the first history file.
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850_r05/shell_commands b/cime_config/testmods_dirs/allactive/wcprod_1850_r05/shell_commands
deleted file mode 100644
index 6e8ae38ac8e9..000000000000
--- a/cime_config/testmods_dirs/allactive/wcprod_1850_r05/shell_commands
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-./xmlchange --append CAM_CONFIG_OPTS='-cosp'
-
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850_r05/user_nl_eam b/cime_config/testmods_dirs/allactive/wcprod_1850_r05/user_nl_eam
deleted file mode 100644
index eeac1d647b1d..000000000000
--- a/cime_config/testmods_dirs/allactive/wcprod_1850_r05/user_nl_eam
+++ /dev/null
@@ -1,11 +0,0 @@
- nhtfrq = -24,-24,-6,-6,-3,-24,-24
- mfilt = 1,30,120,120,240,30,1
- avgflag_pertape = 'A','A','I','A','A','A','I'
- fexcl1 = 'CFAD_SR532_CAL', 'LINOZ_DO3', 'LINOZ_DO3_PSC', 'LINOZ_O3CLIM', 'LINOZ_O3COL', 'LINOZ_SSO3', 'hstobie_linoz'
- fincl1 = 'extinct_sw_inp','extinct_lw_bnd7','extinct_lw_inp','CLD_CAL', 'TREFMNAV', 'TREFMXAV'
- fincl2 = 'FLUT','PRECT','U200','V200','U850','V850','Z500','OMEGA500','UBOT','VBOT','TREFHT','TREFHTMN:M','TREFHTMX:X','QREFHT','TS','PS','TMQ','TUQ','TVQ','TOZ', 'FLDS', 'FLNS', 'FSDS', 'FSNS', 'SHFLX', 'LHFLX', 'TGCLDCWP', 'TGCLDIWP', 'TGCLDLWP', 'CLDTOT', 'T250', 'T200', 'T150', 'T100', 'T050', 'T025', 'T010', 'T005', 'T002', 'T001', 'TTOP', 'U250', 'U150', 'U100', 'U050', 'U025', 'U010', 'U005', 'U002', 'U001', 'UTOP', 'FSNT', 'FLNT'
- fincl3 = 'PSL','T200','T500','U850','V850','UBOT','VBOT','TREFHT', 'Z700', 'TBOT:M'
- fincl4 = 'FLUT','U200','U850','PRECT','OMEGA500'
- fincl5 = 'PRECT','PRECC','TUQ','TVQ','QFLX','SHFLX','U90M','V90M'
- fincl6 = 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANTAU_ISCCP','MEANPTOP_ISCCP','MEANTB_ISCCP','CLDTOT_CAL','CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN','CLDHGH_CAL','CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN','CLDMED_CAL','CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN','CLDLOW_CAL','CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN'
- fincl7 = 'O3', 'PS', 'TROP_P'
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850_r05/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprod_1850_r05/user_nl_elm
deleted file mode 100644
index 9974e1edeb95..000000000000
--- a/cime_config/testmods_dirs/allactive/wcprod_1850_r05/user_nl_elm
+++ /dev/null
@@ -1,7 +0,0 @@
-! Finidat to be updated, The one below not compatible with v3 lnd config (with TOP and BGC mode, new grid)
-! finidat = '${DIN_LOC_ROOT}/lnd/clm2/initdata_map/clmi.WCYCL1850.ne30pg2_r05_EC30to60E2r2.SMS_Ld1.c20230213.nc'
- hist_dov2xy = .true.,.true.
- hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
- hist_mfilt = 1,365
- hist_nhtfrq = -24,-24
- hist_avgflag_pertape = 'A','A'
diff --git a/cime_config/testmods_dirs/allactive/wcprod_1850_r05/user_nl_mosart b/cime_config/testmods_dirs/allactive/wcprod_1850_r05/user_nl_mosart
deleted file mode 100644
index b0a170bcec25..000000000000
--- a/cime_config/testmods_dirs/allactive/wcprod_1850_r05/user_nl_mosart
+++ /dev/null
@@ -1,4 +0,0 @@
- rtmhist_fincl2 = 'RIVER_DISCHARGE_OVER_LAND_LIQ'
- rtmhist_mfilt = 1,365
- rtmhist_ndens = 2
- rtmhist_nhtfrq = -24,-24
diff --git a/cime_config/testmods_dirs/allactive/wcprodrrm/README b/cime_config/testmods_dirs/allactive/wcprodrrm/README
index 22610563ff40..5a23081a3db5 100644
--- a/cime_config/testmods_dirs/allactive/wcprodrrm/README
+++ b/cime_config/testmods_dirs/allactive/wcprodrrm/README
@@ -1,5 +1,2 @@
-The namelist (user_nl_*) and shell commands in this drectory should result in a case
-which is considered as a V2 candidate at this moment (01/26/2020)
-The user_nl_* files should be replaced with "use case" files once v2 configuration
-is finalized.
+These mods should result in output for an RRM production case
diff --git a/cime_config/testmods_dirs/allactive/wcprodrrm/user_nl_eam b/cime_config/testmods_dirs/allactive/wcprodrrm/user_nl_eam
index eeac1d647b1d..095c6946f5de 100644
--- a/cime_config/testmods_dirs/allactive/wcprodrrm/user_nl_eam
+++ b/cime_config/testmods_dirs/allactive/wcprodrrm/user_nl_eam
@@ -1,11 +1,59 @@
- nhtfrq = -24,-24,-6,-6,-3,-24,-24
- mfilt = 1,30,120,120,240,30,1
- avgflag_pertape = 'A','A','I','A','A','A','I'
- fexcl1 = 'CFAD_SR532_CAL', 'LINOZ_DO3', 'LINOZ_DO3_PSC', 'LINOZ_O3CLIM', 'LINOZ_O3COL', 'LINOZ_SSO3', 'hstobie_linoz'
- fincl1 = 'extinct_sw_inp','extinct_lw_bnd7','extinct_lw_inp','CLD_CAL', 'TREFMNAV', 'TREFMXAV'
- fincl2 = 'FLUT','PRECT','U200','V200','U850','V850','Z500','OMEGA500','UBOT','VBOT','TREFHT','TREFHTMN:M','TREFHTMX:X','QREFHT','TS','PS','TMQ','TUQ','TVQ','TOZ', 'FLDS', 'FLNS', 'FSDS', 'FSNS', 'SHFLX', 'LHFLX', 'TGCLDCWP', 'TGCLDIWP', 'TGCLDLWP', 'CLDTOT', 'T250', 'T200', 'T150', 'T100', 'T050', 'T025', 'T010', 'T005', 'T002', 'T001', 'TTOP', 'U250', 'U150', 'U100', 'U050', 'U025', 'U010', 'U005', 'U002', 'U001', 'UTOP', 'FSNT', 'FLNT'
- fincl3 = 'PSL','T200','T500','U850','V850','UBOT','VBOT','TREFHT', 'Z700', 'TBOT:M'
- fincl4 = 'FLUT','U200','U850','PRECT','OMEGA500'
- fincl5 = 'PRECT','PRECC','TUQ','TVQ','QFLX','SHFLX','U90M','V90M'
- fincl6 = 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANTAU_ISCCP','MEANPTOP_ISCCP','MEANTB_ISCCP','CLDTOT_CAL','CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN','CLDHGH_CAL','CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN','CLDMED_CAL','CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN','CLDLOW_CAL','CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN'
- fincl7 = 'O3', 'PS', 'TROP_P'
+cosp_lite = .true.
+
+empty_htapes = .true.
+
+avgflag_pertape = 'A','A','A','A','I','I'
+nhtfrq = -24,-24,-6,-3,-1,-24
+mfilt = 1,30,120,240,720,1
+
+fincl1 = 'AODALL','AODBC','AODDUST','AODPOM','AODSO4','AODSOA','AODSS','AODVIS',
+ 'CLDLOW','CLDMED','CLDHGH','CLDTOT',
+ 'CLDHGH_CAL','CLDLOW_CAL','CLDMED_CAL','CLD_MISR','CLDTOT_CAL',
+ 'CLMODIS','FISCCP1_COSP','FLDS','FLNS','FLNSC','FLNT','FLUT',
+ 'FLUTC','FSDS','FSDSC','FSNS','FSNSC','FSNT','FSNTOA','FSNTOAC','FSNTC',
+ 'ICEFRAC','LANDFRAC','LWCF','OCNFRAC','OMEGA','PRECC','PRECL','PRECSC','PRECSL','PS','PSL','Q',
+ 'QFLX','QREFHT','RELHUM','SCO','SHFLX','SOLIN','SWCF','T','TAUX','TAUY','TCO',
+ 'TGCLDLWP','TMQ','TREFHT','TREFMNAV','TREFMXAV','TS','U','U10','V','Z3',
+ 'dst_a1DDF','dst_a3DDF','dst_c1DDF','dst_c3DDF','dst_a1SFWET','dst_a3SFWET','dst_c1SFWET','dst_c3SFWET',
+ 'O3','LHFLX',
+ 'O3_2DTDA_trop','O3_2DTDB_trop','O3_2DTDD_trop','O3_2DTDE_trop','O3_2DTDI_trop','O3_2DTDL_trop',
+ 'O3_2DTDN_trop','O3_2DTDO_trop','O3_2DTDS_trop','O3_2DTDU_trop','O3_2DTRE_trop','O3_2DTRI_trop',
+ 'O3_SRF','NO_2DTDS','NO_TDLgt','NO2_2DTDD','NO2_2DTDS','NO2_TDAcf','CO_SRF','TROPE3D_P','TROP_P',
+ 'CDNUMC','SFDMS','so4_a1_sfgaex1','so4_a2_sfgaex1','so4_a3_sfgaex1','so4_a5_sfgaex1','soa_a1_sfgaex1',
+ 'soa_a2_sfgaex1','soa_a3_sfgaex1','GS_soa_a1','GS_soa_a2','GS_soa_a3','AQSO4_H2O2','AQSO4_O3',
+ 'SFSO2','SO2_CLXF','SO2','DF_SO2','AQ_SO2','GS_SO2','WD_SO2','ABURDENSO4_STR','ABURDENSO4_TRO',
+ 'ABURDENSO4','ABURDENBC','ABURDENDUST','ABURDENMOM','ABURDENPOM','ABURDENSEASALT',
+ 'ABURDENSOA','AODSO4_STR','AODSO4_TRO',
+ 'EXTINCT','AODABS','AODABSBC','CLDICE','CLDLIQ','CLD_CAL_TMPLIQ','CLD_CAL_TMPICE','Mass_bc_srf',
+ 'Mass_dst_srf','Mass_mom_srf','Mass_ncl_srf','Mass_pom_srf','Mass_so4_srf','Mass_soa_srf','Mass_bc_850',
+ 'Mass_dst_850','Mass_mom_850','Mass_ncl_850','Mass_pom_850','Mass_so4_850','Mass_soa_850','Mass_bc_500',
+ 'Mass_dst_500','Mass_mom_500','Mass_ncl_500','Mass_pom_500','Mass_so4_500','Mass_soa_500','Mass_bc_330',
+ 'Mass_dst_330','Mass_mom_330','Mass_ncl_330','Mass_pom_330','Mass_so4_330','Mass_soa_330','Mass_bc_200',
+ 'Mass_dst_200','Mass_mom_200','Mass_ncl_200','Mass_pom_200','Mass_so4_200','Mass_soa_200',
+ 'O3_2DTDD','O3_2DCIP','O3_2DCIL','CO_2DTDS','CO_2DTDD','CO_2DCEP','CO_2DCEL','NO_2DTDD',
+ 'FLNTC','SAODVIS',
+ 'H2OLNZ',
+ 'dst_a1SF','dst_a3SF',
+ 'PHIS','CLOUD','TGCLDIWP','TGCLDCWP','AREL',
+ 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANPTOP_ISCCP','CLD_CAL',
+ 'CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN',
+ 'CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN',
+ 'CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN',
+ 'CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN',
+ 'CLWMODIS','CLIMODIS'
+
+fincl2 = 'PS', 'FLUT','PRECT','U200','V200','U850','V850',
+ 'TCO','SCO','TREFHTMN','TREFHTMX','TREFHT','QREFHT'
+fincl3 = 'PS', 'PSL','PRECT','TUQ','TVQ','UBOT','VBOT','TREFHT','FLUT','OMEGA500','TBOT','U850','V850','U200','V200','T200','T500','Z700'
+fincl4 = 'PRECT'
+fincl5 = 'O3_SRF'
+fincl6 = 'CO_2DMSD','NO2_2DMSD','NO_2DMSD','O3_2DMSD','O3_2DMSD_trop'
+
+! -- chemUCI settings ------------------
+history_chemdyg_summary = .true.
+history_gaschmbudget_2D = .false.
+history_gaschmbudget_2D_levels = .false.
+history_gaschmbudget_num = 6 !! no impact if history_gaschmbudget_2D = .false.
+
+! -- MAM5 settings ------------------
+is_output_interactive_volc = .true.
diff --git a/cime_config/testmods_dirs/allactive/wcprodrrm/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprodrrm/user_nl_elm
index f6e484326140..cd1adab77404 100644
--- a/cime_config/testmods_dirs/allactive/wcprodrrm/user_nl_elm
+++ b/cime_config/testmods_dirs/allactive/wcprodrrm/user_nl_elm
@@ -1,33 +1,40 @@
-!----------------------------------------------------------------------------------
-! Users should add all user specific namelist changes below in the form of
-! namelist_var = new_namelist_value
-!
-! Include namelist variables for drv_flds_in ONLY if -megan and/or -drydep options
-! are set in the CLM_NAMELIST_OPTS env variable.
-!
-! EXCEPTIONS:
-! Set use_cndv by the compset you use and the CLM_BLDNML_OPTS -dynamic_vegetation setting
-! Set use_vichydro by the compset you use and the CLM_BLDNML_OPTS -vichydro setting
-! Set use_cn by the compset you use and CLM_BLDNML_OPTS -bgc setting
-! Set use_crop by the compset you use and CLM_BLDNML_OPTS -crop setting
-! Set spinup_state by the CLM_BLDNML_OPTS -bgc_spinup setting
-! Set irrigate by the CLM_BLDNML_OPTS -irrig setting
-! Set co2_ppmv with CCSM_CO2_PPMV option
-! Set dtime with L_NCPL option
-! Set fatmlndfrc with LND_DOMAIN_PATH/LND_DOMAIN_FILE options
-! Set finidat with RUN_REFCASE/RUN_REFDATE/RUN_REFTOD options for hybrid or branch cases
-! (includes $inst_string for multi-ensemble cases)
-! Set glc_grid with CISM_GRID option
-! Set glc_smb with GLC_SMB option
-! Set maxpatch_glcmec with GLC_NEC option
-! Set glc_do_dynglacier with GLC_TWO_WAY_COUPLING env variable
-!----------------------------------------------------------------------------------
-
- check_finidat_year_consistency = .false.
- hist_dov2xy = .true.,.true. check_finidat_year_consistency = .false.
- hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE'
- hist_mfilt = 1,365
- hist_nhtfrq = 0,-24
- hist_avgflag_pertape = 'A','A'
- check_finidat_year_consistency = .false.
- !finidat = '${case_scripts_dir}/../init/remap_to_naRRMpg2_20201217.beta1_01.piControlSI.compy.elm.r.0121-01-01-00000.nc'
\ No newline at end of file
+hist_dov2xy = .true.,.true.
+hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP',
+ 'BAF_PEATF','BIOCHEM_PMIN_TO_PLANT','CH4_SURF_AERE_SAT','CH4_SURF_AERE_UNSAT','CH4_SURF_DIFF_SAT',
+ 'CH4_SURF_DIFF_UNSAT','CH4_SURF_EBUL_SAT','CH4_SURF_EBUL_UNSAT','CMASS_BALANCE_ERROR','cn_scalar',
+ 'COL_PTRUNC','CONC_CH4_SAT','CONC_CH4_UNSAT','CONC_O2_SAT','CONC_O2_UNSAT',
+ 'cp_scalar','CWDC_HR','CWDC_LOSS','CWDC_TO_LITR2C','CWDC_TO_LITR3C',
+ 'CWDC_vr','CWDN_TO_LITR2N','CWDN_TO_LITR3N','CWDN_vr','CWDP_TO_LITR2P',
+ 'CWDP_TO_LITR3P','CWDP_vr','DWT_CONV_CFLUX_DRIBBLED','F_CO2_SOIL','F_CO2_SOIL_vr',
+ 'F_DENIT_vr','F_N2O_DENIT','F_N2O_NIT','F_NIT_vr','FCH4_DFSAT',
+ 'FINUNDATED_LAG','FPI_P_vr','FPI_vr','FROOTC_LOSS','HR_vr',
+ 'LABILEP_TO_SECONDP','LABILEP_vr','LAND_UPTAKE','LEAF_MR','leaf_npimbalance',
+ 'LEAFC_LOSS','LEAFC_TO_LITTER','LFC2','LITR1_HR','LITR1C_TO_SOIL1C',
+ 'LITR1C_vr','LITR1N_TNDNCY_VERT_TRANS','LITR1N_TO_SOIL1N','LITR1N_vr','LITR1P_TNDNCY_VERT_TRANS',
+ 'LITR1P_TO_SOIL1P','LITR1P_vr','LITR2_HR','LITR2C_TO_SOIL2C','LITR2C_vr',
+ 'LITR2N_TNDNCY_VERT_TRANS','LITR2N_TO_SOIL2N','LITR2N_vr','LITR2P_TNDNCY_VERT_TRANS','LITR2P_TO_SOIL2P',
+ 'LITR2P_vr','LITR3_HR','LITR3C_TO_SOIL3C','LITR3C_vr','LITR3N_TNDNCY_VERT_TRANS',
+ 'LITR3N_TO_SOIL3N','LITR3N_vr','LITR3P_TNDNCY_VERT_TRANS','LITR3P_TO_SOIL3P','LITR3P_vr',
+ 'M_LITR1C_TO_LEACHING','M_LITR2C_TO_LEACHING','M_LITR3C_TO_LEACHING','M_SOIL1C_TO_LEACHING','M_SOIL2C_TO_LEACHING',
+ 'M_SOIL3C_TO_LEACHING','M_SOIL4C_TO_LEACHING','NDEPLOY','NEM','nlim_m',
+ 'o2_decomp_depth_unsat','OCCLP_vr','PDEPLOY','PLANT_CALLOC','PLANT_NDEMAND',
+ 'PLANT_NDEMAND_COL','PLANT_PALLOC','PLANT_PDEMAND','PLANT_PDEMAND_COL','plim_m',
+ 'POT_F_DENIT','POT_F_NIT','POTENTIAL_IMMOB','POTENTIAL_IMMOB_P','PRIMP_TO_LABILEP',
+ 'PRIMP_vr','PROD1P_LOSS','QOVER_LAG','RETRANSN_TO_NPOOL','RETRANSP_TO_PPOOL',
+ 'SCALARAVG_vr','SECONDP_TO_LABILEP','SECONDP_TO_OCCLP','SECONDP_vr','SMIN_NH4_vr',
+ 'SMIN_NO3_vr','SMINN_TO_SOIL1N_L1','SMINN_TO_SOIL2N_L2','SMINN_TO_SOIL2N_S1','SMINN_TO_SOIL3N_L3',
+ 'SMINN_TO_SOIL3N_S2','SMINN_TO_SOIL4N_S3','SMINP_TO_SOIL1P_L1','SMINP_TO_SOIL2P_L2','SMINP_TO_SOIL2P_S1',
+ 'SMINP_TO_SOIL3P_L3','SMINP_TO_SOIL3P_S2','SMINP_TO_SOIL4P_S3','SMINP_vr','SOIL1_HR','SOIL1C_TO_SOIL2C','SOIL1C_vr','SOIL1N_TNDNCY_VERT_TRANS','SOIL1N_TO_SOIL2N','SOIL1N_vr',
+ 'SOIL1P_TNDNCY_VERT_TRANS','SOIL1P_TO_SOIL2P','SOIL1P_vr','SOIL2_HR','SOIL2C_TO_SOIL3C',
+ 'SOIL2C_vr','SOIL2N_TNDNCY_VERT_TRANS','SOIL2N_TO_SOIL3N','SOIL2N_vr','SOIL2P_TNDNCY_VERT_TRANS',
+ 'SOIL2P_TO_SOIL3P','SOIL2P_vr','SOIL3_HR','SOIL3C_TO_SOIL4C','SOIL3C_vr',
+ 'SOIL3N_TNDNCY_VERT_TRANS','SOIL3N_TO_SOIL4N','SOIL3N_vr','SOIL3P_TNDNCY_VERT_TRANS','SOIL3P_TO_SOIL4P',
+ 'SOIL3P_vr','SOIL4_HR','SOIL4C_vr','SOIL4N_TNDNCY_VERT_TRANS','SOIL4N_TO_SMINN',
+ 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr',
+ 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF',
+ 'wlim_m','WOODC_LOSS','WTGQ'
+hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC'
+hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
+hist_mfilt = 1,365
+hist_nhtfrq = -24,-24
+hist_avgflag_pertape = 'A','A'
diff --git a/cime_config/testmods_dirs/allactive/wcprodrrm_1850/README b/cime_config/testmods_dirs/allactive/wcprodrrm_1850/README
index 22610563ff40..e701b223a6a9 100644
--- a/cime_config/testmods_dirs/allactive/wcprodrrm_1850/README
+++ b/cime_config/testmods_dirs/allactive/wcprodrrm_1850/README
@@ -1,5 +1,2 @@
-The namelist (user_nl_*) and shell commands in this drectory should result in a case
-which is considered as a V2 candidate at this moment (01/26/2020)
-The user_nl_* files should be replaced with "use case" files once v2 configuration
-is finalized.
+These mods should result in production output for an 1850 RRM case
diff --git a/cime_config/testmods_dirs/allactive/wcprodrrm_1850/user_nl_eam b/cime_config/testmods_dirs/allactive/wcprodrrm_1850/user_nl_eam
index eeac1d647b1d..095c6946f5de 100644
--- a/cime_config/testmods_dirs/allactive/wcprodrrm_1850/user_nl_eam
+++ b/cime_config/testmods_dirs/allactive/wcprodrrm_1850/user_nl_eam
@@ -1,11 +1,59 @@
- nhtfrq = -24,-24,-6,-6,-3,-24,-24
- mfilt = 1,30,120,120,240,30,1
- avgflag_pertape = 'A','A','I','A','A','A','I'
- fexcl1 = 'CFAD_SR532_CAL', 'LINOZ_DO3', 'LINOZ_DO3_PSC', 'LINOZ_O3CLIM', 'LINOZ_O3COL', 'LINOZ_SSO3', 'hstobie_linoz'
- fincl1 = 'extinct_sw_inp','extinct_lw_bnd7','extinct_lw_inp','CLD_CAL', 'TREFMNAV', 'TREFMXAV'
- fincl2 = 'FLUT','PRECT','U200','V200','U850','V850','Z500','OMEGA500','UBOT','VBOT','TREFHT','TREFHTMN:M','TREFHTMX:X','QREFHT','TS','PS','TMQ','TUQ','TVQ','TOZ', 'FLDS', 'FLNS', 'FSDS', 'FSNS', 'SHFLX', 'LHFLX', 'TGCLDCWP', 'TGCLDIWP', 'TGCLDLWP', 'CLDTOT', 'T250', 'T200', 'T150', 'T100', 'T050', 'T025', 'T010', 'T005', 'T002', 'T001', 'TTOP', 'U250', 'U150', 'U100', 'U050', 'U025', 'U010', 'U005', 'U002', 'U001', 'UTOP', 'FSNT', 'FLNT'
- fincl3 = 'PSL','T200','T500','U850','V850','UBOT','VBOT','TREFHT', 'Z700', 'TBOT:M'
- fincl4 = 'FLUT','U200','U850','PRECT','OMEGA500'
- fincl5 = 'PRECT','PRECC','TUQ','TVQ','QFLX','SHFLX','U90M','V90M'
- fincl6 = 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANTAU_ISCCP','MEANPTOP_ISCCP','MEANTB_ISCCP','CLDTOT_CAL','CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN','CLDHGH_CAL','CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN','CLDMED_CAL','CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN','CLDLOW_CAL','CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN'
- fincl7 = 'O3', 'PS', 'TROP_P'
+cosp_lite = .true.
+
+empty_htapes = .true.
+
+avgflag_pertape = 'A','A','A','A','I','I'
+nhtfrq = -24,-24,-6,-3,-1,-24
+mfilt = 1,30,120,240,720,1
+
+fincl1 = 'AODALL','AODBC','AODDUST','AODPOM','AODSO4','AODSOA','AODSS','AODVIS',
+ 'CLDLOW','CLDMED','CLDHGH','CLDTOT',
+ 'CLDHGH_CAL','CLDLOW_CAL','CLDMED_CAL','CLD_MISR','CLDTOT_CAL',
+ 'CLMODIS','FISCCP1_COSP','FLDS','FLNS','FLNSC','FLNT','FLUT',
+ 'FLUTC','FSDS','FSDSC','FSNS','FSNSC','FSNT','FSNTOA','FSNTOAC','FSNTC',
+ 'ICEFRAC','LANDFRAC','LWCF','OCNFRAC','OMEGA','PRECC','PRECL','PRECSC','PRECSL','PS','PSL','Q',
+ 'QFLX','QREFHT','RELHUM','SCO','SHFLX','SOLIN','SWCF','T','TAUX','TAUY','TCO',
+ 'TGCLDLWP','TMQ','TREFHT','TREFMNAV','TREFMXAV','TS','U','U10','V','Z3',
+ 'dst_a1DDF','dst_a3DDF','dst_c1DDF','dst_c3DDF','dst_a1SFWET','dst_a3SFWET','dst_c1SFWET','dst_c3SFWET',
+ 'O3','LHFLX',
+ 'O3_2DTDA_trop','O3_2DTDB_trop','O3_2DTDD_trop','O3_2DTDE_trop','O3_2DTDI_trop','O3_2DTDL_trop',
+ 'O3_2DTDN_trop','O3_2DTDO_trop','O3_2DTDS_trop','O3_2DTDU_trop','O3_2DTRE_trop','O3_2DTRI_trop',
+ 'O3_SRF','NO_2DTDS','NO_TDLgt','NO2_2DTDD','NO2_2DTDS','NO2_TDAcf','CO_SRF','TROPE3D_P','TROP_P',
+ 'CDNUMC','SFDMS','so4_a1_sfgaex1','so4_a2_sfgaex1','so4_a3_sfgaex1','so4_a5_sfgaex1','soa_a1_sfgaex1',
+ 'soa_a2_sfgaex1','soa_a3_sfgaex1','GS_soa_a1','GS_soa_a2','GS_soa_a3','AQSO4_H2O2','AQSO4_O3',
+ 'SFSO2','SO2_CLXF','SO2','DF_SO2','AQ_SO2','GS_SO2','WD_SO2','ABURDENSO4_STR','ABURDENSO4_TRO',
+ 'ABURDENSO4','ABURDENBC','ABURDENDUST','ABURDENMOM','ABURDENPOM','ABURDENSEASALT',
+ 'ABURDENSOA','AODSO4_STR','AODSO4_TRO',
+ 'EXTINCT','AODABS','AODABSBC','CLDICE','CLDLIQ','CLD_CAL_TMPLIQ','CLD_CAL_TMPICE','Mass_bc_srf',
+ 'Mass_dst_srf','Mass_mom_srf','Mass_ncl_srf','Mass_pom_srf','Mass_so4_srf','Mass_soa_srf','Mass_bc_850',
+ 'Mass_dst_850','Mass_mom_850','Mass_ncl_850','Mass_pom_850','Mass_so4_850','Mass_soa_850','Mass_bc_500',
+ 'Mass_dst_500','Mass_mom_500','Mass_ncl_500','Mass_pom_500','Mass_so4_500','Mass_soa_500','Mass_bc_330',
+ 'Mass_dst_330','Mass_mom_330','Mass_ncl_330','Mass_pom_330','Mass_so4_330','Mass_soa_330','Mass_bc_200',
+ 'Mass_dst_200','Mass_mom_200','Mass_ncl_200','Mass_pom_200','Mass_so4_200','Mass_soa_200',
+ 'O3_2DTDD','O3_2DCIP','O3_2DCIL','CO_2DTDS','CO_2DTDD','CO_2DCEP','CO_2DCEL','NO_2DTDD',
+ 'FLNTC','SAODVIS',
+ 'H2OLNZ',
+ 'dst_a1SF','dst_a3SF',
+ 'PHIS','CLOUD','TGCLDIWP','TGCLDCWP','AREL',
+ 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANPTOP_ISCCP','CLD_CAL',
+ 'CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN',
+ 'CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN',
+ 'CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN',
+ 'CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN',
+ 'CLWMODIS','CLIMODIS'
+
+fincl2 = 'PS', 'FLUT','PRECT','U200','V200','U850','V850',
+ 'TCO','SCO','TREFHTMN','TREFHTMX','TREFHT','QREFHT'
+fincl3 = 'PS', 'PSL','PRECT','TUQ','TVQ','UBOT','VBOT','TREFHT','FLUT','OMEGA500','TBOT','U850','V850','U200','V200','T200','T500','Z700'
+fincl4 = 'PRECT'
+fincl5 = 'O3_SRF'
+fincl6 = 'CO_2DMSD','NO2_2DMSD','NO_2DMSD','O3_2DMSD','O3_2DMSD_trop'
+
+! -- chemUCI settings ------------------
+history_chemdyg_summary = .true.
+history_gaschmbudget_2D = .false.
+history_gaschmbudget_2D_levels = .false.
+history_gaschmbudget_num = 6 !! no impact if history_gaschmbudget_2D = .false.
+
+! -- MAM5 settings ------------------
+is_output_interactive_volc = .true.
diff --git a/cime_config/testmods_dirs/allactive/wcprodrrm_1850/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprodrrm_1850/user_nl_elm
index 8570ad3cf598..cd1adab77404 100644
--- a/cime_config/testmods_dirs/allactive/wcprodrrm_1850/user_nl_elm
+++ b/cime_config/testmods_dirs/allactive/wcprodrrm_1850/user_nl_elm
@@ -1,34 +1,40 @@
-!----------------------------------------------------------------------------------
-! Users should add all user specific namelist changes below in the form of
-! namelist_var = new_namelist_value
-!
-! Include namelist variables for drv_flds_in ONLY if -megan and/or -drydep options
-! are set in the CLM_NAMELIST_OPTS env variable.
-!
-! EXCEPTIONS:
-! Set use_cndv by the compset you use and the CLM_BLDNML_OPTS -dynamic_vegetation setting
-! Set use_vichydro by the compset you use and the CLM_BLDNML_OPTS -vichydro setting
-! Set use_cn by the compset you use and CLM_BLDNML_OPTS -bgc setting
-! Set use_crop by the compset you use and CLM_BLDNML_OPTS -crop setting
-! Set spinup_state by the CLM_BLDNML_OPTS -bgc_spinup setting
-! Set irrigate by the CLM_BLDNML_OPTS -irrig setting
-! Set co2_ppmv with CCSM_CO2_PPMV option
-! Set dtime with L_NCPL option
-! Set fatmlndfrc with LND_DOMAIN_PATH/LND_DOMAIN_FILE options
-! Set finidat with RUN_REFCASE/RUN_REFDATE/RUN_REFTOD options for hybrid or branch cases
-! (includes $inst_string for multi-ensemble cases)
-! Set glc_grid with CISM_GRID option
-! Set glc_smb with GLC_SMB option
-! Set maxpatch_glcmec with GLC_NEC option
-! Set glc_do_dynglacier with GLC_TWO_WAY_COUPLING env variable
-!----------------------------------------------------------------------------------
-
- check_finidat_year_consistency = .false.
- hist_dov2xy = .true.,.true. check_finidat_year_consistency = .false.
- hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE'
- hist_mfilt = 1,365
- hist_nhtfrq = 0,-24
- hist_avgflag_pertape = 'A','A'
- check_finidat_year_consistency = .false.
-! Finidat to be updated, The one below not compatible with v3 lnd config (with TOP and BGC mode, new grid)
-! finidat = '${DIN_LOC_ROOT}/lnd/clm2/initdata_map/clmi.WCYCL1850.northamericax4v1pg2_WC14to60E2r3.SMS_PS.c20230213.nc'
+hist_dov2xy = .true.,.true.
+hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP',
+ 'BAF_PEATF','BIOCHEM_PMIN_TO_PLANT','CH4_SURF_AERE_SAT','CH4_SURF_AERE_UNSAT','CH4_SURF_DIFF_SAT',
+ 'CH4_SURF_DIFF_UNSAT','CH4_SURF_EBUL_SAT','CH4_SURF_EBUL_UNSAT','CMASS_BALANCE_ERROR','cn_scalar',
+ 'COL_PTRUNC','CONC_CH4_SAT','CONC_CH4_UNSAT','CONC_O2_SAT','CONC_O2_UNSAT',
+ 'cp_scalar','CWDC_HR','CWDC_LOSS','CWDC_TO_LITR2C','CWDC_TO_LITR3C',
+ 'CWDC_vr','CWDN_TO_LITR2N','CWDN_TO_LITR3N','CWDN_vr','CWDP_TO_LITR2P',
+ 'CWDP_TO_LITR3P','CWDP_vr','DWT_CONV_CFLUX_DRIBBLED','F_CO2_SOIL','F_CO2_SOIL_vr',
+ 'F_DENIT_vr','F_N2O_DENIT','F_N2O_NIT','F_NIT_vr','FCH4_DFSAT',
+ 'FINUNDATED_LAG','FPI_P_vr','FPI_vr','FROOTC_LOSS','HR_vr',
+ 'LABILEP_TO_SECONDP','LABILEP_vr','LAND_UPTAKE','LEAF_MR','leaf_npimbalance',
+ 'LEAFC_LOSS','LEAFC_TO_LITTER','LFC2','LITR1_HR','LITR1C_TO_SOIL1C',
+ 'LITR1C_vr','LITR1N_TNDNCY_VERT_TRANS','LITR1N_TO_SOIL1N','LITR1N_vr','LITR1P_TNDNCY_VERT_TRANS',
+ 'LITR1P_TO_SOIL1P','LITR1P_vr','LITR2_HR','LITR2C_TO_SOIL2C','LITR2C_vr',
+ 'LITR2N_TNDNCY_VERT_TRANS','LITR2N_TO_SOIL2N','LITR2N_vr','LITR2P_TNDNCY_VERT_TRANS','LITR2P_TO_SOIL2P',
+ 'LITR2P_vr','LITR3_HR','LITR3C_TO_SOIL3C','LITR3C_vr','LITR3N_TNDNCY_VERT_TRANS',
+ 'LITR3N_TO_SOIL3N','LITR3N_vr','LITR3P_TNDNCY_VERT_TRANS','LITR3P_TO_SOIL3P','LITR3P_vr',
+ 'M_LITR1C_TO_LEACHING','M_LITR2C_TO_LEACHING','M_LITR3C_TO_LEACHING','M_SOIL1C_TO_LEACHING','M_SOIL2C_TO_LEACHING',
+ 'M_SOIL3C_TO_LEACHING','M_SOIL4C_TO_LEACHING','NDEPLOY','NEM','nlim_m',
+ 'o2_decomp_depth_unsat','OCCLP_vr','PDEPLOY','PLANT_CALLOC','PLANT_NDEMAND',
+ 'PLANT_NDEMAND_COL','PLANT_PALLOC','PLANT_PDEMAND','PLANT_PDEMAND_COL','plim_m',
+ 'POT_F_DENIT','POT_F_NIT','POTENTIAL_IMMOB','POTENTIAL_IMMOB_P','PRIMP_TO_LABILEP',
+ 'PRIMP_vr','PROD1P_LOSS','QOVER_LAG','RETRANSN_TO_NPOOL','RETRANSP_TO_PPOOL',
+ 'SCALARAVG_vr','SECONDP_TO_LABILEP','SECONDP_TO_OCCLP','SECONDP_vr','SMIN_NH4_vr',
+ 'SMIN_NO3_vr','SMINN_TO_SOIL1N_L1','SMINN_TO_SOIL2N_L2','SMINN_TO_SOIL2N_S1','SMINN_TO_SOIL3N_L3',
+ 'SMINN_TO_SOIL3N_S2','SMINN_TO_SOIL4N_S3','SMINP_TO_SOIL1P_L1','SMINP_TO_SOIL2P_L2','SMINP_TO_SOIL2P_S1',
+ 'SMINP_TO_SOIL3P_L3','SMINP_TO_SOIL3P_S2','SMINP_TO_SOIL4P_S3','SMINP_vr','SOIL1_HR','SOIL1C_TO_SOIL2C','SOIL1C_vr','SOIL1N_TNDNCY_VERT_TRANS','SOIL1N_TO_SOIL2N','SOIL1N_vr',
+ 'SOIL1P_TNDNCY_VERT_TRANS','SOIL1P_TO_SOIL2P','SOIL1P_vr','SOIL2_HR','SOIL2C_TO_SOIL3C',
+ 'SOIL2C_vr','SOIL2N_TNDNCY_VERT_TRANS','SOIL2N_TO_SOIL3N','SOIL2N_vr','SOIL2P_TNDNCY_VERT_TRANS',
+ 'SOIL2P_TO_SOIL3P','SOIL2P_vr','SOIL3_HR','SOIL3C_TO_SOIL4C','SOIL3C_vr',
+ 'SOIL3N_TNDNCY_VERT_TRANS','SOIL3N_TO_SOIL4N','SOIL3N_vr','SOIL3P_TNDNCY_VERT_TRANS','SOIL3P_TO_SOIL4P',
+ 'SOIL3P_vr','SOIL4_HR','SOIL4C_vr','SOIL4N_TNDNCY_VERT_TRANS','SOIL4N_TO_SMINN',
+ 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr',
+ 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF',
+ 'wlim_m','WOODC_LOSS','WTGQ'
+hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC'
+hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
+hist_mfilt = 1,365
+hist_nhtfrq = -24,-24
+hist_avgflag_pertape = 'A','A'
diff --git a/cime_config/testmods_dirs/allactive/wcprodssp/README b/cime_config/testmods_dirs/allactive/wcprodssp/README
index 65ebc5afc662..66e4a6d06eaa 100644
--- a/cime_config/testmods_dirs/allactive/wcprodssp/README
+++ b/cime_config/testmods_dirs/allactive/wcprodssp/README
@@ -1,9 +1,8 @@
Modifications (in shell_commands) to enable a hybrid run for SSP compsets
-(e.g., SSp370 or SSP585), starting from 2015-01-01 of v2.LR.historical_0101
+(e.g., SSP370 or SSP585), starting from end of v3 historical run
Other modifications (same as for wcprod) should result in a case that has the
same namelist settings as the water cycle production sims
Run these for at least 1 day to see all output.
Also use the CMIP6 compsets.
-If running longer, change the nhtfrq for the first history file.
diff --git a/cime_config/testmods_dirs/allactive/wcprodssp/shell_commands b/cime_config/testmods_dirs/allactive/wcprodssp/shell_commands
index 0ef3c8cc8efa..91b8f207046c 100644
--- a/cime_config/testmods_dirs/allactive/wcprodssp/shell_commands
+++ b/cime_config/testmods_dirs/allactive/wcprodssp/shell_commands
@@ -6,9 +6,9 @@
./xmlchange RUN_TYPE="hybrid"
./xmlchange GET_REFCASE="TRUE"
- ./xmlchange RUN_REFCASE="v2.LR.historical_0101"
+ ./xmlchange RUN_REFCASE="v3.LR.historical_0101"
./xmlchange RUN_REFDATE="2015-01-01"
- ./xmlchange RUN_REFDIR=${INPUTDATA_ROOT}"/e3sm_init/V2.SSP370_SSP585.ne30pg2_EC30to60E2r2/v2.LR.historical_0101/2015-01-01-00000"
+ ./xmlchange RUN_REFDIR=${INPUTDATA_ROOT}"/e3sm_init/v3.SSP.ne30pg2_r05_IcoswISC30E3r5/v3.LR.historical_0101/2015-01-01-00000"
exit
diff --git a/cime_config/testmods_dirs/allactive/wcprodssp/user_nl_eam b/cime_config/testmods_dirs/allactive/wcprodssp/user_nl_eam
index b83a8c6ca22d..7ef3e3782a32 100644
--- a/cime_config/testmods_dirs/allactive/wcprodssp/user_nl_eam
+++ b/cime_config/testmods_dirs/allactive/wcprodssp/user_nl_eam
@@ -1,16 +1,59 @@
- nhtfrq = -24,-24,-6,-6,-3,-24,-24
- mfilt = 1,30,120,120,240,30,1
- avgflag_pertape = 'A','A','I','A','A','A','I'
-!temporarily remove LINOZ O3 related fields from the list until updated linoz v3 style inputdata is ready
-!fexcl1 = 'CFAD_SR532_CAL', 'LINOZ_DO3', 'LINOZ_DO3_PSC', 'LINOZ_O3CLIM', 'LINOZ_O3COL', 'LINOZ_SSO3', 'hstobie_linoz'
- fexcl1 = 'CFAD_SR532_CAL', 'hstobie_linoz'
- fincl1 = 'extinct_sw_inp','extinct_lw_bnd7','extinct_lw_inp','CLD_CAL', 'TREFMNAV', 'TREFMXAV'
- fincl2 = 'FLUT','PRECT','U200','V200','U850','V850','Z500','OMEGA500','UBOT','VBOT','TREFHT','TREFHTMN:M','TREFHTMX:X','QREFHT','TS','PS','TMQ','TUQ','TVQ','TOZ', 'FLDS', 'FLNS', 'FSDS', 'FSNS', 'SHFLX', 'LHFLX', 'TGCLDCWP', 'TGCLDIWP', 'TGCLDLWP', 'CLDTOT', 'T250', 'T200', 'T150', 'T100', 'T050', 'T025', 'T010', 'T005', 'T002', 'T001', 'TTOP', 'U250', 'U150', 'U100', 'U050', 'U025', 'U010', 'U005', 'U002', 'U001', 'UTOP', 'FSNT', 'FLNT'
- fincl3 = 'PSL','T200','T500','U850','V850','UBOT','VBOT','TREFHT', 'Z700', 'TBOT:M'
- fincl4 = 'FLUT','U200','U850','PRECT','OMEGA500'
- fincl5 = 'PRECT','PRECC','TUQ','TVQ','QFLX','SHFLX','U90M','V90M'
- fincl6 = 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANTAU_ISCCP','MEANPTOP_ISCCP','MEANTB_ISCCP','CLDTOT_CAL','CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN','CLDHGH_CAL','CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN','CLDMED_CAL','CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN','CLDLOW_CAL','CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN'
- fincl7 = 'O3', 'PS', 'TROP_P'
+ cosp_lite = .true.
-! Specify an L80 IC to override eam.i from reference case, which is still for L72
- ncdata = '$DIN_LOC_ROOT/atm/cam/inic/homme/eami_mam4_Linoz_ne30np4_L80_c20231010.nc'
+ empty_htapes = .true.
+
+ avgflag_pertape = 'A','A','A','A','I','I'
+ nhtfrq = -24,-24,-6,-3,-1,0
+ mfilt = 1,30,120,240,720,1
+
+ fincl1 = 'AODALL','AODBC','AODDUST','AODPOM','AODSO4','AODSOA','AODSS','AODVIS',
+ 'CLDLOW','CLDMED','CLDHGH','CLDTOT',
+ 'CLDHGH_CAL','CLDLOW_CAL','CLDMED_CAL','CLD_MISR','CLDTOT_CAL',
+ 'CLMODIS','FISCCP1_COSP','FLDS','FLNS','FLNSC','FLNT','FLUT',
+ 'FLUTC','FSDS','FSDSC','FSNS','FSNSC','FSNT','FSNTOA','FSNTOAC','FSNTC',
+ 'ICEFRAC','LANDFRAC','LWCF','OCNFRAC','OMEGA','PRECC','PRECL','PRECSC','PRECSL','PS','PSL','Q',
+ 'QFLX','QREFHT','RELHUM','SCO','SHFLX','SOLIN','SWCF','T','TAUX','TAUY','TCO',
+ 'TGCLDLWP','TMQ','TREFHT','TREFMNAV','TREFMXAV','TS','U','U10','V','Z3',
+ 'dst_a1DDF','dst_a3DDF','dst_c1DDF','dst_c3DDF','dst_a1SFWET','dst_a3SFWET','dst_c1SFWET','dst_c3SFWET',
+ 'O3','LHFLX',
+ 'O3_2DTDA_trop','O3_2DTDB_trop','O3_2DTDD_trop','O3_2DTDE_trop','O3_2DTDI_trop','O3_2DTDL_trop',
+ 'O3_2DTDN_trop','O3_2DTDO_trop','O3_2DTDS_trop','O3_2DTDU_trop','O3_2DTRE_trop','O3_2DTRI_trop',
+ 'O3_SRF','NO_2DTDS','NO_TDLgt','NO2_2DTDD','NO2_2DTDS','NO2_TDAcf','CO_SRF','TROPE3D_P','TROP_P',
+ 'CDNUMC','SFDMS','so4_a1_sfgaex1','so4_a2_sfgaex1','so4_a3_sfgaex1','so4_a5_sfgaex1','soa_a1_sfgaex1',
+ 'soa_a2_sfgaex1','soa_a3_sfgaex1','GS_soa_a1','GS_soa_a2','GS_soa_a3','AQSO4_H2O2','AQSO4_O3',
+ 'SFSO2','SO2_CLXF','SO2','DF_SO2','AQ_SO2','GS_SO2','WD_SO2','ABURDENSO4_STR','ABURDENSO4_TRO',
+ 'ABURDENSO4','ABURDENBC','ABURDENDUST','ABURDENMOM','ABURDENPOM','ABURDENSEASALT',
+ 'ABURDENSOA','AODSO4_STR','AODSO4_TRO',
+ 'EXTINCT','AODABS','AODABSBC','CLDICE','CLDLIQ','CLD_CAL_TMPLIQ','CLD_CAL_TMPICE','Mass_bc_srf',
+ 'Mass_dst_srf','Mass_mom_srf','Mass_ncl_srf','Mass_pom_srf','Mass_so4_srf','Mass_soa_srf','Mass_bc_850',
+ 'Mass_dst_850','Mass_mom_850','Mass_ncl_850','Mass_pom_850','Mass_so4_850','Mass_soa_850','Mass_bc_500',
+ 'Mass_dst_500','Mass_mom_500','Mass_ncl_500','Mass_pom_500','Mass_so4_500','Mass_soa_500','Mass_bc_330',
+ 'Mass_dst_330','Mass_mom_330','Mass_ncl_330','Mass_pom_330','Mass_so4_330','Mass_soa_330','Mass_bc_200',
+ 'Mass_dst_200','Mass_mom_200','Mass_ncl_200','Mass_pom_200','Mass_so4_200','Mass_soa_200',
+ 'O3_2DTDD','O3_2DCIP','O3_2DCIL','CO_2DTDS','CO_2DTDD','CO_2DCEP','CO_2DCEL','NO_2DTDD',
+ 'FLNTC','SAODVIS',
+ 'H2OLNZ',
+ 'dst_a1SF','dst_a3SF',
+ 'PHIS','CLOUD','TGCLDIWP','TGCLDCWP','AREL',
+ 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANPTOP_ISCCP','CLD_CAL',
+ 'CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN',
+ 'CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN',
+ 'CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN',
+ 'CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN',
+ 'CLWMODIS','CLIMODIS'
+
+ fincl2 = 'PS', 'FLUT','PRECT','U200','V200','U850','V850',
+ 'TCO','SCO','TREFHTMN:M','TREFHTMX:X','TREFHT','QREFHT'
+ fincl3 = 'PS', 'PSL','PRECT','TUQ','TVQ','UBOT','VBOT','TREFHT','FLUT','OMEGA500','TBOT','U850','V850','U200','V200','T200','T500','Z700'
+ fincl4 = 'PRECT'
+ fincl5 = 'O3_SRF'
+ fincl6 = 'CO_2DMSD','NO2_2DMSD','NO_2DMSD','O3_2DMSD','O3_2DMSD_trop'
+
+ ! -- chemUCI settings ------------------
+ history_chemdyg_summary = .true.
+ history_gaschmbudget_2D = .false.
+ history_gaschmbudget_2D_levels = .false.
+ history_gaschmbudget_num = 6 !! no impact if history_gaschmbudget_2D = .false.
+
+ ! -- MAM5 settings ------------------
+ is_output_interactive_volc = .true.
diff --git a/cime_config/testmods_dirs/allactive/wcprodssp/user_nl_elm b/cime_config/testmods_dirs/allactive/wcprodssp/user_nl_elm
index ed03b5e2616d..7bfdbac5c84b 100644
--- a/cime_config/testmods_dirs/allactive/wcprodssp/user_nl_elm
+++ b/cime_config/testmods_dirs/allactive/wcprodssp/user_nl_elm
@@ -1,9 +1,44 @@
-! fsurdat used is not the same file for the reference historical run (as recorded in elm.r's global attribute)
+! fsurdat might be set to be not the same file for the reference historical run (as recorded in elm.r's global attribute)
CHECK_FINIDAT_FSURDAT_CONSISTENCY = .false.
-! Finidat to be updated, The one below not compatible with v3 lnd config (with TOP and BGC mode, new grid)
-! finidat = "$DIN_LOC_ROOT/e3sm_init/V2.SSP370_SSP585.ne30pg2_EC30to60E2r2/v2.LR.historical_0101/2015-01-01-00000/v2.LR.historical_0101.elm.r.noNaN.2015-01-01-00000.nc"
+
+
hist_dov2xy = .true.,.true.
+ hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP',
+ 'BAF_PEATF','BIOCHEM_PMIN_TO_PLANT','CH4_SURF_AERE_SAT','CH4_SURF_AERE_UNSAT','CH4_SURF_DIFF_SAT',
+ 'CH4_SURF_DIFF_UNSAT','CH4_SURF_EBUL_SAT','CH4_SURF_EBUL_UNSAT','CMASS_BALANCE_ERROR','cn_scalar',
+ 'COL_PTRUNC','CONC_CH4_SAT','CONC_CH4_UNSAT','CONC_O2_SAT','CONC_O2_UNSAT',
+ 'cp_scalar','CWDC_HR','CWDC_LOSS','CWDC_TO_LITR2C','CWDC_TO_LITR3C',
+ 'CWDC_vr','CWDN_TO_LITR2N','CWDN_TO_LITR3N','CWDN_vr','CWDP_TO_LITR2P',
+ 'CWDP_TO_LITR3P','CWDP_vr','DWT_CONV_CFLUX_DRIBBLED','F_CO2_SOIL','F_CO2_SOIL_vr',
+ 'F_DENIT_vr','F_N2O_DENIT','F_N2O_NIT','F_NIT_vr','FCH4_DFSAT',
+ 'FINUNDATED_LAG','FPI_P_vr','FPI_vr','FROOTC_LOSS','HR_vr',
+ 'LABILEP_TO_SECONDP','LABILEP_vr','LAND_UPTAKE','LEAF_MR','leaf_npimbalance',
+ 'LEAFC_LOSS','LEAFC_TO_LITTER','LFC2','LITR1_HR','LITR1C_TO_SOIL1C',
+ 'LITR1C_vr','LITR1N_TNDNCY_VERT_TRANS','LITR1N_TO_SOIL1N','LITR1N_vr','LITR1P_TNDNCY_VERT_TRANS',
+ 'LITR1P_TO_SOIL1P','LITR1P_vr','LITR2_HR','LITR2C_TO_SOIL2C','LITR2C_vr',
+ 'LITR2N_TNDNCY_VERT_TRANS','LITR2N_TO_SOIL2N','LITR2N_vr','LITR2P_TNDNCY_VERT_TRANS','LITR2P_TO_SOIL2P',
+ 'LITR2P_vr','LITR3_HR','LITR3C_TO_SOIL3C','LITR3C_vr','LITR3N_TNDNCY_VERT_TRANS',
+ 'LITR3N_TO_SOIL3N','LITR3N_vr','LITR3P_TNDNCY_VERT_TRANS','LITR3P_TO_SOIL3P','LITR3P_vr',
+ 'M_LITR1C_TO_LEACHING','M_LITR2C_TO_LEACHING','M_LITR3C_TO_LEACHING','M_SOIL1C_TO_LEACHING','M_SOIL2C_TO_LEACHING',
+ 'M_SOIL3C_TO_LEACHING','M_SOIL4C_TO_LEACHING','NDEPLOY','NEM','nlim_m',
+ 'o2_decomp_depth_unsat','OCCLP_vr','PDEPLOY','PLANT_CALLOC','PLANT_NDEMAND',
+ 'PLANT_NDEMAND_COL','PLANT_PALLOC','PLANT_PDEMAND','PLANT_PDEMAND_COL','plim_m',
+ 'POT_F_DENIT','POT_F_NIT','POTENTIAL_IMMOB','POTENTIAL_IMMOB_P','PRIMP_TO_LABILEP',
+ 'PRIMP_vr','PROD1P_LOSS','QOVER_LAG','RETRANSN_TO_NPOOL','RETRANSP_TO_PPOOL',
+ 'SCALARAVG_vr','SECONDP_TO_LABILEP','SECONDP_TO_OCCLP','SECONDP_vr','SMIN_NH4_vr',
+ 'SMIN_NO3_vr','SMINN_TO_SOIL1N_L1','SMINN_TO_SOIL2N_L2','SMINN_TO_SOIL2N_S1','SMINN_TO_SOIL3N_L3',
+ 'SMINN_TO_SOIL3N_S2','SMINN_TO_SOIL4N_S3','SMINP_TO_SOIL1P_L1','SMINP_TO_SOIL2P_L2','SMINP_TO_SOIL2P_S1',
+ 'SMINP_TO_SOIL3P_L3','SMINP_TO_SOIL3P_S2','SMINP_TO_SOIL4P_S3','SMINP_vr','SOIL1_HR','SOIL1C_TO_SOIL2C','SOIL1C_vr','SOIL1N_TNDNCY_VERT_TRANS','SOIL1N_TO_SOIL2N','SOIL1N_vr',
+ 'SOIL1P_TNDNCY_VERT_TRANS','SOIL1P_TO_SOIL2P','SOIL1P_vr','SOIL2_HR','SOIL2C_TO_SOIL3C',
+ 'SOIL2C_vr','SOIL2N_TNDNCY_VERT_TRANS','SOIL2N_TO_SOIL3N','SOIL2N_vr','SOIL2P_TNDNCY_VERT_TRANS',
+ 'SOIL2P_TO_SOIL3P','SOIL2P_vr','SOIL3_HR','SOIL3C_TO_SOIL4C','SOIL3C_vr',
+ 'SOIL3N_TNDNCY_VERT_TRANS','SOIL3N_TO_SOIL4N','SOIL3N_vr','SOIL3P_TNDNCY_VERT_TRANS','SOIL3P_TO_SOIL4P',
+ 'SOIL3P_vr','SOIL4_HR','SOIL4C_vr','SOIL4N_TNDNCY_VERT_TRANS','SOIL4N_TO_SMINN',
+ 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr',
+ 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF',
+ 'wlim_m','WOODC_LOSS','WTGQ'
+ hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC'
hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
hist_mfilt = 1,365
hist_nhtfrq = -24,-24
diff --git a/cime_config/testmods_dirs/bench/noio/user_nl_mpaso b/cime_config/testmods_dirs/bench/noio/user_nl_mpaso
index fcaa3656188f..046a22bb8831 100644
--- a/cime_config/testmods_dirs/bench/noio/user_nl_mpaso
+++ b/cime_config/testmods_dirs/bench/noio/user_nl_mpaso
@@ -6,3 +6,4 @@ config_am_timeseriesstatsmonthlymin_enable=false
config_am_timeseriesstatsmonthlymax_enable=false
config_am_eddyproductvariables_enable=false
config_am_oceanheatcontent_enable=false
+config_am_conservationcheck_enable=false
diff --git a/cime_config/testmods_dirs/config_pes_tests.xml b/cime_config/testmods_dirs/config_pes_tests.xml
index 3301617b9bb4..4ef7663c540a 100644
--- a/cime_config/testmods_dirs/config_pes_tests.xml
+++ b/cime_config/testmods_dirs/config_pes_tests.xml
@@ -115,34 +115,34 @@
-
+
- tests+chrysalis: -compset WCYCL* -res ne30pg*EC30to60E2r2 on 4 nodes pure-MPI, ~2.38 sypd
+ tests+chrysalis: -compset WCYCL* -res ne30pg*IcoswISC30E3r5 on 6 nodes pure-MPI
- 192
- 192
- 192
- 192
+ 320
+ 320
+ 320
+ 320
64
- 192
+ 320
- 192
+ 320
- tests+chrysalis: --compset BGC* --res ne30pg2_r05_EC30to60E2r2 on 5 nodes pure-MPI, ~0.9 sypd
+ tests+chrysalis: --compset BGC* --res ne30pg2_r05_IcoswISC30E3r5 on 9 nodes pure-MPI
- 256
- 256
- 256
- 256
- 64
- 256
+ 448
+ 448
+ 448
+ 448
+ 128
+ 448
- 256
+ 448
@@ -159,7 +159,7 @@
- tests+anvil: --compset WCYCL* --res ne30pg2_EC30to60E2r2 on 16 nodes pure-MPI, ~2.7 sypd
+ tests+anvil: --compset WCYCL* --res ne30pg2_IcoswISC30E3r5 on 16 nodes pure-MPI
396
396
@@ -173,7 +173,7 @@
- tests+anvil: --compset BGC* --res ne30pg2_r05_EC30to60E2r2 on 30 nodes pure-MPI, ~3 sypd
+ tests+anvil: --compset BGC* --res ne30pg2_r05_IcoswISC30E3r5 on 30 nodes pure-MPI
675
684
@@ -284,4 +284,34 @@
+
+
+
+
+ tests+chrysalis: any compset on oQU240 grid, 1x32x2 NODESxMPIxOMP
+ 32
+ 64
+
+ 32
+ 32
+ 32
+ 32
+ 32
+ 32
+ 32
+ 32
+
+
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+
+
+
+
diff --git a/cime_config/testmods_dirs/dinloc/case/shell_commands b/cime_config/testmods_dirs/dinloc/case/shell_commands
new file mode 100755
index 000000000000..0b9483459f45
--- /dev/null
+++ b/cime_config/testmods_dirs/dinloc/case/shell_commands
@@ -0,0 +1,4 @@
+#!/bin/bash
+# Set DIN to be local to the case
+./xmlchange DIN_LOC_ROOT="`./xmlquery --value CASEROOT`/inputdata"
+./xmlchange DIN_LOC_ROOT_CLMFORC="`./xmlquery --value CASEROOT`/inputdata/atm/datm7"
diff --git a/cime_config/testmods_dirs/dinloc/scratch/shell_commands b/cime_config/testmods_dirs/dinloc/scratch/shell_commands
new file mode 100755
index 000000000000..640ac482947f
--- /dev/null
+++ b/cime_config/testmods_dirs/dinloc/scratch/shell_commands
@@ -0,0 +1,4 @@
+#!/bin/bash
+# Set DIN to be in SCRATCH space
+./xmlchange DIN_LOC_ROOT="${SCRATCH}/inputdata"
+./xmlchange DIN_LOC_ROOT_CLMFORC="${SCRATCH}/inputdata/atm/datm7"
diff --git a/cime_config/tests.py b/cime_config/tests.py
index 5e94f9c30073..b4b54dceeb9c 100644
--- a/cime_config/tests.py
+++ b/cime_config/tests.py
@@ -25,7 +25,7 @@
"e3sm_mosart_exenoshare": {
"time" : "0:45:00",
"tests" : (
- "ERS.ne30pg2_r05_EC30to60E2r2.GPMPAS-JRA.mosart-rof_ocn_2way",
+ "ERS.ne30pg2_r05_IcoswISC30E3r5.GPMPAS-JRA.mosart-rof_ocn_2way",
)
},
@@ -54,9 +54,11 @@
"e3sm_land_exenoshare" : {
"time" : "0:45:00",
"tests" : (
+ "ERS.f19_g16.IERA5ELM",
+ "ERS.f19_g16.IERA56HRELM",
"ERS_Ld20.f45_f45.IELMFATES.elm-fates",
- "ERS.hcru_hcru.I20TRGSWCNPRDCTCBC.elm-erosion",
"ERS.f09_g16.IELMBC.elm-simple_decomp",
+ "ERS.hcru_hcru.IELM.elm-multi_inst",
)
},
@@ -65,7 +67,7 @@
"tests" : (
"ERS_D.f19_f19.IELM.elm-ic_f19_f19_ielm",
"ERS_D.f09_g16.I1850ELMCN",
- "ERS_D.ne11_oQU240.I20TRELM",
+ "ERS_D.ne4pg2_oQU480.I20TRELM.elm-disableDynpftCheck",
"SMS_Ly2_P1x1_D.1x1_smallvilleIA.IELMCNCROP.elm-lulcc_sville",
"ERS_D.f19_g16.I1850GSWCNPRDCTCBC.elm-ctc_f19_g16_I1850GSWCNPRDCTCBC",
"ERS_D.f09_f09.IELM.elm-solar_rad",
@@ -91,7 +93,7 @@
"SMS_Ly2_P1x1.1x1_smallvilleIA.IELMCNCROP.elm-fan",
"SMS.r05_r05.IELM.elm-topounit",
"ERS.ELM_USRDAT.I1850ELM.elm-usrdat",
- "ERS.f09_f09.IELM.elm-lnd_rof_2way",
+ "ERS.r05_r05.IELM.elm-lnd_rof_2way",
"ERS.r05_r05.IELM.elm-V2_ELM_MOSART_features",
"ERS.ELM_USRDAT.IELM.elm-surface_water_dynamics"
)
@@ -100,32 +102,51 @@
"e3sm_atm_developer" : {
"inherit" : ("eam_theta_pg2"),
"tests" : (
- "ERP_Ln18.ne4_oQU240.F2010",
- "SMS_Ln9.ne4_oQU240.F2010.eam-outfrq9s",
- "SMS.ne4_oQU240.F2010.eam-cosplite",
+ "ERP_Ld3.ne4pg2_oQU480.F2010",
+ "SMS_Ln9.ne4pg2_oQU480.F2010.eam-outfrq9s",
+ "SMS.ne4pg2_oQU480.F2010.eam-cosplite",
"SMS_R_Ld5.ne4_ne4.FSCM-ARM97.eam-scm",
- "SMS_D_Ln5.ne4_oQU240.F2010",
+ "SMS_D_Ln5.ne4pg2_oQU480.F2010",
"SMS_Ln5.ne4pg2_oQU480.F2010",
- "ERS_D.ne4_oQU240.F2010.eam-hommexx",
+ "ERS_D.ne4pg2_oQU480.F2010.eam-hommexx",
"SMS_Ln9_P24x1.ne4_ne4.FDPSCREAM-ARM97",
)
},
"e3sm_ice_developer" : {
"tests" : (
- "SMS_D_Ld1.TL319_EC30to60E2r2.DTESTM-JRA1p5.mpassi-jra_1958",
+ "SMS_D_Ld1.TL319_IcoswISC30E3r5.DTESTM-JRA1p5.mpassi-jra_1958",
"ERS_Ld5.T62_oQU240.DTESTM",
"PEM_Ln5.T62_oQU240wLI.DTESTM",
"PET_Ln5.T62_oQU240.DTESTM",
)
},
+ "e3sm_cryo_developer" : {
+ "tests" : (
+ "SMS_D_Ld1.TL319_IcoswISC30E3r5.GMPAS-JRA1p5-DIB-PISMF.mpaso-jra_1958",
+ "ERS_Ld5.T62_oQU240wLI.GMPAS-DIB-IAF-PISMF",
+ "PEM_Ln5.T62_oQU240wLI.GMPAS-DIB-IAF-PISMF",
+ "PET_Ln5.T62_oQU240wLI.GMPAS-DIB-IAF-PISMF",
+ "ERS_Ld5.T62_oQU240wLI.GMPAS-DIB-IAF-DISMF",
+ "PEM_Ln5.T62_oQU240wLI.GMPAS-DIB-IAF-DISMF",
+ "PET_Ln5.T62_oQU240wLI.GMPAS-DIB-IAF-DISMF",
+ )
+ },
+
+ "e3sm_landice_developer" : {
+ "tests" : (
+ "SMS.ne30pg2_r05_EC30to60E2r2_gis20.IGELM_MLI.elm-gis20kmSMS",
+ "ERS.ne30pg2_r05_EC30to60E2r2_gis20.IGELM_MLI.elm-gis20kmERS",
+ )
+ },
+
"eam_condidiag" : {
"tests" : (
"SMS_D_Ln5.ne4pg2_oQU480.F2010",
"SMS_D_Ln5.ne4pg2_oQU480.F2010.eam-condidiag_dcape",
- "ERP_Ln18.ne4_oQU240.F2010.eam-condidiag_dcape",
- "ERP_Ln18.ne4_oQU240.F2010.eam-condidiag_rhi",
+ "ERP_Ld3.ne4pg2_oQU480.F2010.eam-condidiag_dcape",
+ "ERP_Ld3.ne4pg2_oQU480.F2010.eam-condidiag_rhi",
)
},
@@ -167,38 +188,38 @@
"e3sm_atm_integration" : {
"inherit" : ("eam_preqx", "eam_theta"),
"tests" : (
- "ERP_Ln9.ne4_ne4.FAQP",
- "SMS_Ld1.ne4_ne4.FAQP.eam-clubb_only",
- "ERP_Ln9.ne4_ne4.FRCE",
- "PET_Ln5.ne4_oQU240.F2010.allactive-mach-pet",
- "PEM_Ln5.ne4_oQU240.F2010",
- "SMS_D_Ln5.ne4_oQU240.F2010.eam-cosplite_nhtfrq5",
- "SMS_Ln1.ne4_oQU240.F2010.eam-chem_pp",
- "SMS_Ln5.ne30pg2_r05_EC30to60E2r2.BGCEXP_LNDATM_CNPRDCTC_20TR",
- "SMS_Ln5.ne30pg2_r05_EC30to60E2r2.BGCEXP_LNDATM_CNPRDCTC_1850",
- "SMS_D_Ln5.ne4_oQU240.F2010.eam-clubb_sp",
- "ERS_Ld5.ne4_oQU240.F2010.eam-rrtmgp",
- "ERS_Ld5.ne4_oQU240.F2010.eam-rrtmgpxx",
- "REP_Ln5.ne4_oQU240.F2010",
- "SMS_Ld9.ne4pg2_oQU480.F2010.eam-thetahy_sl_pg2_mass",
- "ERP_Ld9.ne4_ne4.FIDEAL.allactive-pioroot1",
+ "ERP_Ln9.ne4pg2_ne4pg2.FAQP",
+ "SMS_Ld1.ne4pg2_ne4pg2.FAQP.eam-clubb_only",
+ "ERP_Ln9.ne4pg2_ne4pg2.FRCE",
+ "PET_Ln5.ne4pg2_oQU480.F2010.allactive-mach-pet",
+ "PEM_Ln5.ne4pg2_oQU480.F2010",
+ "SMS_D_Ln5.ne4pg2_oQU480.F2010.eam-cosplite_nhtfrq5",
+ "SMS_Ln1.ne4pg2_oQU480.F2010.eam-chem_pp",
+ "SMS_Ln5.ne30pg2_r05_IcoswISC30E3r5.BGCEXP_LNDATM_CNPRDCTC_20TR",
+ "SMS_Ln5.ne30pg2_r05_IcoswISC30E3r5.BGCEXP_LNDATM_CNPRDCTC_1850",
+ "SMS_D_Ln5.ne4pg2_oQU480.F2010.eam-clubb_sp",
+ "ERS_Ld5.ne4pg2_oQU480.F2010.eam-rrtmgp",
+ "ERS_Ld5.ne4pg2_oQU480.F2010.eam-rrtmgpxx",
+ "REP_Ln5.ne4pg2_oQU480.F2010",
+ "SMS_Ld3.ne4pg2_oQU480.F2010.eam-thetahy_sl_pg2_mass",
+ "ERP_Ld3.ne4pg2_ne4pg2.FIDEAL.allactive-pioroot1",
)
},
#atmopheric tests for extra coverage
"e3sm_atm_extra_coverage" : {
"tests" : (
- "SMS_Lm1.ne4_oQU240.F2010",
- "ERS_Ld31.ne4_oQU240.F2010",
- "ERP_Lm3.ne4_oQU240.F2010",
- "SMS_D_Ln5.ne30_oECv3.F2010",
- "ERP_Ld3.ne30_oECv3.F2010.allactive-pioroot1",
- "SMS_Ly1.ne4_oQU240.F2010",
+ "SMS_Lm1.ne4pg2_oQU480.F2010",
+ "ERS_Ld31.ne4pg2_oQU480.F2010",
+ "ERP_Lm3.ne4pg2_oQU480.F2010",
+ "SMS_D_Ln5.ne30pg2_r05_IcoswISC30E3r5.F2010",
+ "ERP_Ld3.ne30pg2_r05_IcoswISC30E3r5.F2010.allactive-pioroot1",
+ "SMS_Ly1.ne4pg2_oQU480.F2010",
"SMS_D_Ln5.ne45pg2_ne45pg2.FAQP",
- "SMS_D_Ln5.ne4_oQU240.F2010.eam-implicit_stress",
- "ERS_Ld5.ne30_oECv3.F2010.eam-implicit_stress",
- "ERP_Ln18.ne4_oQU240.F2010.eam-condidiag_dcape",
- "ERP_Ln18.ne4_oQU240.F2010.eam-condidiag_rhi",
+ "SMS_D_Ln5.ne4pg2_oQU480.F2010.eam-implicit_stress",
+ "ERS_Ld5.ne30pg2_r05_IcoswISC30E3r5.F2010.eam-implicit_stress",
+ "ERP_Ld3.ne4pg2_oQU480.F2010.eam-condidiag_dcape",
+ "ERP_Ld3.ne4pg2_oQU480.F2010.eam-condidiag_rhi",
)
},
@@ -212,19 +233,30 @@
"e3sm_atm_prod" : {
"tests" : (
"SMS_Ln5.ne30pg2_r05_IcoswISC30E3r5.F2010.eam-wcprod_F2010",
- "SMS.ne30pg2_r05_IcoswISC30E3r5.F20TR.eam-wcprod_F20TR",
+ "SMS_Ld1.ne30pg2_r05_IcoswISC30E3r5.F20TR.eam-wcprod_F20TR",
)
},
#atmopheric nbfb tests
"e3sm_atm_nbfb" : {
"tests" : (
- "PGN_P1x1.ne4_oQU240.F2010",
- "TSC_PS.ne4_oQU240.F2010",
- "MVK_PS.ne4_oQU240.F2010",
+ "PGN_P1x1.ne4pg2_oQU480.F2010",
+ "TSC_PS.ne4pg2_oQU480.F2010",
+ "MVK_PS.ne4pg2_oQU480.F2010",
+ )
+ },
+
+ #ocean non bit-for-bit test
+ "e3sm_ocn_nbfb": {
+ "tests": (
+ "MVKO_PS.T62_oQU240.GMPAS-NYF",
)
},
+ "e3sm_nbfb": {
+ "inherit": ("e3sm_atm_nbfb", "e3sm_ocn_nbfb")
+ },
+
"e3sm_ocnice_stealth_features" : {
"tests" : (
"SMS_D_Ld1.T62_oQU240wLI.GMPAS-IAF-PISMF.mpaso-impl_top_drag",
@@ -236,8 +268,8 @@
"e3sm_ocnice_extra_coverage" : {
"inherit" : ("e3sm_ocnice_stealth_features"),
"tests" : (
- "ERS_P480_Ld5.T62_ECwISC30to60E2r1.GMPAS-DIB-IAF-PISMF",
- "PEM_P480_Ld5.T62_ECwISC30to60E2r1.GMPAS-DIB-IAF-PISMF",
+ "ERS_P480_Ld5.TL319_IcoswISC30E3r5.GMPAS-JRA1p5-DIB-PISMF.mpaso-jra_1958",
+ "PEM_P480_Ld5.TL319_IcoswISC30E3r5.GMPAS-JRA1p5-DIB-PISMF.mpaso-jra_1958",
"SMS.ne30_oECv3_gis.IGELM_MLI.elm-extrasnowlayers",
)
},
@@ -247,7 +279,7 @@
"tests" : (
"ERP.ne4pg2_oQU480.F2010.eam-v3atm_dustemis",
"REP.ne4pg2_oQU480.F2010.eam-v3atm_dustemis",
- "SMS.ne30pg2_EC30to60E2r2.F2010.eam-v3atm_dustemis",
+ "SMS.ne30pg2_IcoswISC30E3r5.F2010.eam-v3atm_dustemis",
"SMS_D_Ln5.ne4pg2_oQU480.F2010.eam-v3atm_dustemis",
"PET_Ln5.ne4pg2_oQU480.F2010.eam-v3atm_dustemis",
"PEM_Ln5.ne4pg2_oQU480.F2010.eam-v3atm_dustemis",
@@ -256,7 +288,7 @@
},
"e3sm_developer" : {
- "inherit" : ("e3sm_land_developer", "e3sm_atm_developer", "e3sm_ice_developer"),
+ "inherit" : ("e3sm_land_developer", "e3sm_atm_developer", "e3sm_ice_developer", "e3sm_cryo_developer"),
"time" : "0:45:00",
"tests" : (
"ERS.f19_g16_rx1.A",
@@ -266,11 +298,9 @@
"NCK.f19_g16_rx1.A",
"SMS.ne30_f19_g16_rx1.A",
"ERS_Ld5.T62_oQU120.CMPASO-NYF",
- "SMS_Ld1.T62_oQU240wLI.GMPAS-IAF-DISMF",
"ERS.f09_g16_g.MALISIA",
"SMS.T62_oQU120_ais20.MPAS_LISIO_TEST",
- "SMS.f09_g16_a.IGELM_MLI",
- "SMS_P12x2.ne4_oQU240.WCYCL1850NS.allactive-mach_mods",
+ "SMS_P12x2.ne4pg2_oQU480.WCYCL1850NS.allactive-mach_mods",
"ERS_Ln9.ne4pg2_ne4pg2.F2010-MMF1.eam-mmf_crmout",
)
},
@@ -284,27 +314,26 @@
},
"e3sm_integration" : {
- "inherit" : ("e3sm_developer", "e3sm_atm_integration", "e3sm_mmf_integration"),
+ "inherit" : ("e3sm_developer", "e3sm_atm_integration", "e3sm_mmf_integration", "e3sm_rrm"),
"time" : "03:00:00",
"tests" : (
"ERS.ne4pg2_oQU480.WCYCL1850NS",
- "SMS_D_Ld1.ne30pg2_EC30to60E2r2.WCYCL1850.allactive-wcprod",
- "SMS_D_Ld1.ne30pg2_EC30to60E2r2.WCYCLSSP370.allactive-wcprodssp",
- "ERS_Ld3.ne4_oQU240.F2010",
- #"ERT_Ld31.ne16_g37.B1850C5",#add this line back in with the new correct compset
+ "SMS_D_Ld1.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.allactive-wcprod",
+ "SMS_D_Ld1.ne30pg2_r05_IcoswISC30E3r5.WCYCLSSP370.allactive-wcprodssp",
+ "ERS_Ld3.ne4pg2_oQU480.F2010",
"NCK.ne4pg2_oQU480.WCYCL1850NS",
"PET.f19_g16.X.allactive-mach-pet",
"PET.f45_g37_rx1.A.allactive-mach-pet",
- "PET_Ln9_PS.ne30pg2_EC30to60E2r2.WCYCL1850.allactive-mach-pet",
- "PEM_Ln9.ne30pg2_EC30to60E2r2.WCYCL1850",
- "ERP_Ld3.ne30pg2_EC30to60E2r2.WCYCL1850.allactive-pioroot1",
- "SMS_D_Ln5.conusx4v1_r05_oECv3.F2010",
- "SMS_Ld2.ne30pg2_r05_EC30to60E2r2.BGCEXP_CNTL_CNPECACNT_1850.elm-bgcexp",
- "SMS_Ld2.ne30pg2_r05_EC30to60E2r2.BGCEXP_CNTL_CNPRDCTC_1850.elm-bgcexp",
+ "PET_Ln9_PS.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.allactive-mach-pet",
+ "PEM_Ln9.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850",
+ "ERP_Ld3.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.allactive-pioroot1",
+ "SMS_Ld2.ne30pg2_r05_IcoswISC30E3r5.BGCEXP_CNTL_CNPECACNT_1850.elm-bgcexp",
+ "SMS_Ld2.ne30pg2_r05_IcoswISC30E3r5.BGCEXP_CNTL_CNPRDCTC_1850.elm-bgcexp",
"SMS_D_Ld3.T62_oQU120.CMPASO-IAF",
- "SMS_D_Ld1.ne30pg2_r05_EC30to60E2r2.WCYCL1850",
"SMS_Ln5.ne30pg2_ne30pg2.F2010-SCREAM-LR-DYAMOND2",
- "ERS_Ld3.ne30pg2_r05_EC30to60E2r2.WCYCL1850.allactive-nlmaps",
+ "ERS_Ld3.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.allactive-nlmaps",
+ "SMS_D_Ld1.ne30pg2_r05_IcoswISC30E3r5.CRYO1850-DISMF",
+ "ERS.hcru_hcru.I20TRGSWCNPRDCTCBC.elm-erosion",
)
},
@@ -328,7 +357,7 @@
#e3sm tests for RRM grids
"e3sm_rrm" : {
"tests" : (
- "SMS_D_Ln5.conusx4v1_r05_oECv3.F2010",
+ "SMS_D_Ln5.conusx4v1pg2_r05_IcoswISC30E3r5.F2010",
)
},
@@ -346,13 +375,13 @@
"e3sm_prod" : {
"inherit" : "e3sm_atm_prod",
"tests" : (
- "SMS_Ld1.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.allactive-wcprod_1850_r05",
"SMS_Ld1.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850-1pctCO2.allactive-wcprod_1850_1pctCO2",
"SMS_Ld1.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850-4xCO2.allactive-wcprod_1850_4xCO2",
"SMS_Ld1.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.allactive-wcprod_1850",
- "SMS_Ld1.ne30pg2_EC30to60E2r2.WCYCLSSP370.allactive-wcprodssp",
- "SMS_Ld1.ne30pg2_EC30to60E2r2.WCYCLSSP585.allactive-wcprodssp",
- "SMS_PS.northamericax4v1pg2_WC14to60E2r3.WCYCL1850.allactive-wcprodrrm_1850",
+ "SMS_Ld1.ne30pg2_r05_IcoswISC30E3r5.WCYCLSSP370.allactive-wcprodssp",
+ "SMS_Ld1.ne30pg2_r05_IcoswISC30E3r5.WCYCLSSP585.allactive-wcprodssp",
+ "SMS_Ld1_PS.northamericax4v1pg2_WC14to60E2r3.WCYCL1850.allactive-wcprodrrm_1850",
+ "SMS_D_Ld1.ne30pg2_r05_IcoswISC30E3r5.CRYO1850",
)
},
@@ -369,11 +398,8 @@
#e3sm performance-benching of production-like runs
"e3sm_prod_bench" : {
"tests" : (
- "PFS.ne30pg2_r05_oECv3.F2010.bench-noio",
- "PFS.ne30pg2_r05_oECv3.F20TR.bench-noio",
- "PFS.ne30pg2_r05_EC30to60E2r2.WCYCL1850.bench-noio",
- "PFS.ne30pg2_EC30to60E2r2.WCYCL1850.bench-noio",
- "PFS_PS.northamericax4v1pg2_WC14to60E2r3.WCYCL1850.bench-noio",
+ "PFS.ne30pg2_r05_IcoswISC30E3r5.F2010.bench-noio",
+ "PFS.ne30pg2_r05_IcoswISC30E3r5.WCYCL1850.bench-noio",
)
},
@@ -415,6 +441,7 @@
"ERP_D_Ld3.f19_g16.IELMFATES.elm-fates_cold",
"ERS_D_Ld3_PS.f09_g16.IELMFATES.elm-fates_cold",
"ERS_D_Ld5.f45_g37.IELMFATES.elm-fates_cold",
+ "ERS_D_Ld30.f45_g37.IELMFATES.elm-fates_cold_landuse",
"ERS_Ld30.f45_g37.IELMFATES.elm-fates_satphen",
"ERS_Ld30.f45_g37.IELMFATES.elm-fates_cold_fixedbiogeo",
"ERS_Ld30.f45_g37.IELMFATES.elm-fates_cold_nocomp",
@@ -424,6 +451,7 @@
"ERS_Ld60.f45_g37.IELMFATES.elm-fates_cold_nofire",
"ERS_Ld60.f45_g37.IELMFATES.elm-fates_cold_st3",
"ERS_Ld60.f45_g37.IELMFATES.elm-fates_cold_pphys",
+ "SMS_D_Ld15.f45_g37.IELMFATES.elm-fates_cold_twostream",
)
},
@@ -454,27 +482,27 @@
"share" : True,
"time" : "01:00:00",
"tests" : (
- "SMS.ne4_oQU240.F2010.eam-preqx_ftype0",
- "SMS.ne4_oQU240.F2010.eam-preqx_ftype1",
- "SMS.ne4_oQU240.F2010.eam-preqx_ftype4",
+ "SMS.ne4pg2_oQU480.F2010.eam-preqx_ftype0",
+ "SMS.ne4pg2_oQU480.F2010.eam-preqx_ftype1",
+ "SMS.ne4pg2_oQU480.F2010.eam-preqx_ftype4",
)
},
"eam_theta" : {
"share" : True,
"time" : "02:00:00",
"tests" : (
- "SMS.ne4_oQU240.F2010.eam-thetahy_ftype0",
- "SMS.ne4_oQU240.F2010.eam-thetahy_ftype1",
- "SMS.ne4_oQU240.F2010.eam-thetahy_ftype2",
- "SMS.ne4_oQU240.F2010.eam-thetahy_ftype2_energy",
- "SMS.ne4_oQU240.F2010.eam-thetahy_ftype4",
- "SMS.ne4_oQU240.F2010.eam-thetanh_ftype0",
- "SMS.ne4_oQU240.F2010.eam-thetanh_ftype1",
- "SMS.ne4_oQU240.F2010.eam-thetanh_ftype2",
- "SMS.ne4_oQU240.F2010.eam-thetanh_ftype4",
- "SMS.ne4_oQU240.F2010.eam-thetahy_sl",
- "ERS.ne4_oQU240.F2010.eam-thetahy_ftype2",
- "ERS.ne4_oQU240.F2010.eam-thetanh_ftype2",
+ "SMS.ne4pg2_oQU480.F2010.eam-thetahy_ftype0",
+ "SMS.ne4pg2_oQU480.F2010.eam-thetahy_ftype1",
+ "SMS.ne4pg2_oQU480.F2010.eam-thetahy_ftype2",
+ "SMS.ne4pg2_oQU480.F2010.eam-thetahy_ftype2_energy",
+ "SMS.ne4pg2_oQU480.F2010.eam-thetahy_ftype4",
+ "SMS.ne4pg2_oQU480.F2010.eam-thetanh_ftype0",
+ "SMS.ne4pg2_oQU480.F2010.eam-thetanh_ftype1",
+ "SMS.ne4pg2_oQU480.F2010.eam-thetanh_ftype2",
+ "SMS.ne4pg2_oQU480.F2010.eam-thetanh_ftype4",
+ "SMS.ne4pg2_oQU480.F2010.eam-thetahy_sl",
+ "ERS.ne4pg2_oQU480.F2010.eam-thetahy_ftype2",
+ "ERS.ne4pg2_oQU480.F2010.eam-thetanh_ftype2",
)
},
"eam_theta_pg2" : {
@@ -612,13 +640,21 @@
"e3sm_scream_v1_lowres" : {
+ "time" : "01:00:00",
+ "inherit" : ("e3sm_scream_mam4xx_v1_lowres"),
+ "tests" : (
+ "ERP_D_Lh4.ne4_ne4.F2010-SCREAMv1.scream-output-preset-1",
+ "ERS_Ln9.ne4_ne4.F2000-SCREAMv1-AQP1.scream-output-preset-2",
+ "SMS_D_Ln9.ne4_ne4.F2010-SCREAMv1-noAero.scream-output-preset-3",
+ "ERP_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-output-preset-4",
+ "ERS_D_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-rad_frequency_2--scream-output-preset-5",
+ )
+ },
+
+ "e3sm_scream_v1_dp-eamxx" : {
"time" : "01:00:00",
"tests" : (
- "ERP_D_Lh4.ne4_ne4.F2010-SCREAMv1",
- "ERS_Ln9.ne4_ne4.F2000-SCREAMv1-AQP1",
- "SMS_D_Ln9.ne4_ne4.F2010-SCREAMv1-noAero",
- "ERP_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1",
- "ERS_D_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-rad_frequency_2",
+ "ERS_P16_Ln22.ne30_ne30.F2010-SCREAMv1-DP-DYCOMSrf01", # 225 phys cols, roughly size of ne2
)
},
@@ -626,27 +662,26 @@
# should be fast, so we limit it to low res and add some thread tests
# specifically for mappy.
"e3sm_scream_v1_at" : {
- "inherit" : ("e3sm_scream_v1_lowres"),
- "tests" : ("PET_Ln9_P32x2.ne4pg2_ne4pg2.F2010-SCREAMv1")
+ "inherit" : ("e3sm_scream_v1_lowres", "e3sm_scream_v1_dp-eamxx"),
+ "tests" : ("PET_Ln9_P32x2.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-output-preset-1")
},
"e3sm_scream_v1_medres" : {
"time" : "02:00:00",
"tests" : (
# "SMS_D_Ln2.ne30_ne30.F2000-SCREAMv1-AQP1", # Uncomment once IC file for ne30 is ready
- "ERS_Ln22.ne30_ne30.F2010-SCREAMv1.scream-internal_diagnostics_level",
- "PEM_Ln90.ne30pg2_ne30pg2.F2010-SCREAMv1",
- "ERS_Ln90.ne30pg2_ne30pg2.F2010-SCREAMv1.scream-small_kernels",
- "ERP_Ln22.conusx4v1pg2_r05_oECv3.F2010-SCREAMv1-noAero.scream-bfbhash",
+ "ERS_Ln22.ne30_ne30.F2010-SCREAMv1.scream-internal_diagnostics_level--scream-output-preset-3",
+ "PEM_Ln90.ne30pg2_ne30pg2.F2010-SCREAMv1.scream-spa_remap--scream-output-preset-4",
+ "ERS_Ln90.ne30pg2_ne30pg2.F2010-SCREAMv1.scream-small_kernels--scream-output-preset-5",
+ "ERP_Ln22.conusx4v1pg2_r05_oECv3.F2010-SCREAMv1-noAero.scream-bfbhash--scream-output-preset-6",
)
},
+ # Used to track performance
"e3sm_scream_v1_hires" : {
- "time" : "03:00:00",
+ "time" : "01:00:00",
"tests" : (
- "SMS_D_Ln12.ne120_r0125_oRRS18to6v3.F2010-SCREAMv1",
- "SMS_Ln12.ne120_ne120.F2010-SCREAMv1",
-# "SMS_Ln12.ne120_r0125_oRRS18to6v3.F2000-SCREAMv1-AQP1", add when aquap 120 inputs available
+ "SMS_Ln300.ne30pg2_ne30pg2.F2010-SCREAMv1.scream-perf_test--scream-output-preset-1"
)
},
@@ -658,7 +693,7 @@
# Disable the two 111422-commented tests b/c they fail on pm-gpu and
# we're not using MPASSI right now.
#111422 "ERP_Ln22.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.atmlndactive-rtm_off",
- "ERS_D_Ln22.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.atmlndactive-rtm_off",
+ "ERS_D_Ln22.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.atmlndactive-rtm_off--scream-output-preset-1",
# "ERS_Ln22.ne30_oECv3.F2010-SCREAMv1-MPASSI.atmlndactive-rtm_off",
#111422 "PEM_Ln90.ne30pg2_EC30to60E2r2.F2010-SCREAMv1-MPASSI",
# "ERS_Ln22.ne30pg2_EC30to60E2r2.F2010-SCREAMv1-MPASSI.atmlndactive-rtm_off",
@@ -682,6 +717,14 @@
)
},
+ "e3sm_scream_mam4xx_v1_lowres" : {
+ "time" : "01:00:00",
+ "tests" : (
+ "SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-optics",
+ )
+ },
+
+
"e3sm_gpuacc" : {
"tests" : (
"SMS_Ld1.T62_oEC60to30v3.CMPASO-NYF",
@@ -1003,4 +1046,3 @@
"e3sm_superbfb_atm", "e3sm_superbfb_wcycl"),
},
}
-
diff --git a/components/cmake/build_model.cmake b/components/cmake/build_model.cmake
index 16f1f039ebde..535081663a68 100644
--- a/components/cmake/build_model.cmake
+++ b/components/cmake/build_model.cmake
@@ -249,6 +249,11 @@ macro(build_model COMP_CLASS COMP_NAME)
target_link_libraries(${TARGET_NAME} ${ITEM})
endforeach()
+ if (USE_MOAB)
+ target_link_libraries(${TARGET_NAME} ${MOAB_LIBRARIES})
+ target_include_directories(${TARGET_NAME} PRIVATE ${MOAB_INCLUDE_DIRS})
+ endif()
+
# Make sure we link blas/lapack
if (NOT DEFINED ENV{SKIP_BLAS})
target_link_libraries(${TARGET_NAME} BLAS::BLAS LAPACK::LAPACK)
diff --git a/components/cmake/modules/FindPIO.cmake b/components/cmake/modules/FindPIO.cmake
index 7df8a9ba1062..0277918ac8e0 100644
--- a/components/cmake/modules/FindPIO.cmake
+++ b/components/cmake/modules/FindPIO.cmake
@@ -18,6 +18,9 @@ endif()
if (PIO_VERSION STREQUAL 2)
# This is a pio2 library
set(PIOLIBS "${PIO_LIBDIR}/libpiof.a;${PIO_LIBDIR}/libpioc.a")
+ if (DEFINED ENV{ADIOS2_ROOT})
+ list(APPEND PIOLIBS "${PIO_LIBDIR}/libadios2pio-nm-lib.a")
+ endif()
else()
# This is a pio1 library
set(PIOLIBS "${PIO_LIBDIR}/libpio.a")
diff --git a/components/data_comps/datm/cime_config/config_component.xml b/components/data_comps/datm/cime_config/config_component.xml
index 779b930662ca..cb982f52fcff 100644
--- a/components/data_comps/datm/cime_config/config_component.xml
+++ b/components/data_comps/datm/cime_config/config_component.xml
@@ -10,12 +10,14 @@
This file may have atm desc entries.
-->
- Data driven ATM
+ Data driven ATM
QIAN data set
QIAN with water isotopes
CRUNCEP data set
CLM CRU NCEP v7 data set
GSWP3v1 data set
+ Fifth generation ECMWF reanalysis
+ Fifth generation ECMWF reanalysis,6 hourly data
MOSART test data set using older NLDAS data
NLDAS2 regional 0.125 degree data set over the U.S. (25-53N, 235-293E). WARNING: Garbage data will be produced for runs extending beyond this regional domain.
Coupler hist data set (in this mode, it is strongly recommended that the model domain and the coupler history forcing are on the same domain)
@@ -43,13 +45,13 @@
char
- CORE2_NYF,CORE2_IAF,CLM_QIAN,CLM_QIAN_WISO,CLM1PT,CLMCRUNCEP,CLMCRUNCEPv7,CLMGSWP3v1,CLMMOSARTTEST,CLMNLDAS2,CPLHIST,CORE_IAF_JRA,IAF_JRA_1p5,CORE_IAF_JRA_1p4_2018,CORE_RYF8485_JRA,CORE_RYF9091_JRA,CORE_RYF0304_JRA,CFSv2,CFSR
+ CORE2_NYF,CORE2_IAF,CLM_QIAN,CLM_QIAN_WISO,CLM1PT,CLMCRUNCEP,CLMCRUNCEPv7,CLMGSWP3v1,ELMERA5,ERA56HR,CLMMOSARTTEST,CLMNLDAS2,CPLHIST,CORE_IAF_JRA,IAF_JRA_1p5,CORE_IAF_JRA_1p4_2018,CORE_RYF8485_JRA,CORE_RYF9091_JRA,CORE_RYF0304_JRA,CFSv2,CFSR
CORE2_NYF
run_component_datm
env_run.xml
Mode for data atmosphere component.
CORE2_NYF (CORE2 normal year forcing) are modes used in forcing prognostic ocean/sea-ice components.
- CLM_QIAN, CLMCRUNCEP, CLMCRUNCEPv7, CLMGSWP3v1, CLMMOSARTTEST, CLMNLDAS2 and CLM1PT are modes using observational data for forcing prognostic land components.
+ CLM_QIAN, CLMCRUNCEP, CLMCRUNCEPv7, CLMGSWP3v1, ELMERA5,ERA56HR, CLMMOSARTTEST, CLMNLDAS2 and CLM1PT are modes using observational data for forcing prognostic land components.
WARNING for CLMNLDAS2: This is a regional forcing dataset over the U.S. (25-53N, 235-293E). Garbage data will be produced for runs extending beyond this regional domain.
WARNING for CLMGSWP3v1: Humidity is identically zero for last time step in Dec/2013 and all of 2014 so you should NOT use 2014
data (see cime issue #3653 -- https://github.com/ESMCI/cime/issues/3653).
@@ -68,6 +70,8 @@ data (see cime issue #3653 -- https://github.com/ESMCI/cime/issues/3653).
CLMCRUNCEP
CLMCRUNCEPv7
CLMGSWP3v1
+ ELMERA5
+ ERA56HR
CLMMOSARTTEST
CLMNLDAS2
CLM1PT
@@ -240,9 +244,13 @@ data (see cime issue #3653 -- https://github.com/ESMCI/cime/issues/3653).
1
1
$DATM_CLMNCEP_YR_START
+ 1
+ 1
$DATM_CLMNCEP_YR_START
$DATM_CLMNCEP_YR_START
$DATM_CLMNCEP_YR_START
+ $DATM_CLMNCEP_YR_START
+ $DATM_CLMNCEP_YR_START
run_component_datm
env_run.xml
@@ -286,6 +294,8 @@ data (see cime issue #3653 -- https://github.com/ESMCI/cime/issues/3653).
2005
2002
1958
+ 1979
+ 1979
run_component_datm
env_run.xml
@@ -330,6 +340,8 @@ data (see cime issue #3653 -- https://github.com/ESMCI/cime/issues/3653).
2003
2016
2020
+ 1979
+ 1979
run_component_datm
env_run.xml
diff --git a/components/data_comps/datm/cime_config/namelist_definition_datm.xml b/components/data_comps/datm/cime_config/namelist_definition_datm.xml
index e033e9494645..529e79a03f68 100644
--- a/components/data_comps/datm/cime_config/namelist_definition_datm.xml
+++ b/components/data_comps/datm/cime_config/namelist_definition_datm.xml
@@ -36,6 +36,8 @@
CLMCRUNCEP = Run with the CLM CRU NCEP V4 ( default ) forcing valid from 1900 to 2010 (force CLM)
CLMCRUNCEPv7 = Run with the CLM CRU NCEP V7 forcing valid from 1900 to 2010 (force CLM)
CLMGSWP3v1 = Run with the CLM GSWP3 V1 forcing (force CLM)
+ ELMERA5 = Run with the ELM fifth generation ECMWF reanalysis from 1979 to present
+ ERA56HR = Run with the ELM fifth generation ECMWF reanalysis from 1979 to present
CLMMOSARTTEST = Run with the CLM NLDAS data (force CLM) for testing MOSART
CLMNLDAS2 = Run with the CLM NLDAS2 regional forcing valid from 1980 to 2018 (force CLM)
CLM1PT = Run with supplied single point data (force CLM)
@@ -103,6 +105,26 @@
CLMGSWP3v1.Solar
CLMGSWP3v1.Precip
CLMGSWP3v1.TPQW
+
+ ELMERA5.msdrswrf # mean surface direct shortwave radiation flux
+ ELMERA5.msdfswrf # mean surface diffuse shortwave radiation flux
+ ELMERA5.mcpr # mean convective precipitation rate
+ ELMERA5.mlspr # mean large-scale precipitation rate
+ ELMERA5.t2m # temperature at 2 m
+ ELMERA5.sp # surface pressure
+ ELMERA5.d2m # dew point temperature at 2 m
+ ELMERA5.w10 # wind speed at 10 m
+ ELMERA5.msdwlwrf # mean surface downward longwave radiation flux
+
+ ERA56HR.msdrswrf # mean surface direct shortwave radiation flux
+ ERA56HR.msdfswrf # mean surface diffuse shortwave radiation flux
+ ERA56HR.mcpr # mean convective precipitation rate
+ ERA56HR.mlspr # mean large-scale precipitation rate
+ ERA56HR.t2m # temperature at 2 m
+ ERA56HR.sp # surface pressure
+ ERA56HR.d2m # dew point temperature at 2 m
+ ERA56HR.w10 # wind speed at 10 m
+ ERA56HR.msdwlwrf # mean surface downward longwave radiation flux
CLMMOSARTTEST
@@ -202,6 +224,8 @@
CLMCRUNCEP.Solar,CLMCRUNCEP.Precip,CLMCRUNCEP.TPQW
CLMCRUNCEPv7.Solar,CLMCRUNCEPv7.Precip,CLMCRUNCEPv7.TPQW
CLMGSWP3v1.Solar,CLMGSWP3v1.Precip,CLMGSWP3v1.TPQW
+ ELMERA5.msdrswrf,ELMERA5.msdfswrf,ELMERA5.mcpr,ELMERA5.mlspr,ELMERA5.t2m,ELMERA5.sp,ELMERA5.d2m,ELMERA5.w10,ELMERA5.msdwlwrf
+ ERA56HR.msdrswrf,ERA56HR.msdfswrf,ERA56HR.mcpr,ERA56HR.mlspr,ERA56HR.t2m,ERA56HR.sp,ERA56HR.d2m,ERA56HR.w10,ERA56HR.msdwlwrf
CLMMOSARTTEST
CLMNLDAS2.Solar,CLMNLDAS2.Precip,CLMNLDAS2.TPQW
CORE2_NYF.GISS,CORE2_NYF.GXGXS,CORE2_NYF.NCEP
@@ -234,6 +258,8 @@
$DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.cruncep_qianFill.0.5d.v7.c160715
$DIN_LOC_ROOT/share/domains/domain.clm
$DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.GSWP3.0.5d.v1.c170516
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.0.25d.v5.c180614
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.6HRLY.0.25d.v5.c180614
$DIN_LOC_ROOT/share/domains/domain.clm
$DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.cruncep_qianFill.0.5d.V5.c140715
$DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.GSWP3.0.5d.v1.c170516
@@ -302,6 +328,8 @@
domain.lnd.360x720.130305.nc
domain.lnd.360x720_gswp3.0v1.c170606.nc
domain.lnd.360x720_gswp3.0v1.c170606.nc
+ domain.lnd.era5_721x1440_rdrlat_EC30to60E2r2.221115.nc
+ domain.lnd.era5_721x1440_rdrlat_EC30to60E2r2.221115.nc
domain.lnd.nldas2_0224x0464_c110415.nc
domain.lnd.0.125nldas2_0.125nldas2.190410.nc
nyf.giss.T62.051007.nc
@@ -478,6 +506,24 @@
$DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.GSWP3.0.5d.v1.c170516/Solar3Hrly
$DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.GSWP3.0.5d.v1.c170516/Precip3Hrly
$DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.GSWP3.0.5d.v1.c170516/TPHWL3Hrly
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.0.25d.v5.c180614/swdn
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.0.25d.v5.c180614/swdn
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.0.25d.v5.c180614/prec
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.0.25d.v5.c180614/prec
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.0.25d.v5.c180614/tbot
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.0.25d.v5.c180614/pbot
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.0.25d.v5.c180614/tdew
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.0.25d.v5.c180614/wind
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.0.25d.v5.c180614/lwdn
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.6HRLY.0.25d.v5.c180614/swdn
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.6HRLY.0.25d.v5.c180614/swdn
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.6HRLY.0.25d.v5.c180614/prec
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.6HRLY.0.25d.v5.c180614/prec
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.6HRLY.0.25d.v5.c180614/tbot
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.6HRLY.0.25d.v5.c180614/pbot
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.6HRLY.0.25d.v5.c180614/tdew
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.6HRLY.0.25d.v5.c180614/wind
+ $DIN_LOC_ROOT_CLMFORC/atm_forcing.datm7.ERA.6HRLY.0.25d.v5.c180614/lwdn
$DIN_LOC_ROOT/atm/datm7/NLDAS
$DIN_LOC_ROOT/atm/datm7/atm_forcing.datm7.NLDAS2.0.125d.v1/Solar
$DIN_LOC_ROOT/atm/datm7/atm_forcing.datm7.NLDAS2.0.125d.v1/Precip
@@ -553,6 +599,24 @@
clmforc.GSWP3.c2011.0.5x0.5.Solr.%ym.nc
clmforc.GSWP3.c2011.0.5x0.5.Prec.%ym.nc
clmforc.GSWP3.c2011.0.5x0.5.TPQWL.%ym.nc
+ elmforc.ERA5.c2018.0.25d.msdrswrf.%ym.nc
+ elmforc.ERA5.c2018.0.25d.msdfswrf.%ym.nc
+ elmforc.ERA5.c2018.0.25d.mcpr.%ym.nc
+ elmforc.ERA5.c2018.0.25d.mlspr.%ym.nc
+ elmforc.ERA5.c2018.0.25d.t2m.%ym.nc
+ elmforc.ERA5.c2018.0.25d.sp.%ym.nc
+ elmforc.ERA5.c2018.0.25d.d2m.%ym.nc
+ elmforc.ERA5.c2018.0.25d.w10.%ym.nc
+ elmforc.ERA5.c2018.0.25d.msdwlwrf.%ym.nc
+ elmforc.ERA5.c2018.0.25d.msdrswrf.%ym.nc
+ elmforc.ERA5.c2018.0.25d.msdfswrf.%ym.nc
+ elmforc.ERA5.c2018.0.25d.mcpr.%ym.nc
+ elmforc.ERA5.c2018.0.25d.mlspr.%ym.nc
+ elmforc.ERA5.c2018.0.25d.t2m.%ym.nc
+ elmforc.ERA5.c2018.0.25d.sp.%ym.nc
+ elmforc.ERA5.c2018.0.25d.d2m.%ym.nc
+ elmforc.ERA5.c2018.0.25d.w10.%ym.nc
+ elmforc.ERA5.c2018.0.25d.msdwlwrf.%ym.nc
clmforc.nldas.%ym.nc
ctsmforc.NLDAS2.0.125d.v1.Solr.%ym.nc
ctsmforc.NLDAS2.0.125d.v1.Prec.%ym.nc
@@ -1523,6 +1587,60 @@
PSRF pbot
FLDS lwdn
+
+ msdrswrf swdndr
+
+
+ msdfswrf swdndf
+
+
+ mcpr precc
+
+
+ mlspr precl
+
+
+ t2m tbot
+
+
+ sp pbot
+
+
+ d2m tdew
+
+
+ w10 wind
+
+
+ msdwlwrf lwdn
+
+
+ msdrswrf swdndr
+
+
+ msdfswrf swdndf
+
+
+ mcpr precc
+
+
+ mlspr precl
+
+
+ t2m tbot
+
+
+ sp pbot
+
+
+ d2m tdew
+
+
+ w10 wind
+
+
+ msdwlwrf lwdn
+
TBOT tbot
WIND wind
@@ -1793,13 +1911,15 @@
$DATM_CLMNCEP_YR_ALIGN
$DATM_CLMNCEP_YR_ALIGN
$DATM_CLMNCEP_YR_ALIGN
+ $DATM_CLMNCEP_YR_ALIGN
+ $DATM_CLMNCEP_YR_ALIGN
$DATM_CLMNCEP_YR_ALIGN
$DATM_CLMNCEP_YR_ALIGN
1
1
1
- 1
- 1
+ $DATM_CLMNCEP_YR_ALIGN
+ $DATM_CLMNCEP_YR_ALIGN
1
1850
@@ -1843,6 +1963,8 @@
$DATM_CLMNCEP_YR_START
$DATM_CLMNCEP_YR_START
$DATM_CLMNCEP_YR_START
+ $DATM_CLMNCEP_YR_START
+ $DATM_CLMNCEP_YR_START
$DATM_CLMNCEP_YR_START
$DATM_CLMNCEP_YR_START
1
@@ -1914,6 +2036,8 @@
$DATM_CLMNCEP_YR_END
$DATM_CLMNCEP_YR_END
$DATM_CLMNCEP_YR_END
+ $DATM_CLMNCEP_YR_END
+ $DATM_CLMNCEP_YR_END
$DATM_CLMNCEP_YR_END
$DATM_CLMNCEP_YR_END
1
@@ -1988,6 +2112,16 @@
900
0
0
+ -3600
+ -3600
+ -60
+ -60
+ -60
+ -21600
+ -21600
+ -60
+ -60
+ -60
@@ -2054,6 +2188,8 @@
NULL
CLMNCEP
+ CLMNCEP
+ CLMNCEP
CORE2_NYF
CORE2_IAF
CORE_IAF_JRA
@@ -2093,7 +2229,9 @@
valid values: 'copy','spval','nn','nnoni','nnonj'
- nn
+ nn
+ copy
+ copy
@@ -2248,6 +2386,16 @@
nearest
coszen
nearest
+ coszen
+ coszen
+ upper
+ linear
+ linear
+ coszen
+ coszen
+ upper
+ linear
+ linear
coszen
nearest
nearest
@@ -2340,6 +2488,25 @@
3.0
3.0
3.0
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+ 2.5
+
diff --git a/components/data_comps/datm/src/atm_comp_mct.F90 b/components/data_comps/datm/src/atm_comp_mct.F90
index a5f2855ae63e..4970ac726d79 100644
--- a/components/data_comps/datm/src/atm_comp_mct.F90
+++ b/components/data_comps/datm/src/atm_comp_mct.F90
@@ -18,6 +18,11 @@ module atm_comp_mct
use datm_shr_mod , only: presaero
use seq_flds_mod , only: seq_flds_a2x_fields, seq_flds_x2a_fields
+#ifdef HAVE_MOAB
+ use seq_comm_mct, only : mphaid ! iMOAB app id for phys atm; comp atm is 5, phys 5+200
+ use iso_c_binding
+ use iMOAB , only: iMOAB_RegisterApplication
+#endif
! !PUBLIC TYPES:
implicit none
private ! except
@@ -80,6 +85,9 @@ subroutine atm_init_mct( EClock, cdata, x2a, a2x, NLFilename )
real(R8) :: orbObliqr ! orb obliquity (radians)
real(R8) :: nextsw_cday ! calendar of next atm sw
+#ifdef HAVE_MOAB
+ integer(IN) :: ATM_PHYS_CID ! used to create a new comp id for phys atm; 200+ compid
+#endif
!--- formats ---
character(*), parameter :: F00 = "('(datm_comp_init) ',8a)"
integer(IN) , parameter :: master_task=0 ! task number of master task
@@ -164,6 +172,18 @@ subroutine atm_init_mct( EClock, cdata, x2a, a2x, NLFilename )
! Initialize datm
!----------------------------------------------------------------------------
+
+#ifdef HAVE_MOAB
+ ATM_PHYS_CID = 200 + compid
+ ierr = iMOAB_RegisterApplication(trim("DATM")//C_NULL_CHAR, mpicom, ATM_PHYS_CID, mphaid)
+ if (ierr .ne. 0) then
+ write(logunit,*) subname,' error in registering data atm comp'
+ call shr_sys_abort(subname//' ERROR in registering data atm comp')
+ endif
+ ! send path of atm domain file to MOAB coupler. Note that here we may have the land domain in some cases?
+ call seq_infodata_PutData( infodata, atm_mesh=SDATM%domainFile)
+#endif
+
call datm_comp_init(Eclock, x2a, a2x, &
seq_flds_x2a_fields, seq_flds_a2x_fields, &
SDATM, gsmap, ggrid, mpicom, compid, my_task, master_task, &
diff --git a/components/data_comps/datm/src/datm_comp_mod.F90 b/components/data_comps/datm/src/datm_comp_mod.F90
index 3ad18c4a238b..6f0adeedcd08 100644
--- a/components/data_comps/datm/src/datm_comp_mod.F90
+++ b/components/data_comps/datm/src/datm_comp_mod.F90
@@ -32,6 +32,9 @@ module datm_comp_mod
use datm_shr_mod , only: iradsw ! namelist input
use datm_shr_mod , only: nullstr
+#ifdef HAVE_MOAB
+ use iso_c_binding
+#endif
! !PUBLIC TYPES:
implicit none
@@ -212,6 +215,13 @@ subroutine datm_comp_init(Eclock, x2a, a2x, &
scmMode, scmlat, scmlon, &
orbEccen, orbMvelpp, orbLambm0, orbObliqr, phase, nextsw_cday)
+#ifdef HAVE_MOAB
+ use iMOAB, only: iMOAB_DefineTagStorage, iMOAB_GetDoubleTagStorage, &
+ iMOAB_SetIntTagStorage, iMOAB_SetDoubleTagStorage, &
+ iMOAB_ResolveSharedEntities, iMOAB_CreateVertices, &
+ iMOAB_GetMeshInfo, iMOAB_UpdateMeshInfo, iMOAB_WriteMesh
+ use seq_comm_mct, only : mphaid ! iMOAB app id for phys atm; comp atm is 5, phys 5+200
+#endif
! !DESCRIPTION: initialize data atm model
implicit none
@@ -258,6 +268,19 @@ subroutine datm_comp_init(Eclock, x2a, a2x, &
character(CL) :: calendar ! calendar type
character(CL) :: flds_strm
+#ifdef HAVE_MOAB
+ character*400 tagname
+ real(R8) latv, lonv
+ integer iv, tagindex, ilat, ilon, ierr !, arrsize, nfields
+ real(R8), allocatable, target :: data(:)
+ integer(IN), pointer :: idata(:) ! temporary
+ real(r8), dimension(:), allocatable :: moab_vert_coords ! temporary
+ !real(R8), allocatable, target :: vtags_zero(:, :)
+#ifdef MOABDEBUG
+ character*100 outfile, wopts
+#endif
+#endif
+
!--- formats ---
character(*), parameter :: F00 = "('(datm_comp_init) ',8a)"
character(*), parameter :: F0L = "('(datm_comp_init) ',a, l2)"
@@ -347,6 +370,110 @@ subroutine datm_comp_init(Eclock, x2a, a2x, &
call shr_dmodel_rearrGGrid(SDATM%grid, ggrid, gsmap, rearr, mpicom)
call t_stopf('datm_initmctdom')
+#ifdef HAVE_MOAB
+ ilat = mct_aVect_indexRA(ggrid%data,'lat')
+ ilon = mct_aVect_indexRA(ggrid%data,'lon')
+ allocate(moab_vert_coords(lsize*3))
+ do iv = 1, lsize
+ lonv = ggrid%data%rAttr(ilon, iv) * SHR_CONST_PI/180.
+ latv = ggrid%data%rAttr(ilat, iv) * SHR_CONST_PI/180.
+ moab_vert_coords(3*iv-2)=COS(latv)*COS(lonv)
+ moab_vert_coords(3*iv-1)=COS(latv)*SIN(lonv)
+ moab_vert_coords(3*iv )=SIN(latv)
+ enddo
+
+ ! create the vertices with coordinates from MCT domain
+ ierr = iMOAB_CreateVertices(mphaid, lsize*3, 3, moab_vert_coords)
+ if (ierr .ne. 0) &
+ call shr_sys_abort('Error: fail to create MOAB vertices in land model')
+
+ tagname='GLOBAL_ID'//C_NULL_CHAR
+ ierr = iMOAB_DefineTagStorage(mphaid, tagname, &
+ 0, & ! dense, integer
+ 1, & ! number of components
+ tagindex )
+ if (ierr .ne. 0) &
+ call shr_sys_abort('Error: fail to retrieve GLOBAL_ID tag ')
+
+ ! get list of global IDs for Dofs
+ call mct_gsMap_orderedPoints(gsMap, my_task, idata)
+
+ ierr = iMOAB_SetIntTagStorage ( mphaid, tagname, lsize, &
+ 0, & ! vertex type
+ idata)
+ if (ierr .ne. 0) &
+ call shr_sys_abort('Error: fail to set GLOBAL_ID tag ')
+
+ ierr = iMOAB_ResolveSharedEntities( mphaid, lsize, idata );
+ if (ierr .ne. 0) &
+ call shr_sys_abort('Error: fail to resolve shared entities')
+
+ deallocate(moab_vert_coords)
+ deallocate(idata)
+
+ ierr = iMOAB_UpdateMeshInfo( mphaid )
+ if (ierr .ne. 0) &
+ call shr_sys_abort('Error: fail to update mesh info ')
+
+ allocate(data(lsize))
+ ierr = iMOAB_DefineTagStorage( mphaid, "area:aream:frac:mask"//C_NULL_CHAR, &
+ 1, & ! dense, double
+ 1, & ! number of components
+ tagindex )
+ if (ierr > 0 ) &
+ call shr_sys_abort('Error: fail to create tag: area:aream:frac:mask' )
+
+ data(:) = ggrid%data%rAttr(mct_aVect_indexRA(ggrid%data,'area'),:)
+ tagname='area'//C_NULL_CHAR
+ ierr = iMOAB_SetDoubleTagStorage ( mphaid, tagname, lsize, &
+ 0, & ! set data on vertices
+ data)
+ if (ierr > 0 ) &
+ call shr_sys_abort('Error: fail to get area tag ')
+
+ ! set the same data for aream (model area) as area
+ ! data(:) = ggrid%data%rAttr(mct_aVect_indexRA(ggrid%data,'aream'),:)
+ tagname='aream'//C_NULL_CHAR
+ ierr = iMOAB_SetDoubleTagStorage ( mphaid, tagname, lsize, &
+ 0, & ! set data on vertices
+ data)
+ if (ierr > 0 ) &
+ call shr_sys_abort('Error: fail to set aream tag ')
+
+ data(:) = ggrid%data%rAttr(mct_aVect_indexRA(ggrid%data,'mask'),:)
+ tagname='mask'//C_NULL_CHAR
+ ierr = iMOAB_SetDoubleTagStorage ( mphaid, tagname, lsize, &
+ 0, & ! set data on vertices
+ data)
+ if (ierr > 0 ) &
+ call shr_sys_abort('Error: fail to set mask tag ')
+
+ data(:) = ggrid%data%rAttr(mct_aVect_indexRA(ggrid%data,'frac'),:)
+ tagname='frac'//C_NULL_CHAR
+ ierr = iMOAB_SetDoubleTagStorage ( mphaid, tagname, lsize, &
+ 0, & ! set data on vertices
+ data)
+ if (ierr > 0 ) &
+ call shr_sys_abort('Error: fail to set frac tag ')
+
+ deallocate(data)
+
+ ! define tags
+ ierr = iMOAB_DefineTagStorage( mphaid, trim(seq_flds_x2a_fields)//C_NULL_CHAR, &
+ 1, & ! dense, double
+ 1, & ! number of components
+ tagindex )
+ if (ierr > 0 ) &
+ call shr_sys_abort('Error: fail to create seq_flds_x2a_fields tags ')
+
+ ierr = iMOAB_DefineTagStorage( mphaid, trim(seq_flds_a2x_fields)//C_NULL_CHAR, &
+ 1, & ! dense, double
+ 1, & ! number of components
+ tagindex )
+ if (ierr > 0 ) &
+ call shr_sys_abort('Error: fail to create seq_flds_a2x_fields tags ')
+
+#endif
!----------------------------------------------------------------------------
! Initialize MCT attribute vectors
!----------------------------------------------------------------------------
@@ -479,6 +606,24 @@ subroutine datm_comp_init(Eclock, x2a, a2x, &
yc(:) = ggrid%data%rAttr(klat,:)
call t_stopf('datm_initmctavs')
+#ifdef HAVE_MOAB
+ ierr = iMOAB_DefineTagStorage( mphaid, trim(flds_strm)//C_NULL_CHAR, &
+ 1, & ! dense, double
+ 1, & ! number of components
+ tagindex )
+ if (ierr > 0 ) &
+ call shr_sys_abort('Error: fail to create flds_strm tags ')
+#ifdef MOABDEBUG
+ ! debug test
+ outfile = 'AtmDataMesh.h5m'//C_NULL_CHAR
+ wopts = ';PARALLEL=WRITE_PART'//C_NULL_CHAR !
+ ! write out the mesh file to disk
+ ierr = iMOAB_WriteMesh(mphaid, trim(outfile), trim(wopts))
+ if (ierr .ne. 0) then
+ call shr_sys_abort(subname//' ERROR in writing data mesh atm ')
+ endif
+#endif
+#endif
!----------------------------------------------------------------------------
! Read restart
@@ -580,7 +725,14 @@ subroutine datm_comp_run(EClock, x2a, a2x, &
nextsw_cday, case_name)
! !DESCRIPTION: run method for datm model
-
+#ifdef HAVE_MOAB
+ use seq_flds_mod , only: seq_flds_a2x_fields ! this should not be an argument in datm_comp_init
+ use seq_comm_mct, only : mphaid !
+ use seq_flds_mod, only: moab_set_tag_from_av
+#ifdef MOABDEBUG
+ use iMOAB, only: iMOAB_WriteMesh
+#endif
+#endif
implicit none
! !INPUT/OUTPUT PARAMETERS:
@@ -627,7 +779,18 @@ subroutine datm_comp_run(EClock, x2a, a2x, &
!--- temporaries
real(R8) :: uprime,vprime,swndr,swndf,swvdr,swvdf,ratio_rvrf
real(R8) :: tbot,pbot,rtmp,vp,ea,e,qsat,frac
+#ifdef HAVE_MOAB
+ real(R8), allocatable, target :: datam(:)
+ type(mct_list) :: temp_list
+ integer :: size_list, index_list
+ type(mct_string) :: mctOStr !
+ character*400 tagname, mct_field
+#ifdef MOABDEBUG
+ integer :: cur_datm_stepno, ierr
+ character*100 outfile, wopts, lnum
+#endif
+#endif
character(*), parameter :: F00 = "('(datm_comp_run) ',8a)"
character(*), parameter :: F04 = "('(datm_comp_run) ',2a,2i8,'s')"
character(*), parameter :: subName = "(datm_comp_run) "
@@ -675,6 +838,8 @@ subroutine datm_comp_run(EClock, x2a, a2x, &
allocate(count_av(SDATM%nstreams))
allocate(count_st(SDATM%nstreams))
end if
+
+
do n = 1,SDATM%nstreams
if (firstcall) then
call shr_dmodel_translate_list(SDATM%avs(n),a2x,&
@@ -685,6 +850,7 @@ subroutine datm_comp_run(EClock, x2a, a2x, &
ilist_av(n),olist_av(n),rearr)
end if
enddo
+
do n = 1,SDATM%nstreams
if (firstcall) then
call shr_dmodel_translate_list(SDATM%avs(n),avstrm,&
@@ -696,7 +862,6 @@ subroutine datm_comp_run(EClock, x2a, a2x, &
end if
enddo
call t_stopf('datm_scatter')
-
!-------------------------------------------------
! Determine data model behavior based on the mode
!-------------------------------------------------
@@ -1110,7 +1275,6 @@ subroutine datm_comp_run(EClock, x2a, a2x, &
!----------------------------------------------------------
! bias correction / anomaly forcing ( end block )
!----------------------------------------------------------
-
!--------------------
! Write restart
!--------------------
@@ -1145,6 +1309,33 @@ subroutine datm_comp_run(EClock, x2a, a2x, &
! Reset shr logging to original values
!----------------------------------------------------------------------------
+#ifdef HAVE_MOAB
+ lsize = mct_avect_lsize(a2x) ! is it the same as mct_avect_lsize(avstrm) ?
+ allocate(datam(lsize)) !
+ call mct_list_init(temp_list ,seq_flds_a2x_fields)
+ size_list=mct_list_nitem (temp_list)
+ do index_list = 1, size_list
+ call mct_list_get(mctOStr,index_list,temp_list)
+ mct_field = mct_string_toChar(mctOStr)
+ tagname= trim(mct_field)//C_NULL_CHAR
+ call moab_set_tag_from_av(tagname, a2x, index_list, mphaid, datam, lsize) ! loop over all a2x fields, not just a few
+ enddo
+ call mct_list_clean(temp_list)
+ deallocate(datam) ! maybe we should keep it around, deallocate at the final only?
+
+#ifdef MOABDEBUG
+ call seq_timemgr_EClockGetData( EClock, stepno=cur_datm_stepno )
+ write(lnum,"(I0.2)")cur_datm_stepno
+ outfile = 'datm_comp_run_'//trim(lnum)//'.h5m'//C_NULL_CHAR
+ wopts = 'PARALLEL=WRITE_PART'//C_NULL_CHAR
+ ierr = iMOAB_WriteMesh(mphaid, outfile, wopts)
+ if (ierr > 0 ) then
+ write(logunit,*) 'Failed to write data atm component state '
+ endif
+#endif
+
+#endif
+
call t_startf('datm_run2')
if (my_task == master_task) then
write(logunit,F04) trim(myModelName),': model date ', CurrentYMD,CurrentTOD
diff --git a/components/data_comps/docn/src/docn_comp_mod.F90 b/components/data_comps/docn/src/docn_comp_mod.F90
index beefa9901b0e..e692882c9db1 100644
--- a/components/data_comps/docn/src/docn_comp_mod.F90
+++ b/components/data_comps/docn/src/docn_comp_mod.F90
@@ -31,6 +31,12 @@ module docn_comp_mod
use docn_shr_mod , only: sst_constant_value ! namelist input
use docn_shr_mod , only: nullstr
+#ifdef HAVE_MOAB
+! character(1024) :: domain_file ! file containing domain info (set my input)
+ use seq_comm_mct, only: mpoid ! iMOAB pid for ocean mesh on component pes
+
+ use iso_c_binding
+#endif
! !PUBLIC TYPES:
implicit none
@@ -75,6 +81,10 @@ module docn_comp_mod
integer(IN), pointer :: imask(:)
real(R8), pointer :: xc(:), yc(:) ! arryas of model latitudes and longitudes
+#ifdef HAVE_MOAB
+ integer :: mdpoid ! data: ocean local component
+#endif
+
!--------------------------------------------------------------------------
integer(IN) , parameter :: ktrans = 8
character(12) , parameter :: avifld(1:ktrans) = &
@@ -90,6 +100,18 @@ module docn_comp_mod
CONTAINS
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#ifdef HAVE_MOAB
+ SUBROUTINE errorout(ierr, message)
+ integer ierr
+ character*(*) message
+ if (ierr.ne.0) then
+ print *, message
+ call exit (1)
+ end if
+ return
+ end subroutine
+#endif
+
!===============================================================================
subroutine docn_comp_init(Eclock, x2o, o2x, &
seq_flds_x2o_fields, seq_flds_o2x_fields, &
@@ -100,6 +122,13 @@ subroutine docn_comp_init(Eclock, x2o, o2x, &
! !DESCRIPTION: initialize docn model
use pio , only : iosystem_desc_t
use shr_pio_mod, only : shr_pio_getiosys, shr_pio_getiotype
+#ifdef HAVE_MOAB
+#include "moab/MOABConfig.h"
+ use iMOAB, only: iMOAB_DefineTagStorage, iMOAB_GetDoubleTagStorage, &
+ iMOAB_SetIntTagStorage, iMOAB_SetDoubleTagStorage, &
+ iMOAB_ResolveSharedEntities, iMOAB_CreateVertices, &
+ iMOAB_GetMeshInfo, iMOAB_UpdateMeshInfo
+#endif
implicit none
! !INPUT/OUTPUT PARAMETERS:
@@ -139,6 +168,15 @@ subroutine docn_comp_init(Eclock, x2o, o2x, &
logical :: write_restart=.false.
type(iosystem_desc_t), pointer :: ocn_pio_subsystem
+#ifdef HAVE_MOAB
+ character*400 tagname
+ real(R8) latv, lonv
+ integer iv, tagindex
+ real(R8), allocatable, target :: data(:)
+ integer(IN), pointer :: idata(:) ! temporary
+ real(r8), dimension(:), allocatable :: moab_vert_coords ! temporary
+#endif
+
!--- formats ---
character(*), parameter :: F00 = "('(docn_comp_init) ',8a)"
character(*), parameter :: F0L = "('(docn_comp_init) ',a, l2)"
@@ -147,7 +185,7 @@ subroutine docn_comp_init(Eclock, x2o, o2x, &
character(*), parameter :: F03 = "('(docn_comp_init) ',a,i8,a)"
character(*), parameter :: F04 = "('(docn_comp_init) ',2a,2i8,'s')"
character(*), parameter :: F05 = "('(docn_comp_init) ',a,2f10.4)"
- character(*), parameter :: F06 = "('(docn_comp_init) ',a,f10.4)"
+ character(*), parameter :: F06 = "('(docn_comp_init) ',a,5i8)"
character(*), parameter :: F90 = "('(docn_comp_init) ',73('='))"
character(*), parameter :: F91 = "('(docn_comp_init) ',73('-'))"
character(*), parameter :: subName = "(docn_comp_init) "
@@ -279,13 +317,6 @@ subroutine docn_comp_init(Eclock, x2o, o2x, &
kmask = mct_aVect_indexRA(ggrid%data,'mask')
imask(:) = nint(ggrid%data%rAttr(kmask,:))
- kfrac = mct_aVect_indexRA(ggrid%data,'frac')
-
- ksomask = mct_aVect_indexRA(o2x,'So_omask', perrwith='quiet')
- if (ksomask /= 0) then
- o2x%rAttr(ksomask, :) = ggrid%data%rAttr(kfrac,:)
- end if
-
index_lon = mct_aVect_indexRA(ggrid%data,'lon')
xc(:) = ggrid%data%rAttr(index_lon,:)
@@ -294,6 +325,115 @@ subroutine docn_comp_init(Eclock, x2o, o2x, &
call t_stopf('docn_initmctavs')
+#ifdef HAVE_MOAB
+
+ allocate(moab_vert_coords(lsize*3))
+ do iv = 1, lsize
+ lonv = xc(iv) * SHR_CONST_PI/180.
+ latv = yc(iv) * SHR_CONST_PI/180.
+ moab_vert_coords(3*iv-2)=COS(latv)*COS(lonv)
+ moab_vert_coords(3*iv-1)=COS(latv)*SIN(lonv)
+ moab_vert_coords(3*iv )=SIN(latv)
+ enddo
+
+ ! create the vertices with coordinates from MCT domain
+ ierr = iMOAB_CreateVertices(mpoid, lsize*3, 3, moab_vert_coords)
+ if (ierr .ne. 0) &
+ call shr_sys_abort('Error: fail to create MOAB vertices in land model')
+
+ tagname='GLOBAL_ID'//C_NULL_CHAR
+ ierr = iMOAB_DefineTagStorage(mpoid, tagname, &
+ 0, & ! dense, integer
+ 1, & ! number of components
+ tagindex )
+ if (ierr .ne. 0) &
+ call shr_sys_abort('Error: fail to retrieve GLOBAL_ID tag ')
+
+ ! get list of global IDs for Dofs
+ call mct_gsMap_orderedPoints(gsMap, my_task, idata)
+
+ ierr = iMOAB_SetIntTagStorage ( mpoid, tagname, lsize, &
+ 0, & ! vertex type
+ idata)
+ if (ierr .ne. 0) &
+ call shr_sys_abort('Error: fail to set GLOBAL_ID tag ')
+
+ ierr = iMOAB_ResolveSharedEntities( mpoid, lsize, idata );
+ if (ierr .ne. 0) &
+ call shr_sys_abort('Error: fail to resolve shared entities')
+
+ deallocate(moab_vert_coords)
+ deallocate(idata)
+
+ ierr = iMOAB_UpdateMeshInfo( mpoid )
+ if (ierr .ne. 0) &
+ call shr_sys_abort('Error: fail to update mesh info ')
+
+ allocate(data(lsize))
+ ierr = iMOAB_DefineTagStorage( mpoid, "area:aream:frac:mask"//C_NULL_CHAR, &
+ 1, & ! dense, double
+ 1, & ! number of components
+ tagindex )
+ if (ierr > 0 ) &
+ call errorout(ierr, 'Error: fail to create tag: area:aream:frac:mask' )
+
+ data(:) = ggrid%data%rAttr(mct_aVect_indexRA(ggrid%data,'area'),:)
+ tagname='area'//C_NULL_CHAR
+ ierr = iMOAB_SetDoubleTagStorage ( mpoid, tagname, lsize, &
+ 0, & ! set data on vertices
+ data)
+ if (ierr > 0 ) &
+ call errorout(ierr, 'Error: fail to get area tag ')
+
+ ! set the same data for aream (model area) as area
+ ! data(:) = ggrid%data%rAttr(mct_aVect_indexRA(ggrid%data,'aream'),:)
+ tagname='aream'//C_NULL_CHAR
+ ierr = iMOAB_SetDoubleTagStorage ( mpoid, tagname, lsize, &
+ 0, & ! set data on vertices
+ data)
+ if (ierr > 0 ) &
+ call errorout(ierr, 'Error: fail to set aream tag ')
+
+ data(:) = ggrid%data%rAttr(kmask,:)
+ tagname='mask'//C_NULL_CHAR
+ ierr = iMOAB_SetDoubleTagStorage ( mpoid, tagname, lsize, &
+ 0, & ! set data on vertices
+ data)
+ if (ierr > 0 ) &
+ call errorout(ierr, 'Error: fail to set mask tag ')
+
+ data(:) = ggrid%data%rAttr(kfrac,:)
+ tagname='frac'//C_NULL_CHAR
+ ierr = iMOAB_SetDoubleTagStorage ( mpoid, tagname, lsize, &
+ 0, & ! set data on vertices
+ data)
+ if (ierr > 0 ) &
+ call errorout(ierr, 'Error: fail to set frac tag ')
+
+ deallocate(data)
+
+ ! define tags
+ ierr = iMOAB_DefineTagStorage( mpoid, trim(seq_flds_x2o_fields)//C_NULL_CHAR, &
+ 1, & ! dense, double
+ 1, & ! number of components
+ tagindex )
+ if (ierr > 0 ) &
+ call errorout(ierr, 'Error: fail to create seq_flds_x2o_fields tags ')
+
+ ierr = iMOAB_DefineTagStorage( mpoid, trim(seq_flds_o2x_fields)//C_NULL_CHAR, &
+ 1, & ! dense, double
+ 1, & ! number of components
+ tagindex )
+ if (ierr > 0 ) &
+ call errorout(ierr, 'Error: fail to create seq_flds_o2x_fields tags ')
+
+ ierr = iMOAB_DefineTagStorage( mpoid, trim(flds_strm)//C_NULL_CHAR, &
+ 1, & ! dense, double
+ 1, & ! number of components
+ tagindex )
+ if (ierr > 0 ) &
+ call errorout(ierr, 'Error: fail to create flds_strm tags ')
+#endif
!----------------------------------------------------------------------------
! Read restart
!----------------------------------------------------------------------------
@@ -379,14 +519,19 @@ subroutine docn_comp_init(Eclock, x2o, o2x, &
end subroutine docn_comp_init
- !===============================================================================
-
subroutine docn_comp_run(EClock, x2o, o2x, &
SDOCN, gsmap, ggrid, mpicom, compid, my_task, master_task, &
inst_suffix, logunit, read_restart, write_restart, &
target_ymd, target_tod, case_name)
! !DESCRIPTION: run method for docn model
+#ifdef HAVE_MOAB
+ use iMOAB, only: iMOAB_GetMeshInfo, &
+ iMOAB_SetDoubleTagStorage, &
+ iMOAB_WriteMesh
+ use seq_flds_mod, only: moab_set_tag_from_av
+#endif
+
implicit none
! !INPUT/OUTPUT PARAMETERS:
@@ -423,6 +568,19 @@ subroutine docn_comp_run(EClock, x2o, o2x, &
real(R8), parameter :: &
swp = 0.67_R8*(exp((-1._R8*shr_const_zsrflyr) /1.0_R8)) + 0.33_R8*exp((-1._R8*shr_const_zsrflyr)/17.0_R8)
+#ifdef HAVE_MOAB
+ integer :: ierr ! error code
+ integer :: kgg
+ character*100 tagname
+ integer tagindex
+ real(R8), allocatable, target :: data(:)
+#ifdef MOABDEBUG
+ integer :: cur_docn_stepno
+ character*100 outfile, wopts, lnum
+#endif
+
+#endif
+
character(*), parameter :: F00 = "('(docn_comp_run) ',8a)"
character(*), parameter :: F01 = "('(docn_comp_run) ',a, i7,2x,i5,2x,i5,2x,d21.14)"
character(*), parameter :: F04 = "('(docn_comp_run) ',2a,2i8,'s')"
@@ -486,6 +644,8 @@ subroutine docn_comp_run(EClock, x2o, o2x, &
! Determine data model behavior based on the mode
!-------------------------------------------------
+ if (my_task .EQ. master_task) &
+ write(logunit,*) "DOCN datamode case = ", trim(datamode)
call t_startf('docn_datamode')
select case (trim(datamode))
@@ -647,10 +807,70 @@ subroutine docn_comp_run(EClock, x2o, o2x, &
call t_stopf('docn_datamode')
+#ifdef HAVE_MOAB
+
+ allocate(data(lsize))
+ data(:) = 0.0
+
+ ! set dense double tags on vertices of the temporary DOCN app
+ ! first set o2x data
+ call moab_set_tag_from_av('So_t'//C_NULL_CHAR, o2x, kt, mpoid, data, lsize)
+
+ call moab_set_tag_from_av('So_s'//C_NULL_CHAR, o2x, ks, mpoid, data, lsize)
+
+ call moab_set_tag_from_av( 'So_u'//C_NULL_CHAR, o2x, ku, mpoid, data, lsize)
+
+ call moab_set_tag_from_av( 'So_v'//C_NULL_CHAR, o2x, kv, mpoid, data, lsize)
+
+ call moab_set_tag_from_av( 'So_dhdx'//C_NULL_CHAR, o2x, kdhdx, mpoid, data, lsize)
+
+ call moab_set_tag_from_av( 'So_dhdy'//C_NULL_CHAR, o2x, kdhdy, mpoid, data, lsize)
+
+ call moab_set_tag_from_av( 'Fioo_q'//C_NULL_CHAR, o2x, kq, mpoid, data, lsize)
+
+ if (kswp /= 0) then
+ call moab_set_tag_from_av( 'So_fswpen'//C_NULL_CHAR, o2x, kswp, mpoid, data, lsize)
+ endif
+
+ ! next set x2o data
+ call moab_set_tag_from_av( 'Foxx_swnet'//C_NULL_CHAR, x2o, kswnet, mpoid, data, lsize)
+
+ call moab_set_tag_from_av( 'Foxx_lwup'//C_NULL_CHAR, x2o, klwup, mpoid, data, lsize)
+
+ call moab_set_tag_from_av( 'Foxx_sen'//C_NULL_CHAR, x2o, ksen, mpoid, data, lsize)
+
+ call moab_set_tag_from_av( 'Foxx_lat'//C_NULL_CHAR, x2o, klat, mpoid, data, lsize)
+
+ call moab_set_tag_from_av( 'Foxx_rofi'//C_NULL_CHAR, x2o, krofi, mpoid, data, lsize)
+
+ call moab_set_tag_from_av( 'Faxa_lwdn'//C_NULL_CHAR, x2o, klwdn, mpoid, data, lsize)
+
+ call moab_set_tag_from_av( 'Faxa_snow'//C_NULL_CHAR, x2o, ksnow, mpoid, data, lsize)
+
+ call moab_set_tag_from_av( 'Fioi_melth'//C_NULL_CHAR, x2o, kmelth, mpoid, data, lsize)
+
+ ! next set avstrm data
+ call moab_set_tag_from_av( 'strm_h'//C_NULL_CHAR, avstrm, kh, mpoid, data, lsize)
+
+ call moab_set_tag_from_av( 'strm_qbot'//C_NULL_CHAR, avstrm, kqbot, mpoid, data, lsize)
+
+
+#ifdef MOABDEBUG
+ call seq_timemgr_EClockGetData( EClock, stepno=cur_docn_stepno )
+ write(lnum,"(I0.2)")cur_docn_stepno
+ outfile = 'docn_comp_run_'//trim(lnum)//'.h5m'//C_NULL_CHAR
+ wopts = 'PARALLEL=WRITE_PART'//C_NULL_CHAR
+ ierr = iMOAB_WriteMesh(mpoid, outfile, wopts)
+ if (ierr > 0 ) then
+ write(logunit,*) 'Failed to write ocean component state '
+ endif
+#endif
+
+#endif
+
!----------------------------------------------------------
! Debug output
!----------------------------------------------------------
-
if (dbug > 0 .and. my_task == master_task) then
do n = 1,lsize
write(logunit,F01)'import: ymd,tod,n,Foxx_swnet = ', target_ymd, target_tod, n, x2o%rattr(kswnet,n)
diff --git a/components/data_comps/docn/src/ocn_comp_mct.F90 b/components/data_comps/docn/src/ocn_comp_mct.F90
index 22c095b3b57b..6b029981438f 100644
--- a/components/data_comps/docn/src/ocn_comp_mct.F90
+++ b/components/data_comps/docn/src/ocn_comp_mct.F90
@@ -18,6 +18,11 @@ module ocn_comp_mct
use docn_shr_mod , only: docn_shr_read_namelists
use seq_flds_mod , only: seq_flds_x2o_fields, seq_flds_o2x_fields
+#ifdef HAVE_MOAB
+ use seq_comm_mct, only: mpoid ! iMOAB pid for ocean mesh on component pes
+ use iso_c_binding
+#endif
+
! !PUBLIC TYPES:
implicit none
private ! except
@@ -53,6 +58,10 @@ module ocn_comp_mct
!===============================================================================
subroutine ocn_init_mct( EClock, cdata, x2o, o2x, NLFilename )
+#ifdef HAVE_MOAB
+ use iMOAB, only: iMOAB_RegisterApplication
+#endif
+
! !DESCRIPTION: initialize docn model
implicit none
@@ -156,6 +165,17 @@ subroutine ocn_init_mct( EClock, cdata, x2o, o2x, NLFilename )
! Initialize docn
!----------------------------------------------------------------------------
+
+#ifdef HAVE_MOAB
+ ierr = iMOAB_RegisterApplication(trim("DOCN")//C_NULL_CHAR, mpicom, compid, mpoid)
+ if (ierr .ne. 0) then
+ write(logunit,*) subname,' error in registering data ocn comp'
+ call shr_sys_abort(subname//' ERROR in registering data ocn comp')
+ endif
+ ! send path of ocean domain file to MOAB coupler.
+ call seq_infodata_PutData( infodata, ocn_domain=SDOCN%domainFile)
+#endif
+
call docn_comp_init(Eclock, x2o, o2x, &
seq_flds_x2o_fields, seq_flds_o2x_fields, &
SDOCN, gsmap, ggrid, mpicom, compid, my_task, master_task, &
diff --git a/components/data_comps/drof/cime_config/namelist_definition_drof.xml b/components/data_comps/drof/cime_config/namelist_definition_drof.xml
index 369e23965189..c4139552c706 100644
--- a/components/data_comps/drof/cime_config/namelist_definition_drof.xml
+++ b/components/data_comps/drof/cime_config/namelist_definition_drof.xml
@@ -205,10 +205,10 @@
RAF_9091.JRA.v1.3.runoff.180404.nc
RAF_0304.JRA.v1.3.runoff.180404.nc
- JRA.v1.5.runoff.%y.no_rofi_no_rofl.210505.nc
+ JRA.v1.5.runoff.%y.no_rofi_no_rofl.240411.nc
- JRA.v1.5.runoff.%y.210505.nc
+ JRA.v1.5.runoff.%y.240411.nc
JRA.v1.4.runoff.%y.no_rofi.190214.nc
diff --git a/components/eam/bld/namelist_files/namelist_defaults_eam.xml b/components/eam/bld/namelist_files/namelist_defaults_eam.xml
index 56c816b1753c..cfd9bf682c8e 100755
--- a/components/eam/bld/namelist_files/namelist_defaults_eam.xml
+++ b/components/eam/bld/namelist_files/namelist_defaults_eam.xml
@@ -917,6 +917,7 @@
1.0D0
.false.
100.D6
+ 200.D6
0.1D6
-999.
-999.
diff --git a/components/eam/bld/namelist_files/namelist_definition.xml b/components/eam/bld/namelist_files/namelist_definition.xml
index bc9977f67b58..b3ecb5e9290a 100644
--- a/components/eam/bld/namelist_files/namelist_definition.xml
+++ b/components/eam/bld/namelist_files/namelist_definition.xml
@@ -473,6 +473,26 @@ Turn on additional verbose output for integrated conservation checks.
Default: FALSE
+
+
+
+Number of zonal mean basis functions (number of m=0 spherical harmonics) used in
+Transformed Eulerian Mean (TEM) diagnostics
+
+
+
+Number of latitude grid points for zonal average TEM diagnostics history fields
+
+
+
+ Frequency of TEM diagnostic calculations.
+ If > 0, frequency is specified as number of timesteps.
+ If < 0, frequency is specified as number of hours.
+
+
-Turn off microphysics computation.
+Turn off microphysics computation for MG2. For P3 this disables the generation of
+liquid precipitation via autoconversion only, to be used for idealized simulations of
+warm phase boundary layer clouds.
Default: FALSE
|
|
diff --git a/components/eam/bld/namelist_files/use_cases/1850_eam_CMIP6_chemUCI-Linoz-mam5-vbs-1pctCO2.xml b/components/eam/bld/namelist_files/use_cases/1850_eam_CMIP6_chemUCI-Linoz-mam5-vbs-1pctCO2.xml
index c4f96718134e..41803ef4469f 100644
--- a/components/eam/bld/namelist_files/use_cases/1850_eam_CMIP6_chemUCI-Linoz-mam5-vbs-1pctCO2.xml
+++ b/components/eam/bld/namelist_files/use_cases/1850_eam_CMIP6_chemUCI-Linoz-mam5-vbs-1pctCO2.xml
@@ -15,7 +15,7 @@
18500101
FIXED
-
+
808.249e-9
273.0211e-9
diff --git a/components/eam/bld/namelist_files/use_cases/1850_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/1850_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml
index 1518954b5332..c8cc7ee0b0fb 100644
--- a/components/eam/bld/namelist_files/use_cases/1850_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml
+++ b/components/eam/bld/namelist_files/use_cases/1850_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml
@@ -15,7 +15,7 @@
18500101
FIXED
-
+
808.249e-9
273.0211e-9
diff --git a/components/eam/bld/namelist_files/use_cases/1950_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/1950_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml
new file mode 100644
index 000000000000..b415cd84b844
--- /dev/null
+++ b/components/eam/bld/namelist_files/use_cases/1950_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml
@@ -0,0 +1,136 @@
+----- modified based on 1850 version ---- combined with 1950 use_case for V2
+
+
+
+
+
+.true.
+
+
+atm/cam/inic/homme/NGD_v3atm.ne30pg2.eam.i.0001-01-01-00000.c20230106.nc
+
+
+
+atm/cam/solar/Solar_1950control_input4MIPS_c20171208.nc
+19500101
+FIXED
+
+
+
+1163.821e-9
+289.739e-9
+62.83147e-12
+6.382257e-12
+
+
+.true.
+.true.
+.true.
+
+
+CYCLICAL
+1950
+atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc
+
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/so2_elev_strat_1950.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_elev_1850-2014_1.9x2.5_c20230201.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_elev_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_elev_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_elev_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_elev_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_elev_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_elev_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_elev_1850-2014_c180205.nc
+
+
+CYCLICAL
+1950
+atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H4_surface_1850-2014_1.9x2.5_c20210323.nc
+atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H6_surface_1850-2014_1.9x2.5_c20210323.nc
+atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C3H8_surface_1850-2014_1.9x2.5_c20210323.nc
+atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH2O_surface_1850-2014_1.9x2.5_c20210323.nc
+atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3CHO_surface_1850-2014_1.9x2.5_c20210323.nc
+atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3COCH3_surface_1850-2014_1.9x2.5_c20210323.nc
+atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CO_surface_1850-2014_1.9x2.5_c20210323.nc
+atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc
+atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc
+atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_MTERP_surface_1850-2014_1.9x2.5_c20230126.nc
+atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_NO_surface_1850-2014_1.9x2.5_c20220425.nc
+atm/cam/chem/trop_mozart_aero/emis/DMSflux.1950.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20171210.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_surf_1850-2014_1.9x2.5_c20230201.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_surf_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_surf_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_surf_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_surf_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_surf_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_surf_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_surf_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_surf_1850-2014_c180205.nc
+atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions_E90_surface_1750-2015_1.9x2.5_c20210408.nc
+
+
+
+
+CYCLICAL
+1955
+oxid_1.9x2.5_L26_1850-2015_c20181106.nc
+''
+atm/cam/chem/trop_mozart_aero/oxid
+'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH'
+
+
+ch4_oxid_1.9x2.5_L26_1990-1999clim.c090804.nc
+atm/cam/chem/methane
+CYCLICAL
+1995
+''
+'prsd_ch4:CH4'
+
+
+
+ 'A:H2OLNZ:H2O', 'N:O2:O2', 'N:CO2:CO2',
+ 'A:O3:O3', 'A:N2OLNZ:N2O', 'A:CH4LNZ:CH4',
+ 'N:CFC11:CFC11', 'N:CFC12:CFC12',
+ 'M:mam5_mode1:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc',
+ 'M:mam5_mode2:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc',
+ 'M:mam5_mode3:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc',
+ 'M:mam5_mode4:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc',
+ 'M:mam5_mode5:$INPUTDATA_ROOT/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc'
+
+
+
+3
+1
+'atm/cam/chem/trop_mam/marine_BGC/'
+'CYCLICAL'
+'monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc'
+0
+0
+'chla:CHL1','mpoly:TRUEPOLYC','mprot:TRUEPROTC','mlip:TRUELIPC'
+
+
+atm/cam/chem/trop_mozart/ub/Linoz_Chlorine_Loading_CMIP6_0003-2017_c20171114.nc
+19500101
+FIXED
+1950
+linv3_1849-2017_CMIP6_Hist_10deg_58km_c20230705.nc
+atm/cam/chem/trop_mozart/ub
+CYCLICAL
+
+
+'xactive_lnd'
+'O3','H2O2','CH2O','CH3OOH','NO','NO2','HNO3','HO2NO2','PAN','CO','CH3COCH3','C2H5OOH','CH3CHO','H2SO4','SO2','NO3','N2O5','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31'
+'NEU'
+'C2H5OOH','CH2O','CH3CHO','CH3OOH','H2O2','H2SO4','HNO3','HO2NO2','SO2','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31'
+'CH2O', 'CH3O2', 'CH3OOH', 'PAN', 'CO', 'C2H6', 'C3H8', 'C2H4', 'ROHO2', 'CH3COCH3', 'C2H5O2', 'C2H5OOH', 'CH3CHO', 'CH3CO3', 'ISOP', 'ISOPO2', 'MVKMACR', 'MVKO2'
+
+''
+
+
+1950
+
+
+
+
+
+
diff --git a/components/eam/bld/namelist_files/use_cases/SSP245_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/SSP245_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml
new file mode 100644
index 000000000000..120fb939165e
--- /dev/null
+++ b/components/eam/bld/namelist_files/use_cases/SSP245_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml
@@ -0,0 +1,107 @@
+
+
+
+
+.true.
+
+
+atm/cam/solar/Solar_1850-2299_input4MIPS_c20181106.nc
+SERIAL
+
+
+atm/cam/ggas/GHG_CMIP_SSP245-1-2-1_Annual_Global_2015-2500_c20200807.nc
+RAMPED
+
+
+.true.
+.true.
+.true.
+
+
+INTERP_MISSING_MONTHS
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_NO2_aircraft_vertical_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_so2_volc_elev_2015-2100_c240331.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_SOAG0_elev_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_bc_a4_elev_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_num_a1_elev_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_num_a2_elev_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_num_a4_elev_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_pom_a4_elev_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_so4_a1_elev_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_so4_a2_elev_2015-2100_c200716.nc
+
+
+INTERP_MISSING_MONTHS
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_C2H4_surface_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_C2H6_surface_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_C3H8_surface_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_CH2O_surface_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_CH3CHO_surface_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_CH3COCH3_surface_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_CO_surface_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_ISOP_surface_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_ISOP_surface_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_MTERP_surface_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_NO_surface_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/DMSflux.1850-2100.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20160727.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_so2_surf_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/emissions-cmip6_ssp245_e3sm_SOAG0_surf_2015-2100_1.9x2.5_c20240219.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_bc_a4_surf_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_num_a1_surf_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_num_a2_surf_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_num_a4_surf_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_pom_a4_surf_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_so4_a1_surf_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP245_ne30/cmip6_ssp245_mam4_so4_a2_surf_2015-2100_c200716.nc
+atm/cam/chem/trop_mozart/ub/emissions_E90_surface_1750-2101_1.9x2.5_c20231222.nc
+
+
+
+
+INTERP_MISSING_MONTHS
+atm/cam/chem/trop_mozart_aero/oxid
+oxid_SSP245_1.9x2.5_L70_1849-2101_c20240228.nc
+'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH'
+''
+
+
+
+ 'A:H2OLNZ:H2O', 'N:O2:O2', 'N:CO2:CO2',
+ 'A:O3:O3', 'A:N2OLNZ:N2O', 'A:CH4LNZ:CH4',
+ 'N:CFC11:CFC11', 'N:CFC12:CFC12',
+ 'M:mam5_mode1:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc',
+ 'M:mam5_mode2:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc',
+ 'M:mam5_mode3:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc',
+ 'M:mam5_mode4:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc',
+ 'M:mam5_mode5:$INPUTDATA_ROOT/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc'
+
+
+
+3
+1
+'atm/cam/chem/trop_mam/marine_BGC/'
+'CYCLICAL'
+'monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc'
+0
+0
+'chla:CHL1','mpoly:TRUEPOLYC','mprot:TRUEPROTC','mlip:TRUELIPC'
+
+
+atm/cam/chem/trop_mozart/ub/Linoz_Chlorine_Loading_CMIP6_Hist_SSP245_0003-2503_c20200808.nc
+SERIAL
+linv3_1849-2101_CMIP6_Hist_SSP245_10deg_58km_c20230705.nc
+atm/cam/chem/trop_mozart/ub
+INTERP_MISSING_MONTHS
+
+
+'xactive_lnd'
+'O3','H2O2','CH2O','CH3OOH','NO','NO2','HNO3','HO2NO2','PAN','CO','CH3COCH3','C2H5OOH','CH3CHO','H2SO4','SO2','NO3','N2O5','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31'
+'NEU'
+'C2H5OOH','CH2O','CH3CHO','CH3OOH','H2O2','H2SO4','HNO3','HO2NO2','SO2','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31'
+'CH2O', 'CH3O2', 'CH3OOH', 'PAN', 'CO', 'C2H6', 'C3H8', 'C2H4', 'ROHO2', 'CH3COCH3', 'C2H5O2', 'C2H5OOH', 'CH3CHO', 'CH3CO3', 'ISOP', 'ISOPO2', 'MVKMACR', 'MVKO2'
+''
+
+
+2015-2100
+
+
diff --git a/components/eam/bld/namelist_files/use_cases/SSP370_eam_CMIP6.xml b/components/eam/bld/namelist_files/use_cases/SSP370_eam_CMIP6.xml
old mode 100755
new mode 100644
diff --git a/components/eam/bld/namelist_files/use_cases/SSP370_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/SSP370_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml
old mode 100755
new mode 100644
index 60912c544194..e15be0889fdc
--- a/components/eam/bld/namelist_files/use_cases/SSP370_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml
+++ b/components/eam/bld/namelist_files/use_cases/SSP370_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml
@@ -12,13 +12,6 @@
atm/cam/ggas/GHG_CMIP_SSP370-1-2-1_Annual_Global_2015-2500_c20210509.nc
RAMPED
-
-atm/cam/volc
-CMIP_DOE-ACME_radiation_average_1850-2014_v3_c20171204.nc
-VOLC_CMIP6
-CYCLICAL
-1
-
.true.
.true.
@@ -26,8 +19,9 @@
INTERP_MISSING_MONTHS
-atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_so2_elev_2015-2100_c210216.nc
-atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_soag_elev_2015-2100_c210216.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_NO2_aircraft_vertical_2015-2100_1.9x2.5_c20240208.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_so2_volc_elev_2015-2100_c240331.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_SOAG0_elev_2015-2100_1.9x2.5_c20240208.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_bc_a4_elev_2015-2100_c210216.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_num_a1_elev_2015-2100_c210216.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_num_a2_elev_2015-2100_c210216.nc
@@ -38,8 +32,20 @@
INTERP_MISSING_MONTHS
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_C2H4_surface_2015-2100_1.9x2.5_c20240208.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_C2H6_surface_2015-2100_1.9x2.5_c20240208.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_C3H8_surface_2015-2100_1.9x2.5_c20240208.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_CH2O_surface_2015-2100_1.9x2.5_c20240208.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_CH3CHO_surface_2015-2100_1.9x2.5_c20240208.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_CH3COCH3_surface_2015-2100_1.9x2.5_c20240208.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_CO_surface_2015-2100_1.9x2.5_c20240208.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_ISOP_surface_2015-2100_1.9x2.5_c20240208.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_ISOP_surface_2015-2100_1.9x2.5_c20240208.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_MTERP_surface_2015-2100_1.9x2.5_c20240208.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_NO_surface_2015-2100_1.9x2.5_c20240208.nc
atm/cam/chem/trop_mozart_aero/emis/DMSflux.1850-2100.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20160727.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_so2_surf_2015-2100_c210216.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_SOAG0_surf_2015-2100_1.9x2.5_c20240208.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_bc_a4_surf_2015-2100_c210216.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_num_a1_surf_2015-2100_c210216.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_num_a2_surf_2015-2100_c210216.nc
@@ -47,14 +53,28 @@
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_pom_a4_surf_2015-2100_c210216.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_so4_a1_surf_2015-2100_c210216.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_so4_a2_surf_2015-2100_c210216.nc
+atm/cam/chem/trop_mozart/ub/emissions_E90_surface_1750-2101_1.9x2.5_c20231222.nc
+
+
INTERP_MISSING_MONTHS
atm/cam/chem/trop_mozart_aero/oxid
-oxid_SSP370_1.9x2.5_L70_2015-2100_c20211006.nc
+oxid_SSP370_1.9x2.5_L70_1849-2101_c20240228.nc
+'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH'
''
-
+
+
+ 'A:H2OLNZ:H2O', 'N:O2:O2', 'N:CO2:CO2',
+ 'A:O3:O3', 'A:N2OLNZ:N2O', 'A:CH4LNZ:CH4',
+ 'N:CFC11:CFC11', 'N:CFC12:CFC12',
+ 'M:mam5_mode1:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc',
+ 'M:mam5_mode2:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc',
+ 'M:mam5_mode3:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc',
+ 'M:mam5_mode4:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc',
+ 'M:mam5_mode5:$INPUTDATA_ROOT/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc'
+
3
@@ -74,7 +94,12 @@
INTERP_MISSING_MONTHS
-'H2O2', 'H2SO4', 'SO2'
+'xactive_lnd'
+'O3','H2O2','CH2O','CH3OOH','NO','NO2','HNO3','HO2NO2','PAN','CO','CH3COCH3','C2H5OOH','CH3CHO','H2SO4','SO2','NO3','N2O5','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31'
+'NEU'
+'C2H5OOH','CH2O','CH3CHO','CH3OOH','H2O2','H2SO4','HNO3','HO2NO2','SO2','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31'
+'CH2O', 'CH3O2', 'CH3OOH', 'PAN', 'CO', 'C2H6', 'C3H8', 'C2H4', 'ROHO2', 'CH3COCH3', 'C2H5O2', 'C2H5OOH', 'CH3CHO', 'CH3CO3', 'ISOP', 'ISOPO2', 'MVKMACR', 'MVKO2'
+''
2015-2100
diff --git a/components/eam/bld/namelist_files/use_cases/SSP585_eam_CMIP6.xml b/components/eam/bld/namelist_files/use_cases/SSP585_eam_CMIP6.xml
old mode 100755
new mode 100644
diff --git a/components/eam/bld/namelist_files/use_cases/SSP585_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml b/components/eam/bld/namelist_files/use_cases/SSP585_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml
old mode 100755
new mode 100644
index 98e2dcf76042..f9c45623d5a9
--- a/components/eam/bld/namelist_files/use_cases/SSP585_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml
+++ b/components/eam/bld/namelist_files/use_cases/SSP585_eam_CMIP6_chemUCI-Linoz-mam5-vbs.xml
@@ -12,13 +12,6 @@
atm/cam/ggas/GHG_CMIP_SSP585-1-2-1_Annual_Global_2015-2500_c20190310.nc
RAMPED
-
-atm/cam/volc
-CMIP_DOE-ACME_radiation_average_1850-2014_v3_c20171204.nc
-VOLC_CMIP6
-CYCLICAL
-1
-
.true.
.true.
@@ -26,8 +19,9 @@
INTERP_MISSING_MONTHS
-atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/cmip6_ssp585_mam4_so2_elev_2015-2100_c190828.nc
-atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/cmip6_ssp585_mam4_soag_elev_2015-2100_c190828.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_NO2_aircraft_vertical_2015-2100_1.9x2.5_c20240304.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/cmip6_ssp585_mam4_so2_volc_elev_2015-2100_c240331.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_SOAG0_elev_2015-2100_1.9x2.5_c20240304.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/cmip6_ssp585_mam4_bc_a4_elev_2015-2100_c190828.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/cmip6_ssp585_mam4_num_a1_elev_2015-2100_c190828.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/cmip6_ssp585_mam4_num_a2_elev_2015-2100_c190828.nc
@@ -38,8 +32,20 @@
INTERP_MISSING_MONTHS
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_C2H4_surface_2015-2100_1.9x2.5_c20240304.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_C2H6_surface_2015-2100_1.9x2.5_c20240304.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_C3H8_surface_2015-2100_1.9x2.5_c20240304.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_CH2O_surface_2015-2100_1.9x2.5_c20240304.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_CH3CHO_surface_2015-2100_1.9x2.5_c20240304.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_CH3COCH3_surface_2015-2100_1.9x2.5_c20240304.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_CO_surface_2015-2100_1.9x2.5_c20240304.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_ISOP_surface_2015-2100_1.9x2.5_c20240304.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_ISOP_surface_2015-2100_1.9x2.5_c20240304.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_MTERP_surface_2015-2100_1.9x2.5_c20240304.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_NO_surface_2015-2100_1.9x2.5_c20240304.nc
atm/cam/chem/trop_mozart_aero/emis/DMSflux.1850-2100.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20160727.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/cmip6_ssp585_mam4_so2_surf_2015-2100_c190828.nc
+atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/emissions-cmip6_ssp585_e3sm_SOAG0_surf_2015-2100_1.9x2.5_c20240304.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/cmip6_ssp585_mam4_bc_a4_surf_2015-2100_c190828.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/cmip6_ssp585_mam4_num_a1_surf_2015-2100_c190828.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/cmip6_ssp585_mam4_num_a2_surf_2015-2100_c190828.nc
@@ -47,14 +53,28 @@
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/cmip6_ssp585_mam4_pom_a4_surf_2015-2100_c190828.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/cmip6_ssp585_mam4_so4_a1_surf_2015-2100_c190828.nc
atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP585_ne30/cmip6_ssp585_mam4_so4_a2_surf_2015-2100_c190828.nc
+atm/cam/chem/trop_mozart/ub/emissions_E90_surface_1750-2101_1.9x2.5_c20231222.nc
+
+
INTERP_MISSING_MONTHS
atm/cam/chem/trop_mozart_aero/oxid
-oxid_1.9x2.5_L70_2015-2100_c20190421.nc
+oxid_SSP585_1.9x2.5_L70_2014-2101_c20240228.nc
+'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH'
''
-
+
+
+ 'A:H2OLNZ:H2O', 'N:O2:O2', 'N:CO2:CO2',
+ 'A:O3:O3', 'A:N2OLNZ:N2O', 'A:CH4LNZ:CH4',
+ 'N:CFC11:CFC11', 'N:CFC12:CFC12',
+ 'M:mam5_mode1:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc',
+ 'M:mam5_mode2:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc',
+ 'M:mam5_mode3:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc',
+ 'M:mam5_mode4:$INPUTDATA_ROOT/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc',
+ 'M:mam5_mode5:$INPUTDATA_ROOT/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc'
+
3
@@ -74,7 +94,12 @@
INTERP_MISSING_MONTHS
-'H2O2', 'H2SO4', 'SO2'
+'xactive_lnd'
+'O3','H2O2','CH2O','CH3OOH','NO','NO2','HNO3','HO2NO2','PAN','CO','CH3COCH3','C2H5OOH','CH3CHO','H2SO4','SO2','NO3','N2O5','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31'
+'NEU'
+'C2H5OOH','CH2O','CH3CHO','CH3OOH','H2O2','H2SO4','HNO3','HO2NO2','SO2','SOAG0','SOAG15','SOAG24','SOAG35','SOAG34','SOAG33','SOAG32','SOAG31'
+'CH2O', 'CH3O2', 'CH3OOH', 'PAN', 'CO', 'C2H6', 'C3H8', 'C2H4', 'ROHO2', 'CH3COCH3', 'C2H5O2', 'C2H5OOH', 'CH3CHO', 'CH3CO3', 'ISOP', 'ISOPO2', 'MVKMACR', 'MVKO2'
+''
2015-2100
diff --git a/components/eam/bld/namelist_files/use_cases/scam_generic.xml b/components/eam/bld/namelist_files/use_cases/scam_generic.xml
index 395d9a6ec860..2b77e3b630ae 100644
--- a/components/eam/bld/namelist_files/use_cases/scam_generic.xml
+++ b/components/eam/bld/namelist_files/use_cases/scam_generic.xml
@@ -3,7 +3,6 @@
-atm/cam/inic/homme/cami_mam3_Linoz_ne4np4_L72_c160909.nc
atm/cam/chem/trop_mozart_aero/emis/aces4bgc_nvsoa_soag_elev_2000_c160427.nc
diff --git a/components/eam/cime_config/config_component.xml b/components/eam/cime_config/config_component.xml
index c7585072ac94..1a961b84affe 100755
--- a/components/eam/cime_config/config_component.xml
+++ b/components/eam/cime_config/config_component.xml
@@ -53,8 +53,7 @@
-phys default
&eamv3_phys_defaults; &eamv3_chem_defaults;
&eamv3_phys_defaults; &eamv3_chem_defaults;
- &eamv3_phys_defaults; &eamv3_chem_defaults;
- &eamv3_phys_defaults; &eamv2_chem_defaults;
+ &eamv3_phys_defaults; &eamv3_chem_defaults;
-bc_dep_to_snow_updates
-co2_cycle
@@ -129,6 +128,7 @@
20TR_eam_CMIP6_chemUCI-Linoz-mam5-vbs
SSP585_eam_CMIP6_chemUCI-Linoz-mam5-vbs
SSP370_eam_CMIP6_chemUCI-Linoz-mam5-vbs
+ SSP245_eam_CMIP6_chemUCI-Linoz-mam5-vbs
SSP585_cam5_CMIP6_bgc
20TR_E3SMv1_superfast_ar5-emis
20TRS_E3SMv1_superfast_ar5-emis
@@ -136,7 +136,7 @@
20TR_eam_chemUCI-Linoz-mam5
scam_arm95
scm_arm97_chemUCI-Linoz-mam5-vbs
- scm_generic_chemUCI-Linoz-mam5-vbs
+ scam_generic
1850-PD_cam5
aquaplanet_EAMv1
RCEMIP_EAMv1
@@ -194,24 +194,24 @@
- cam5 physics:
- EAM with complete set of E3SM atmospheric mods for V3 (72 layers model) with chemUCI, Linozv3, MAM5 and VBS SOA - CMIP6-DECK:
- high-res (ne120 w/ 18to6 ocn) 72 layer E3SM v1 atmos model with CMIP6 forcings
- low-res (ne30 w/ oECv3 ocn) 72 layer E3SM v1 atmos model with CMIP6 forcings
+ EAM with
+ complete set of E3SM atmospheric mods for V3 (80 layers, P3, ZM with convective microphysics, chemUCI, Linozv3, MAM5 and VBS SOA):
+ CMIP6 forcings:
E3SM plus super-fast chemistry with AR5 emissions:
EAM super_fast_llnl chemistry:
EAM CO2 ramp:
- single column EAM ARM95 IOP test case:
- single column EAM ARM97 IOP test case:
+ single column ARM95 IOP test case:
+ single column ARM97 IOP test case:
single column EAM RICO IOP test case:
- EAM adiabatic physics:
- EAM ideal physics:
+ adiabatic physics:
+ ideal physics:
Atmospheric Model Intercomparison Project protocol:
- EAM prognostic CO2 cycle turned on.
+ prognostic CO2 cycle turned on.
Fortran version of SCREAM with SHOC, P3, RRTMGP, and prescribed aerosol. Initialized for DYAMOND1 (2016-08-01).
Fortran version of SCREAM with NH dycore, SHOC, P3, RRTMGP, prescribed aerosol, and no deep convection. Initialized for DYAMOND1 (2016-08-01).
Fortran version of SCREAM with SHOC, P3, RRTMGP, and prescribed aerosol. Initialized for DYAMOND2 (2020-01-20).
Fortran version of SCREAM with NH dycore, SHOC, P3, RRTMGP, prescribed aerosol, and no deep convection. Initialized for DYAMOND2 (2020-01-20).
+ Fortran version of SCREAM with SHOC, P3, RRTMGP, and prescribed aerosol: doubly periodic boundary conditions.
Fortran version of SCREAM with SHOC, P3, RRTMGP, and prescribed aerosol.
Fortran version of SCREAM with NH dycore, SHOC, P3, RRTMGP, prescribed aerosol, and no deep convection.
diff --git a/components/eam/cime_config/config_compsets.xml b/components/eam/cime_config/config_compsets.xml
index 894ecccea05d..39971fbb0945 100644
--- a/components/eam/cime_config/config_compsets.xml
+++ b/components/eam/cime_config/config_compsets.xml
@@ -23,12 +23,12 @@
F1950-CICE
- 1950_EAM%CMIP6_ELM%SPBC_CICE%PRES_DOCN%DOM_SROF_SGLC_SWAV
+ 1950_EAM%CMIP6_ELM%CNPRDCTCBCTOP_CICE%PRES_DOCN%DOM_SROF_SGLC_SWAV
F1950
- 1950_EAM%CMIP6_ELM%SPBC_MPASSI%PRES_DOCN%DOM_MOSART_SGLC_SWAV
+ 1950_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI%PRES_DOCN%DOM_MOSART_SGLC_SWAV
@@ -51,14 +51,19 @@
2010_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI%PRES_DOCN%DOM_MOSART_SGLC_SWAV
+
+ FSSP245
+ SSP245_eam_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI%PRES_DOCN%DOM_MOSART_SGLC_SWAV
+
+
FSSP370
- SSP370_eam_EAM%CMIP6_ELM%SPBC_MPASSI%PRES_DOCN%DOM_MOSART_SGLC_SWAV
+ SSP370_eam_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI%PRES_DOCN%DOM_MOSART_SGLC_SWAV
FSSP585
- SSP585_eam_EAM%CMIP6_ELM%SPBC_MPASSI%PRES_DOCN%DOM_MOSART_SGLC_SWAV
+ SSP585_eam_EAM%CMIP6_ELM%CNPRDCTCBCTOP_MPASSI%PRES_DOCN%DOM_MOSART_SGLC_SWAV
diff --git a/components/eam/cime_config/config_pes.xml b/components/eam/cime_config/config_pes.xml
index 79f0b1c0dfcd..15a45fe92726 100644
--- a/components/eam/cime_config/config_pes.xml
+++ b/components/eam/cime_config/config_pes.xml
@@ -293,6 +293,21 @@
+
+
+ pm-cpu: any compset on ne4pg2 grid
+
+ 96
+ 96
+ 96
+ 96
+ 96
+ 96
+ 1
+ 1
+
+
+
@@ -756,6 +771,21 @@
+
+
+ improv pelayout for tri-grid BGC tests with EAM+DOCN
+
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+
+
+
@@ -774,7 +804,7 @@
-
@@ -799,7 +829,7 @@
-
@@ -840,6 +870,22 @@
+
+
+
+
+ gcp12 eam F compset --res ne30pg2_IcoswISC30E3r5 on 4 nodes
+
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+
+
+
+
@@ -1062,6 +1108,21 @@
+
+
+ --res conusx4v1_r05_oECv3 --compset F2010
+
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+ -4
+
+
+
--res conusx4v1_r05_oECv3 --compset F2010
@@ -1075,6 +1136,19 @@
+
+
+ pm-cpu/gcp, eam, 2 nodes: --res conusx4v1_r05_oECv3 --compset F2010
+
+ -2
+ -2
+ -2
+ -2
+ -2
+ -2
+
+
+
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype0/user_nl_eam b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype0/user_nl_eam
index fa2b5daa6400..ae9a48579dfe 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype0/user_nl_eam
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype0/user_nl_eam
@@ -1,4 +1,4 @@
se_ftype=0
-cubed_sphere_map=0
+cubed_sphere_map=2
theta_hydrostatic_mode=.true.
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype1/user_nl_eam b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype1/user_nl_eam
index 2f675809c25e..ad90db9711b8 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype1/user_nl_eam
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype1/user_nl_eam
@@ -1,5 +1,5 @@
se_ftype=1
-cubed_sphere_map=0
+cubed_sphere_map=2
theta_hydrostatic_mode=.true.
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype2/user_nl_eam b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype2/user_nl_eam
index 601317baa1c8..03cda6cbf372 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype2/user_nl_eam
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype2/user_nl_eam
@@ -1,5 +1,5 @@
se_ftype=2
-cubed_sphere_map=0
+cubed_sphere_map=2
theta_hydrostatic_mode=.true.
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype4/user_nl_eam b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype4/user_nl_eam
index 59083a775066..c05cebbabef9 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype4/user_nl_eam
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_ftype4/user_nl_eam
@@ -1,5 +1,5 @@
se_ftype=4
-cubed_sphere_map=0
+cubed_sphere_map=2
theta_hydrostatic_mode=.true.
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_sl/user_nl_eam b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_sl/user_nl_eam
index 2810cbd5a285..06a1bab6fca8 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_sl/user_nl_eam
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetahy_sl/user_nl_eam
@@ -1,7 +1,7 @@
theta_hydrostatic_mode=.true.
tstep_type=5
-cubed_sphere_map=0
+cubed_sphere_map=2
transport_alg=12
semi_lagrange_cdr_alg=20
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype0/user_nl_eam b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype0/user_nl_eam
index ed3e180931d5..ed5fffdd21cb 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype0/user_nl_eam
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype0/user_nl_eam
@@ -1,5 +1,5 @@
se_ftype=0
-cubed_sphere_map=0
+cubed_sphere_map=2
theta_hydrostatic_mode=.false.
tstep_type=7
se_nsplit=10
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype1/user_nl_eam b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype1/user_nl_eam
index f9600e5abde0..d0d6c6b9edca 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype1/user_nl_eam
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype1/user_nl_eam
@@ -1,5 +1,5 @@
se_ftype=1
-cubed_sphere_map=0
+cubed_sphere_map=2
theta_hydrostatic_mode=.false.
tstep_type=7
se_nsplit=10
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype2/user_nl_eam b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype2/user_nl_eam
index e147f00913c9..a380b60b76b3 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype2/user_nl_eam
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype2/user_nl_eam
@@ -1,5 +1,5 @@
se_ftype=2
-cubed_sphere_map=0
+cubed_sphere_map=2
theta_hydrostatic_mode=.false.
tstep_type=7
transport_alg=0
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype4/user_nl_eam b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype4/user_nl_eam
index 455deb86d7f6..f1cc0ef1f330 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype4/user_nl_eam
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/thetanh_ftype4/user_nl_eam
@@ -1,5 +1,5 @@
se_ftype=4
-cubed_sphere_map=0
+cubed_sphere_map=2
theta_hydrostatic_mode=.false.
tstep_type=7
se_nsplit=10
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/shell_commands b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/shell_commands
index 6e8ae38ac8e9..0067b2f35de5 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/shell_commands
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/shell_commands
@@ -1,3 +1,3 @@
#!/bin/bash
-./xmlchange --append CAM_CONFIG_OPTS='-cosp'
+./xmlchange --append CAM_CONFIG_OPTS='-cosp'
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/user_nl_eam b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/user_nl_eam
index eeac1d647b1d..095c6946f5de 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/user_nl_eam
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/user_nl_eam
@@ -1,11 +1,59 @@
- nhtfrq = -24,-24,-6,-6,-3,-24,-24
- mfilt = 1,30,120,120,240,30,1
- avgflag_pertape = 'A','A','I','A','A','A','I'
- fexcl1 = 'CFAD_SR532_CAL', 'LINOZ_DO3', 'LINOZ_DO3_PSC', 'LINOZ_O3CLIM', 'LINOZ_O3COL', 'LINOZ_SSO3', 'hstobie_linoz'
- fincl1 = 'extinct_sw_inp','extinct_lw_bnd7','extinct_lw_inp','CLD_CAL', 'TREFMNAV', 'TREFMXAV'
- fincl2 = 'FLUT','PRECT','U200','V200','U850','V850','Z500','OMEGA500','UBOT','VBOT','TREFHT','TREFHTMN:M','TREFHTMX:X','QREFHT','TS','PS','TMQ','TUQ','TVQ','TOZ', 'FLDS', 'FLNS', 'FSDS', 'FSNS', 'SHFLX', 'LHFLX', 'TGCLDCWP', 'TGCLDIWP', 'TGCLDLWP', 'CLDTOT', 'T250', 'T200', 'T150', 'T100', 'T050', 'T025', 'T010', 'T005', 'T002', 'T001', 'TTOP', 'U250', 'U150', 'U100', 'U050', 'U025', 'U010', 'U005', 'U002', 'U001', 'UTOP', 'FSNT', 'FLNT'
- fincl3 = 'PSL','T200','T500','U850','V850','UBOT','VBOT','TREFHT', 'Z700', 'TBOT:M'
- fincl4 = 'FLUT','U200','U850','PRECT','OMEGA500'
- fincl5 = 'PRECT','PRECC','TUQ','TVQ','QFLX','SHFLX','U90M','V90M'
- fincl6 = 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANTAU_ISCCP','MEANPTOP_ISCCP','MEANTB_ISCCP','CLDTOT_CAL','CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN','CLDHGH_CAL','CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN','CLDMED_CAL','CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN','CLDLOW_CAL','CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN'
- fincl7 = 'O3', 'PS', 'TROP_P'
+cosp_lite = .true.
+
+empty_htapes = .true.
+
+avgflag_pertape = 'A','A','A','A','I','I'
+nhtfrq = -24,-24,-6,-3,-1,-24
+mfilt = 1,30,120,240,720,1
+
+fincl1 = 'AODALL','AODBC','AODDUST','AODPOM','AODSO4','AODSOA','AODSS','AODVIS',
+ 'CLDLOW','CLDMED','CLDHGH','CLDTOT',
+ 'CLDHGH_CAL','CLDLOW_CAL','CLDMED_CAL','CLD_MISR','CLDTOT_CAL',
+ 'CLMODIS','FISCCP1_COSP','FLDS','FLNS','FLNSC','FLNT','FLUT',
+ 'FLUTC','FSDS','FSDSC','FSNS','FSNSC','FSNT','FSNTOA','FSNTOAC','FSNTC',
+ 'ICEFRAC','LANDFRAC','LWCF','OCNFRAC','OMEGA','PRECC','PRECL','PRECSC','PRECSL','PS','PSL','Q',
+ 'QFLX','QREFHT','RELHUM','SCO','SHFLX','SOLIN','SWCF','T','TAUX','TAUY','TCO',
+ 'TGCLDLWP','TMQ','TREFHT','TREFMNAV','TREFMXAV','TS','U','U10','V','Z3',
+ 'dst_a1DDF','dst_a3DDF','dst_c1DDF','dst_c3DDF','dst_a1SFWET','dst_a3SFWET','dst_c1SFWET','dst_c3SFWET',
+ 'O3','LHFLX',
+ 'O3_2DTDA_trop','O3_2DTDB_trop','O3_2DTDD_trop','O3_2DTDE_trop','O3_2DTDI_trop','O3_2DTDL_trop',
+ 'O3_2DTDN_trop','O3_2DTDO_trop','O3_2DTDS_trop','O3_2DTDU_trop','O3_2DTRE_trop','O3_2DTRI_trop',
+ 'O3_SRF','NO_2DTDS','NO_TDLgt','NO2_2DTDD','NO2_2DTDS','NO2_TDAcf','CO_SRF','TROPE3D_P','TROP_P',
+ 'CDNUMC','SFDMS','so4_a1_sfgaex1','so4_a2_sfgaex1','so4_a3_sfgaex1','so4_a5_sfgaex1','soa_a1_sfgaex1',
+ 'soa_a2_sfgaex1','soa_a3_sfgaex1','GS_soa_a1','GS_soa_a2','GS_soa_a3','AQSO4_H2O2','AQSO4_O3',
+ 'SFSO2','SO2_CLXF','SO2','DF_SO2','AQ_SO2','GS_SO2','WD_SO2','ABURDENSO4_STR','ABURDENSO4_TRO',
+ 'ABURDENSO4','ABURDENBC','ABURDENDUST','ABURDENMOM','ABURDENPOM','ABURDENSEASALT',
+ 'ABURDENSOA','AODSO4_STR','AODSO4_TRO',
+ 'EXTINCT','AODABS','AODABSBC','CLDICE','CLDLIQ','CLD_CAL_TMPLIQ','CLD_CAL_TMPICE','Mass_bc_srf',
+ 'Mass_dst_srf','Mass_mom_srf','Mass_ncl_srf','Mass_pom_srf','Mass_so4_srf','Mass_soa_srf','Mass_bc_850',
+ 'Mass_dst_850','Mass_mom_850','Mass_ncl_850','Mass_pom_850','Mass_so4_850','Mass_soa_850','Mass_bc_500',
+ 'Mass_dst_500','Mass_mom_500','Mass_ncl_500','Mass_pom_500','Mass_so4_500','Mass_soa_500','Mass_bc_330',
+ 'Mass_dst_330','Mass_mom_330','Mass_ncl_330','Mass_pom_330','Mass_so4_330','Mass_soa_330','Mass_bc_200',
+ 'Mass_dst_200','Mass_mom_200','Mass_ncl_200','Mass_pom_200','Mass_so4_200','Mass_soa_200',
+ 'O3_2DTDD','O3_2DCIP','O3_2DCIL','CO_2DTDS','CO_2DTDD','CO_2DCEP','CO_2DCEL','NO_2DTDD',
+ 'FLNTC','SAODVIS',
+ 'H2OLNZ',
+ 'dst_a1SF','dst_a3SF',
+ 'PHIS','CLOUD','TGCLDIWP','TGCLDCWP','AREL',
+ 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANPTOP_ISCCP','CLD_CAL',
+ 'CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN',
+ 'CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN',
+ 'CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN',
+ 'CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN',
+ 'CLWMODIS','CLIMODIS'
+
+fincl2 = 'PS', 'FLUT','PRECT','U200','V200','U850','V850',
+ 'TCO','SCO','TREFHTMN','TREFHTMX','TREFHT','QREFHT'
+fincl3 = 'PS', 'PSL','PRECT','TUQ','TVQ','UBOT','VBOT','TREFHT','FLUT','OMEGA500','TBOT','U850','V850','U200','V200','T200','T500','Z700'
+fincl4 = 'PRECT'
+fincl5 = 'O3_SRF'
+fincl6 = 'CO_2DMSD','NO2_2DMSD','NO_2DMSD','O3_2DMSD','O3_2DMSD_trop'
+
+! -- chemUCI settings ------------------
+history_chemdyg_summary = .true.
+history_gaschmbudget_2D = .false.
+history_gaschmbudget_2D_levels = .false.
+history_gaschmbudget_num = 6 !! no impact if history_gaschmbudget_2D = .false.
+
+! -- MAM5 settings ------------------
+is_output_interactive_volc = .true.
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/user_nl_elm b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/user_nl_elm
index a93edc10b690..cd1adab77404 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/user_nl_elm
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod/user_nl_elm
@@ -1,6 +1,40 @@
- finidat = ' '
- hist_dov2xy = .true.,.true.
- hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
- hist_mfilt = 1,365
- hist_nhtfrq = -24,-24
- hist_avgflag_pertape = 'A','A'
+hist_dov2xy = .true.,.true.
+hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP',
+ 'BAF_PEATF','BIOCHEM_PMIN_TO_PLANT','CH4_SURF_AERE_SAT','CH4_SURF_AERE_UNSAT','CH4_SURF_DIFF_SAT',
+ 'CH4_SURF_DIFF_UNSAT','CH4_SURF_EBUL_SAT','CH4_SURF_EBUL_UNSAT','CMASS_BALANCE_ERROR','cn_scalar',
+ 'COL_PTRUNC','CONC_CH4_SAT','CONC_CH4_UNSAT','CONC_O2_SAT','CONC_O2_UNSAT',
+ 'cp_scalar','CWDC_HR','CWDC_LOSS','CWDC_TO_LITR2C','CWDC_TO_LITR3C',
+ 'CWDC_vr','CWDN_TO_LITR2N','CWDN_TO_LITR3N','CWDN_vr','CWDP_TO_LITR2P',
+ 'CWDP_TO_LITR3P','CWDP_vr','DWT_CONV_CFLUX_DRIBBLED','F_CO2_SOIL','F_CO2_SOIL_vr',
+ 'F_DENIT_vr','F_N2O_DENIT','F_N2O_NIT','F_NIT_vr','FCH4_DFSAT',
+ 'FINUNDATED_LAG','FPI_P_vr','FPI_vr','FROOTC_LOSS','HR_vr',
+ 'LABILEP_TO_SECONDP','LABILEP_vr','LAND_UPTAKE','LEAF_MR','leaf_npimbalance',
+ 'LEAFC_LOSS','LEAFC_TO_LITTER','LFC2','LITR1_HR','LITR1C_TO_SOIL1C',
+ 'LITR1C_vr','LITR1N_TNDNCY_VERT_TRANS','LITR1N_TO_SOIL1N','LITR1N_vr','LITR1P_TNDNCY_VERT_TRANS',
+ 'LITR1P_TO_SOIL1P','LITR1P_vr','LITR2_HR','LITR2C_TO_SOIL2C','LITR2C_vr',
+ 'LITR2N_TNDNCY_VERT_TRANS','LITR2N_TO_SOIL2N','LITR2N_vr','LITR2P_TNDNCY_VERT_TRANS','LITR2P_TO_SOIL2P',
+ 'LITR2P_vr','LITR3_HR','LITR3C_TO_SOIL3C','LITR3C_vr','LITR3N_TNDNCY_VERT_TRANS',
+ 'LITR3N_TO_SOIL3N','LITR3N_vr','LITR3P_TNDNCY_VERT_TRANS','LITR3P_TO_SOIL3P','LITR3P_vr',
+ 'M_LITR1C_TO_LEACHING','M_LITR2C_TO_LEACHING','M_LITR3C_TO_LEACHING','M_SOIL1C_TO_LEACHING','M_SOIL2C_TO_LEACHING',
+ 'M_SOIL3C_TO_LEACHING','M_SOIL4C_TO_LEACHING','NDEPLOY','NEM','nlim_m',
+ 'o2_decomp_depth_unsat','OCCLP_vr','PDEPLOY','PLANT_CALLOC','PLANT_NDEMAND',
+ 'PLANT_NDEMAND_COL','PLANT_PALLOC','PLANT_PDEMAND','PLANT_PDEMAND_COL','plim_m',
+ 'POT_F_DENIT','POT_F_NIT','POTENTIAL_IMMOB','POTENTIAL_IMMOB_P','PRIMP_TO_LABILEP',
+ 'PRIMP_vr','PROD1P_LOSS','QOVER_LAG','RETRANSN_TO_NPOOL','RETRANSP_TO_PPOOL',
+ 'SCALARAVG_vr','SECONDP_TO_LABILEP','SECONDP_TO_OCCLP','SECONDP_vr','SMIN_NH4_vr',
+ 'SMIN_NO3_vr','SMINN_TO_SOIL1N_L1','SMINN_TO_SOIL2N_L2','SMINN_TO_SOIL2N_S1','SMINN_TO_SOIL3N_L3',
+ 'SMINN_TO_SOIL3N_S2','SMINN_TO_SOIL4N_S3','SMINP_TO_SOIL1P_L1','SMINP_TO_SOIL2P_L2','SMINP_TO_SOIL2P_S1',
+ 'SMINP_TO_SOIL3P_L3','SMINP_TO_SOIL3P_S2','SMINP_TO_SOIL4P_S3','SMINP_vr','SOIL1_HR','SOIL1C_TO_SOIL2C','SOIL1C_vr','SOIL1N_TNDNCY_VERT_TRANS','SOIL1N_TO_SOIL2N','SOIL1N_vr',
+ 'SOIL1P_TNDNCY_VERT_TRANS','SOIL1P_TO_SOIL2P','SOIL1P_vr','SOIL2_HR','SOIL2C_TO_SOIL3C',
+ 'SOIL2C_vr','SOIL2N_TNDNCY_VERT_TRANS','SOIL2N_TO_SOIL3N','SOIL2N_vr','SOIL2P_TNDNCY_VERT_TRANS',
+ 'SOIL2P_TO_SOIL3P','SOIL2P_vr','SOIL3_HR','SOIL3C_TO_SOIL4C','SOIL3C_vr',
+ 'SOIL3N_TNDNCY_VERT_TRANS','SOIL3N_TO_SOIL4N','SOIL3N_vr','SOIL3P_TNDNCY_VERT_TRANS','SOIL3P_TO_SOIL4P',
+ 'SOIL3P_vr','SOIL4_HR','SOIL4C_vr','SOIL4N_TNDNCY_VERT_TRANS','SOIL4N_TO_SMINN',
+ 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr',
+ 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF',
+ 'wlim_m','WOODC_LOSS','WTGQ'
+hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC'
+hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
+hist_mfilt = 1,365
+hist_nhtfrq = -24,-24
+hist_avgflag_pertape = 'A','A'
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/shell_commands b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/shell_commands
index 6e8ae38ac8e9..0067b2f35de5 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/shell_commands
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/shell_commands
@@ -1,3 +1,3 @@
#!/bin/bash
-./xmlchange --append CAM_CONFIG_OPTS='-cosp'
+./xmlchange --append CAM_CONFIG_OPTS='-cosp'
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/user_nl_eam b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/user_nl_eam
index eeac1d647b1d..095c6946f5de 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/user_nl_eam
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/user_nl_eam
@@ -1,11 +1,59 @@
- nhtfrq = -24,-24,-6,-6,-3,-24,-24
- mfilt = 1,30,120,120,240,30,1
- avgflag_pertape = 'A','A','I','A','A','A','I'
- fexcl1 = 'CFAD_SR532_CAL', 'LINOZ_DO3', 'LINOZ_DO3_PSC', 'LINOZ_O3CLIM', 'LINOZ_O3COL', 'LINOZ_SSO3', 'hstobie_linoz'
- fincl1 = 'extinct_sw_inp','extinct_lw_bnd7','extinct_lw_inp','CLD_CAL', 'TREFMNAV', 'TREFMXAV'
- fincl2 = 'FLUT','PRECT','U200','V200','U850','V850','Z500','OMEGA500','UBOT','VBOT','TREFHT','TREFHTMN:M','TREFHTMX:X','QREFHT','TS','PS','TMQ','TUQ','TVQ','TOZ', 'FLDS', 'FLNS', 'FSDS', 'FSNS', 'SHFLX', 'LHFLX', 'TGCLDCWP', 'TGCLDIWP', 'TGCLDLWP', 'CLDTOT', 'T250', 'T200', 'T150', 'T100', 'T050', 'T025', 'T010', 'T005', 'T002', 'T001', 'TTOP', 'U250', 'U150', 'U100', 'U050', 'U025', 'U010', 'U005', 'U002', 'U001', 'UTOP', 'FSNT', 'FLNT'
- fincl3 = 'PSL','T200','T500','U850','V850','UBOT','VBOT','TREFHT', 'Z700', 'TBOT:M'
- fincl4 = 'FLUT','U200','U850','PRECT','OMEGA500'
- fincl5 = 'PRECT','PRECC','TUQ','TVQ','QFLX','SHFLX','U90M','V90M'
- fincl6 = 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANTAU_ISCCP','MEANPTOP_ISCCP','MEANTB_ISCCP','CLDTOT_CAL','CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN','CLDHGH_CAL','CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN','CLDMED_CAL','CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN','CLDLOW_CAL','CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN'
- fincl7 = 'O3', 'PS', 'TROP_P'
+cosp_lite = .true.
+
+empty_htapes = .true.
+
+avgflag_pertape = 'A','A','A','A','I','I'
+nhtfrq = -24,-24,-6,-3,-1,-24
+mfilt = 1,30,120,240,720,1
+
+fincl1 = 'AODALL','AODBC','AODDUST','AODPOM','AODSO4','AODSOA','AODSS','AODVIS',
+ 'CLDLOW','CLDMED','CLDHGH','CLDTOT',
+ 'CLDHGH_CAL','CLDLOW_CAL','CLDMED_CAL','CLD_MISR','CLDTOT_CAL',
+ 'CLMODIS','FISCCP1_COSP','FLDS','FLNS','FLNSC','FLNT','FLUT',
+ 'FLUTC','FSDS','FSDSC','FSNS','FSNSC','FSNT','FSNTOA','FSNTOAC','FSNTC',
+ 'ICEFRAC','LANDFRAC','LWCF','OCNFRAC','OMEGA','PRECC','PRECL','PRECSC','PRECSL','PS','PSL','Q',
+ 'QFLX','QREFHT','RELHUM','SCO','SHFLX','SOLIN','SWCF','T','TAUX','TAUY','TCO',
+ 'TGCLDLWP','TMQ','TREFHT','TREFMNAV','TREFMXAV','TS','U','U10','V','Z3',
+ 'dst_a1DDF','dst_a3DDF','dst_c1DDF','dst_c3DDF','dst_a1SFWET','dst_a3SFWET','dst_c1SFWET','dst_c3SFWET',
+ 'O3','LHFLX',
+ 'O3_2DTDA_trop','O3_2DTDB_trop','O3_2DTDD_trop','O3_2DTDE_trop','O3_2DTDI_trop','O3_2DTDL_trop',
+ 'O3_2DTDN_trop','O3_2DTDO_trop','O3_2DTDS_trop','O3_2DTDU_trop','O3_2DTRE_trop','O3_2DTRI_trop',
+ 'O3_SRF','NO_2DTDS','NO_TDLgt','NO2_2DTDD','NO2_2DTDS','NO2_TDAcf','CO_SRF','TROPE3D_P','TROP_P',
+ 'CDNUMC','SFDMS','so4_a1_sfgaex1','so4_a2_sfgaex1','so4_a3_sfgaex1','so4_a5_sfgaex1','soa_a1_sfgaex1',
+ 'soa_a2_sfgaex1','soa_a3_sfgaex1','GS_soa_a1','GS_soa_a2','GS_soa_a3','AQSO4_H2O2','AQSO4_O3',
+ 'SFSO2','SO2_CLXF','SO2','DF_SO2','AQ_SO2','GS_SO2','WD_SO2','ABURDENSO4_STR','ABURDENSO4_TRO',
+ 'ABURDENSO4','ABURDENBC','ABURDENDUST','ABURDENMOM','ABURDENPOM','ABURDENSEASALT',
+ 'ABURDENSOA','AODSO4_STR','AODSO4_TRO',
+ 'EXTINCT','AODABS','AODABSBC','CLDICE','CLDLIQ','CLD_CAL_TMPLIQ','CLD_CAL_TMPICE','Mass_bc_srf',
+ 'Mass_dst_srf','Mass_mom_srf','Mass_ncl_srf','Mass_pom_srf','Mass_so4_srf','Mass_soa_srf','Mass_bc_850',
+ 'Mass_dst_850','Mass_mom_850','Mass_ncl_850','Mass_pom_850','Mass_so4_850','Mass_soa_850','Mass_bc_500',
+ 'Mass_dst_500','Mass_mom_500','Mass_ncl_500','Mass_pom_500','Mass_so4_500','Mass_soa_500','Mass_bc_330',
+ 'Mass_dst_330','Mass_mom_330','Mass_ncl_330','Mass_pom_330','Mass_so4_330','Mass_soa_330','Mass_bc_200',
+ 'Mass_dst_200','Mass_mom_200','Mass_ncl_200','Mass_pom_200','Mass_so4_200','Mass_soa_200',
+ 'O3_2DTDD','O3_2DCIP','O3_2DCIL','CO_2DTDS','CO_2DTDD','CO_2DCEP','CO_2DCEL','NO_2DTDD',
+ 'FLNTC','SAODVIS',
+ 'H2OLNZ',
+ 'dst_a1SF','dst_a3SF',
+ 'PHIS','CLOUD','TGCLDIWP','TGCLDCWP','AREL',
+ 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANPTOP_ISCCP','CLD_CAL',
+ 'CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN',
+ 'CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN',
+ 'CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN',
+ 'CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN',
+ 'CLWMODIS','CLIMODIS'
+
+fincl2 = 'PS', 'FLUT','PRECT','U200','V200','U850','V850',
+ 'TCO','SCO','TREFHTMN','TREFHTMX','TREFHT','QREFHT'
+fincl3 = 'PS', 'PSL','PRECT','TUQ','TVQ','UBOT','VBOT','TREFHT','FLUT','OMEGA500','TBOT','U850','V850','U200','V200','T200','T500','Z700'
+fincl4 = 'PRECT'
+fincl5 = 'O3_SRF'
+fincl6 = 'CO_2DMSD','NO2_2DMSD','NO_2DMSD','O3_2DMSD','O3_2DMSD_trop'
+
+! -- chemUCI settings ------------------
+history_chemdyg_summary = .true.
+history_gaschmbudget_2D = .false.
+history_gaschmbudget_2D_levels = .false.
+history_gaschmbudget_num = 6 !! no impact if history_gaschmbudget_2D = .false.
+
+! -- MAM5 settings ------------------
+is_output_interactive_volc = .true.
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/user_nl_elm b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/user_nl_elm
index b2a7d247ac2b..cd1adab77404 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/user_nl_elm
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F2010/user_nl_elm
@@ -1,7 +1,40 @@
-! finidat below not compatitle with new t05 fsurdat with _TOP scheme. This test to be replaced later
-! finidat = '${DIN_LOC_ROOT}/lnd/clm2/initdata_map/clmi.F2010.ne30pg2_r05_oECv3.SMS_Ln5.c20230213.nc'
- hist_dov2xy = .true.,.true.
- hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
- hist_mfilt = 1,365
- hist_nhtfrq = -24,-24
- hist_avgflag_pertape = 'A','A'
+hist_dov2xy = .true.,.true.
+hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP',
+ 'BAF_PEATF','BIOCHEM_PMIN_TO_PLANT','CH4_SURF_AERE_SAT','CH4_SURF_AERE_UNSAT','CH4_SURF_DIFF_SAT',
+ 'CH4_SURF_DIFF_UNSAT','CH4_SURF_EBUL_SAT','CH4_SURF_EBUL_UNSAT','CMASS_BALANCE_ERROR','cn_scalar',
+ 'COL_PTRUNC','CONC_CH4_SAT','CONC_CH4_UNSAT','CONC_O2_SAT','CONC_O2_UNSAT',
+ 'cp_scalar','CWDC_HR','CWDC_LOSS','CWDC_TO_LITR2C','CWDC_TO_LITR3C',
+ 'CWDC_vr','CWDN_TO_LITR2N','CWDN_TO_LITR3N','CWDN_vr','CWDP_TO_LITR2P',
+ 'CWDP_TO_LITR3P','CWDP_vr','DWT_CONV_CFLUX_DRIBBLED','F_CO2_SOIL','F_CO2_SOIL_vr',
+ 'F_DENIT_vr','F_N2O_DENIT','F_N2O_NIT','F_NIT_vr','FCH4_DFSAT',
+ 'FINUNDATED_LAG','FPI_P_vr','FPI_vr','FROOTC_LOSS','HR_vr',
+ 'LABILEP_TO_SECONDP','LABILEP_vr','LAND_UPTAKE','LEAF_MR','leaf_npimbalance',
+ 'LEAFC_LOSS','LEAFC_TO_LITTER','LFC2','LITR1_HR','LITR1C_TO_SOIL1C',
+ 'LITR1C_vr','LITR1N_TNDNCY_VERT_TRANS','LITR1N_TO_SOIL1N','LITR1N_vr','LITR1P_TNDNCY_VERT_TRANS',
+ 'LITR1P_TO_SOIL1P','LITR1P_vr','LITR2_HR','LITR2C_TO_SOIL2C','LITR2C_vr',
+ 'LITR2N_TNDNCY_VERT_TRANS','LITR2N_TO_SOIL2N','LITR2N_vr','LITR2P_TNDNCY_VERT_TRANS','LITR2P_TO_SOIL2P',
+ 'LITR2P_vr','LITR3_HR','LITR3C_TO_SOIL3C','LITR3C_vr','LITR3N_TNDNCY_VERT_TRANS',
+ 'LITR3N_TO_SOIL3N','LITR3N_vr','LITR3P_TNDNCY_VERT_TRANS','LITR3P_TO_SOIL3P','LITR3P_vr',
+ 'M_LITR1C_TO_LEACHING','M_LITR2C_TO_LEACHING','M_LITR3C_TO_LEACHING','M_SOIL1C_TO_LEACHING','M_SOIL2C_TO_LEACHING',
+ 'M_SOIL3C_TO_LEACHING','M_SOIL4C_TO_LEACHING','NDEPLOY','NEM','nlim_m',
+ 'o2_decomp_depth_unsat','OCCLP_vr','PDEPLOY','PLANT_CALLOC','PLANT_NDEMAND',
+ 'PLANT_NDEMAND_COL','PLANT_PALLOC','PLANT_PDEMAND','PLANT_PDEMAND_COL','plim_m',
+ 'POT_F_DENIT','POT_F_NIT','POTENTIAL_IMMOB','POTENTIAL_IMMOB_P','PRIMP_TO_LABILEP',
+ 'PRIMP_vr','PROD1P_LOSS','QOVER_LAG','RETRANSN_TO_NPOOL','RETRANSP_TO_PPOOL',
+ 'SCALARAVG_vr','SECONDP_TO_LABILEP','SECONDP_TO_OCCLP','SECONDP_vr','SMIN_NH4_vr',
+ 'SMIN_NO3_vr','SMINN_TO_SOIL1N_L1','SMINN_TO_SOIL2N_L2','SMINN_TO_SOIL2N_S1','SMINN_TO_SOIL3N_L3',
+ 'SMINN_TO_SOIL3N_S2','SMINN_TO_SOIL4N_S3','SMINP_TO_SOIL1P_L1','SMINP_TO_SOIL2P_L2','SMINP_TO_SOIL2P_S1',
+ 'SMINP_TO_SOIL3P_L3','SMINP_TO_SOIL3P_S2','SMINP_TO_SOIL4P_S3','SMINP_vr','SOIL1_HR','SOIL1C_TO_SOIL2C','SOIL1C_vr','SOIL1N_TNDNCY_VERT_TRANS','SOIL1N_TO_SOIL2N','SOIL1N_vr',
+ 'SOIL1P_TNDNCY_VERT_TRANS','SOIL1P_TO_SOIL2P','SOIL1P_vr','SOIL2_HR','SOIL2C_TO_SOIL3C',
+ 'SOIL2C_vr','SOIL2N_TNDNCY_VERT_TRANS','SOIL2N_TO_SOIL3N','SOIL2N_vr','SOIL2P_TNDNCY_VERT_TRANS',
+ 'SOIL2P_TO_SOIL3P','SOIL2P_vr','SOIL3_HR','SOIL3C_TO_SOIL4C','SOIL3C_vr',
+ 'SOIL3N_TNDNCY_VERT_TRANS','SOIL3N_TO_SOIL4N','SOIL3N_vr','SOIL3P_TNDNCY_VERT_TRANS','SOIL3P_TO_SOIL4P',
+ 'SOIL3P_vr','SOIL4_HR','SOIL4C_vr','SOIL4N_TNDNCY_VERT_TRANS','SOIL4N_TO_SMINN',
+ 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr',
+ 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF',
+ 'wlim_m','WOODC_LOSS','WTGQ'
+hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC'
+hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
+hist_mfilt = 1,365
+hist_nhtfrq = -24,-24
+hist_avgflag_pertape = 'A','A'
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/shell_commands b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/shell_commands
index 6e8ae38ac8e9..0067b2f35de5 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/shell_commands
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/shell_commands
@@ -1,3 +1,3 @@
#!/bin/bash
-./xmlchange --append CAM_CONFIG_OPTS='-cosp'
+./xmlchange --append CAM_CONFIG_OPTS='-cosp'
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/user_nl_eam b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/user_nl_eam
index eeac1d647b1d..095c6946f5de 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/user_nl_eam
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/user_nl_eam
@@ -1,11 +1,59 @@
- nhtfrq = -24,-24,-6,-6,-3,-24,-24
- mfilt = 1,30,120,120,240,30,1
- avgflag_pertape = 'A','A','I','A','A','A','I'
- fexcl1 = 'CFAD_SR532_CAL', 'LINOZ_DO3', 'LINOZ_DO3_PSC', 'LINOZ_O3CLIM', 'LINOZ_O3COL', 'LINOZ_SSO3', 'hstobie_linoz'
- fincl1 = 'extinct_sw_inp','extinct_lw_bnd7','extinct_lw_inp','CLD_CAL', 'TREFMNAV', 'TREFMXAV'
- fincl2 = 'FLUT','PRECT','U200','V200','U850','V850','Z500','OMEGA500','UBOT','VBOT','TREFHT','TREFHTMN:M','TREFHTMX:X','QREFHT','TS','PS','TMQ','TUQ','TVQ','TOZ', 'FLDS', 'FLNS', 'FSDS', 'FSNS', 'SHFLX', 'LHFLX', 'TGCLDCWP', 'TGCLDIWP', 'TGCLDLWP', 'CLDTOT', 'T250', 'T200', 'T150', 'T100', 'T050', 'T025', 'T010', 'T005', 'T002', 'T001', 'TTOP', 'U250', 'U150', 'U100', 'U050', 'U025', 'U010', 'U005', 'U002', 'U001', 'UTOP', 'FSNT', 'FLNT'
- fincl3 = 'PSL','T200','T500','U850','V850','UBOT','VBOT','TREFHT', 'Z700', 'TBOT:M'
- fincl4 = 'FLUT','U200','U850','PRECT','OMEGA500'
- fincl5 = 'PRECT','PRECC','TUQ','TVQ','QFLX','SHFLX','U90M','V90M'
- fincl6 = 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANTAU_ISCCP','MEANPTOP_ISCCP','MEANTB_ISCCP','CLDTOT_CAL','CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN','CLDHGH_CAL','CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN','CLDMED_CAL','CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN','CLDLOW_CAL','CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN'
- fincl7 = 'O3', 'PS', 'TROP_P'
+cosp_lite = .true.
+
+empty_htapes = .true.
+
+avgflag_pertape = 'A','A','A','A','I','I'
+nhtfrq = -24,-24,-6,-3,-1,-24
+mfilt = 1,30,120,240,720,1
+
+fincl1 = 'AODALL','AODBC','AODDUST','AODPOM','AODSO4','AODSOA','AODSS','AODVIS',
+ 'CLDLOW','CLDMED','CLDHGH','CLDTOT',
+ 'CLDHGH_CAL','CLDLOW_CAL','CLDMED_CAL','CLD_MISR','CLDTOT_CAL',
+ 'CLMODIS','FISCCP1_COSP','FLDS','FLNS','FLNSC','FLNT','FLUT',
+ 'FLUTC','FSDS','FSDSC','FSNS','FSNSC','FSNT','FSNTOA','FSNTOAC','FSNTC',
+ 'ICEFRAC','LANDFRAC','LWCF','OCNFRAC','OMEGA','PRECC','PRECL','PRECSC','PRECSL','PS','PSL','Q',
+ 'QFLX','QREFHT','RELHUM','SCO','SHFLX','SOLIN','SWCF','T','TAUX','TAUY','TCO',
+ 'TGCLDLWP','TMQ','TREFHT','TREFMNAV','TREFMXAV','TS','U','U10','V','Z3',
+ 'dst_a1DDF','dst_a3DDF','dst_c1DDF','dst_c3DDF','dst_a1SFWET','dst_a3SFWET','dst_c1SFWET','dst_c3SFWET',
+ 'O3','LHFLX',
+ 'O3_2DTDA_trop','O3_2DTDB_trop','O3_2DTDD_trop','O3_2DTDE_trop','O3_2DTDI_trop','O3_2DTDL_trop',
+ 'O3_2DTDN_trop','O3_2DTDO_trop','O3_2DTDS_trop','O3_2DTDU_trop','O3_2DTRE_trop','O3_2DTRI_trop',
+ 'O3_SRF','NO_2DTDS','NO_TDLgt','NO2_2DTDD','NO2_2DTDS','NO2_TDAcf','CO_SRF','TROPE3D_P','TROP_P',
+ 'CDNUMC','SFDMS','so4_a1_sfgaex1','so4_a2_sfgaex1','so4_a3_sfgaex1','so4_a5_sfgaex1','soa_a1_sfgaex1',
+ 'soa_a2_sfgaex1','soa_a3_sfgaex1','GS_soa_a1','GS_soa_a2','GS_soa_a3','AQSO4_H2O2','AQSO4_O3',
+ 'SFSO2','SO2_CLXF','SO2','DF_SO2','AQ_SO2','GS_SO2','WD_SO2','ABURDENSO4_STR','ABURDENSO4_TRO',
+ 'ABURDENSO4','ABURDENBC','ABURDENDUST','ABURDENMOM','ABURDENPOM','ABURDENSEASALT',
+ 'ABURDENSOA','AODSO4_STR','AODSO4_TRO',
+ 'EXTINCT','AODABS','AODABSBC','CLDICE','CLDLIQ','CLD_CAL_TMPLIQ','CLD_CAL_TMPICE','Mass_bc_srf',
+ 'Mass_dst_srf','Mass_mom_srf','Mass_ncl_srf','Mass_pom_srf','Mass_so4_srf','Mass_soa_srf','Mass_bc_850',
+ 'Mass_dst_850','Mass_mom_850','Mass_ncl_850','Mass_pom_850','Mass_so4_850','Mass_soa_850','Mass_bc_500',
+ 'Mass_dst_500','Mass_mom_500','Mass_ncl_500','Mass_pom_500','Mass_so4_500','Mass_soa_500','Mass_bc_330',
+ 'Mass_dst_330','Mass_mom_330','Mass_ncl_330','Mass_pom_330','Mass_so4_330','Mass_soa_330','Mass_bc_200',
+ 'Mass_dst_200','Mass_mom_200','Mass_ncl_200','Mass_pom_200','Mass_so4_200','Mass_soa_200',
+ 'O3_2DTDD','O3_2DCIP','O3_2DCIL','CO_2DTDS','CO_2DTDD','CO_2DCEP','CO_2DCEL','NO_2DTDD',
+ 'FLNTC','SAODVIS',
+ 'H2OLNZ',
+ 'dst_a1SF','dst_a3SF',
+ 'PHIS','CLOUD','TGCLDIWP','TGCLDCWP','AREL',
+ 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANPTOP_ISCCP','CLD_CAL',
+ 'CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN',
+ 'CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN',
+ 'CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN',
+ 'CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN',
+ 'CLWMODIS','CLIMODIS'
+
+fincl2 = 'PS', 'FLUT','PRECT','U200','V200','U850','V850',
+ 'TCO','SCO','TREFHTMN','TREFHTMX','TREFHT','QREFHT'
+fincl3 = 'PS', 'PSL','PRECT','TUQ','TVQ','UBOT','VBOT','TREFHT','FLUT','OMEGA500','TBOT','U850','V850','U200','V200','T200','T500','Z700'
+fincl4 = 'PRECT'
+fincl5 = 'O3_SRF'
+fincl6 = 'CO_2DMSD','NO2_2DMSD','NO_2DMSD','O3_2DMSD','O3_2DMSD_trop'
+
+! -- chemUCI settings ------------------
+history_chemdyg_summary = .true.
+history_gaschmbudget_2D = .false.
+history_gaschmbudget_2D_levels = .false.
+history_gaschmbudget_num = 6 !! no impact if history_gaschmbudget_2D = .false.
+
+! -- MAM5 settings ------------------
+is_output_interactive_volc = .true.
diff --git a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/user_nl_elm b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/user_nl_elm
index b2a7d247ac2b..cd1adab77404 100644
--- a/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/user_nl_elm
+++ b/components/eam/cime_config/testdefs/testmods_dirs/eam/wcprod_F20TR/user_nl_elm
@@ -1,7 +1,40 @@
-! finidat below not compatitle with new t05 fsurdat with _TOP scheme. This test to be replaced later
-! finidat = '${DIN_LOC_ROOT}/lnd/clm2/initdata_map/clmi.F2010.ne30pg2_r05_oECv3.SMS_Ln5.c20230213.nc'
- hist_dov2xy = .true.,.true.
- hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
- hist_mfilt = 1,365
- hist_nhtfrq = -24,-24
- hist_avgflag_pertape = 'A','A'
+hist_dov2xy = .true.,.true.
+hist_fexcl1 = 'AGWDNPP','ALTMAX_LASTYEAR','AVAIL_RETRANSP','AVAILC','BAF_CROP',
+ 'BAF_PEATF','BIOCHEM_PMIN_TO_PLANT','CH4_SURF_AERE_SAT','CH4_SURF_AERE_UNSAT','CH4_SURF_DIFF_SAT',
+ 'CH4_SURF_DIFF_UNSAT','CH4_SURF_EBUL_SAT','CH4_SURF_EBUL_UNSAT','CMASS_BALANCE_ERROR','cn_scalar',
+ 'COL_PTRUNC','CONC_CH4_SAT','CONC_CH4_UNSAT','CONC_O2_SAT','CONC_O2_UNSAT',
+ 'cp_scalar','CWDC_HR','CWDC_LOSS','CWDC_TO_LITR2C','CWDC_TO_LITR3C',
+ 'CWDC_vr','CWDN_TO_LITR2N','CWDN_TO_LITR3N','CWDN_vr','CWDP_TO_LITR2P',
+ 'CWDP_TO_LITR3P','CWDP_vr','DWT_CONV_CFLUX_DRIBBLED','F_CO2_SOIL','F_CO2_SOIL_vr',
+ 'F_DENIT_vr','F_N2O_DENIT','F_N2O_NIT','F_NIT_vr','FCH4_DFSAT',
+ 'FINUNDATED_LAG','FPI_P_vr','FPI_vr','FROOTC_LOSS','HR_vr',
+ 'LABILEP_TO_SECONDP','LABILEP_vr','LAND_UPTAKE','LEAF_MR','leaf_npimbalance',
+ 'LEAFC_LOSS','LEAFC_TO_LITTER','LFC2','LITR1_HR','LITR1C_TO_SOIL1C',
+ 'LITR1C_vr','LITR1N_TNDNCY_VERT_TRANS','LITR1N_TO_SOIL1N','LITR1N_vr','LITR1P_TNDNCY_VERT_TRANS',
+ 'LITR1P_TO_SOIL1P','LITR1P_vr','LITR2_HR','LITR2C_TO_SOIL2C','LITR2C_vr',
+ 'LITR2N_TNDNCY_VERT_TRANS','LITR2N_TO_SOIL2N','LITR2N_vr','LITR2P_TNDNCY_VERT_TRANS','LITR2P_TO_SOIL2P',
+ 'LITR2P_vr','LITR3_HR','LITR3C_TO_SOIL3C','LITR3C_vr','LITR3N_TNDNCY_VERT_TRANS',
+ 'LITR3N_TO_SOIL3N','LITR3N_vr','LITR3P_TNDNCY_VERT_TRANS','LITR3P_TO_SOIL3P','LITR3P_vr',
+ 'M_LITR1C_TO_LEACHING','M_LITR2C_TO_LEACHING','M_LITR3C_TO_LEACHING','M_SOIL1C_TO_LEACHING','M_SOIL2C_TO_LEACHING',
+ 'M_SOIL3C_TO_LEACHING','M_SOIL4C_TO_LEACHING','NDEPLOY','NEM','nlim_m',
+ 'o2_decomp_depth_unsat','OCCLP_vr','PDEPLOY','PLANT_CALLOC','PLANT_NDEMAND',
+ 'PLANT_NDEMAND_COL','PLANT_PALLOC','PLANT_PDEMAND','PLANT_PDEMAND_COL','plim_m',
+ 'POT_F_DENIT','POT_F_NIT','POTENTIAL_IMMOB','POTENTIAL_IMMOB_P','PRIMP_TO_LABILEP',
+ 'PRIMP_vr','PROD1P_LOSS','QOVER_LAG','RETRANSN_TO_NPOOL','RETRANSP_TO_PPOOL',
+ 'SCALARAVG_vr','SECONDP_TO_LABILEP','SECONDP_TO_OCCLP','SECONDP_vr','SMIN_NH4_vr',
+ 'SMIN_NO3_vr','SMINN_TO_SOIL1N_L1','SMINN_TO_SOIL2N_L2','SMINN_TO_SOIL2N_S1','SMINN_TO_SOIL3N_L3',
+ 'SMINN_TO_SOIL3N_S2','SMINN_TO_SOIL4N_S3','SMINP_TO_SOIL1P_L1','SMINP_TO_SOIL2P_L2','SMINP_TO_SOIL2P_S1',
+ 'SMINP_TO_SOIL3P_L3','SMINP_TO_SOIL3P_S2','SMINP_TO_SOIL4P_S3','SMINP_vr','SOIL1_HR','SOIL1C_TO_SOIL2C','SOIL1C_vr','SOIL1N_TNDNCY_VERT_TRANS','SOIL1N_TO_SOIL2N','SOIL1N_vr',
+ 'SOIL1P_TNDNCY_VERT_TRANS','SOIL1P_TO_SOIL2P','SOIL1P_vr','SOIL2_HR','SOIL2C_TO_SOIL3C',
+ 'SOIL2C_vr','SOIL2N_TNDNCY_VERT_TRANS','SOIL2N_TO_SOIL3N','SOIL2N_vr','SOIL2P_TNDNCY_VERT_TRANS',
+ 'SOIL2P_TO_SOIL3P','SOIL2P_vr','SOIL3_HR','SOIL3C_TO_SOIL4C','SOIL3C_vr',
+ 'SOIL3N_TNDNCY_VERT_TRANS','SOIL3N_TO_SOIL4N','SOIL3N_vr','SOIL3P_TNDNCY_VERT_TRANS','SOIL3P_TO_SOIL4P',
+ 'SOIL3P_vr','SOIL4_HR','SOIL4C_vr','SOIL4N_TNDNCY_VERT_TRANS','SOIL4N_TO_SMINN',
+ 'SOIL4N_vr','SOIL4P_TNDNCY_VERT_TRANS','SOIL4P_TO_SMINP','SOIL4P_vr','SOLUTIONP_vr',
+ 'TCS_MONTH_BEGIN','TCS_MONTH_END','TOTCOLCH4','water_scalar','WF',
+ 'wlim_m','WOODC_LOSS','WTGQ'
+hist_fincl1 = 'SNOWDP','COL_FIRE_CLOSS','NPOOL','PPOOL','TOTPRODC'
+hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA'
+hist_mfilt = 1,365
+hist_nhtfrq = -24,-24
+hist_avgflag_pertape = 'A','A'
diff --git a/components/eam/docs/dev-guide/index.md b/components/eam/docs/dev-guide/index.md
index 553bf5f36975..6879c32cbe3c 100644
--- a/components/eam/docs/dev-guide/index.md
+++ b/components/eam/docs/dev-guide/index.md
@@ -1 +1,3 @@
-start of the EAM Developer's Guide
+# EAM Developer Guide
+
+coming soon.
diff --git a/components/eam/docs/index.md b/components/eam/docs/index.md
index 6632c22ca62d..55870e3778d0 100644
--- a/components/eam/docs/index.md
+++ b/components/eam/docs/index.md
@@ -1,7 +1,7 @@
# The E3SM Atmosphere Model (EAM)
-Some introductory text here
+EAM is the state-of-the-art atmospheric component of the E3SM model that uses a Spectral Element Dynamical Core and a suite of parameterizations to represent a range of atmospheric processes, which are described in the Technical Guide (see below). Its nominal resolution is roughly 100km in the horizontal, with a model time step of 1800 seconds, and runs with 80 layers in the vertical (model top of 60km).
-* The [EAM User's Guide](user-guide/index.md) explains how to control EAM when its running within E3SM.
-* The [EAM Developer's Guide](dev-guide/index.md) explains EAM data structures and how to write new code.
-* The [EAM Techincal Guide](tech-guide/index.md) explains the science behind EAM's code
+* The [EAM User Guide](user-guide/index.md) explains how to control EAM when its running within E3SM.
+* The [EAM Developer Guide](dev-guide/index.md) explains EAM data structures and how to write new code.
+* The [EAM Technical Guide](tech-guide/index.md) explains the science behind EAM's code
diff --git a/components/eam/docs/tech-guide/armdiags.md b/components/eam/docs/tech-guide/armdiags.md
new file mode 100644
index 000000000000..47266db48f2a
--- /dev/null
+++ b/components/eam/docs/tech-guide/armdiags.md
@@ -0,0 +1,56 @@
+# ARM diagnostics
+
+## Overview
+
+The ARM data-oriented metrics and diagnostics package (ARM Diags) was developed to facilitate the use of ARM data in climate model evaluation and model intercomparison (Zhang et al., 2020)[@zhang_arm_2020]. It includes ARM data sets, compiled from multiple ARM data products, and a Python-based analysis toolkit for computation ad visualization. It also includes simulation data from models participating the CMIP, which allows climate-modeling groups to compare a new, candidate version of their model to existing CMIP models. The ARM Diags has been applied in several model evaluation studies to help address a range of issues in climate models (Zheng et al., 2023;[@zheng_assessment_2023] Emmenegger et al., 2022;[@emmenegger_evaluating_2022] Zhang et al., 2018[@zhang_causes_2018]). The Majority of ARM Diags sets are ported into E3SM Diags (Zhang et al., 2022)[@zhang_e3sm_2022] for routine evaluation of the model.
+
+## To enable the use of ARM Diags
+
+To enable using ARM Diags for a simulation, often, a new tape that output at high-frequency over limited-area (nearest grid box to supported ARM site) needs to be included in the namelist file, an example as follows:
+
+```fortran
+fincl7 = 'PS','Q','T','Z3','CLOUD','CONCLD','CLDICE',
+ 'CLDLIQ','FREQR','REI','REL','PRECT','TMQ','PRECC',
+ 'TREFHT','QREFHT','OMEGA','CLDTOT','LHFLX','SHFLX',
+ 'FLDS','FSDS','FLNS','FSNS','FLNSC','FSDSC','FSNSC',
+ 'AODVIS','AODABS','LS_FLXPRC','LS_FLXSNW',
+ 'LS_REFFRAIN','ZMFLXPRC','ZMFLXSNW','CCN1','CCN2',
+ 'CCN3','CCN4','CCN5','num_a1','num_a2','num_a3',
+ 'num_a4','so4_a1','so4_a2','so4_a3','AREL','TGCLDLWP',
+ 'AQRAIN','ANRAIN','FREQR','PRECL','RELHUM'
+fincl7lonlat='262.5e_36.6n','203.4e_71.3n','147.4e_2.0s',
+ '166.9e_0.5s','130.9e_12.4s','331.97e_39.09n'
+```
+
+Note that in this example fincl7 should set to write output at hourly (`nhtfrq = -1`). And here additional variables are included for ARM simulator analysis. The ARM site information is shown below:
+
+```fortran
+ "sgpc1": ["97.5W 36.4N Oklahoma ARM"],
+
+ "nsac1": ["156.6W 71.3N Barrow ARM"],
+
+ "twpc1": ["147.4E 2.1S Manus ARM"],
+
+ "twpc2": ["166.9E 0.5S Nauru ARM"],
+
+ "twpc3": ["130.9E 12.4S Darwin ARM"],
+
+ "enac1": ["28.0E 39.1N Graciosa Island ARM"],
+```
+
+## Diagnostics and metrics currently implemented in the ARM Diags
+
+| Statistical Metrics | Variables | Time sampling |
+| ------------------------- | --------------------------------------------------------------- | ----------------- |
+| Line plots and Taylor diagrams for annual cycle variability of each variable | Precipitation, column water vapor, surface energy budget components, near-surface temperature and specific humidity, surface pressure, total cloud fraction, and aerosol optical depth. | Monthly mean |
+| Contour and vertical profiles of annual cycle and diurnal cycle of cloud fraction | Vertical profiles of cloud fraction | Hourly mean |
+| Line and harmonic dial plots of diurnal cycle of precipitation | Surface precipitation rate | Hourly mean |
+| Probability density function (PDF) plots of precipitation rate | Surface precipitation rate | Hourly mean |
+| CCN Annual Cycles | CCN number concentrations at 0.1%, 0.2%, 0.5% and 1.0% supersaturation levels | Hourly mean |
+| Aerosol Annual Cycles | Total aerosol number concentration | Hourly mean |
+| Aerosol Chemical Annual Cycles | Organic, sulfate, nitrate, ammonium, chloride mass concentration | Hourly mean |
+
+| Process-oriented metrics | Variables | Time sampling |
+| ------------------------- | ------------------------------------------------------------- | ----------------- |
+| Convection Onset | 1. Surface precipitation rate
2. Column Precipitable Water Vapor | Hourly mean |
+| Aerosol-CCN Activation | 1. Total aerosol number concentration
2. CCN number concentrations at different supersaturation levels (0.1%, 0.2%, 0.5% and 1.0) | Hourly mean |
diff --git a/components/eam/docs/tech-guide/chemUCIlinozv3.md b/components/eam/docs/tech-guide/chemUCIlinozv3.md
new file mode 100644
index 000000000000..b6b202c00f8c
--- /dev/null
+++ b/components/eam/docs/tech-guide/chemUCIlinozv3.md
@@ -0,0 +1,9 @@
+# chemUCI and Linoz
+
+## Overview
+
+Atmospheric interactive chemistry is handled by chemUCI (in the troposphere) and Linoz v3 (in the stratosphere). chemUCI consists of 28 advected tracers for the O3-CH4-HOx-NOx-NMVOCs chemistry. Compared to E3SMv2, the E3SMv3 linearized stratospheric chemistry scheme (Linoz v3) expends the interactive species to include O3, N2O, NOy, and CH4. The boundary between stratosphere and troposphere adopts the e90 tropopause algorithm.
+
+## Namelist parameters
+
+[chemUCI and Linoz Namelist Parameters](../user-guide/namelist_parameters.md#chemuci-and-linoz-v3)
diff --git a/components/eam/docs/tech-guide/clubb.md b/components/eam/docs/tech-guide/clubb.md
new file mode 100644
index 000000000000..2737f753850e
--- /dev/null
+++ b/components/eam/docs/tech-guide/clubb.md
@@ -0,0 +1,9 @@
+# Cloud Layers Unified By Binormals
+
+## Overview
+
+The Cloud Layers Unified By Binormals (CLUBB) parameterization is a parameterization of subgrid-scale turbulence and clouds.[@larson_clubb-silhs_2022,@bogenschutz_path_2018,@larson_using_2005,@golaz_pdf-based_2002] It prognoses turbulent fluxes of heat, moisture, and momentum, and it diagnoses the liquid cloud fraction and liquid water mixing ratio. To do so, it prognoses higher-order turbulence moments and closes those prognostic equations by use of an assumed double-Gaussian shape of the subgrid probability density function. CLUBB operates throughout the troposphere, but it contributes especially to the planetary boundary layer and low-cloud regimes, including stratocumulus and shallow cumulus regimes.
+
+## Namelist parameters
+
+[CLUBB Namelist Parameters](../user-guide/namelist_parameters.md#cloud-layers-unified-by-binormals)
diff --git a/components/eam/docs/tech-guide/cosp.md b/components/eam/docs/tech-guide/cosp.md
new file mode 100644
index 000000000000..ef724b12a9f5
--- /dev/null
+++ b/components/eam/docs/tech-guide/cosp.md
@@ -0,0 +1,27 @@
+# Cloud Feedback Model Intercomparison Project (CFMIP) Observation Simulator Package
+
+## Overview
+
+The Cloud Feedback Model Intercomparison Project (CFMIP) Observation Simulator Package (COSP; Bodas-Salcedo et al., 2011;[@bodas-salcedo_cosp_2011] Swales et al., 2018;[@swales_cloud_2018] Zhang et al., 2019;[@zhang_evaluation_2019] Zhang et al., 2024[@zhang_understanding_2024]) was developed to improve the consistency between model clouds and satellite observations. COSP contains several independent satellite simulators for better comparing model clouds with satellite measurements collected by the International Satellite Cloud Climatology Project (ISCCP), the Moderate Resolution Imaging Spectroradiometer (MODIS), the Multi-angle Imaging SpectroRadiometer (MISR), Cloud-Aerosol Lidar and Infrared Pathfinder Satellite Observation (CALIPSO), and CloudSat. The use of satellite simulators will not only make a fairer comparison between model clouds and satellite data but also allow a more in-depth analysis of clouds. For example, clouds can be assessed in terms of their optical properties and vertical location, which dictate their radiative effects.
+
+## Namelist parameters
+
+[COSP Namelist Parameters](../user-guide/namelist_parameters.md#cloud-feedback-model-intercomparison-project-cfmip-observation-simulator-package)
+
+## To turn on COSP outputs
+
+Run (add to the run script) the following command before running `./case.setup`
+
+`./xmlchange --id CAM_CONFIG_OPTS --append --val='-cosp'`
+
+| Related Outputs | Description |
+| ------------------------- | ----------------------------------------------------------------- |
+| `FISCCP1_COSP` | Grid-box fraction covered by each ISCCP D level cloud type |
+| `CLMODIS` | MODIS Cloud Area Fraction |
+| `CLD_MISR` | Cloud Fraction from MISR Simulator |
+| `CLDTOT_CAL` | Calipso Total Cloud Fraction |
+| `CLDHGH_CAL` | Calipso High-level Cloud Fraction |
+| `CLDMED_CAL` | Calipso Mid-level Cloud Fraction |
+| `CLDLOW_CAL` | Calipso Low-level Cloud Fraction |
+| `CLD_CAL_TMPLIQ` | Calipso Liquid Cloud Fraction as a function of temperature |
+| `CLD_CAL_TMPICE` | Calipso Ice Cloud Fraction as a function of temperature |
diff --git a/components/eam/docs/tech-guide/dust.md b/components/eam/docs/tech-guide/dust.md
new file mode 100644
index 000000000000..59f7cc3a966b
--- /dev/null
+++ b/components/eam/docs/tech-guide/dust.md
@@ -0,0 +1,9 @@
+# Dust aerosol
+
+## Overview
+
+Dust-related processes are represented in the E3SM atmosphere and land model components. In E3SMv3, dust deposition will also be coupled with the sea ice and ocean biogeochemistry in the ocean model. Total emission fluxes of dust particles are calculated at each model time step. A new dust emission scheme following Kok et al. (2014)[@kok_improved_2014] is implemented to E3SMv3, replacing the Zender scheme (Zender et al., 2003)[@zender_mineral_2003] in E3SMv1 and v2 as the default option. The new dust emission scheme includes a time-varying soil erodibility factor for dust mobilization, and includes dust sources in high latitudes (e.g., >60 degree N). A manuscript by Feng et al. is in prep to document the performance of the new emission scheme on dust life cycle and radiative effects in E3SMv3. Dust aerosol is represented in the accumulation and coarse aerosol modes of the MAM4 module following emission. Other dust properties such as optical properties and size distribution at emission are documented in Feng et al. (2022).[@feng_global_2022]
+
+## Namelist parameters
+
+[Dust Namelist Parameters](../user-guide/namelist_parameters.md#dust-aerosol)
diff --git a/components/eam/docs/tech-guide/homme.md b/components/eam/docs/tech-guide/homme.md
new file mode 100644
index 000000000000..42561abde98b
--- /dev/null
+++ b/components/eam/docs/tech-guide/homme.md
@@ -0,0 +1,11 @@
+# High-Order Methods Modeling Environment
+
+## Overview
+
+EAM uses the a dynamical core (dycore) from the High Order Method Modeling Environment (HOMME).[@taylor_compatible_2010,@guba_spectral_2014,@taylor_energy_2020] The EAM dycore solves the atmospheric primitive equations governing the evolution of velocity, density, pressure and temperature, as well as the transport of water species and related hydrometers, aerosols and other atmospheric constituents. The governing equations are written in a vertically lagrangian terrain following mass coordinate. They are discretized with second order finite differences in the radial direction and spectral finite elements in the horizontal (surface of the sphere) directions, and advanced in time with a 3rd order accurate 5 stage Runge-Kutta method. Dissipation is added through the use of monotoncity contraints on some advectiion terms, explicitly added hyperviscosity, and a Laplacian-based sponge layer in the first few layers at the model top. The transported species makes use of an efficient interpolatory semi-Lagrangian method. EAMv3 uses 80 layers in the vertical. The use of the spectral finite element method allows EAMv3 to run on fully unstructured grids, including the cubed-sphere grid ([SE Atmosphere Grid Overview (EAM & CAM)](https://acme-climate.atlassian.net/wiki/spaces/DOC/pages/34113147)) which provides quasi-uniform resolution over the globe, and regionally refined meshes (RRM) which enhance horizontal resolution in regions of interest ([Library of Regionally-Refined Model (RRM) Grids](https://acme-climate.atlassian.net/wiki/spaces/DOC/pages/3690397775)).
+
+## Namelist parameters
+
+Many dynamical core parameters can not be changed independently. For example, increasing the hyperviscosity coefficient may require reducing the hyperviscosity timestep. Dycore timesteps are tuned for each resolution and the defaults are close to the CFL stability limit. For complete details, as well as their interactions, see [EAM's HOMME dycore](https://acme-climate.atlassian.net/wiki/spaces/DOC/pages/1044644202/EAM+s+HOMME+dycore).
+
+[HOMME Namelist Parameters](../user-guide/namelist_parameters.md#homme)
diff --git a/components/eam/docs/tech-guide/index.md b/components/eam/docs/tech-guide/index.md
index 44a4f1921e25..437f5636edfe 100644
--- a/components/eam/docs/tech-guide/index.md
+++ b/components/eam/docs/tech-guide/index.md
@@ -1 +1,31 @@
-start of the EAM Technical Guide
+# EAM Technical Guide
+
+This Technical Guide describes the physics of version 3 of the E3SM Atmospheric Model
+
+## Dynamics and Physics
+
+- [HOMME](homme.md): Dynamical core.
+
+- [P3](p3.md): Stratiform cloud microphysics scheme.
+
+- [CLUBB](clubb.md): Parameterization of subgrid-scale turbulence and clouds.
+
+- [Zhang-McFarlane](zm.md): Deep convection parameterization.
+
+- [RRTMG](rrtmg.md): Parameterization of radiation.
+
+- [MAM](mam.md): Primary parameterization schemes used to represent aerosols.
+
+- [VBS](vbs.md): Parameterization of secondary organic aerosols.
+
+- [Dust](dust.md): Parameterization of dust emissions.
+
+- [OCEANFILMS](oceanfilms.md): Parameterization of sea soray irganic aerosol emissions.
+
+- [chemUCI + Linoz v3](chemUCIlinozv3.md): Interactive atmospheric chemistry packages.
+
+## Diagnostic outputs
+
+- [COSP](cosp.md): Scheme that allows the model to output satellite simulator output.
+
+- [ARM Diags](armdiags.md): Diagnostic package that allows the model output to be compared against ARM measurements.
diff --git a/components/eam/docs/tech-guide/mam.md b/components/eam/docs/tech-guide/mam.md
new file mode 100644
index 000000000000..99886682f463
--- /dev/null
+++ b/components/eam/docs/tech-guide/mam.md
@@ -0,0 +1,17 @@
+# Modal Aerosol Module
+
+## MAM5 Overview
+
+The Five-mode Modal Aerosol Model (MAM5) supersedes the MAM4 utilized in previous iterations of E3SM (E3SM-V1 and -V2). MAM5 introduces a fifth mode, specifically designed to represent stratospheric coarse mode aerosols, primarily originating from volcanic eruptions and DMS decomposition. This mode exclusively comprises sulfate aerosols, characterized by a smaller standard deviation (STD) value of 1.2. The STD value denotes the width of the aerosol mode, where a higher STD implies a greater gravitational settling effect (Wang et al., 2020;[@wang_aerosols_2020] Liu et al., 2012[@liu_toward_2012]). By setting the STD to 1.2, the simulated properties of volcanic aerosols align closely with observational findings (Mills et al., 2016).[@mills_global_2016] MAM5 represents a pioneering aerosol model, effectively segregating tropospheric and stratospheric aerosols (Ke et al., in preparation), thereby mitigating the risk of overestimating dust and sea salt aerosols within the stratosphere in previous MAM4 (Visioni et al., 2021).[@visioni_limitations_2022] Volcanic eruptions derived from Neely and Schmidt (2016).[@neely_iii_volcaneesm_2016]
+
+## MAM4 Overview
+
+The representation of atmospheric aerosols and their roles in the Earth system by EAMv1/v2/v3 was inherited from the global aerosol-climate model EAMv0 and its four-mode modal aerosol module (MAM4), including Aitken, primary-carbon, accumulation, and coarse modes (Liu et al., 2016).[@liu_description_2016] It treats a combination of processes, controlling the evolution of aerosols that are either directly emitted or converted from precursor gases from a variety of natural and anthropogenic sources. The processes include transport (by grid-scale wind, subgrid turbulence, convection, and sedimentation), aerosol microphysics (i.e., particle nucleation, condensation/evaporation of trace gases, aging, and coagulation), cloud processing (i.e., aqueous chemistry, scavenging by hydrometeors, resuspension from evaporating hydrometeors, and wet deposition), and dry deposition. Aerosol species in the original MAM4 (Liu et al., 2016)[@liu_description_2016] include sulfate, primary organic aerosol (POA) or particulate organic matter (POM), secondary organic aerosol (SOA), black carbon (BC), sea salt, and mineral dust. As described by Wang et al. (2020),[@wang_aerosols_2020] the enhanced MAM4 in EAMv1/v2 added marine organic aerosol (MOA) to all four modes (Burrows et al., 2022).[@burrows_oceanfilms_2022] In MAM4 of EAMv3, the Aitken mode has sulfate, sea salt, SOA and MOA; the primary-carbon mode has BC, POA and MOA; the accumulation and coarse modes include all seven species. Ammonium (NH4) and nitrate (NO3) aerosols are also explicitly treated in EAMv3 (Wu et al., 2022),[@wu_development_2022] as an optional feature for research, in which new species (NH4, NO3, Ca, CO3, Na, Cl) are introduced to the Aitken, accumulation and coarse modes. All aerosol species within each of the four individual modes the MAM4 is assumed to be internally mixed and represented by a single number concentration, while particles are externally mixed among the different modes.
+
+### Sea salt
+
+In MAM4, sea salt aerosol is represented in the Aitken, accumulation, and coarse mode with particle emission size (diameter) ranges of 0.02-0.08, 0.08-1.0, and 1.0-10.0 μm, respectively. The emission flux of natural sea salt is first divided into 31 size bins, following the parameterization of Mårtensson et al. (2003)[@martensson_laboratory_2003] and Monahan et al. (1986),[@monahan_model_1986] and then redistributed to the three MAM4 size modes.
+
+## Namelist parameters
+
+[MAM Namelist Parameters](../user-guide/namelist_parameters.md#modal-aerosol-module)
diff --git a/components/eam/docs/tech-guide/oceanfilms.md b/components/eam/docs/tech-guide/oceanfilms.md
new file mode 100644
index 000000000000..1ac45cfd7999
--- /dev/null
+++ b/components/eam/docs/tech-guide/oceanfilms.md
@@ -0,0 +1,9 @@
+# OCEANFILMS
+
+## Overview
+
+E3SM (v1-v3) uses the OCEANFILMS (Organic Compounds from Ecosystems to Aerosols: Natural Films and Interfaces via Langmuir Molecular Surfactants) parameterization to represent sea spray organic aerosol emissions. OCEANFILMS is a physically based model that links sea spray chemistry with ocean biogeochemistry using a Langmuir partitioning approach. The underlying physical assumptions and parameterization are described in Burrows et al. (2014);[@burrows_physically_2014] the implementation in E3SM and impact on clouds and climate are documented in Burrows et al. (2022).[@burrows_oceanfilms_2022]
+
+## Namelist parameters
+
+[OCEANFILMS Namelist Parameters](../user-guide/namelist_parameters.md#oceanfilms)
diff --git a/components/eam/docs/tech-guide/p3.md b/components/eam/docs/tech-guide/p3.md
new file mode 100644
index 000000000000..af06aaa6aab0
--- /dev/null
+++ b/components/eam/docs/tech-guide/p3.md
@@ -0,0 +1,9 @@
+# Predicted Particle Properties
+
+## Overview
+
+The stratiform cloud microphysics scheme in v3 is Predicted Particle Properties (P3; Morrison & Milbrandt, 2015;[@morrison_parameterization_2015] Milbrandt & Morrison, 2016[@milbrandt_parameterization_2016]). P3 offers a new approach to representing the evolution of ice particles that is more physical than the traditional approach of using predefined ice categories. It has been implemented in E3SM (Wang et al., 2021)[@wang_impact_2021] to address the limitations in the original microphysics scheme- the lack of riming particles and the artificial conversion between ice crystals and snow particles. The current version in E3SM is a two-moment scheme with a single ice category (Morrison & Milbrandt, 2015).[@morrison_parameterization_2015] In addition to the total ice number and mass mixing ratios, P3 prognoses the rimed mass and rimed volume mixing ratios, which allows for the prediction of the continuous evolution of the rime fraction and particle density. It is worth noting that the ice nucleation parameterizations are changed to be aerosol-dependent in this study, with the heterogenous ice nucleation parameterizations from the Classical Nucleation Theory (Liu et al., 2012)[@liu_toward_2012] and the homogenous in-situ cirrus formation based on Liu and Penner (2005).[@liu_ice_2005] This differs from the P3 used in WRF and that used in the E3SM v1 in Wang et al. (2021)[@wang_impact_2021] where the heterogeneous ice nucleation parameterizations are temperature dependent only.
+
+## Namelist parameters
+
+[P3 Namelist Parameters](../user-guide/namelist_parameters.md#predicted-particle-properties)
diff --git a/components/eam/docs/tech-guide/rrtmg.md b/components/eam/docs/tech-guide/rrtmg.md
new file mode 100644
index 000000000000..7afa8df61224
--- /dev/null
+++ b/components/eam/docs/tech-guide/rrtmg.md
@@ -0,0 +1,9 @@
+# Rapid Radiative Transfer Model for GCMs
+
+## Overview
+
+The calculation of radiative energy flux through the atmosphere is done using the RRTMG radiation package (Iacono et al., 2008;[@iacono_radiative_2008] Mlawer et al., 1997[@mlawer_radiative_1997]). The details are consistent with the implementation in CAM5 described in Neale et al. (2012).[@neale_description_2012] Radiative fluxes are broadly split into shortwave and longwave and computed by separate codes. The shortwave solver uses the 2-stream approximation, while the longwave is an absorption/emission code. Both shortwave and longwave use the correlated k-distribution method for integration of fluxes. Subgrid cloud overlap is accounted for using the Monte Carlo Independent Column Approximation (MCICA; Pincus and Morcrette, 2003),[@pincus_fast_2003] assuming the cloudy portions of the column are maximally overlapped in vertically contiguous layers and randomly overlapped when two layers are separated by a completely clear layer. Cloud optics are parameterized as described in Neale et al.(2010).[@neale_description_2012]
+
+## Namelist parameters
+
+[RRTMG Namelist Parameters](../user-guide/namelist_parameters.md#rapid-radiative-transfer-model-for-gcms)
diff --git a/components/eam/docs/tech-guide/vbs.md b/components/eam/docs/tech-guide/vbs.md
new file mode 100644
index 000000000000..26535a89308d
--- /dev/null
+++ b/components/eam/docs/tech-guide/vbs.md
@@ -0,0 +1,5 @@
+# Volatility Basis Set (VBS) approach for SOA
+
+## Overview
+
+A modified volatility basis set (VBS) approach is used for both SOA precursor gases and particulate SOA that includes gas‐phase functionalization/fragmentation and particle‐phase oligomerization similar to FragNVSOA configuration of Shrivastava et al. (2015).[@shrivastava_global_2015] It includes a detailed treatment of SOA precursor gas chemistry including multigenerational aging via fragmentation and functionalization reactions, particle‐phase oligomerization that generates low “effective volatility” SOA, and particle‐phase loss by photolysis. The sources of SOA include natural biogenic, anthropogenic and biomass burning organic gases that are oxidized to form lower volatility species and undergo dynamic gas-particle partitioning to form SOA. Biogenic SOA is formed by oxidation of isoprene (ISOP_VBS) and monoterpene (C10H16) volatile organic compounds (VOCs). Emissions of anthropogenic and biomass burning organic gases in the range of intermediate volatility organics (IVOCs, referred to as SOAG0) are estimated as total primary organic matter (POM) emitted from these sources multiplied by specified tunable factors. IVOCs undergo multigenerational aging with OH radicals forming SOA corresponding to anthropogenic and biomass burning sources. Photolysis of SOA is included as a chemical sink in the particle phase, in addition to dry and wet removal sinks. The photolysis rate constant of particle-phase SOA is assumed to be 0.04% of typical NO2 photolysis frequencies following Hodzic et al. (2016).[@hodzic_rethinking_2016] The emissions of VBS SOA related gas species and oxidants (prescribed) read from a file are documented in the [User Guide](../user-guide/index.md).
diff --git a/components/eam/docs/tech-guide/zm.md b/components/eam/docs/tech-guide/zm.md
new file mode 100644
index 000000000000..2e3c5b9b6070
--- /dev/null
+++ b/components/eam/docs/tech-guide/zm.md
@@ -0,0 +1,27 @@
+# Zhang and McFarlane deep convection scheme
+
+## Overview
+
+The ZM scheme (Zhang and McFarlane, 1995)[@zhang_sensitivity_1995] used in E3SMv3 is a bulk mass flux-type scheme; it has three components: a trigger for convection initiation, a cloud model including both updrafts and downdrafts, and a closure. The original CAPE-based trigger for convection was replaced by a trigger function based on dynamic CAPE generation by Xie et al. (2019)[@xie_improved_2019] (see dCAPE-ULL description below for more details). The closure predicts cloud base mass flux using dilute CAPE (Neale et al., 2008).[@neale_impact_2008] The updraft model is a bulk entraining plume model. Both updrafts and downdrafts are assumed saturated, with downdraft mass flux at the downdraft initiation level set proportional to the updraft cloud base mass flux. The microphysical processes inside the updrafts are represented by a convective microphysics scheme (see ZM convective microphysics description below). An additional adjustment is made to cloud base mass flux to incorporate the effect of large-scale circulation (see mass flux adjustment description below).
+
+### dCAPE-ULL
+
+A notable update related to clouds and precipitation in E3SMv2 is the use of a new convective trigger function described by Xie et al. (2019)[@xie_improved_2019] in ZM to improve the simulation of precipitation and its diurnal cycle. The new convective trigger named as dCAPE-ULL uses the dynamic CAPE (dCAPE) trigger developed by Xie and Zhang (2000)[@xie_impact_2000] with an unrestricted air parcel launch level (ULL) approach used by Wang et al. (2015).[@wang_impacts_2015] It was designed to address the unrealistically strong coupling of convection to the surface heating in ZM that often results in unrealistically too active model convection during the day in summer season over lands and improve the model capability to capture mid-level convection for nocturnal precipitation.
+
+### ZM convective microphysics
+
+The convective microphysics scheme is based on the work of Song and Zhang (2011)[@song_microphysics_2011] to improve the representation of microphysical processes in convective clouds and their interaction with aerosol and stratiform clouds in GCMs. It explicitly treats the mass mixing ratio and number concentration of five hydrometeor species (cloud water, cloud ice, rain, snow, and graupel). The scheme is linked to stratiform cloud microphysics parameterization through convective detrainment of cloud liquid/ice water content and droplet/crystal number concentration, and to aerosols through cloud droplet activation and ice nucleation processes. Previous evaluations of the scheme showed that it improved the simulation of convective cloud properties and cloud hydrological cycle (Song et al., 2012;[@song_evaluation_2012] Storer et al., 2015[@storer_effects_2015]). The assessment demonstrates that the convective microphysics scheme not only significantly improves the simulation of tropical variability across multiple scales but also enhances the simulation of climatological mean states.
+
+### Mass flux adjustment
+
+The convective mass flux adjustment (MAdj) is designed to represent the dynamical effects of large-scale vertical motion on convection. With MAdj, convection is enhanced (suppressed) when there is large-scale ascending (descending) motion at the planetary boundary layer top. The coupling of convection with the large-scale circulation significantly improves the simulation of climate variability across multiple scales from diurnal cycle, convectively coupled equatorial waves, to Madden-Julian oscillations (Song et al., 2023).[@song_incorporating_2023]
+
+### MCSP
+
+Due to inadequate model resolution, organized mesoscale convection cannot be resolved in general circulation models and thus needs to be parameterized. The Multiscale Coherent Structure Parameterization (MCSP) aims at representing the dynamical and physical effects of organized mesoscale convection.
+
+MCSP applies a sinusoidal baroclinic profile in the temperature, moisture, and momentum fields to represent the impact. Moncrieff et al. (2017)[@moncrieff_simulation_2017] and Chen et al. (2021)[@chen_effects_2021] have found that by adding MCSP, the both the representation of large-scale precipitation systems and the modes of variability from Tropical waves are improved.
+
+## Namelist parameters
+
+[ZM Namelist Parameters](../user-guide/namelist_parameters.md#zhang-and-mcfarlane-deep-convection-scheme)
diff --git a/components/eam/docs/user-guide/aerosol_phys_prop.md b/components/eam/docs/user-guide/aerosol_phys_prop.md
new file mode 100644
index 000000000000..6d80565d9718
--- /dev/null
+++ b/components/eam/docs/user-guide/aerosol_phys_prop.md
@@ -0,0 +1,111 @@
+
+# Aerosol physical properties
+
+## Description
+
+Key information
+
+- Original physical properties of aerosols are documented in Liu et al. (2012).[@liu_toward_2012] Detailed information is included in the supplement.
+
+- Physical properties of aerosols used in E3SMv1 are documented in Wang et al. (2020).[@wang_aerosols_2020]
+
+- Marine organic aerosol properties are defined in Burrows et al. (2022).[@burrows_oceanfilms_2022]
+
+- Dust refractive index and longwave absorption coefficients are updated by Feng et al. (2022).[@feng_global_2022]
+
+- BC and POM hygroscopicity values are updated by Shan et al. (2024).
+
+- Physical properties of the fifth mode aerosols are documented by Ke et al. (2024).
+
+## Included fields
+
+### Mode properties
+
+- Geometric standard deviation of each lognormal mode
+
+- Nominal geometric mean diameter and its lower/upper bound of values for each mode
+
+- Coefficients of polynomial expression (lookup-table) for extinction, absorption, and asymmetry parameter calculations
+
+- Aerosol refractive index table needed for interpolation (lookup-table) calculation (for different wavelengths)
+
+- Crystalization and deliquesence relative humidity thresholds for aerosol wateruptake calculations
+
+### Species properties
+
+- Aerosol refractive index for each species
+
+- Density for each species
+
+- Aerosol hygroscopicity for each species
+
+- Note that some of variables in the species property file are for bulk aerosols, so we ignore the description for them.
+
+## Files
+
+Species properties
+
+```fortran
+/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/sulfate_rrtmg_c080918.nc
+/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/ocpho_rrtmg_c130709_kPOM0.04.nc
+/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/ocphi_rrtmg_c100508.nc
+/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/bcpho_rrtmg_c100508.nc
+/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/dust_aeronet_rrtmg_c141106.nc
+/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/ssam_rrtmg_c100508.nc
+/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/poly_rrtmg_c130816.nc
+```
+
+Mode properties
+
+```fortran
+/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc',
+/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc',
+/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc',
+/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc',
+/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc'
+```
+
+## Namelist
+
+```fortran
+ mode_defs = 'mam5_mode1:accum:=',
+ 'A:num_a1:N:num_c1:num_mr:+',
+ 'A:so4_a1:N:so4_c1:sulfate:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/sulfate_rrtmg_c080918.nc:+',
+ 'A:pom_a1:N:pom_c1:p-organic:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/ocpho_rrtmg_c130709_kPOM0.04.nc:+',
+ 'A:soa_a1:N:soa_c1:s-organic:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/ocphi_rrtmg_c100508.nc:+',
+ 'A:bc_a1:N:bc_c1:black-c:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/bcpho_rrtmg_c100508.nc:+',
+ 'A:dst_a1:N:dst_c1:dust:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/dust_aeronet_rrtmg_c141106.nc:+',
+ 'A:ncl_a1:N:ncl_c1:seasalt:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/ssam_rrtmg_c100508.nc:+',
+ 'A:mom_a1:N:mom_c1:m-organic:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/poly_rrtmg_c130816.nc',
+ 'mam5_mode2:aitken:=',
+ 'A:num_a2:N:num_c2:num_mr:+',
+ 'A:so4_a2:N:so4_c2:sulfate:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/sulfate_rrtmg_c080918.nc:+',
+ 'A:soa_a2:N:soa_c2:s-organic:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/ocphi_rrtmg_c100508.nc:+',
+ 'A:ncl_a2:N:ncl_c2:seasalt:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/ssam_rrtmg_c100508.nc:+',
+ 'A:mom_a2:N:mom_c2:m-organic:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/poly_rrtmg_c130816.nc',
+ 'mam5_mode3:coarse:=',
+ 'A:num_a3:N:num_c3:num_mr:+',
+ 'A:dst_a3:N:dst_c3:dust:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/dust_aeronet_rrtmg_c141106.nc:+',
+ 'A:ncl_a3:N:ncl_c3:seasalt:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/ssam_rrtmg_c100508.nc:+',
+ 'A:so4_a3:N:so4_c3:sulfate:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/sulfate_rrtmg_c080918.nc:+',
+ 'A:bc_a3:N:bc_c3:black-c:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/bcpho_rrtmg_c100508.nc:+',
+ 'A:pom_a3:N:pom_c3:p-organic:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/ocpho_rrtmg_c130709_kPOM0.04.nc:+',
+ 'A:soa_a3:N:soa_c3:s-organic:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/ocphi_rrtmg_c100508.nc:+',
+ 'A:mom_a3:N:mom_c3:m-organic:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/poly_rrtmg_c130816.nc',
+ 'mam5_mode4:primary_carbon:=',
+ 'A:num_a4:N:num_c4:num_mr:+',
+ 'A:pom_a4:N:pom_c4:p-organic:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/ocpho_rrtmg_c130709_kPOM0.04.nc:+',
+ 'A:bc_a4:N:bc_c4:black-c:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/bcpho_rrtmg_c100508.nc:+',
+ 'A:mom_a4:N:mom_c4:m-organic:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/poly_rrtmg_c130816.nc',
+ 'mam5_mode5:strat_coarse:=',
+ 'A:num_a5:N:num_c5:num_mr:+',
+ 'A:so4_a5:N:so4_c5:sulfate:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/sulfate_rrtmg_c080918.nc'
+ rad_climate = 'A:H2OLNZ:H2O', 'N:O2:O2','N:CO2:CO2', 'A:O3:O3',
+ 'A:N2OLNZ:N2O', 'A:CH4LNZ:CH4','N:CFC11:CFC11', 'N:CFC12:CFC12',
+ 'M:mam5_mode1:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/mam4_mode1_rrtmg_aeronetdust_c141106.nc',
+ 'M:mam5_mode2:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/mam4_mode2_rrtmg_c130628.nc',
+ 'M:mam5_mode3:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/mam4_mode3_rrtmg_aeronetdust_c141106.nc',
+ 'M:mam5_mode4:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/mam4_mode4_rrtmg_c130628.nc',
+ 'M:mam5_mode5:/lcrc/group/e3sm/data/inputdata/atm/cam/physprops/mam5_mode5_rrtmg_sig1.2_dgnl.40_c03072023.nc'
+
+```
diff --git a/components/eam/docs/user-guide/emission_oxidant_files.md b/components/eam/docs/user-guide/emission_oxidant_files.md
new file mode 100644
index 000000000000..72868b6b8458
--- /dev/null
+++ b/components/eam/docs/user-guide/emission_oxidant_files.md
@@ -0,0 +1,196 @@
+
+# Emission files for EAMv3 gas and aerosol species and oxidant file for VBS SOA and stratosphere sulfate formation
+
+## Overview
+
+This page documents emissions data for all required aerosols and precursor gases as well as oxidants input data for running EAMv3, mostly for the MAM4 aerosol scheme, from anthropogenic (i.e., industrial, energy, transportation, domestic, and agriculture activity sectors) and natural (i.e., sea spray, vegetation, fire smoke, volcano) sources. Sulfur from agriculture, domestic, transportation, waste, and shipping sectors is emitted at the surface while sulfur from energy and industry sectors is emitted at 100-300 m above the surface, and sulfur from forest fire and grass fire is emitted at higher elevations (0-6 km). POM and BC from forest fire and grass fire are emitted at 0-6 km, while those from other sources (domestic, energy, industry, transportation, waste, and shipping) are emitted at the surface. Injection height profiles for fire emissions are derived from the corresponding AeroCom profiles (Dentener et al., 2006)[@dentener_emissions_2006], which give emissions in 6 altitude ranges (0-0.1, 0.1-0.5, 0.5-1, 1-2, 2-3, and 3-6 km). Otherwise, species emissions are assumed to be at the surface (bottom layer). Number emission fluxes each mode are calculated from mass emission fluxes based on AeroCom prescribed lognormal size distributions.
+
+## Aerosols and gas precursors (common for EAMv1/v2/v3)
+
+* Species: SO2, SOAG0, DMS, bc_a4, pom_a4, so4_a1, so4_a2, num_a1, num_a2, num_a4
+* Data sources
+ * Most of the original data are directly from input4MIPs with the following exceptions (E3SM specific treatments)
+ * SO2 takes 97.5% from the input4MIPs data (all SO2-em-anthro_input4MIPs sectors)
+ * SO4_a1 surf takes 2.5% from the corresponding surface sectors of input4MIPs data (SO2-em-anthro_input4MIPs sectors: AGR, SLV, WST, SHP)
+ * SO4_a2 surf takes 2.5% from the corresponding surface sectors of input4MIPs data (SO2-em-anthro_input4MIPs sectors: TRA, RCO)
+ * SO4_a1 elev takes 2.5% from the corresponding elevated sectors of input4MIPs data (SO2-em-anthro_input4MIPs sectors: ENE, IND)
+ * SO2 (97.5%) and SO4_a1 (2.5%) also take emissions from AR5 input file for sector contvolc (constant volcanic degassing)
+ * SOAG0 emissions are obtained by scaling OC (POM) emissions with a tunable factor.
+ * num_a1, num_a2 and num_a4 are determined by mass concentration of aerosols species in the corresponding sectors and modes.
+
+## Marine organic sea spray
+
+Marine organic sea spray aerosol contributions are parameterized following the OCEANFILMS parameterization (E3SMv1; Burrows et al., 2014;[@burrows_physically_2014] 2022[@burrows_oceanfilms_2022]). The input file for this parameterization provides a climatology of the ocean surface concentrations of several groups of organic macromolecules. Briefly, the Parallel Ocean Program (POP; Maltrud et al., 1998)[@maltrud_global_1998] and its biogeochemical elemental cycling (BEC) routines (Moore et al., 2004)[@moore_upper_2004] were used to simulate marine biogeochemistry fields, including particulate organic matter (POC), chlorophyll, and zooplankton concentrations; these fields were used to generate maps of the estimated surface distributions of classes of macromolecules following the methods described in Burrows et al. (2014).[@burrows_physically_2014] The scripts used to accomplish this translation are available [here](https://github.com/E3SM-Project/PreAndPostProcessingScripts/blob/devel/prepare_model_inputfiles/emis/marine_organic_aerosol/JAN_1850_MASTERLANG.jnl).
+
+The file used as an input to E3SM is available here:
+[https://web.lcrc.anl.gov/public/e3sm/inputdata/atm/cam/chem/trop_mam/marine_BGC/monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc](https://web.lcrc.anl.gov/public/e3sm/inputdata/atm/cam/chem/trop_mam/marine_BGC/monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc)
+
+And is also published as a citeable dataset on Zenodo:
+
+Elliott, S. M., Maltrud, M., & Burrows, S. M. (2015). Macromolecule distributions input file for the OCEANFILMS parameterization (Version v1) [Data set]. [Zenodo](https://doi.org/10.5281/zenodo.6320812).
+
+## Oceanic dimethyl sulfide concentrations
+
+Dimethyl sulfide (DMS) fluxes to the atmosphere are calculated in E3SM as a function of prescribed surface oceanic DMS concentrations, and an air-sea flux piston velocity that is a function of wind speed.
+
+E3SM uses a DMS surface concentration dataset developed from a dynamic ocean biogeochemistry simulation; the methods and underlying assumptions used to produce this dataset are documented in Wang, et al. (2015). The resolution in the DMS dataset is 1.9x2.5 degrees.
+
+## New gas species for chemUCI in EAMv3
+
+* Species: C2H4, C2H6, C3H8, CH2O, CH3CHO, CH3COCH3, CO, E90, ISOP, NO, NO2
+* Data sources
+ * anthropogenic, biomass burning, and aircraft emissions (NO2) are regridded from NCAR CESM2 emission files. They are time-dependent during historical period and in the future scenarios.
+ * biogenic emissions (C2H4, C2H6, C3H8, CH2O, CH3CHO, CH3COCH3, CO, ISOP) are from MEGAN-MACC offline data
+ * 1850-1979: monthly input cycled yearly from 30-year mean (1980-2009)
+ * 1980-2014: time-varying MEGAN-MACC data (historical)
+ * 2015-2100: monthly input cycled yearly from 30-year mean (1980-2009)
+ * natural emissions from oceans (C2H4, C2H6, C3H8, CO) and soil (NO) are regridded from NCAR CESM2 emission files. Just cycled yearly during the historical period and in the future scenarios.
+ * E90 emissions?
+
+## Oxidants file needed for VBS SOA and stratosphere sulfate formation
+
+* Species: prsd_O3, prsd_NO3, prsd_OH
+* Data sources
+ * the file for historical simulation is the same as v1 and v2, inherited from CESM
+ * files for SSPs are regridded from NCAR CESM2 tracer files
+
+## Namelist setting for emissions input
+
+### Historical (WCYCL20TR)/AMIP (F20TR)
+
+```fortran
+ ext_frc_specifier = 'NO2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_1750-2015_1.9x2.5_c20170608.nc',
+ 'SO2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_elev_1850-2014_c180205_kzm_1850_2014_volcano.nc',
+ 'SOAG0 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_elev_1850-2014_1.9x2.5_c20230201.nc',
+ 'bc_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_elev_1850-2014_c180205.nc',
+ 'num_a1 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_elev_1850-2014_c180205.nc',
+ 'num_a2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_elev_1850-2014_c180205.nc',
+ 'num_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_elev_1850-2014_c180205.nc',
+ 'pom_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_elev_1850-2014_c180205.nc',
+ 'so4_a1 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_elev_1850-2014_c180205.nc',
+ 'so4_a2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_elev_1850-2014_c180205.nc'
+
+ srf_emis_specifier = 'C10H16 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_MTERP_surface_1850-2014_1.9x2.5_c20230126.nc',
+ 'C2H4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H4_surface_1850-2014_1.9x2.5_c20210323.nc',
+ 'C2H6 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H6_surface_1850-2014_1.9x2.5_c20210323.nc',
+ 'C3H8 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C3H8_surface_1850-2014_1.9x2.5_c20210323.nc',
+ 'CH2O -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH2O_surface_1850-2014_1.9x2.5_c20210323.nc',
+ 'CH3CHO -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3CHO_surface_1850-2014_1.9x2.5_c20210323.nc',
+ 'CH3COCH3 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3COCH3_surface_1850-2014_1.9x2.5_c20210323.nc',
+ 'CO -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CO_surface_1850-2014_1.9x2.5_c20210323.nc',
+ 'DMS -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DMSflux.1850-2100.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20160727.nc',
+ 'E90 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions_E90_surface_1750-2015_1.9x2.5_c20210408.nc',
+ 'ISOP -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc',
+ 'ISOP_VBS -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_1850-2014_1.9x2.5_c20210323.nc',
+ 'NO -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_NO_surface_1850-2014_1.9x2.5_c20220425.nc',
+ 'SO2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_surf_1850-2014_c180205.nc',
+ 'SOAG0 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_surf_1850-2014_1.9x2.5_c20230201.nc',
+ 'bc_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_surf_1850-2014_c180205.nc',
+ 'num_a1 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_surf_1850-2014_c180205.nc',
+ 'num_a2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_surf_1850-2014_c180205.nc',
+ 'num_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_surf_1850-2014_c180205.nc',
+ 'pom_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_surf_1850-2014_c180205.nc',
+ 'so4_a1 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_surf_1850-2014_c180205.nc',
+ 'so4_a2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_surf_1850-2014_c180205.nc'
+
+ tracer_cnst_datapath = '\$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/oxid'
+ tracer_cnst_file = 'oxid_1.9x2.5_L26_1850-2015_c20181106.nc'
+ tracer_cnst_filelist = ''
+ tracer_cnst_specifier = 'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH'
+ tracer_cnst_type = 'INTERP_MISSING_MONTHS'
+```
+
+### F2010
+
+```fortran
+ ext_frc_cycle_yr = 2010
+ ext_frc_specifier = 'NO2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_NO2_aircraft_vertical_2010_clim_1.9x2.5_c20230213.nc',
+ 'SO2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_elev_1x1_2010_clim_c20190821.nc',
+ 'SOAG0 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_elev_2010_clim_1.9x2.5_c20230213.nc',
+ 'bc_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_elev_1x1_2010_clim_c20190821.nc',
+ 'num_a1 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_elev_1x1_2010_clim_c20190821.nc',
+ 'num_a2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_elev_1x1_2010_clim_c20190821.nc',
+ 'num_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_elev_1x1_2010_clim_c20190821.nc',
+ 'pom_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_elev_1x1_2010_clim_c20190821.nc',
+ 'so4_a1 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_elev_1x1_2010_clim_c20190821.nc',
+ 'so4_a2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_elev_1x1_2010_clim_c20190821.nc'
+ ext_frc_type = 'CYCLICAL'
+
+ srf_emis_cycle_yr = 2010
+ srf_emis_specifier = 'C10H16 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_MTERP_surface_2010_clim_1.9x2.5_c20230213.nc',
+ 'C2H4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H4_surface_2010_clim_1.9x2.5_c20230213.nc',
+ 'C2H6 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C2H6_surface_2010_clim_1.9x2.5_c20230213.nc',
+ 'C3H8 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_C3H8_surface_2010_clim_1.9x2.5_c20230213.nc',
+ 'CH2O -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH2O_surface_2010_clim_1.9x2.5_c20230213.nc',
+ 'CH3CHO -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3CHO_surface_2010_clim_1.9x2.5_c20230213.nc',
+ 'CH3COCH3 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CH3COCH3_surface_2010_clim_1.9x2.5_c20230213.nc',
+ 'CO -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_CO_surface_2010_clim_1.9x2.5_c20230213.nc',
+ 'DMS -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DMSflux.2010.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20190220.nc',
+ 'E90 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions_E90_surface_2010_clim_1.9x2.5_c20230213.nc',
+ 'ISOP -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_2010_clim_1.9x2.5_c20230213.nc',
+ 'ISOP_VBS -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_ISOP_surface_2010_clim_1.9x2.5_c20230213.nc',
+ 'NO -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/chem_gases/2degrees/emissions-cmip6_e3sm_NO_surface_2010_clim_1.9x2.5_c20230213.nc',
+ 'SO2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so2_surf_1x1_2010_clim_c20190821.nc',
+ 'SOAG0 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/emissions-cmip6_e3sm_SOAG0_surf_2010_clim_1.9x2.5_c20230213.nc',
+ 'bc_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_bc_a4_surf_1x1_2010_clim_c20190821.nc',
+ 'num_a1 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a1_surf_1x1_2010_clim_c20190821.nc',
+ 'num_a2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a2_surf_1x1_2010_clim_c20190821.nc',
+ 'num_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_num_a4_surf_1x1_2010_clim_c20190821.nc',
+ 'pom_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_pom_a4_surf_1x1_2010_clim_c20190821.nc',
+ 'so4_a1 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a1_surf_1x1_2010_clim_c20190821.nc',
+ 'so4_a2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DECK_ne30/cmip6_mam4_so4_a2_surf_1x1_2010_clim_c20190821.nc'
+ srf_emis_type = 'CYCLICAL'
+
+ tracer_cnst_cycle_yr = 2015
+ tracer_cnst_datapath = '\$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/oxid'
+ tracer_cnst_file = 'oxid_1.9x2.5_L26_1850-2015_c20181106.nc'
+ tracer_cnst_filelist = ''
+ tracer_cnst_specifier = 'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH'
+ tracer_cnst_type = 'CYCLICAL'
+ ```
+
+### Future Scenarios
+
+#### SSP370
+
+```fortran
+ext_frc_specifier = 'NO2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_NO2_aircraft_vertical_2015-2100_1.9x2.5_c20240208.nc',
+ 'SO2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_so2_elev_2015-2100_c210216.nc',
+ 'SOAG0 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_SOAG0_elev_2015-2100_1.9x2.5_c20240208.nc',
+ 'bc_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_bc_a4_elev_2015-2100_c210216.nc',
+ 'num_a1 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_num_a1_elev_2015-2100_c210216.nc',
+ 'num_a2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_num_a2_elev_2015-2100_c210216.nc',
+ 'num_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_num_a4_elev_2015-2100_c210216.nc',
+ 'pom_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_pom_a4_elev_2015-2100_c210216.nc',
+ 'so4_a1 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_so4_a1_elev_2015-2100_c210216.nc',
+ 'so4_a2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_so4_a2_elev_2015-2100_c210216.nc'
+
+srf_emis_specifier = 'C10H16 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_MTERP_surface_2015-2100_1.9x2.5_c20240208.nc',
+ 'C2H4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_C2H4_surface_2015-2100_1.9x2.5_c20240208.nc',
+ 'C2H6 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_C2H6_surface_2015-2100_1.9x2.5_c20240208.nc',
+ 'C3H8 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_C3H8_surface_2015-2100_1.9x2.5_c20240208.nc',
+ 'CH2O -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_CH2O_surface_2015-2100_1.9x2.5_c20240208.nc',
+ 'CH3CHO -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_CH3CHO_surface_2015-2100_1.9x2.5_c20240208.nc',
+ 'CH3COCH3 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_CH3COCH3_surface_2015-2100_1.9x2.5_c20240208.nc',
+ 'CO -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_CO_surface_2015-2100_1.9x2.5_c20240208.nc ',
+ 'DMS -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/DMSflux.1850-2100.1deg_latlon_conserv.POPmonthlyClimFromACES4BGC_c20160727.nc',
+ 'E90 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart/ub/emissions_E90_surface_1750-2101_1.9x2.5_c20231222.nc',
+ 'ISOP -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_ISOP_surface_2015-2100_1.9x2.5_c20240208.nc',
+ 'ISOP_VBS -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_ISOP_surface_2015-2100_1.9x2.5_c20240208.nc',
+ 'NO -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_NO_surface_2015-2100_1.9x2.5_c20240208.nc',
+ 'SO2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_so2_surf_2015-2100_c210216.nc',
+ 'SOAG0 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/emissions-cmip6_ssp370_e3sm_SOAG0_surf_2015-2100_1.9x2.5_c20240208.nc',
+ 'bc_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_bc_a4_surf_2015-2100_c210216.nc',
+ 'num_a1 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_num_a1_surf_2015-2100_c210216.nc',
+ 'num_a2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_num_a2_surf_2015-2100_c210216.nc',
+ 'num_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_num_a4_surf_2015-2100_c210216.nc',
+ 'pom_a4 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_pom_a4_surf_2015-2100_c210216.nc',
+ 'so4_a1 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_so4_a1_surf_2015-2100_c210216.nc',
+ 'so4_a2 -> \$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/emis/CMIP6_SSP370_ne30/cmip6_ssp370_mam4_so4_a2_surf_2015-2100_c210216.nc'
+
+ tracer_cnst_datapath = '\$DIN_LOC_ROOT/atm/cam/chem/trop_mozart_aero/oxid'
+ tracer_cnst_file = 'oxid_SSP370_1.9x2.5_L70_1849-2101_c20240228.nc'
+ tracer_cnst_filelist = ''
+ tracer_cnst_specifier = 'prsd_O3:O3','prsd_NO3:NO3','prsd_OH:OH'
+ tracer_cnst_type = 'INTERP_MISSING_MONTHS'
+```
diff --git a/components/eam/docs/user-guide/index.md b/components/eam/docs/user-guide/index.md
index 81084e869cde..c2bd7f065383 100644
--- a/components/eam/docs/user-guide/index.md
+++ b/components/eam/docs/user-guide/index.md
@@ -1 +1,175 @@
-start of the EAM User's Guide
+
+# EAM User Guide
+
+This User Guide describes how to set up and run EAM.
+
+## Steps to build and run EAM
+
+EAM is not available as a standalone model. Instead, EAM can be run in an atmosphere-only configuration.
+The difference when running in atmosphere-only mode (without an interactive ocean or sea-ice) would be to
+change the *compset* and *grid*.
+See the
+[Case Control System Basic Usage](https://esmci.github.io/cime/versions/master/html/users_guide/index.html#case-control-system-part-1-basic-usage) for general descriptions of compsets and grids.
+
+Certain namelist paramaters, input data files, and output file specifcations can also be modified.
+These are described below as ways to customize runs.
+
+Step-by-step instructions on how to run and analyze E3SM with a script can be found at
+[E3SM step-by-step guide](https://docs.e3sm.org/running-e3sm-guide/)
+
+## Scientifically supported compsets and grids
+
+### Compsets
+
+All of the compsets below run with the complete set of E3SM atmospheric configuration of EAMV3. For more information on the schemes in EAMv3, see the [Technical Guide](../tech-guide/index.md)
+
+`F2010` - Climatological present day climate (year 2010)
+
+`F1850` - Climatological pre-industrial-day climate (year 1850)
+
+`F20TR` - Historical EAM simulation with time varying sea-surface temperatures, aerosol emissions, and greenhouse gas forcings (year 1850-2014)
+
+### Grids
+
+Only one grid combination is currently supported for the above compsets:
+
+`ne30pg2_r05_IcoswISC30E3r5` - ne30pg2 atmosphere, 0.5deg x 0.5deg land grid, and Icosahedral 30 km mesh with ice shelves cavities (wISC), E3SMv3 (E3) revision r5
+
+## Customizing runs
+
+### Compile-time options
+
+Some customizations require making changes before the model is built.
+
+### Run-time options
+
+Run-time customization is enabled by a Fortran namelist.
+
+Namelist parameters can be changed from default values by putting them in the `user_nl_eam` file in the case directory
+with the desired new value.
+
+This [Table of Namelist Parameters](namelist_parameters.md) includes many of the paramaters that control
+physics schemes described in the [tech-guide](../tech-guide/index.md)
+
+#### History File Namelist Parameters
+
+By default, EAM will output a set of monthly-averaged variables. Additional output files can be specified using the following flags in the `user_nl_eam` file:
+
+`finclX` - List of variables (in single quotes and separated by commas) that are added to tape X.
+
+`fexclX` - List of variables (in single quotes and separated by commas) that will be excluded in tape X.
+
+`nhtfrq` - List of write frequencies for each of the history files. A value of 0 denotes a monthly frequency. Negative values denote hourly frequencies (e.g., `-3` will write an output every 3 hours). Positive values denotes the frequency in model timesteps (e.g., `4` will write an output every 4 timesteps).
+
+`mfilt` - List that sets the number of timesteps to write in a single file before starting a new file.
+
+`avgflag_pertape` - List that sets the type of output to write. Choices are `'A'` for time-averaged output, `'A'` for instantaneous output, `'M'` for time-minimum output, and `'X'` for time-maximum output.
+
+#### Example output specification
+
+```fortran
+nhtfrq = 0,-24,-6,-3
+mfilt = 1,30,120,24
+avgflag_pertape = 'A','A','A','I'
+
+fexcl1 = 'U10' # Removes U10 output from monthly files
+fincl2 = 'PS','FLUT','PRECT','U200','V200','U850',
+ 'V850','TCO','SCO','TREFHT','QREFHT' # Output files of daily-averaged output, which includes 30 days of output in each file
+fincl3 = 'PS', 'PSL','PRECT','TUQ','TVQ','UBOT',
+ 'VBOT','TREFHT','FLUT','OMEGA500','TBOT',
+ 'U850','V850','U200','V200','T200','T500',
+ 'Z700' # Output files of 6-hour-averaged output, which includes 30 days of output in each file
+fincl4 = 'PRECT' # Output files of 3-hourly output with 3 days of output in every file
+```
+
+## Input datasets
+
+Many properties of the simulated atmosphere are controlled by data sets read in by the model during initialization.
+Changing the content of these files is another way to customize a run.
+
+### Greenhouse gases (non-reacting)
+
+Greenhouse gas concentration inputs of non-reacting species are taken from CMIP6 Forcing Datasets provided from the input4MIPs data collection. In addition to what is provided by the input4MIPS, 2015 and 2016 have been added by extrapolating from 2013 and 2014.
+
+```fortran
+inputdata/atm/cam/ggas/GHG_CMIP-1-2-0_Annual_Global_0000-2014_c20180105.nc
+```
+
+### [Aerosol physical properties](aerosol_phys_prop.md)
+
+The aerosol properties files provide aerosol refractive index, density, and aerosol hygroscopicty information for
+each aerosol species, as well as information about lognormal mode definition and lookup tables of polynomial
+expression coefficients for aerosol optics calculation for each mode. These aerosol physical and chemical properties
+are used by the radiation, aerosol microphysics and other related source and sink processes, and droplet
+activation/ice nucleation schemes.
+
+### [Aerosol and gas emission and oxidant files](emission_oxidant_files.md)
+
+Details of the aerosol and gas emission and oxidant files used in various historical, present-day, and future scenarios.
+
+### Linoz v3 input files
+
+Linozv3 uses the ozone tendency, (net production minus loss) calculated from its climatological mean state (function of month, latitude, altitude) and a first-order Taylor series expansion about the local ozone, temperature, and overhead ozone column. For historical simulation, Linozv3 uses the linozv3 data files with monthly resolution, spanning the dates 1849-01 -- 2014-12.
+
+#### Historical files
+
+```fortran
+ linoz_data_file = ‘linv3_1849-2101_CMIP6_Hist_10deg_58km_c20231207.nc’
+ linoz_data_path = '/lcrc/group/e3sm/data/inputdata/atm/cam/chem/trop_mozart/ub'
+ linoz_data_type = 'INTERP_MISSING_MONTHS'
+```
+
+Refer to [this page](https://acme-climate.atlassian.net/wiki/spaces/DOC/pages/3764486280/Production+of+the+Linoz+v3+data) for more details on Linoz v3 input files.
+
+### Topography
+
+The global elevation on the atmosphere grid is a key input dataset. The dataset is grid dependent. It contains the geopotential data (on both the GLL dynamics and PG2 physics grids) and two surface roughness quantities, `SGH` and `SGH30`.
+
+EAMv3 NE30 data:
+
+```fortran
+inputdata/atm/cam/topo/USGS-gtopo30_ne30np4pg2_x6t-SGH.c20210614.nc'
+```
+
+This file is computed via a complex procedure that starts with high resolution dataset (for EAMv3, we use the GTOPO30, a 30 arc-second resolution data set on a lat-lon grid) that is then downsampled to a 3km cubed-sphere grid (cube3000) and then downsampled to the atmosphere grid on the (GLL nodes), and then smoothed with the same viscosity operator used by the dycore. The smoothed GLL topography is then mapped to the PG2 grid. Finally, two different surface roughness fields are computed:
+
+- `SGH30`: the variance between GTOPO30 and GTOPO30-downsampled-to-PG2 (independent of any dycore specific smoothing). (used by CLUBB, TMS, vertical_diffusion)
+- `SGH`: the variance between the cube3000 data and the smoothed PG2 data. (used by GWD parameterizations)
+
+### Land-use / land cover change
+
+Info needed on land-use land cover change / land surface data
+
+Refer to [ELM documentation](https://docs.e3sm.org/E3SM/ELM/).
+
+### Ocean/sea ice
+
+The sea surface temperature and sea-ice coverage data used in F-case simulations are based on CMIP6 Forcing Datasets provided from the input4MIPs data collection. The file for the `F2010` compset is created from taking a monthly climatology of years 2005-2014. The file for the `F1850` compset is created from taking a monthly climatology of years 1870-1879.*
+
+*[Provenenance for F1850 file](https://acme-climate.atlassian.net/wiki/spaces/ATM/pages/201525378/Provenance+for+CMIP6+DECK+SST+Sea-Ice+input+data+for+E3SM)
+
+`F20TR`
+
+```fortran
+inputdata/ocn/docn7/SSTDATA/sst_ice_CMIP6_DECK_E3SM_1x1_c20180213.nc
+```
+
+`F2010`
+
+```fortran
+inputdata/ocn/docn7/SSTDATA/sst_ice_CMIP6_DECK_E3SM_1x1_2010_clim_c20190821.nc
+```
+
+`F1850`
+
+```fortran
+inputdata/ocn/docn7/SSTDATA/sst_ice_CMIP6_DECK_E3SM_1x1_1850_clim_c20190125.nc
+```
+
+### Solar input
+
+As with greenhouse gas emissions, solar input files are taken from the input4MIPs data collection that were prepared for CMIP6 Forcing Datasets.
+
+```fortran
+inputdata/atm/cam/solar/Solar_1850-2299_input4MIPS_c20181106.nc
+```
diff --git a/components/eam/docs/user-guide/namelist_parameters.md b/components/eam/docs/user-guide/namelist_parameters.md
new file mode 100644
index 000000000000..b09e8c44ffde
--- /dev/null
+++ b/components/eam/docs/user-guide/namelist_parameters.md
@@ -0,0 +1,158 @@
+
+# Namelist parameters associated with atmosphere schemes
+
+## chemUCI and Linoz v3
+
+| Parameter | Description | Default value* |
+| ---------------------------- | ------------------------------------------------------------------------ | ---------------------- |
+| `airpl_emis_file` | Aviation emission | |
+| `chlorine_loading_file` | Chlorine loading | |
+| `chlorine_loading_fixed_ymd` | | |
+| `chlorine_loading_type` | | |
+| `ext_frc_specifier` | 3-D emissions | |
+| `ext_frc_cycle_yr` | | |
+| `ext_frc_type` | | |
+| `srf_emis_specifier` | Surface emissions | |
+| `srf_emis_cycle_yr` | | |
+| `srf_emis_type` | Upper bound of mean raindrop diameter | |
+| `linoz_data_file` | Linoz data file | |
+| `linoz_data_cycle_yr` | | |
+| `linoz_data_path` | | |
+| `linoz_data_type` | | |
+| `lght_no_prd_factor` | Lightning NOx emission factor | `5.0` |
+| `fstrat_efold_list` | Tracer (from troposphere) list with e-folding decay in the stratosphere | |
+
+* Many of these namelist parameters specify input data files. Check the `atm_in` file for examples or refer to the [Users' Guide](../user-guide/index.md).
+
+## Cloud Layers Unified By Binormals
+
+| Parameter | Description | Default value |
+| -------------- | ------------------------------------------------------------------------------------------- | -------------- |
+| `gamma_coef` | Width of vertical velocity within a Gaussian PDF component at low skewness | `0.12` |
+| `gamma_coefb` | Width of vertical velocity within a Gaussian PDF component at high skewness | `0.28` |
+| `C8` | Coefficient of damping of third moment of vertical velocity, w’3 | `5.2` |
+| `C1` | Coefficient of damping of second vertical moment of vertical velocity, w’2, at low skewness | `2.4` |
+| `C14` | Coefficient of damping of second horizontal moments of vertical velocity, u’2 and v’2 | `2.0` |
+| `c_k10` | Ratio of diffusivity of momentum to heat | `0.35` |
+
+## Dust aerosol
+
+| Parameter | Description | Default value |
+| ------------------------- | ---------------------------------------------- | ------------------------------------------------- |
+| `dust_emis_scheme`* | The v3 dust emission scheme (Kok et al., 2014) | `2`
(set to 1 to switch to the v1/v2 scheme) |
+
+*This parameter is set in `user_nl_drv`
+
+## HOMME
+
+| Parameter | Description | Default value |
+| ---------------- | ------------------------------------------------------------------------------------------- | -------------- |
+| `se_tstep` | Main dycore timestep. Additional parameters control the hyper viscsosity, trancer and vertical remap timesteps, which are derived from se_tstep.
units = seconds | Scales linearly with horizontal resolution.
NE30 default: `300` |
+| `nu` | Tensor hyperviscosity coefficient, independent of spatial resolution.
units = 1/s | `3.4e-8` |
+| `nu_top` | Scalar viscosity at model top.
units = m^2/s | Horizontal resolution dependent
NE30 default: `2.5e5` |
+| `transport_alg` | Select between semi-lagrangian and Eulerian based transport schemes | `12` = semi-lagranian method with monotinicity and mass preservation |
+| `statefreq` | print a varieity of dycore metrics to the atm.log file every “statefreq” timesteps | `480` |
+| `vert_remap_alg` | Algorithm used to remap the vertically lagrangian levels back to the reference levels | `10` = strict monotonicity applied on top of a 2nd order accurate PPM method |
+| `se_ftype` | Controls how physics tendencies are applied. 0=”dribbled” in during dynamics timesteps. 1=”hard adjustment” after each physics timestep. 2=hybrid approach: hard adjustment for tracers, dribbled for remaining tendencies | `2` |
+
+## Modal Aerosol Module
+
+| Parameter | Description | Default value |
+| ------------------------ | ----------------------------------------------------------------------------------- | --------------------------- |
+| `is_output_interactive_volc` | Switch for diagnostic output of the stratospheric aerosol optics | `.false.` |
+| `mam_amicphys_optaa` | Recommended option of the new time-splitting treatment of H2SO4 production and loss | `1`
(0 to turn it off) |
+| `n_so4_monolayers_pcage` | Number of monolayers required to age primary-carbon mode particles | `3` |
+| `seasalt_emis_scale` | Tuning parameter for sea salt emission | `0.55` |
+
+## OCEANFILMS
+
+| Parameter | Description | Default value |
+| ------------------------- | ----------------------------------------------------------------- | ---------------------- |
+| `mam_mom_cycle_yr` | | `1` |
+| `mam_mom_datapath` | Full pathname of the directory that contains the files specified in mam_mom_filelist | `'atm/cam/chem/trop_mam/marine_BGC/'` |
+| `mam_mom_filename` | Filename of file that contains a sequence of filenames for prescribed marine organic matter ocean concentrations. The filenames in this file are relative to the directory specified by mam_mom_datapath.| `'monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc'` |
+| `mam_mom_rmfile` | Remove the file containing prescribed aerosol deposition fluxes from local disk when no longer needed. | `FALSE` |
+| `mam_mom_specifier` | Names of variables containing aerosol data in the prescribed aerosol datasets. | `'chla:CHL1','mpoly:TRUEPOLYC','mprot:TRUEPROTC','mlip:TRUELIPC'` |
+| `mam_mom_datatype` | Type of time interpolation for data in mam_mom files. Can be set to `'CYCLICAL'`, `'SERIAL'`, `'INTERP_MISSING_MONTHS'`, or `'FIXED'`. | `'CYCLICAL'` |
+| `mam_mom_cycle_yr` | The cycle year of the prescribed aerosol flux data if mam_mom_type is `'CYCLICAL'`. Format: YYYY | `1` |
+| `mam_mom_fixed_ymd` | The date at which the prescribed aerosol flux data is fixed if mam_mom_type is `'FIXED'`. Format: YYYYMMDD | `0` |
+| `mam_mom_fixed_tod` | The time of day (seconds) corresponding to mam_mom_fixed_ymd at which the prescribed aerosol flux data is fixed if mam_mom_type is 'FIXED'. | `0` |
+| `mam_mom_bubble_thickness` | Bubble film thickness (in m) for marine organic aerosol emission mechanism. The physically reasonable range is approximately (0.1 - 1) x 10^ -6. | `0.1e-6` |
+| `mam_mom_mixing_state` | Switch to select mixing state assumption in marine organic aerosol code. Currently implemented options: 0 : total external mixture, add to mass; 1 : total external mixture, replace mass; 2 : total internal mixture, add to mass; 3 : total internal mixture, replace mass. | `0` [Note: set to 3 in the atm_in namelist] |
+| `mam_mom_parameterization` | Selection of alternate parameterizations for marine organic matter emissions. Set fmoa=1 for Burrows et al. (2014) [@burrows_physically_2014] parameterization; fmoa=2 for Gantt et al. (2011) [@gantt_wind_2011] parameterization; fmoa=3 for simple parameterization based on Quinn et al., 2014; [@quinn_contribution_2014] fmoa=4 for Rinaldi et al. (JGR, 2013).* [@rinaldi_is_2013] | `1` |
+
+*Note: non-default values have not been carefully tested and may not work as expected.
+
+## Predicted Particle Properties
+
+| Parameter | Description | Default value |
+| ------------------------- | ----------------------------------------------------------------- | ---------------------- |
+| `do_prescribed_ccn` | Turn on the prescribed CCN if true | `false` |
+| `micro_aerosolactivation` | Turn on aerosol activation if true | `true` |
+| `micro_p3_lookup_dir` | Directory of P3 look-up tables | `inputdata/atm/cam/physprops` |
+| `micro_p3_tableversion` | P3 look-up table Version | `4.1.2` |
+| `micro_subgrid_cloud` | Sub-grid cloud properties | `true` |
+| `micro_tend_output` | Output of P3 microphysical process rates | `false` |
+| `p3_accret_coeff` | Tunable parameter for adjusting rain accretion efficiency | `117.25` |
+| `p3_autocon_coeff` | Tunable parameter for adjusting droplet autoconversion efficiency | `30500` |
+| `p3_embryonic_rain_size` | Radius of embryomic raindrops from auto-conversion | `0.000025` (m) |
+| `p3_max_mean_rain_size` | Upper bound of mean raindrop diameter | `0.005` (m) |
+| `p3_mincdnc` | Lower bound of droplet number concentration | `20.d6` (# m-3) |
+| `p3_nc_autocon_expon` | Nc exponent in droplet auto-conversion | `-1.1` |
+| `p3_qc_accret_expon` | Qc exponent in rain accretion | `1.15` |
+| `p3_qc_autocon_expon` | Qc exponeent in droplet autoconversion | `3.19` |
+| `p3_wbf_coeff` | Tunable parameter for adjusting WBF efficiency | `1.0` |
+| `do_cooper_inp3` | Turn on Cooper ice nucleation scheme if true | `false` |
+
+## Rapid Radiative Transfer Model for GCMs
+
+| Parameter | Description | Default value |
+| ------------------------- | ----------------------------------------------------------------- | ---------------------- |
+| `iradsw` | Frequency for updating shortwave fluxes and heating rate; iradsw > 0 interpreted as number of timesteps, iradsw < 0 interpreted as hours; iradsw = 0 disables shortwave radiation entirely | `-1` |
+| `iradlw` | Frequency for updating longwave fluxes and heating rate; iradlw > 0 interpreted as number of timesteps, iradlw < 0 interpreted as hours; iradlw = 0 disables longwave radiation entirely | `-1` |
+| `irad_always` | Length of time in timesteps (irad_always > 0) or in hours (irad_always < 0) SW/LW radiation will be run continuously from the start of an initial or restart run | `0` |
+| `use_rad_dt_cosz` | If true, use the radiation dt for all cosz calculations; calculates solar zenith angle averaged over a time step. In default model solar zenith angle is held constant over time | `.true.`
(set by namelist_defaults_eam.xml for default physics) |
+| `spectralflux` | Calculate fluxes (up and down) per band | `.false.` |
+| `liqcldoptics` | Choice of cloud optical property parameterization for liquid clouds. Valid options are ‘slingo’ or ‘gammadist’ | `gammadist` |
+| `icecldoptics` | Choice of cloud optical property parameterization for ice clouds. Valid options are ‘ebertcurry’ or ‘mitchell’ | `mitchell` |
+
+## Zhang and McFarlane deep convection scheme
+
+| ZM Parameters | Description | Default value |
+| ------------------------- | ----------------------------------------------------------------- | ---------------------- |
+| `zmconv_ke` | Tunable evaporation efficiency in ZM deep convection scheme | `2.5E-6` |
+| `zmconv_tau` | Relaxation time in ZM deep convection scheme | `3600` |
+| `zmconv_dmpdz` | Parcel fractional mass entrainment rate | `-0.7E-3` |
+| `zmconv_alfa` | Initial downdraft mass flux fraction | `0.14D0` |
+| `zmconv_tiedke_add` | Temperature perturbation of an air parcel | `0.8D0` |
+| `zmconv_cape_cin` | Number of negative buoyancy regions that are allowed | `1` |
+
+| dCAPE-ULL Parameters | Description | Default value |
+| ------------------------- | ----------------------------------------------------------------- | ---------------------- |
+| `zmconv_trigdcape_ull` | DCAPE trigger along with unrestricted launching level for ZM deep convection scheme | `.true.` |
+| `zmconv_trig_dcape_only` | DCAPE only trigger for ZM deep convection scheme | `.false.`
If true, zmconv_trigdcape_ull must be false to use the dcape only trigger. |
+| `zmconv_trig_ull_only` | Use unrestricted launching level (ULL) only trigger for ZM deep convection scheme | `.false.`
If true, zmconv_trigdcape_ull must be false to use the ull only trigger. |
+
+| Conv. micro. Parameters | Description | Default value |
+| ------------------------- | ----------------------------------------------------------------- | ---------------------- |
+| `zmconv_microp` | Convective microphysics option in ZM convection scheme | `true` |
+| `zmconv_auto_fac` | Cloud droplet-rain autoconversion enhancement factor in the convective microphysics scheme | `7.0` |
+| `zmconv_accr_fac` | Cloud droplet-rain accretion enhancement factor in the convective microphysics scheme | `1.5` |
+| `zmconv_micro_dcs` | Autoconversion size threshold for cloud ice to snow (m) | `150.E-6` |
+
+| Mass flux adj. Parameters | Description | Default value |
+| ------------------------- | ----------------------------------------------------------------- | ---------------------- |
+| `zmconv_clos_dyn_adj` | Apply mass flux adjustment to ZM convection scheme | `true` |
+
+| MCSP Parameters | Description | Default value |
+| ---------------------------- | ----------------------------------------------------------------- | ---------------------- |
+| `zmconv_mcsp_heat_coeff` | MCSP heating coefficient | `0.3` |
+| `zmconv_mcsp_moisture_coeff` | MCSP moisture coefficient | `0.0` |
+| `zmconv_mcsp_uwind_coeff` | MCSP zonal wind coefficient | `0.0` |
+| `zmconv_mcsp_vwind_coeff` | MCSP meridional wind coefficient | `0.0` |
+
+## Cloud Feedback Model Intercomparison Project (CFMIP) Observation Simulator Package
+
+| Parameter | Description | Default value |
+| ------------------------- | ----------------------------------------------------------------- | ---------------------- |
+| `cosp_lite` | This namelist sets cosp_ncolumns=10 and cosp_nradsteps=3 (appropriate for COSP statistics derived from seasonal averages), and runs MISR, ISCCP, MODIS, and CALIPSO lidar simulators (cosp_lmisr_sim=.true.,cosp_lisccp_sim=.true., cosp_lmodis_sim=.true.,cosp_llidar_sim=.true.). | `false` |
diff --git a/components/eam/mkdocs.yml b/components/eam/mkdocs.yml
index f64ab33620fa..c310e410285b 100644
--- a/components/eam/mkdocs.yml
+++ b/components/eam/mkdocs.yml
@@ -2,6 +2,23 @@ site_name: EAM
nav:
- Introduction: 'index.md'
- - Users's Guide: user-guide/index.md
- - Developers's Guide: dev-guide/index.md
- - Technical Guide: tech-guide/index.md
+ - User Guide:
+ - user-guide/index.md
+ - Namelist Parameters: user-guide/namelist_parameters.md
+ - Aerosol Properties: user-guide/aerosol_phys_prop.md
+ - Emission Oxidants: user-guide/emission_oxidant_files.md
+ - Developer Guide: dev-guide/index.md
+ - Technical Guide:
+ - tech-guide/index.md
+ - tech-guide/homme.md
+ - tech-guide/p3.md
+ - tech-guide/clubb.md
+ - tech-guide/zm.md
+ - RRTMG: tech-guide/rrtmg.md
+ - tech-guide/mam.md
+ - tech-guide/vbs.md
+ - tech-guide/dust.md
+ - tech-guide/oceanfilms.md
+ - tech-guide/chemUCIlinozv3.md
+ - COSP: tech-guide/cosp.md
+ - tech-guide/armdiags.md
diff --git a/components/eam/src/chemistry/mozart/chemistry.F90 b/components/eam/src/chemistry/mozart/chemistry.F90
index 57412d8f8189..f78ceda1dea7 100644
--- a/components/eam/src/chemistry/mozart/chemistry.F90
+++ b/components/eam/src/chemistry/mozart/chemistry.F90
@@ -1574,44 +1574,43 @@ subroutine chem_timestep_tend( state, ptend, cam_in, cam_out, dt, pbuf, fh2o, f
end if
! HHLEE 20210923
if (history_gaschmbudget_2D_levels .or. history_chemdyg_summary) then
- ftem_layers = 0.0_r8
- gas_ac_layers = 0.0_r8
-
- gas_ac_idx = pbuf_get_index(gas_ac_name(n))
- call pbuf_get_field(pbuf, gas_ac_idx, gas_ac )
+ ftem_layers = 0.0_r8
+ gas_ac_layers = 0.0_r8
+ if( nstep /= 0 ) then
+ gas_ac_idx = pbuf_get_index(gas_ac_name(n))
+ call pbuf_get_field(pbuf, gas_ac_idx, gas_ac )
- if (gaschmbudget_2D_L1_e .lt. gaschmbudget_2D_L1_s .or. gaschmbudget_2D_L2_e .lt. gaschmbudget_2D_L2_s .or. &
- gaschmbudget_2D_L3_e .lt. gaschmbudget_2D_L3_s .or. gaschmbudget_2D_L4_e .lt. gaschmbudget_2D_L4_s ) then
- call endrun('chem_readnl: ERROR 2D chem diags layers, layer ending index is less than starting index')
- end if
+ if (gaschmbudget_2D_L1_e .lt. gaschmbudget_2D_L1_s .or. gaschmbudget_2D_L2_e .lt. gaschmbudget_2D_L2_s .or. &
+ gaschmbudget_2D_L3_e .lt. gaschmbudget_2D_L3_s .or. gaschmbudget_2D_L4_e .lt. gaschmbudget_2D_L4_s ) then
+ call endrun('chem_readnl: ERROR 2D chem diags layers, layer ending index is less than starting index')
+ end if
- do k= gaschmbudget_2D_L1_s, gaschmbudget_2D_L1_e ! 0-90 hPa
- ftem_layers(:ncol,1) = ftem_layers(:ncol,1) + ftem(:ncol,k)
- gas_ac_layers(:ncol,1) = gas_ac_layers(:ncol,1) + gas_ac(:ncol,k)
- end do
- do k= gaschmbudget_2D_L2_s, gaschmbudget_2D_L2_e ! 90-300 hPa
- ftem_layers(:ncol,2) = ftem_layers(:ncol,2) + ftem(:ncol,k)
- gas_ac_layers(:ncol,2) = gas_ac_layers(:ncol,2) + gas_ac(:ncol,k)
- end do
- do k= gaschmbudget_2D_L3_s, gaschmbudget_2D_L3_e ! 300-850 hPa
- ftem_layers(:ncol,3) = ftem_layers(:ncol,3) + ftem(:ncol,k)
- gas_ac_layers(:ncol,3) = gas_ac_layers(:ncol,3) + gas_ac(:ncol,k)
- end do
- do k= gaschmbudget_2D_L4_s, gaschmbudget_2D_L4_e ! 850 hPa - surface
- ftem_layers(:ncol,4) = ftem_layers(:ncol,4) + ftem(:ncol,k)
- gas_ac_layers(:ncol,4) = gas_ac_layers(:ncol,4) + gas_ac(:ncol,k)
- end do
+ do k= gaschmbudget_2D_L1_s, gaschmbudget_2D_L1_e ! 0-90 hPa
+ ftem_layers(:ncol,1) = ftem_layers(:ncol,1) + ftem(:ncol,k)
+ gas_ac_layers(:ncol,1) = gas_ac_layers(:ncol,1) + gas_ac(:ncol,k)
+ end do
+ do k= gaschmbudget_2D_L2_s, gaschmbudget_2D_L2_e ! 90-300 hPa
+ ftem_layers(:ncol,2) = ftem_layers(:ncol,2) + ftem(:ncol,k)
+ gas_ac_layers(:ncol,2) = gas_ac_layers(:ncol,2) + gas_ac(:ncol,k)
+ end do
+ do k= gaschmbudget_2D_L3_s, gaschmbudget_2D_L3_e ! 300-850 hPa
+ ftem_layers(:ncol,3) = ftem_layers(:ncol,3) + ftem(:ncol,k)
+ gas_ac_layers(:ncol,3) = gas_ac_layers(:ncol,3) + gas_ac(:ncol,k)
+ end do
+ do k= gaschmbudget_2D_L4_s, gaschmbudget_2D_L4_e ! 850 hPa - surface
+ ftem_layers(:ncol,4) = ftem_layers(:ncol,4) + ftem(:ncol,k)
+ gas_ac_layers(:ncol,4) = gas_ac_layers(:ncol,4) + gas_ac(:ncol,k)
+ end do
+ endif
if (history_gaschmbudget_2D_levels ) then
- call outfld(trim(solsym(n))//'_2DMSB_L1', ftem_layers(:ncol,1), pcols, lchnk)
- call outfld(trim(solsym(n))//'_2DMSB_L2', ftem_layers(:ncol,2), pcols, lchnk)
- call outfld(trim(solsym(n))//'_2DMSB_L3', ftem_layers(:ncol,3), pcols, lchnk)
- call outfld(trim(solsym(n))//'_2DMSB_L4', ftem_layers(:ncol,4), pcols, lchnk)
+ call outfld(trim(solsym(n))//'_2DMSB_L1', ftem_layers(:ncol,1), pcols, lchnk)
+ call outfld(trim(solsym(n))//'_2DMSB_L2', ftem_layers(:ncol,2), pcols, lchnk)
+ call outfld(trim(solsym(n))//'_2DMSB_L3', ftem_layers(:ncol,3), pcols, lchnk)
+ call outfld(trim(solsym(n))//'_2DMSB_L4', ftem_layers(:ncol,4), pcols, lchnk)
endif
- if( nstep == 0 ) then
- Diff_layers(:ncol,:) = 0.0_r8
- else
- Diff_layers(:ncol,:) = 0.0_r8
+ Diff_layers(:ncol,:) = 0.0_r8
+ if( nstep /= 0 ) then
Diff_layers(:ncol,1) = (ftem_layers(:ncol,1) - gas_ac_layers(:ncol,1))/dt
Diff_layers(:ncol,2) = (ftem_layers(:ncol,2) - gas_ac_layers(:ncol,2))/dt
Diff_layers(:ncol,3) = (ftem_layers(:ncol,3) - gas_ac_layers(:ncol,3))/dt
@@ -1629,18 +1628,18 @@ subroutine chem_timestep_tend( state, ptend, cam_in, cam_out, dt, pbuf, fh2o, f
trim(solsym(n))=='N2OLNZ' .or. trim(solsym(n))=='CH4LNZ') then
ftem_layers = 0.0_r8
gas_ac_layers = 0.0_r8
- do k=1,pver
- ftem_layers(:ncol,1) = ftem_layers(:ncol,1) + ftem(:ncol,k) * tropFlagInt(:ncol,k)
- gas_ac_layers(:ncol,1) = gas_ac_layers(:ncol,1) + gas_ac(:ncol,k) * tropFlagInt(:ncol,k)
- end do
+ if( nstep /= 0 ) then
+ do k=1,pver
+ ftem_layers(:ncol,1) = ftem_layers(:ncol,1) + ftem(:ncol,k) * tropFlagInt(:ncol,k)
+ gas_ac_layers(:ncol,1) = gas_ac_layers(:ncol,1) + gas_ac(:ncol,k) * tropFlagInt(:ncol,k)
+ end do
+ endif
if (history_gaschmbudget_2D_levels ) then
- call outfld(trim(solsym(n))//'_2DMSB_trop', ftem_layers(:ncol,1), pcols, lchnk )
+ call outfld(trim(solsym(n))//'_2DMSB_trop', ftem_layers(:ncol,1), pcols, lchnk )
endif
-
- if( nstep == 0 ) then
- Diff_layers(:ncol,:) = 0.0_r8
- else
- Diff_layers(:ncol,:) = 0.0_r8
+
+ Diff_layers(:ncol,:) = 0.0_r8
+ if( nstep /= 0 ) then
Diff_layers(:ncol,1) = (ftem_layers(:ncol,1) - gas_ac_layers(:ncol,1))/dt
end if
diff --git a/components/eam/src/chemistry/mozart/mo_chm_diags.F90 b/components/eam/src/chemistry/mozart/mo_chm_diags.F90
index 8154d4ff3e90..6ae4cfe2f656 100644
--- a/components/eam/src/chemistry/mozart/mo_chm_diags.F90
+++ b/components/eam/src/chemistry/mozart/mo_chm_diags.F90
@@ -1488,16 +1488,16 @@ subroutine chm_diags( lchnk, ncol, vmr, mmr, rxt_rates, invariants, depvel, depf
call outfld( 'Mass_'//trim(aerosol_name(aerosol_idx))//'_srf', mass_3d_tmp(:ncol,pver), ncol, lchnk )
- call vertinterp(ncol, pcols, pver, pmid, 85000._r8, mass_3d_tmp, mass_at_pressure)
+ call vertinterp(ncol, ncol, pver, pmid(:ncol,:), 85000._r8, mass_3d_tmp, mass_at_pressure)
call outfld( 'Mass_'//trim(aerosol_name(aerosol_idx))//'_850', mass_at_pressure, ncol, lchnk )
- call vertinterp(ncol, pcols, pver, pmid, 50000._r8, mass_3d_tmp, mass_at_pressure)
+ call vertinterp(ncol, ncol, pver, pmid(:ncol,:), 50000._r8, mass_3d_tmp, mass_at_pressure)
call outfld( 'Mass_'//trim(aerosol_name(aerosol_idx))//'_500', mass_at_pressure, ncol, lchnk )
- call vertinterp(ncol, pcols, pver, pmid, 33000._r8, mass_3d_tmp, mass_at_pressure)
+ call vertinterp(ncol, ncol, pver, pmid(:ncol,:), 33000._r8, mass_3d_tmp, mass_at_pressure)
call outfld( 'Mass_'//trim(aerosol_name(aerosol_idx))//'_330', mass_at_pressure, ncol, lchnk )
- call vertinterp(ncol, pcols, pver, pmid, 20000._r8, mass_3d_tmp, mass_at_pressure)
+ call vertinterp(ncol, ncol, pver, pmid(:ncol,:), 20000._r8, mass_3d_tmp, mass_at_pressure)
call outfld( 'Mass_'//trim(aerosol_name(aerosol_idx))//'_200', mass_at_pressure, ncol, lchnk )
end do
diff --git a/components/eam/src/control/cam_history.F90 b/components/eam/src/control/cam_history.F90
index c1b66c734d4e..1d7d84245c77 100644
--- a/components/eam/src/control/cam_history.F90
+++ b/components/eam/src/control/cam_history.F90
@@ -2727,7 +2727,7 @@ subroutine patch_init(t)
end if
do i = 1, size(tape(t)%grid_ids)
call cam_grid_compute_patch(tape(t)%grid_ids(i), patchptr%patches(i),&
- beglon, endlon, beglat, endlat)
+ beglon, endlon, beglat, endlat, collect_column_output(t))
end do
nullify(patchptr)
end do
diff --git a/components/eam/src/control/runtime_opts.F90 b/components/eam/src/control/runtime_opts.F90
index 27dd2931a097..c52c02a5c238 100644
--- a/components/eam/src/control/runtime_opts.F90
+++ b/components/eam/src/control/runtime_opts.F90
@@ -275,6 +275,7 @@ subroutine read_namelist(single_column_in, scmlon_in, scmlat_in, scm_multcols_in
use cam_diagnostics, only: diag_readnl
use nudging, only: nudging_readnl
use radheat, only: radheat_readnl
+ use phys_grid_ctem, only: phys_grid_ctem_readnl
#if ( defined OFFLINE_DYN )
use metdata, only: metdata_readnl
#endif
@@ -540,6 +541,7 @@ subroutine read_namelist(single_column_in, scmlon_in, scmlat_in, scm_multcols_in
call nudging_readnl(nlfilename)
call radheat_readnl(nlfilename)
call vd_readnl(nlfilename)
+ call phys_grid_ctem_readnl(nlfilename,dtime)
#if ( defined OFFLINE_DYN )
call metdata_readnl(nlfilename)
#endif
diff --git a/components/eam/src/dynamics/se/inital.F90 b/components/eam/src/dynamics/se/inital.F90
index 7d4c7b946bd8..552568a070ba 100644
--- a/components/eam/src/dynamics/se/inital.F90
+++ b/components/eam/src/dynamics/se/inital.F90
@@ -25,6 +25,7 @@ subroutine cam_initial(dyn_in, dyn_out, NLFileName)
use startup_initialconds, only: initial_conds
use cam_logfile, only: iulog
use perf_mod, only: t_startf, t_stopf
+ use phys_grid_ctem, only: phys_grid_ctem_reg
! modules from SE
use parallel_mod, only : par
@@ -42,6 +43,9 @@ subroutine cam_initial(dyn_in, dyn_out, NLFileName)
if(par%masterproc ) write(iulog,*) 'Running phys_grid_init()'
call phys_grid_init()
+ ! Register zonal average grid for phys TEM diagnostics
+ call phys_grid_ctem_reg()
+
! Initialize index values for advected and non-advected tracers
call phys_register()
diff --git a/components/eam/src/dynamics/se/restart_dynamics.F90 b/components/eam/src/dynamics/se/restart_dynamics.F90
index 8412da32d335..5fce98b2d4b2 100644
--- a/components/eam/src/dynamics/se/restart_dynamics.F90
+++ b/components/eam/src/dynamics/se/restart_dynamics.F90
@@ -379,6 +379,7 @@ subroutine read_restart_dynamics (File, dyn_in, dyn_out, NLFileName)
use spmd_dyn, only: spmd_readnl
use control_mod, only: qsplit
use time_mod, only: TimeLevel_Qdp
+ use phys_grid_ctem, only: phys_grid_ctem_reg
!
! Input arguments
@@ -413,6 +414,9 @@ subroutine read_restart_dynamics (File, dyn_in, dyn_out, NLFileName)
if(par%masterproc ) write(iulog,*) 'Running phys_grid_init()'
call phys_grid_init()
+ ! Register zonal average grid for phys TEM diagnostics
+ call phys_grid_ctem_reg()
+
! Initialize index values for advected and non-advected tracers
call phys_register()
diff --git a/components/eam/src/dynamics/se/se_iop_intr_mod.F90 b/components/eam/src/dynamics/se/se_iop_intr_mod.F90
index 02862980053c..b77ef1540d4c 100644
--- a/components/eam/src/dynamics/se/se_iop_intr_mod.F90
+++ b/components/eam/src/dynamics/se/se_iop_intr_mod.F90
@@ -56,7 +56,7 @@ subroutine iop_setinitial(elem)
integer i, j, k, cix, ie, thelev
integer inumliq, inumice, icldliq, icldice
- if (.not. use_replay .and. get_nstep() .eq. 0 .and. par%dynproc) then
+ if (get_nstep() .eq. 0 .and. par%dynproc) then
call cnst_get_ind('NUMLIQ', inumliq, abrtf=.false.)
call cnst_get_ind('NUMICE', inumice, abrtf=.false.)
call cnst_get_ind('CLDLIQ', icldliq)
@@ -215,8 +215,7 @@ subroutine iop_setfield(elem,iop_update_phase1)
integer i, j, k, ie
do ie=1,nelemd
- if (have_ps .and. use_replay .and. .not. iop_update_phase1) elem(ie)%state%ps_v(:,:,:) = psobs
- if (have_ps .and. .not. use_replay) elem(ie)%state%ps_v(:,:,:) = psobs
+ if (have_ps) elem(ie)%state%ps_v(:,:,:) = psobs
do i=1, PLEV
! If DP CRM mode do NOT write over dycore vertical velocity
if ((have_omega .and. iop_update_phase1) .and. .not. dp_crm) elem(ie)%derived%omega_p(:,:,i)=wfld(i) ! set t to tobs at first
diff --git a/components/eam/src/dynamics/se/stepon.F90 b/components/eam/src/dynamics/se/stepon.F90
index 831fd6d87603..783122d31473 100644
--- a/components/eam/src/dynamics/se/stepon.F90
+++ b/components/eam/src/dynamics/se/stepon.F90
@@ -526,9 +526,10 @@ subroutine stepon_run3(dtime, cam_out, phys_state, dyn_in, dyn_out)
use hycoef, only: hyam, hybm
use dimensions_mod, only: nlev, nelemd, np, npsq
use se_iop_intr_mod, only: iop_setfield, iop_setinitial
- use dyn_comp, only: TimeLevel
+ use dyn_comp, only: TimeLevel, hvcoord
use cam_history, only: outfld
use cam_logfile, only: iulog
+ use element_ops, only: get_temperature
use mpishorthand
real(r8), intent(in) :: dtime ! Time-step
real(r8) :: ftmp_temp(np,np,nlev,nelemd), ftmp_q(np,np,nlev,pcnst,nelemd)
@@ -542,6 +543,7 @@ subroutine stepon_run3(dtime, cam_out, phys_state, dyn_in, dyn_out)
type (dyn_export_t), intent(inout) :: dyn_out ! Dynamics export container
type (element_t), pointer :: elem(:)
integer :: rc, i, j, k, p, ie, tl_f
+ real(r8) :: temperature(np,np,nlev) ! Temperature from dynamics
#if defined (E3SM_SCM_REPLAY)
real(r8) :: forcing_temp(npsq,nlev), forcing_q(npsq,nlev,pcnst)
#endif
@@ -554,7 +556,10 @@ subroutine stepon_run3(dtime, cam_out, phys_state, dyn_in, dyn_out)
! Save ftmp stuff to get state before dynamics is called
do ie=1,nelemd
- ftmp_temp(:,:,:,ie) = dyn_in%elem(ie)%state%T(:,:,:,tl_f)
+
+ call get_temperature(dyn_in%elem(ie),temperature,hvcoord,tl_f)
+
+ ftmp_temp(:,:,:,ie) = temperature(:,:,:)
ftmp_q(:,:,:,:,ie) = dyn_in%elem(ie)%state%Q(:,:,:,:)
enddo
@@ -585,8 +590,8 @@ subroutine stepon_run3(dtime, cam_out, phys_state, dyn_in, dyn_out)
if (dp_crm) then
do ie=1,nelemd
- out_gridx(:,:) = dyn_in%elem(ie)%spherep(:,:)%lat
- out_gridy(:,:) = dyn_in%elem(ie)%spherep(:,:)%lon
+ out_gridx(:,:) = dyn_in%elem(ie)%spherep(:,:)%lon
+ out_gridy(:,:) = dyn_in%elem(ie)%spherep(:,:)%lat
call outfld('crm_grid_x', out_gridx, npsq, ie)
call outfld('crm_grid_y', out_gridy, npsq, ie)
enddo
@@ -599,6 +604,10 @@ subroutine stepon_run3(dtime, cam_out, phys_state, dyn_in, dyn_out)
tl_f = TimeLevel%n0
do ie=1,nelemd
+
+ ! Get temperature from dynamics state
+ call get_temperature(dyn_in%elem(ie),temperature,hvcoord,tl_f)
+
do k=1,nlev
do j=1,np
do i=1,np
@@ -606,9 +615,9 @@ subroutine stepon_run3(dtime, cam_out, phys_state, dyn_in, dyn_out)
! Note that this calculation will not provide b4b results with
! an E3SM because the dynamics tendency is not computed in the exact
! same way as an E3SM run, introducing error with roundoff
- forcing_temp(i+(j-1)*np,k) = (dyn_in%elem(ie)%state%T(i,j,k,tl_f) - &
+ forcing_temp(i+(j-1)*np,k) = (temperature(i,j,k) - &
ftmp_temp(i,j,k,ie))/dtime - dyn_in%elem(ie)%derived%FT(i,j,k)
- out_temp(i+(j-1)*np,k) = dyn_in%elem(ie)%state%T(i,j,k,tl_f)
+ out_temp(i+(j-1)*np,k) = temperature(i,j,k)
out_u(i+(j-1)*np,k) = dyn_in%elem(ie)%state%v(i,j,1,k,tl_f)
out_v(i+(j-1)*np,k) = dyn_in%elem(ie)%state%v(i,j,2,k,tl_f)
out_q(i+(j-1)*np,k) = dyn_in%elem(ie)%state%Q(i,j,k,1)
diff --git a/components/eam/src/physics/cam/co2_diagnostics.F90 b/components/eam/src/physics/cam/co2_diagnostics.F90
index c24c908a5246..81fdb3e9d76b 100644
--- a/components/eam/src/physics/cam/co2_diagnostics.F90
+++ b/components/eam/src/physics/cam/co2_diagnostics.F90
@@ -433,16 +433,24 @@ subroutine print_global_carbon_diags(state, dtime, nstep)
( co2_print_diags_monthly .and. is_end_curr_month() ) .or. &
( co2_print_diags_total .and. is_last_step() ) ) then
call gmean(tc, tc_glob, c_num_var)
+ else
+ tc_glob(:) = 1.e36
end if
if ( co2_print_diags_timestep) then
call gmean(flux_ts, flux_ts_glob, f_ts_num_var)
+ else
+ flux_ts_glob(:) = 0._r8
end if
if ( co2_print_diags_monthly .and. is_end_curr_month() ) then
call gmean(flux_mon, flux_mon_glob, f_mon_num_var)
+ else
+ flux_mon_glob(:) = 0._r8
end if
if ( co2_print_diags_total .and. is_last_step() ) then
call gmean(flux_run, flux_run_glob, f_run_num_var)
+ else
+ flux_run_glob(:) = 0._r8
end if
! assign global means to readable variables
diff --git a/components/eam/src/physics/cam/ndrop.F90 b/components/eam/src/physics/cam/ndrop.F90
index b4dc999309bf..6ffe89fa730b 100644
--- a/components/eam/src/physics/cam/ndrop.F90
+++ b/components/eam/src/physics/cam/ndrop.F90
@@ -58,6 +58,10 @@ module ndrop
(/ 0.02_r8, 0.05_r8, 0.1_r8, 0.2_r8, 0.5_r8, 1.0_r8 /)
character(len=8) :: ccn_name(psat)= &
(/'CCN1','CCN2','CCN3','CCN4','CCN5','CCN6'/)
+! The following additional fields output CCN in units of 1/kg,
+! which could be handy for appplications such as SCREAM-SPA.
+character(len=8) :: ccnmair_name(psat)= &
+ (/'CCN1MAIR','CCN2MAIR','CCN3MAIR','CCN4MAIR','CCN5MAIR','CCN6MAIR'/)
! indices in state and pbuf structures
integer :: numliq_idx = -1
@@ -274,6 +278,12 @@ subroutine ndrop_init
call addfld('CCN5',(/ 'lev' /), 'A','1/cm3','CCN concentration at S=0.5%')
call addfld('CCN6',(/ 'lev' /), 'A','1/cm3','CCN concentration at S=1.0%')
+ call addfld('CCN1MAIR',(/ 'lev' /), 'A','1/kg','CCN concentration at S=0.02%')
+ call addfld('CCN2MAIR',(/ 'lev' /), 'A','1/kg','CCN concentration at S=0.05%')
+ call addfld('CCN3MAIR',(/ 'lev' /), 'A','1/kg','CCN concentration at S=0.1%')
+ call addfld('CCN4MAIR',(/ 'lev' /), 'A','1/kg','CCN concentration at S=0.2%')
+ call addfld('CCN5MAIR',(/ 'lev' /), 'A','1/kg','CCN concentration at S=0.5%')
+ call addfld('CCN6MAIR',(/ 'lev' /), 'A','1/kg','CCN concentration at S=1.0%')
call addfld('WTKE', (/ 'lev' /), 'A', 'm/s', 'Standard deviation of updraft velocity')
call addfld('NDROPMIX', (/ 'lev' /), 'A', '1/kg/s', 'Droplet number mixing')
@@ -435,7 +445,8 @@ subroutine dropmixnuc( &
real(r8), allocatable :: coltend(:,:) ! column tendency for diagnostic output
real(r8), allocatable :: coltend_cw(:,:) ! column tendency
- real(r8) :: ccn(pcols,pver,psat) ! number conc of aerosols activated at supersat
+ real(r8) :: ccn(pcols,pver,psat) ! number conc [1/m3] of aerosols activated at supersat
+ real(r8) :: ccnmair(pcols,pver,psat) ! number conc [1/kg] of aerosols activated at supersat
integer :: ccn3d_idx
real(r8), pointer :: ccn3d(:, :)
@@ -1105,9 +1116,10 @@ subroutine dropmixnuc( &
call outfld('NDROPMIX', ndropmix, pcols, lchnk)
call outfld('WTKE ', wtke, pcols, lchnk)
- call ccncalc(state, pbuf, cs, ccn)
+ call ccncalc(state, pbuf, cs, ccn, ccnmair)
do l = 1, psat
call outfld(ccn_name(l), ccn(1,1,l), pcols, lchnk)
+ call outfld(ccnmair_name(l), ccnmair(1,1,l), pcols, lchnk)
enddo
if(do_aerocom_ind3) then
@@ -1704,7 +1716,7 @@ end subroutine maxsat
!===============================================================================
-subroutine ccncalc(state, pbuf, cs, ccn)
+subroutine ccncalc(state, pbuf, cs, ccn, ccnmair)
! calculates number concentration of aerosols activated as CCN at
! supersaturation supersat.
@@ -1721,6 +1733,7 @@ subroutine ccncalc(state, pbuf, cs, ccn)
real(r8), intent(in) :: cs(pcols,pver) ! air density (kg/m3)
real(r8), intent(out) :: ccn(pcols,pver,psat) ! number conc of aerosols activated at supersat (#/m3)
+ real(r8), intent(out) :: ccnmair(pcols,pver,psat) ! number conc of aerosols activated at supersat (#/kg)
! local
@@ -1770,6 +1783,7 @@ subroutine ccncalc(state, pbuf, cs, ccn)
end do
ccn = 0._r8
+ ccnmair = 0._r8
do k=top_lev,pver
do i=1,ncol
@@ -1796,6 +1810,7 @@ subroutine ccncalc(state, pbuf, cs, ccn)
do i=1,ncol
arg(i)=argfactor(m)*log(sm(i)/super(l))
ccn(i,k,l)=ccn(i,k,l)+naerosol(i)*0.5_r8*(1._r8-erf(arg(i)))
+ ccnmair(i,k,l)=ccn(i,k,l)/cs(i,k) ! convert from #/m3 to #/kg
enddo
enddo
enddo
diff --git a/components/eam/src/physics/cam/phys_grid_ctem.F90 b/components/eam/src/physics/cam/phys_grid_ctem.F90
new file mode 100644
index 000000000000..470264a66819
--- /dev/null
+++ b/components/eam/src/physics/cam/phys_grid_ctem.F90
@@ -0,0 +1,405 @@
+!----------------------------------------------------------------------------------
+! circulation diagnostics -- terms of the Transformed Eulerian Mean (TEM) equation
+!
+! This module makes use of the zonal_mean_mod methods to produce terms needed
+! for the TEM budget from the physics grid state. Without this online
+! calculation of terms, high-frequency 3D history output would be required to
+! calculate the terms offline. The resulting zonal mean quantities and eddy
+! covariance terms take up much less disk space and can be output monthly
+!
+! History output variables:
+! Uzm Zonal-Mean zonal wind
+! Vzm Zonal-Mean meridional wind
+! Wzm Zonal-Mean vertical wind
+! THzm Zonal-Mean potential temp
+! VTHzm Meridional Heat Flux
+! WTHzm Vertical Heat Flux
+! UVzm Meridional Flux of Zonal Momentum
+! UWzm Vertical Flux of Zonal Momentum
+! THphys Potential temp
+!----------------------------------------------------------------------------------
+module phys_grid_ctem
+use shr_kind_mod, only: r8 => shr_kind_r8
+use ppgrid, only: begchunk, endchunk, pcols, pver
+use physics_types, only: physics_state
+use cam_history, only: addfld, outfld
+use zonal_mean_mod,only: ZonalAverage_t, ZonalMean_t
+use physconst, only: pi
+use cam_logfile, only: iulog
+use cam_abortutils,only: endrun, handle_allocate_error
+use namelist_utils,only: find_group_name
+use spmd_utils, only: masterproc, mpi_integer, masterprocid, mpicom
+use time_manager, only: get_nstep
+
+use shr_const_mod, only: rgas => shr_const_rgas ! J/K/kmole
+use shr_const_mod, only: grav => shr_const_g ! m/s2
+use string_utils, only: int2str
+
+implicit none
+
+private
+public :: phys_grid_ctem_readnl
+public :: phys_grid_ctem_reg
+public :: phys_grid_ctem_init
+public :: phys_grid_ctem_diags
+public :: phys_grid_ctem_final
+
+type(ZonalMean_t) :: ZMobj
+type(ZonalAverage_t) :: ZAobj
+
+integer :: nzalat = -huge(1)
+integer :: nzmbas = -huge(1)
+
+integer :: ntimesteps = -huge(1) ! number of time steps bewteen TEM calculations
+
+logical :: do_tem_diags = .false.
+
+contains
+
+!------------------------------------------------------------------------------
+!------------------------------------------------------------------------------
+subroutine phys_grid_ctem_readnl(nlfile,dtime)
+ character(len=*), intent(in) :: nlfile
+ integer, intent(in) :: dtime ! Step time in seconds
+ integer :: ierr, unitn
+
+ character(len=*), parameter :: prefix = 'phys_grid_ctem_readnl: '
+
+ integer :: phys_grid_ctem_zm_nbas
+ integer :: phys_grid_ctem_za_nlat
+ integer :: phys_grid_ctem_nfreq
+
+ namelist /phys_grid_ctem_opts/ phys_grid_ctem_zm_nbas, phys_grid_ctem_za_nlat, phys_grid_ctem_nfreq
+
+ phys_grid_ctem_zm_nbas = 0
+ phys_grid_ctem_za_nlat = 0
+ phys_grid_ctem_nfreq = 0
+
+ ! Read in namelist values
+ !------------------------
+ if(masterproc) then
+ open(newunit=unitn, file=trim(nlfile), status='old')
+ call find_group_name(unitn, 'phys_grid_ctem_opts', status=ierr)
+ if(ierr == 0) then
+ read(unitn,phys_grid_ctem_opts,iostat=ierr)
+ if(ierr /= 0) then
+ call endrun(prefix//'ERROR reading namelist')
+ end if
+ end if
+ close(unitn)
+ end if
+
+ call MPI_bcast(phys_grid_ctem_zm_nbas, 1, mpi_integer, masterprocid, mpicom, ierr)
+ if (ierr /= 0) call endrun(prefix//'FATAL: mpi_bcast: phys_grid_ctem_zm_nbas')
+ call MPI_bcast(phys_grid_ctem_za_nlat, 1, mpi_integer, masterprocid, mpicom, ierr)
+ if (ierr /= 0) call endrun(prefix//'FATAL: mpi_bcast: phys_grid_ctem_za_nlat')
+ call MPI_bcast(phys_grid_ctem_nfreq, 1, mpi_integer, masterprocid, mpicom, ierr)
+ if (ierr /= 0) call endrun(prefix//'FATAL: mpi_bcast: phys_grid_ctem_nfreq')
+
+ do_tem_diags = .false.
+ if (phys_grid_ctem_nfreq/=0) then
+ if (.not.(phys_grid_ctem_zm_nbas>0 .and. phys_grid_ctem_za_nlat>0)) then
+ call endrun(prefix//'inconsistent phys_grid_ctem namelist settings -- phys_grid_ctem_zm_nbas=' &
+ //int2str(phys_grid_ctem_zm_nbas)//', phys_grid_ctem_za_nlat='//int2str(phys_grid_ctem_za_nlat))
+ end if
+ if (phys_grid_ctem_nfreq>0) then
+ ntimesteps = phys_grid_ctem_nfreq
+ else
+ ntimesteps = nint( -phys_grid_ctem_nfreq*3600._r8/dtime )
+ end if
+ if (ntimesteps<1) then
+ call endrun(prefix//'invalid ntimesteps -- phys_grid_ctem_nfreq needs to be a larger negative value ' &
+ //'or the model time step needs to be shorter')
+ end if
+ do_tem_diags = .true.
+ end if
+
+ if (masterproc) then
+ if (do_tem_diags) then
+ write(iulog,*) 'TEM diagnostics will be calculated every ',ntimesteps,' time steps'
+ write(iulog,*) ' phys_grid_ctem_zm_nbas = ', phys_grid_ctem_zm_nbas
+ write(iulog,*) ' phys_grid_ctem_za_nlat = ', phys_grid_ctem_za_nlat
+ write(iulog,*) ' phys_grid_ctem_nfreq = ', phys_grid_ctem_nfreq
+ else
+ write(iulog,*) 'TEM diagnostics will not be performed'
+ end if
+ endif
+
+ if (do_tem_diags) then
+ nzalat = phys_grid_ctem_za_nlat
+ nzmbas = phys_grid_ctem_zm_nbas
+ end if
+
+end subroutine phys_grid_ctem_readnl
+
+!-----------------------------------------------------------------------------
+!-----------------------------------------------------------------------------
+subroutine phys_grid_ctem_reg
+
+ use cam_grid_support, only: horiz_coord_t, horiz_coord_create, iMap, cam_grid_register
+
+ type(horiz_coord_t), pointer :: zalon_coord
+ type(horiz_coord_t), pointer :: zalat_coord
+ integer(iMap), pointer :: grid_map(:,:)
+
+ real(r8) :: zalats(nzalat)
+ real(r8) :: area(nzalat)
+ real(r8) :: zalons(1)
+ real(r8) :: dlatrad, dlatdeg, lat1, lat2
+ real(r8) :: total_area
+ real(r8) :: total_wght
+ integer :: j, astat
+
+ real(r8), parameter :: latdeg0 = -90._r8
+ real(r8), parameter :: latrad0 = -pi*0.5_r8
+ real(r8), parameter :: fourpi = pi*4._r8
+
+ integer, parameter :: ctem_zavg_phys_decomp = 333 ! Must be unique within CAM
+
+ if (.not.do_tem_diags) return
+
+ nullify(zalat_coord)
+ nullify(zalon_coord)
+ nullify(grid_map)
+
+ zalons(1) = 0._r8
+
+ dlatrad = pi/real(nzalat,kind=r8)
+ dlatdeg = 180._r8/real(nzalat,kind=r8)
+ total_area = 0._r8
+ total_wght = 0._r8
+
+ ! calculate latitudes and areas of zonal average grid boxes
+ do j = 1,nzalat
+ zalats(j) = latdeg0 + (real(j,kind=r8)-0.5_r8)*dlatdeg
+ lat1 = latrad0 + real(j-1,kind=r8)*dlatrad
+ lat2 = latrad0 + real(j ,kind=r8)*dlatrad
+ area(j) = 2._r8*pi*(sin(lat2)-sin(lat1))
+ total_area = total_area + area(j)
+ total_wght = total_wght + 0.5_r8*(sin(lat2)-sin(lat1))
+ end do
+
+ ! sanity check
+ if ( abs(1._r8-total_wght)>1.e-12_r8 .or. abs(fourpi-total_area)>1.e-12_r8 ) then
+ call endrun('phys_grid_ctem_reg: problem with area/wght calc')
+ end if
+
+ ! initialize zonal-average and zonal-mean utility objects
+ call ZAobj%init(zalats,area,nzalat,GEN_GAUSSLATS=.false.)
+ call ZMobj%init(nzmbas)
+
+ ! Zonal average grid for history fields
+
+ zalat_coord => horiz_coord_create('zalat', '', nzalat, 'latitude', 'degrees_north', 1, nzalat, zalats)
+ zalon_coord => horiz_coord_create('zalon', '', 1, 'longitude', 'degrees_east', 1, 1, zalons)
+
+ ! grid decomposition map
+ allocate(grid_map(4,nzalat), stat=astat)
+ call handle_allocate_error(astat, 'phys_grid_ctem_reg', 'grid_map')
+
+ do j = 1,nzalat
+ grid_map(1,j) = 1
+ grid_map(2,j) = j
+ if (masterproc) then
+ grid_map(3,j) = 1
+ grid_map(4,j) = j
+ else
+ grid_map(3,j) = 0
+ grid_map(4,j) = 0
+ end if
+ end do
+
+ ! register the zonal average grid
+ call cam_grid_register('ctem_zavg_phys', ctem_zavg_phys_decomp, zalat_coord, zalon_coord, grid_map, &
+ unstruct=.false., zonal_grid=.true.)
+
+end subroutine phys_grid_ctem_reg
+
+!-----------------------------------------------------------------------------
+!-----------------------------------------------------------------------------
+subroutine phys_grid_ctem_init
+
+ if (.not.do_tem_diags) return
+
+ call addfld ('Uzm', (/'lev'/), 'A','m s-1', 'Zonal-Mean zonal wind', gridname='ctem_zavg_phys' )
+ call addfld ('Vzm', (/'lev'/), 'A','m s-1', 'Zonal-Mean meridional wind', gridname='ctem_zavg_phys' )
+ call addfld ('Wzm', (/'lev'/), 'A','m s-1', 'Zonal-Mean vertical wind', gridname='ctem_zavg_phys' )
+ call addfld ('THzm', (/'lev'/), 'A','K', 'Zonal-Mean potential temp', gridname='ctem_zavg_phys' )
+ call addfld ('VTHzm',(/'lev'/), 'A','K m s-1','Meridional Heat Flux:', gridname='ctem_zavg_phys')
+ call addfld ('WTHzm',(/'lev'/), 'A','K m s-1','Vertical Heat Flux:', gridname='ctem_zavg_phys')
+ call addfld ('UVzm', (/'lev'/), 'A','m2 s-2', 'Meridional Flux of Zonal Momentum', gridname='ctem_zavg_phys')
+ call addfld ('UWzm', (/'lev'/), 'A','m2 s-2', 'Vertical Flux of Zonal Momentum', gridname='ctem_zavg_phys')
+ call addfld ('THphys',(/'lev'/), 'A', 'K', 'Potential temp', gridname='physgrid' )
+
+end subroutine phys_grid_ctem_init
+
+!-----------------------------------------------------------------------------
+!-----------------------------------------------------------------------------
+subroutine phys_grid_ctem_diags(phys_state)
+ type(physics_state), intent(in) :: phys_state(begchunk:endchunk)
+
+ character(len=*), parameter :: prefix = 'phys_grid_ctem_diags: '
+
+ real(r8) :: u(pcols,pver,begchunk:endchunk)
+ real(r8) :: v(pcols,pver,begchunk:endchunk)
+ real(r8) :: w(pcols,pver,begchunk:endchunk)
+
+ real(r8) :: uzm(pcols,pver,begchunk:endchunk)
+ real(r8) :: vzm(pcols,pver,begchunk:endchunk)
+ real(r8) :: wzm(pcols,pver,begchunk:endchunk)
+
+ real(r8) :: ud(pcols,pver,begchunk:endchunk)
+ real(r8) :: vd(pcols,pver,begchunk:endchunk)
+ real(r8) :: wd(pcols,pver,begchunk:endchunk)
+ real(r8) :: thd(pcols,pver,begchunk:endchunk)
+
+ real(r8) :: uvp(pcols,pver,begchunk:endchunk)
+ real(r8) :: uwp(pcols,pver,begchunk:endchunk)
+ real(r8) :: vthp(pcols,pver,begchunk:endchunk)
+ real(r8) :: wthp(pcols,pver,begchunk:endchunk)
+
+ integer :: lchnk, ncol, j, k
+
+ ! potential temperature
+ real(r8) :: theta(pcols,pver,begchunk:endchunk)
+ real(r8) :: thzm(pcols,pver,begchunk:endchunk)
+
+ real(r8) :: uvza(nzalat,pver)
+ real(r8) :: uwza(nzalat,pver)
+ real(r8) :: vthza(nzalat,pver)
+ real(r8) :: wthza(nzalat,pver)
+
+ real(r8) :: uza(nzalat,pver)
+ real(r8) :: vza(nzalat,pver)
+ real(r8) :: wza(nzalat,pver)
+ real(r8) :: thza(nzalat,pver)
+
+ real(r8) :: mbarv ! molecular weight of dry air (g/mol)
+ real(r8) :: sheight(pcols,pver) ! pressure scale height (m)
+
+ if (.not.do_calc()) return
+
+ ! In CESM/WACCM the variable mbarv is provided by the "air_composition"
+ ! module, which is not in E3SM, so we just use a rough approximation
+ mbarv = 28.97
+
+ do lchnk = begchunk,endchunk
+
+ ncol = phys_state(lchnk)%ncol
+
+ ! scale height
+ sheight(:ncol,:) = phys_state(lchnk)%t(:ncol,:) * rgas / ( mbarv * grav ) ! meters
+
+ ! potential temperature
+ theta(:ncol,:,lchnk) = phys_state(lchnk)%t(:ncol,:) * phys_state(lchnk)%exner(:ncol,:)
+
+ ! vertical velocity
+ w(:ncol,:,lchnk) = -sheight(:ncol,:) * phys_state(lchnk)%omega(:ncol,:) / phys_state(lchnk)%pmid(:ncol,:)
+
+ u(:ncol,:,lchnk) = phys_state(lchnk)%u(:ncol,:)
+ v(:ncol,:,lchnk) = phys_state(lchnk)%v(:ncol,:)
+
+ end do
+
+ ! zonal means evaluated on the physics grid (3D) to be used in the deviations calculation below
+ uzm(:,:,:) = zmean_fld(u(:,:,:))
+ vzm(:,:,:) = zmean_fld(v(:,:,:))
+ wzm(:,:,:) = zmean_fld(w(:,:,:))
+ thzm(:,:,:) = zmean_fld(theta(:,:,:))
+
+
+ ! diagnostic output
+ do lchnk = begchunk, endchunk
+ call outfld( 'THphys', theta(:,:,lchnk), pcols, lchnk)
+ end do
+
+ do lchnk = begchunk,endchunk
+ ncol = phys_state(lchnk)%ncol
+ do k = 1,pver
+ ! zonal deviations
+ thd(:ncol,k,lchnk) = theta(:ncol,k,lchnk) - thzm(:ncol,k,lchnk)
+ ud(:ncol,k,lchnk) = u(:ncol,k,lchnk) - uzm(:ncol,k,lchnk)
+ vd(:ncol,k,lchnk) = v(:ncol,k,lchnk) - vzm(:ncol,k,lchnk)
+ wd(:ncol,k,lchnk) = w(:ncol,k,lchnk) - wzm(:ncol,k,lchnk)
+ ! fluxes
+ uvp(:ncol,k,lchnk) = ud(:ncol,k,lchnk) * vd(:ncol,k,lchnk)
+ uwp(:ncol,k,lchnk) = ud(:ncol,k,lchnk) * wd(:ncol,k,lchnk)
+ vthp(:ncol,k,lchnk) = vd(:ncol,k,lchnk) * thd(:ncol,k,lchnk)
+ wthp(:ncol,k,lchnk) = wd(:ncol,k,lchnk) * thd(:ncol,k,lchnk)
+ end do
+ end do
+
+ ! evaluate and output fluxes on the zonal-average grid
+ call ZAobj%binAvg(uvp, uvza)
+ call ZAobj%binAvg(uwp, uwza)
+ call ZAobj%binAvg(vthp, vthza)
+ call ZAobj%binAvg(wthp, wthza)
+
+
+ if (any(abs(uvza)>1.e20_r8)) call endrun(prefix//'bad values in uvza')
+ if (any(abs(uwza)>1.e20_r8)) call endrun(prefix//'bad values in uwza')
+ if (any(abs(vthza)>1.e20_r8)) call endrun(prefix//'bad values in vthza')
+ if (any(abs(wthza)>1.e20_r8)) call endrun(prefix//'bad values in wthza')
+
+ call ZAobj%binAvg(uzm, uza)
+ call ZAobj%binAvg(vzm, vza)
+ call ZAobj%binAvg(wzm, wza)
+ call ZAobj%binAvg(thzm, thza)
+
+
+ if (any(abs(uza)>1.e20_r8)) call endrun(prefix//'bad values in uza')
+ if (any(abs(vza)>1.e20_r8)) call endrun(prefix//'bad values in vza')
+ if (any(abs(wza)>1.e20_r8)) call endrun(prefix//'bad values in wza')
+ if (any(abs(thza)>1.e20_r8)) call endrun(prefix//'bad values in thza')
+
+ ! diagnostic output
+ do j = 1,nzalat
+ call outfld('Uzm',uza(j,:),1,j)
+ call outfld('Vzm',vza(j,:),1,j)
+ call outfld('Wzm',wza(j,:),1,j)
+ call outfld('THzm',thza(j,:),1,j)
+ call outfld('UVzm',uvza(j,:),1,j)
+ call outfld('UWzm',uwza(j,:),1,j)
+ call outfld('VTHzm',vthza(j,:),1,j)
+ call outfld('WTHzm',wthza(j,:),1,j)
+ end do
+
+ contains
+
+ !------------------------------------------------------------------------------
+ ! utility function for evaluating 3D zonal mean fields
+ !------------------------------------------------------------------------------
+ function zmean_fld( fld ) result(fldzm)
+
+ real(r8), intent(in) :: fld(pcols,pver,begchunk:endchunk)
+
+ real(r8) :: fldzm(pcols,pver,begchunk:endchunk)
+
+ real(r8) :: Zonal_Bamp3d(nzmbas,pver)
+
+ call ZMobj%calc_amps(fld,Zonal_Bamp3d)
+ call ZMobj%eval_grid(Zonal_Bamp3d,fldzm)
+
+ end function zmean_fld
+
+ !------------------------------------------------------------------------------
+ ! utility function returns TRUE when time to update TEM diags
+ !------------------------------------------------------------------------------
+ logical function do_calc()
+
+ integer :: nstep
+ nstep = get_nstep()
+ do_calc = do_tem_diags .and. mod(nstep,ntimesteps) == 0
+
+ end function do_calc
+
+end subroutine phys_grid_ctem_diags
+
+!-----------------------------------------------------------------------------
+!-----------------------------------------------------------------------------
+subroutine phys_grid_ctem_final
+ call ZAobj%final()
+ call ZMobj%final()
+end subroutine phys_grid_ctem_final
+
+end module phys_grid_ctem
diff --git a/components/eam/src/physics/cam/physpkg.F90 b/components/eam/src/physics/cam/physpkg.F90
index 5f942152a20f..5ece67252791 100644
--- a/components/eam/src/physics/cam/physpkg.F90
+++ b/components/eam/src/physics/cam/physpkg.F90
@@ -526,10 +526,6 @@ subroutine phys_inidat( cam_out, pbuf2d )
end do
deallocate(tptr)
- do lchnk=begchunk,endchunk
- cam_out(lchnk)%tbot(:) = posinf
- end do
-
!
! 3-D fields
!
@@ -788,6 +784,7 @@ subroutine phys_init( phys_state, phys_tend, pbuf2d, cam_out )
use output_aerocom_aie, only: output_aerocom_aie_init, do_aerocom_ind3
use misc_diagnostics, only: dcape_diags_init
use conditional_diag_output_utils, only: cnd_diag_output_init
+ use phys_grid_ctem, only: phys_grid_ctem_init
! Input/output arguments
type(physics_state), pointer :: phys_state(:)
@@ -1013,6 +1010,9 @@ subroutine phys_init( phys_state, phys_tend, pbuf2d, cam_out )
!--------------------------------
if(Nudge_Model) call nudging_init
+ ! Initialize Transformed Eularian Mean (TEM) diagnostics
+ call phys_grid_ctem_init()
+
!BSINGH - addfld and adddefault calls for perturb growth testing
if(pergro_test_active)call add_fld_default_calls()
@@ -1495,6 +1495,7 @@ subroutine phys_final( phys_state, phys_tend, pbuf2d, phys_diag )
use chemistry, only : chem_final
use wv_saturation, only : wv_sat_final
use radiation, only: radiation_final
+ use phys_grid_ctem, only : phys_grid_ctem_final
!-----------------------------------------------------------------------
!
! Purpose:
@@ -1531,6 +1532,10 @@ subroutine phys_final( phys_state, phys_tend, pbuf2d, phys_diag )
call print_cost_p
call t_stopf ('print_cost_p')
+ call t_startf ('phys_grid_ctem_final')
+ call phys_grid_ctem_final()
+ call t_stopf ('phys_grid_ctem_final')
+
end subroutine phys_final
@@ -3147,6 +3152,7 @@ subroutine phys_timestep_init(phys_state, cam_out, pbuf2d)
use nudging, only: Nudge_Model,nudging_timestep_init
use seasalt_model, only: advance_ocean_data, has_mam_mom
+ use phys_grid_ctem, only: phys_grid_ctem_diags
implicit none
@@ -3225,6 +3231,9 @@ subroutine phys_timestep_init(phys_state, cam_out, pbuf2d)
!----------------------------------
if(Nudge_Model) call nudging_timestep_init(phys_state)
+ ! Update Transformed Eularian Mean (TEM) diagnostics
+ call phys_grid_ctem_diags(phys_state)
+
end subroutine phys_timestep_init
diff --git a/components/eam/src/physics/cam/zonal_mean_mod.F90 b/components/eam/src/physics/cam/zonal_mean_mod.F90
new file mode 100644
index 000000000000..e3e52d0bd6dd
--- /dev/null
+++ b/components/eam/src/physics/cam/zonal_mean_mod.F90
@@ -0,0 +1,2000 @@
+module zonal_mean_mod
+!======================================================================
+!
+! Purpose: Compute and make use of Zonal Mean values on physgrid
+!
+! This module implements 3 data structures for the spectral analysis
+! and synthesis of zonal mean values based on m=0 spherical harmonics.
+!
+! ZonalMean_t: For the analysis/synthesis of zonal mean values
+! on a 2D grid of points distributed over the
+! surface of a sphere.
+! ZonalProfile_t: For the analysis/synthesis of zonal mean values
+! on a meridional grid that spans the latitudes
+! from SP to NP
+! ZonalAverage_t: To calculate zonal mean values via a simple
+! area weighted bin-averaging of 2D grid points
+! assigned to each latitude band.
+!
+! NOTE: The weighting of the Zonal Profiles values is scaled such
+! that ZonalMean_t amplitudes can be used to evaluate values
+! on the ZonalProfile_t grid and vice-versa.
+!
+! The ZonalMean_t computes global integrals to compute basis
+! amplitudes. For distributed environments the cost of these
+! can be reduced using the The ZonalAverage_t data structures.
+!
+! USAGE:
+!
+! (1) Compute Zonal mean amplitudes and synthesize values on 2D/3D physgrid
+!
+! Usage: type(ZonalMean_t):: ZM
+! =========================================
+! call ZM%init(nbas)
+! ------------------
+! - Initialize the data structure with 'nbas' basis functions
+! for the given physgrid latitudes and areas.
+!
+! Arguments:
+! integer ,intent(in):: nbas -Number of m=0 spherical harmonics
+!
+! call ZM%calc_amps(Gdata,Bamp)
+! -----------------------------
+! - For the initialized ZonalMean_t; Given Gdata() values on the physgrid,
+! compute the zonal mean basis amplitudes Bamp().
+!
+! Interface: 2D data on the physgrid
+! real(r8),intent(in ):: Gdata(pcols,begchunk:endchunk)
+! real(r8),intent(out):: Bamp (nbas)
+!
+! Interface: 3D data on the physgrid
+! real(r8),intent(in ):: Gdata(pcols,pver,begchunk:endchunk)
+! real(r8),intent(out):: Bamp (nbas,pver)
+!
+! call ZM%eval_grid(Bamp,Gdata)
+! -----------------------------
+! - For the initialized ZonalMean_t; Given Bamp() zonal mean basis
+! amplitudes, compute the Gdata() values on the physgrid.
+!
+! Interface: 2D data on the physgrid
+! real(r8),intent(in ):: Bamp (nbas)
+! real(r8),intent(out):: Gdata(pcols,begchunk:endchunk)
+!
+! Interface: 3D data on the physgrid
+! real(r8),intent(in ):: Bamp (nbas,pver)
+! real(r8),intent(out):: Gdata(pcols,pver,begchunk:endchunk)
+!
+!
+! (2) Compute Zonal mean amplitudes and synthesize values on Zonal profile grid
+!
+! Usage: type(ZonalProfile_t):: ZP
+! =========================================
+! call ZP%init(lats,area,nlat,nbas,GEN_GAUSSLATS=.true.)
+! ------------------------------------------------------
+! - Initialize the data structure for the given number of
+! latitudes. Either use the given Latitudes and weights,
+! or OPTIONALLY create profile gridpoints and associated
+! area weights from SP to NP. Then initialize 'nbas' basis
+! functions for the profile gridpoints.
+! If the user supplies the lats/area values, the area values must
+! be correctly scaled such that the global area adds up to 4PI.
+! Otherwise, the ampitudes between ZonalProfile_t and ZonalMean_t
+! are not interchangable.
+!
+! Arguments:
+! real(r8),intent(inout):: lats(:) - Latitudes of meridional grid.
+! real(r8),intent(inout):: area(:) - Area of each meridional gridpoint.
+! integer ,intent(in) :: nlat - Number of meridional gridpoints.
+! integer ,intent(in) :: nbas - Number of m=0 spherical harmonics
+! logical ,intent(in),optional:: GEN_GAUSLATS - Flag to generate
+! lats/areas values.
+!
+! call ZP%calc_amps(Zdata,Bamp)
+! -----------------------------
+! - Given Zdata() on the Zonal profile grid, compute the
+! zonal basis amplitudes Bamp().
+!
+! Interface: 1D data on (nlat) grid
+! real(r8),intent(in ):: Zdata(nlat) - Meridional Profile data
+! real(r8),intent(out):: Bamp (nbas) - Zonal Basis Amplitudes
+!
+! Interface: 2D data on (nlat,pver) grid
+! real(r8),intent(in ):: Zdata(nlat,pver) - Meridional Profile data
+! real(r8),intent(out):: Bamp (nbas,pver) - Zonal Basis Amplitudes
+!
+! call ZP%eval_grid(Bamp,Zdata)
+! -----------------------------
+! - Given Bamp() zonal basis amplitudes, evaluate the Zdata()
+! values on the Zonal profile grid.
+!
+! Interface: 1D data on (nlat) grid
+! real(r8),intent(in ):: Bamp (nbas) - Zonal Basis Amplitudes
+! real(r8),intent(out):: Zdata(nlat) - Meridional Profile data
+!
+! Interface: 2D data on (nlat,pver) grid
+! real(r8),intent(in ):: Bamp (nbas,pver) - Zonal Basis Amplitudes
+! real(r8),intent(out):: Zdata(nlat,pver) - Meridional Profile data
+!
+! (3) Compute Zonal mean averages (FASTER/LESS-ACCURATE) on Zonal profile grid
+! (For the created zonal profile, just bin average area weighted
+! 2D/3D physgrid grid values)
+!
+! Usage: type(ZonalAverage_t):: ZA
+! =========================================
+! call ZA%init(lats,area,nlat,GEN_GAUSSLATS=.true.)
+! --------------------------------------------------
+! - Given the latitude/area for the nlat meridional gridpoints, initialize
+! the ZonalAverage data structure for computing bin-averaging of physgrid
+! values. It is assumed that the domain of these gridpoints of the
+! profile span latitudes from SP to NP.
+! The optional GEN_GAUSSLATS flag allows for the generation of Gaussian
+! latitude gridpoints. The generated grid over-writes the given values
+! lats and area passed by the user.
+!
+! Arguments:
+! real(r8),intent(inout):: lats(nlat) - Latitudes of meridional grid.
+! real(r8),intent(inout):: area(nlat) - Area of meridional gridpoints.
+! integer ,intent(in):: nlat - Number of meridional gridpoints
+! logical,intent(in),optional:: GEN_GAUSLATS - Flag to generate
+! lats/areas values.
+!
+! call ZA%binAvg(Gdata,Zdata)
+! ---------------------------
+! - For the initialized ZonalAverage_t; Given Gdata() on the physgrid,
+! compute bin averages and return Zdata() on the Zonal profile grid.
+!
+! Interface: 2D data on the physgrid
+! real(r8),intent(out):: Gdata(pcols,begchunk:endchunk)
+! real(r8),intent(out):: Zdata(nlat)
+!
+! Interface: 3D data on the physgrid
+! real(r8),intent(out):: Gdata(pcols,pver,begchunk:endchunk)
+! real(r8),intent(out):: Zdata(nlat,pver)
+!
+!======================================================================
+
+use shr_kind_mod, only: r8=>SHR_KIND_R8
+use phys_grid, only: get_ncols_p, get_rlat_p, get_wght_all_p, get_nlcols_p
+use ppgrid, only: begchunk, endchunk, pcols
+use shr_reprosum_mod,only: shr_reprosum_calc
+use cam_abortutils, only: endrun, handle_allocate_error
+use spmd_utils, only: mpicom
+use physconst, only: pi
+use phys_grid, only: ngcols_p
+use cam_logfile, only: iulog
+
+implicit none
+private
+
+public :: ZonalMean_t
+public :: ZonalProfile_t
+public :: ZonalAverage_t
+
+! Type definitions
+!-------------------
+type ZonalMean_t
+ private
+ integer :: nbas
+ real(r8),allocatable:: area (:,:)
+ real(r8),allocatable:: basis(:,:,:)
+ real(r8),allocatable:: map (:,:)
+ contains
+ procedure,pass:: init => init_ZonalMean
+ generic,public:: calc_amps => calc_ZonalMean_2Damps, &
+ calc_ZonalMean_3Damps
+ generic,public:: eval_grid => eval_ZonalMean_2Dgrid, &
+ eval_ZonalMean_3Dgrid
+ procedure,private,pass:: calc_ZonalMean_2Damps
+ procedure,private,pass:: calc_ZonalMean_3Damps
+ procedure,private,pass:: eval_ZonalMean_2Dgrid
+ procedure,private,pass:: eval_ZonalMean_3Dgrid
+ procedure, pass :: final => final_ZonalMean
+end type ZonalMean_t
+
+type ZonalProfile_t
+ private
+ integer :: nlat
+ integer :: nbas
+ real(r8),allocatable:: area (:)
+ real(r8),allocatable:: basis(:,:)
+ real(r8),allocatable:: map (:,:)
+ contains
+ procedure,pass:: init => init_ZonalProfile
+ generic,public:: calc_amps => calc_ZonalProfile_1Damps, &
+ calc_ZonalProfile_2Damps
+ generic,public:: eval_grid => eval_ZonalProfile_1Dgrid, &
+ eval_ZonalProfile_2Dgrid
+ procedure,private,pass:: calc_ZonalProfile_1Damps
+ procedure,private,pass:: calc_ZonalProfile_2Damps
+ procedure,private,pass:: eval_ZonalProfile_1Dgrid
+ procedure,private,pass:: eval_ZonalProfile_2Dgrid
+ procedure, pass :: final => final_ZonalProfile
+end type ZonalProfile_t
+
+type ZonalAverage_t
+ private
+ integer :: nlat
+ real(r8),allocatable:: area (:)
+ real(r8),allocatable:: a_norm (:)
+ real(r8),allocatable:: area_g (:,:)
+ integer ,allocatable:: idx_map(:,:)
+ contains
+ procedure,pass:: init => init_ZonalAverage
+ generic,public:: binAvg => calc_ZonalAverage_2DbinAvg, &
+ calc_ZonalAverage_3DbinAvg
+ procedure,private,pass:: calc_ZonalAverage_2DbinAvg
+ procedure,private,pass:: calc_ZonalAverage_3DbinAvg
+ procedure, pass :: final => final_ZonalAverage
+end type ZonalAverage_t
+
+real(r8), parameter :: halfPI = 0.5_r8*pi
+real(r8), parameter :: twoPI = 2.0_r8*pi
+real(r8), parameter :: fourPI = 4.0_r8*pi
+real(r8), parameter :: qrtrPI = 0.25_r8*pi
+real(r8), parameter :: invSqrt4pi = 1._r8/sqrt(fourPI)
+
+contains
+!=======================================================================
+subroutine init_ZonalMean(this,I_nbas)
+ !
+ ! init_ZonalMean: Initialize the ZonalMean data structures for the
+ ! physics grid. It is assumed that the domain
+ ! of these gridpoints spans the surface of the sphere.
+ ! The representation of basis functions is
+ ! normalized w.r.t integration over the sphere.
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ class(ZonalMean_t) :: this
+ integer ,intent(in):: I_nbas
+ !
+ ! Local Values
+ !--------------
+ real(r8),allocatable:: Clats(:,:)
+ real(r8),allocatable:: Bcoef(:)
+ real(r8),allocatable:: Csum (:,:)
+ real(r8),allocatable:: Cvec (:)
+ real(r8),allocatable:: Bsum (:,:)
+ real(r8),allocatable:: Bnorm(:)
+ real(r8),allocatable:: Bcov (:,:)
+ real(r8):: area(pcols),rlat
+
+ integer :: nn,n2,nb,lchnk,ncols,cc
+ integer :: cnum,Cvec_len
+
+ integer :: nlcols, count, astat
+ character(len=*), parameter :: subname = 'init_ZonalMean'
+
+ if (I_nbas<1) then
+ call endrun('ZonalMean%init: ERROR I_nbas must be greater than 0')
+ end if
+
+ ! Allocate space
+ !-----------------
+ if(allocated(this%area )) deallocate(this%area)
+ if(allocated(this%basis)) deallocate(this%basis)
+ if(allocated(this%map )) deallocate(this%map)
+
+ this%nbas = I_nbas
+ allocate(this%area (pcols,begchunk:endchunk), stat=astat)
+ call handle_allocate_error(astat, subname, 'this%area')
+ allocate(this%basis(pcols,begchunk:endchunk,I_nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'this%basis')
+ allocate(this%map (I_nbas,I_nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'this%map')
+ this%area (:,:) = 0._r8
+ this%basis(:,:,:) = 0._r8
+ this%map (:,:) = 0._r8
+
+ Cvec_len = 0
+ do nn= 1,this%nbas
+ do n2=nn,this%nbas
+ Cvec_len = Cvec_len + 1
+ end do
+ end do
+
+ nlcols = get_nlcols_p()
+
+ allocate(Clats(pcols,begchunk:endchunk), stat=astat)
+ call handle_allocate_error(astat, subname, 'Clats')
+ allocate(Bcoef(I_nbas/2+1), stat=astat)
+ call handle_allocate_error(astat, subname, 'Bcoef')
+ allocate(Csum (nlcols, Cvec_len), stat=astat)
+ call handle_allocate_error(astat, subname, 'Csum')
+ allocate(Cvec (Cvec_len), stat=astat)
+ call handle_allocate_error(astat, subname, 'Cvec')
+ allocate(Bsum (nlcols, I_nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'Bsum')
+ allocate(Bnorm(I_nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'Bnorm')
+ allocate(Bcov (I_nbas,I_nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'Bcov')
+
+ Bsum(:,:) = 0._r8
+ Csum(:,:) = 0._r8
+
+ ! Save a copy of the area weights for each ncol gridpoint
+ ! and convert Latitudes to SP->NP colatitudes in radians
+ !-------------------------------------------------------
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ call get_wght_all_p(lchnk, ncols, area)
+ do cc = 1,ncols
+ rlat=get_rlat_p(lchnk,cc)
+ this%area(cc,lchnk) = area(cc)
+ Clats (cc,lchnk) = rlat + halfPI
+ end do
+ end do
+
+ ! Add first basis for the mean values.
+ !------------------------------------------
+ this%basis(:,begchunk:endchunk,1) = invSqrt4pi
+
+ ! Loop over the remaining basis functions
+ !---------------------------------------
+ do nn=2,this%nbas
+ nb = nn-1
+
+ ! Generate coefs for the basis
+ !------------------------------
+ call sh_gen_basis_coefs(nb,0,Bcoef)
+
+ ! Create basis for the coefs at each ncol gridpoint
+ !---------------------------------------------------
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ do cc = 1,ncols
+ call sh_create_basis(nb,0,Clats(cc,lchnk),Bcoef,this%basis(cc,lchnk,nn))
+ end do
+ end do
+ end do ! nn=2,this%nbas
+
+ ! Numerically normalize the basis funnctions
+ !--------------------------------------------------------------
+ do nn=1,this%nbas
+ count = 0
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ do cc = 1,ncols
+ count=count+1
+ Bsum(count,nn) = this%basis(cc,lchnk,nn)*this%basis(cc,lchnk,nn)*this%area(cc,lchnk)
+ end do
+ end do
+ end do ! nn=1,this%nbas
+
+ call shr_reprosum_calc(Bsum, Bnorm, count, nlcols, this%nbas, gbl_count=ngcols_p, commid=mpicom)
+
+ do nn=1,this%nbas
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ this%basis(:ncols,lchnk,nn) = this%basis(:ncols,lchnk,nn)/sqrt(Bnorm(nn))
+ end do
+ end do ! nn=1,this%nbas
+
+ ! Compute covariance matrix for basis functions
+ ! (Yes, they are theoretically orthonormal, but lets make sure)
+ !---------------------------------------------------------------
+ cnum = 0
+ do nn= 1,this%nbas
+ do n2=nn,this%nbas
+ cnum = cnum + 1
+ count = 0
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ do cc = 1,ncols
+ count=count+1
+ Csum(count,cnum) = this%basis(cc,lchnk,nn)*this%basis(cc,lchnk,n2)*this%area(cc,lchnk)
+ end do
+ end do
+
+ end do
+ end do
+
+ call shr_reprosum_calc(Csum, Cvec, count, nlcols, Cvec_len, gbl_count=ngcols_p, commid=mpicom)
+
+ cnum = 0
+ do nn= 1,this%nbas
+ do n2=nn,this%nbas
+ cnum = cnum + 1
+ Bcov(nn,n2) = Cvec(cnum)
+ Bcov(n2,nn) = Cvec(cnum)
+ end do
+ end do
+
+ ! Invert to get the basis amplitude map
+ !--------------------------------------
+ call Invert_Matrix(Bcov,this%nbas,this%map)
+
+ ! End Routine
+ !------------
+ deallocate(Clats)
+ deallocate(Bcoef)
+ deallocate(Csum )
+ deallocate(Cvec )
+ deallocate(Bsum )
+ deallocate(Bnorm)
+ deallocate(Bcov )
+
+end subroutine init_ZonalMean
+!=======================================================================
+
+
+!=======================================================================
+subroutine calc_ZonalMean_2Damps(this,I_Gdata,O_Bamp)
+ !
+ ! calc_ZonalMean_2Damps: Given 2D data values for the ncol gridpoints,
+ ! compute the zonal mean basis amplitudes.
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ class(ZonalMean_t) :: this
+ real(r8),intent(in ) :: I_Gdata(pcols,begchunk:endchunk)
+ real(r8),intent(out) :: O_Bamp(:)
+ !
+ ! Local Values
+ !--------------
+ real(r8),allocatable :: Csum(:,:)
+ real(r8),allocatable :: Gcov(:)
+ integer :: nn,n2,ncols,lchnk,cc
+ integer :: nlcols, count, astat
+
+ character(len=*), parameter :: subname = 'calc_ZonalMean_2Damps'
+
+ nlcols = get_nlcols_p()
+
+ allocate(Gcov(this%nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'Gcov')
+ allocate(Csum(nlcols, this%nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'Csum')
+ Csum(:,:) = 0._r8
+
+ ! Compute Covariance with input data and basis functions
+ !--------------------------------------------------------
+ do nn= 1,this%nbas
+ count = 0
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ do cc = 1,ncols
+ count=count+1
+ Csum(count,nn) = I_Gdata(cc,lchnk)*this%basis(cc,lchnk,nn)*this%area(cc,lchnk)
+ end do
+ end do
+ end do
+
+ call shr_reprosum_calc(Csum, Gcov, count, nlcols, this%nbas, gbl_count=ngcols_p, commid=mpicom)
+
+ ! Multiply by map to get the amplitudes
+ !-------------------------------------------
+ do nn=1,this%nbas
+ O_Bamp(nn) = 0._r8
+ do n2=1,this%nbas
+ O_Bamp(nn) = O_Bamp(nn) + this%map(n2,nn)*Gcov(n2)
+ end do
+ end do
+
+ ! End Routine
+ !------------
+ deallocate(Csum)
+ deallocate(Gcov)
+
+end subroutine calc_ZonalMean_2Damps
+!=======================================================================
+
+
+!=======================================================================
+subroutine calc_ZonalMean_3Damps(this,I_Gdata,O_Bamp)
+ !
+ ! calc_ZonalMean_3Damps: Given 3D data values for the ncol,nlev gridpoints,
+ ! compute the zonal mean basis amplitudes.
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ class(ZonalMean_t) :: this
+ real(r8),intent(in ):: I_Gdata(:,:,begchunk:)
+ real(r8),intent(out):: O_Bamp (:,:)
+ !
+ ! Local Values
+ !--------------
+ real(r8),allocatable:: Csum (:,:)
+ real(r8),allocatable:: Gcov (:)
+ integer:: nn,n2,ncols,lchnk,cc
+ integer:: Nsum,ns,ll
+ integer :: nlcols, count, astat
+
+ integer :: nlev
+ character(len=*), parameter :: subname = 'calc_ZonalMean_3Damps'
+
+ nlev = size(I_Gdata,dim=2)
+
+ nlcols = get_nlcols_p()
+ allocate(Gcov(this%nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'Gcov')
+ allocate(Csum(nlcols, this%nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'Csum')
+
+ Csum(:,:) = 0._r8
+ O_Bamp(:,:) = 0._r8
+
+ ! Compute Covariance with input data and basis functions
+ !--------------------------------------------------------
+ do ll= 1,nlev
+
+ Csum(:,:) = 0._r8
+ Gcov(:) = 0._r8
+
+ do nn= 1,this%nbas
+ count = 0
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ do cc = 1,ncols
+ count=count+1
+ Csum(count,nn) = I_Gdata(cc,ll,lchnk)*this%basis(cc,lchnk,nn)*this%area(cc,lchnk)
+ end do
+ end do
+ end do
+
+ call shr_reprosum_calc(Csum, Gcov, count, nlcols, this%nbas, gbl_count=ngcols_p, commid=mpicom)
+
+ ! Multiply by map to get the amplitudes
+ !-------------------------------------------
+ do nn=1,this%nbas
+ O_Bamp(nn,ll) = 0._r8
+ do n2=1,this%nbas
+ O_Bamp(nn,ll) = O_Bamp(nn,ll) + this%map(n2,nn)*Gcov(n2)
+ end do
+ end do
+
+ end do
+
+ ! End Routine
+ !------------
+ deallocate(Csum)
+ deallocate(Gcov)
+
+end subroutine calc_ZonalMean_3Damps
+!=======================================================================
+
+
+!=======================================================================
+subroutine eval_ZonalMean_2Dgrid(this,I_Bamp,O_Gdata)
+ !
+ ! eval_ZonalMean_2Dgrid: Given the zonal mean basis amplitudes,
+ ! compute 2D data values for the ncol gridpoints.
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ class(ZonalMean_t) :: this
+ real(r8),intent(in ):: I_Bamp (:)
+ real(r8),intent(out):: O_Gdata(pcols,begchunk:endchunk)
+ !
+ ! Local Values
+ !--------------
+ integer:: nn,ncols,lchnk,cc
+
+ O_Gdata(:,:) = 0._r8
+
+ ! Construct grid values from basis amplitudes.
+ !--------------------------------------------------
+
+ do nn=1,this%nbas
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ do cc = 1,ncols
+ O_Gdata(cc,lchnk) = O_Gdata(cc,lchnk) + (I_Bamp(nn)*this%basis(cc,lchnk,nn))
+ end do
+ end do
+ end do
+
+end subroutine eval_ZonalMean_2Dgrid
+!=======================================================================
+
+
+!=======================================================================
+subroutine eval_ZonalMean_3Dgrid(this,I_Bamp,O_Gdata)
+ !
+ ! eval_ZonalMean_3Dgrid: Given the zonal mean basis amplitudes,
+ ! compute 3D data values for the ncol,nlev gridpoints.
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ class(ZonalMean_t) :: this
+ real(r8),intent(in ):: I_Bamp (:,:)
+ real(r8),intent(out):: O_Gdata(:,:,begchunk:)
+ !
+ ! Local Values
+ !--------------
+ integer:: nn,ncols,lchnk,cc
+ integer:: ll
+
+ integer :: nlev
+ nlev = size(O_Gdata,dim=2)
+
+ O_Gdata(:,:,:) = 0._r8
+
+ ! Construct grid values from basis amplitudes.
+ !--------------------------------------------------
+
+ do ll = 1,nlev
+ do nn=1,this%nbas
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ do cc = 1,ncols
+ O_Gdata(cc,ll,lchnk) = O_Gdata(cc,ll,lchnk) + (I_Bamp(nn,ll)*this%basis(cc,lchnk,nn))
+ end do
+ end do
+ end do
+ end do
+
+end subroutine eval_ZonalMean_3Dgrid
+!=======================================================================
+
+!=======================================================================
+subroutine final_ZonalMean(this)
+ class(ZonalMean_t) :: this
+
+ if(allocated(this%area )) deallocate(this%area)
+ if(allocated(this%basis)) deallocate(this%basis)
+ if(allocated(this%map )) deallocate(this%map)
+
+end subroutine final_ZonalMean
+!=======================================================================
+
+!=======================================================================
+subroutine init_ZonalProfile(this,IO_lats,IO_area,I_nlat,I_nbas,GEN_GAUSSLATS)
+ !
+ ! init_ZonalProfile: Initialize the ZonalProfile data structure for the
+ ! given nlat gridpoints. It is assumed that the domain
+ ! of these gridpoints of the profile span latitudes
+ ! from SP to NP.
+ ! The representation of basis functions functions is
+ ! normalized w.r.t integration over the sphere so that
+ ! when configured for tha same number of basis functions,
+ ! the calculated amplitudes are interchangable with
+ ! those for the ZonalMean_t class.
+ !
+ ! The optional GEN_GAUSSLATS flag allows for the
+ ! generation of Gaussian latitudes. The generated grid
+ ! over-writes the values of IO_lats/IO_area passed by
+ ! the user.
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ class(ZonalProfile_t) :: this
+ real(r8) ,intent(inout):: IO_lats(:)
+ real(r8) ,intent(inout):: IO_area(:)
+ integer ,intent(in):: I_nlat
+ integer ,intent(in):: I_nbas
+ logical,optional,intent(in):: GEN_GAUSSLATS
+ !
+ ! Local Values
+ !--------------
+ real(r8),allocatable:: Clats(:)
+ real(r8),allocatable:: Bcoef(:)
+ real(r8),allocatable:: Bcov (:,:)
+ real(r8):: Bnorm
+ integer :: ii,nn,n2,nb,ierr, astat
+ logical :: generate_lats
+
+ character(len=*), parameter :: subname = 'init_ZonalProfile'
+
+ generate_lats = .false.
+
+ if (present(GEN_GAUSSLATS)) then
+ generate_lats = GEN_GAUSSLATS
+ end if
+
+ ! Allocate space
+ !-----------------
+ if(allocated(this%area )) deallocate(this%area)
+ if(allocated(this%basis)) deallocate(this%basis)
+ if(allocated(this%map )) deallocate(this%map)
+
+ this%nlat = I_nlat
+ this%nbas = I_nbas
+ allocate(this%area (I_nlat), stat=astat)
+ call handle_allocate_error(astat, subname, 'this%area')
+ allocate(this%basis(I_nlat,I_nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'this%basis')
+ allocate(this%map (I_nbas,I_nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'this%map')
+
+ allocate(Clats(I_nlat), stat=astat)
+ call handle_allocate_error(astat, subname, 'Clats')
+ allocate(Bcoef(I_nbas/2+1), stat=astat)
+ call handle_allocate_error(astat, subname, 'Bcoef')
+ allocate(Bcov (I_nbas,I_nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'Bcov')
+
+ ! Optionally create the Latitude Gridpoints
+ ! and their associated area weights. Otherwise
+ ! they need to be supplied by the user.
+ !-----------------------------------------------
+ if(generate_lats) then
+
+ ! Create a Gaussian grid from SP to NP
+ !--------------------------------------
+ call sh_create_gaus_grid(I_nlat,Clats,IO_area,ierr)
+ if (ierr/=0) then
+ call endrun('init_ZonalProfile: Error creating Gaussian grid')
+ end if
+
+ ! Convert generated colatitudes SP->NP to Lats and convert
+ ! to degrees and scale the area for global 2D integrals
+ !-----------------------------------------------------------
+ do nn=1,I_nlat
+ IO_lats(nn) = (45._r8*Clats(nn)/qrtrPI) - 90._r8
+ IO_area(nn) = IO_area(nn)*twoPI
+ end do
+ else
+ ! Convert Latitudes to SP->NP colatitudes in radians
+ !----------------------------------------------------
+ do nn=1,I_nlat
+ Clats(nn) = (IO_lats(nn) + 90._r8)*qrtrPI/45._r8
+ end do
+ endif
+
+ ! Copy the area weights for each nlat
+ ! gridpoint to the data structure
+ !---------------------------------------
+ this%area(1:I_nlat) = IO_area(1:I_nlat)
+
+ ! Add first basis for the mean values.
+ !------------------------------------------
+ this%basis(:,1) = invSqrt4pi
+ Bnorm = 0._r8
+ do ii=1,I_nlat
+ Bnorm = Bnorm + (this%basis(ii,1)*this%basis(ii,1)*this%area(ii))
+ end do
+ this%basis(:,1) = this%basis(:,1)/sqrt(Bnorm)
+
+ ! Loop over the remaining basis functions
+ !---------------------------------------
+ do nn=2,I_nbas
+ nb = nn-1
+
+ ! Generate coefs for the basis
+ !------------------------------
+ call sh_gen_basis_coefs(nb,0,Bcoef)
+
+ ! Create an un-normalized basis for the
+ ! coefs at each nlat gridpoint
+ !---------------------------------------
+ do ii=1,I_nlat
+ call sh_create_basis(nb,0,Clats(ii),Bcoef,this%basis(ii,nn))
+ end do
+
+ ! Numerically normalize the basis funnction
+ !--------------------------------------------------------------
+ Bnorm = 0._r8
+ do ii=1,I_nlat
+ Bnorm = Bnorm + (this%basis(ii,nn)*this%basis(ii,nn)*this%area(ii))
+ end do
+ this%basis(:,nn) = this%basis(:,nn)/sqrt(Bnorm)
+
+ end do ! nn=1,I_nbas
+
+ ! Compute covariance matrix for basis functions
+ ! (Yes, they are theoretically orthonormal, but lets make sure)
+ !--------------------------------------------------------------
+ do nn=1,I_nbas
+ do n2=1,I_nbas
+ Bcov(nn,n2) = 0._r8
+ do ii=1,I_nlat
+ Bcov(nn,n2) = Bcov(nn,n2) + (this%basis(ii,nn)*this%basis(ii,n2)*this%area(ii))
+ end do
+ end do
+ end do
+
+ ! Invert to get the basis amplitude map
+ !--------------------------------------
+ call Invert_Matrix(Bcov,I_nbas,this%map)
+
+ ! End Routine
+ !------------
+ deallocate(Clats)
+ deallocate(Bcoef)
+ deallocate(Bcov )
+
+end subroutine init_ZonalProfile
+!=======================================================================
+
+
+!=======================================================================
+subroutine calc_ZonalProfile_1Damps(this,I_Zdata,O_Bamp)
+ !
+ ! calc_ZonalProfile_1Damps: Given 1D data values for the nlat zonal
+ ! profiles gridpoints, compute the zonal
+ ! profile basis amplitudes.
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ class(ZonalProfile_t):: this
+ real(r8),intent(in ):: I_Zdata(:)
+ real(r8),intent(out):: O_Bamp (:)
+ !
+ ! Local Values
+ !--------------
+ real(r8),allocatable:: Gcov(:)
+ integer:: ii,nn,n2, astat
+ character(len=*), parameter :: subname = 'calc_ZonalProfile_1Damps'
+
+ ! Compute Covariance with input data and basis functions
+ !--------------------------------------------------------
+ allocate(Gcov(this%nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'Gcov')
+ do nn=1,this%nbas
+ Gcov(nn) = 0._r8
+ do ii=1,this%nlat
+ Gcov(nn) = Gcov(nn) + (I_Zdata(ii)*this%basis(ii,nn)*this%area(ii))
+ end do
+ end do
+
+ ! Multiply by map to get the amplitudes
+ !-------------------------------------------
+ do nn=1,this%nbas
+ O_Bamp(nn) = 0._r8
+ do n2=1,this%nbas
+ O_Bamp(nn) = O_Bamp(nn) + this%map(n2,nn)*Gcov(n2)
+ end do
+ end do
+
+ deallocate(Gcov)
+
+end subroutine calc_ZonalProfile_1Damps
+!=======================================================================
+
+
+!=======================================================================
+subroutine calc_ZonalProfile_2Damps(this,I_Zdata,O_Bamp)
+ !
+ ! calc_ZonalProfile_2Damps: Given 2D data values for the nlat,nlev zonal
+ ! profiles gridpoints, compute the zonal
+ ! profile basis amplitudes.
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ class(ZonalProfile_t):: this
+ real(r8),intent(in ):: I_Zdata(:,:)
+ real(r8),intent(out):: O_Bamp (:,:)
+ !
+ ! Local Values
+ !--------------
+ real(r8),allocatable:: Gcov(:,:)
+ integer:: ii,nn,n2,ilev
+
+ integer :: nlev, astat
+ character(len=*), parameter :: subname = 'calc_ZonalProfile_2Damps'
+
+ nlev = size(I_Zdata,dim=2)
+
+ ! Compute Covariance with input data and basis functions
+ !--------------------------------------------------------
+ allocate(Gcov(this%nbas,nlev), stat=astat)
+ call handle_allocate_error(astat, subname, 'Gcov')
+ do ilev=1,nlev
+ do nn=1,this%nbas
+ Gcov(nn,ilev) = 0._r8
+ do ii=1,this%nlat
+ Gcov(nn,ilev) = Gcov(nn,ilev) + (I_Zdata(ii,ilev)*this%basis(ii,nn)*this%area(ii))
+ end do
+ end do
+ end do
+
+ ! Multiply by map to get the amplitudes
+ !-------------------------------------------
+ do ilev=1,nlev
+ do nn=1,this%nbas
+ O_Bamp(nn,ilev) = 0._r8
+ do n2=1,this%nbas
+ O_Bamp(nn,ilev) = O_Bamp(nn,ilev) + this%map(n2,nn)*Gcov(n2,ilev)
+ end do
+ end do
+ end do
+ deallocate(Gcov)
+
+end subroutine calc_ZonalProfile_2Damps
+!=======================================================================
+
+
+!=======================================================================
+subroutine eval_ZonalProfile_1Dgrid(this,I_Bamp,O_Zdata)
+ !
+ ! eval_ZonalProfile_1Dgrid: Given the zonal profile basis amplitudes,
+ ! compute 1D data values for the nlat gridpoints.
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ class(ZonalProfile_t):: this
+ real(r8),intent(in ):: I_Bamp (:)
+ real(r8),intent(out):: O_Zdata(:)
+ !
+ ! Local Values
+ !--------------
+ integer:: ii,nn
+
+ ! Construct grid values from basis amplitudes.
+ !--------------------------------------------------
+ O_Zdata(1:this%nlat) = 0._r8
+ do nn=1,this%nbas
+ do ii=1,this%nlat
+ O_Zdata(ii) = O_Zdata(ii) + (I_Bamp(nn)*this%basis(ii,nn))
+ end do
+ end do
+
+end subroutine eval_ZonalProfile_1Dgrid
+!=======================================================================
+
+
+!=======================================================================
+subroutine eval_ZonalProfile_2Dgrid(this,I_Bamp,O_Zdata)
+ !
+ ! eval_ZonalProfile_2Dgrid: Given the zonal profile basis amplitudes,
+ ! compute 2D data values for the nlat,nlev gridpoints.
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ class(ZonalProfile_t):: this
+ real(r8),intent(in ):: I_Bamp (:,:)
+ real(r8),intent(out):: O_Zdata(:,:)
+ !
+ ! Local Values
+ !--------------
+ integer:: ii,nn,ilev
+
+ integer :: nlev
+
+ nlev = size(I_Bamp,dim=2)
+
+ ! Construct grid values from basis amplitudes.
+ !--------------------------------------------------
+ O_Zdata(1:this%nlat,1:nlev) = 0._r8
+ do nn=1,this%nbas
+ do ilev=1,nlev
+ do ii=1,this%nlat
+ O_Zdata(ii,ilev) = O_Zdata(ii,ilev) + (I_Bamp(nn,ilev)*this%basis(ii,nn))
+ end do
+ end do
+ end do
+
+end subroutine eval_ZonalProfile_2Dgrid
+!=======================================================================
+
+!=======================================================================
+subroutine final_ZonalProfile(this)
+ class(ZonalProfile_t) :: this
+
+ if(allocated(this%area )) deallocate(this%area)
+ if(allocated(this%basis)) deallocate(this%basis)
+ if(allocated(this%map )) deallocate(this%map)
+
+end subroutine final_ZonalProfile
+!=======================================================================
+
+!=======================================================================
+subroutine init_ZonalAverage(this,IO_lats,IO_area,I_nlat,GEN_GAUSSLATS)
+ !
+ ! init_ZonalAverage: Initialize the ZonalAverage data structure for the
+ ! given nlat gridpoints. It is assumed that the domain
+ ! of these gridpoints of the profile span latitudes
+ ! from SP to NP.
+ !
+ ! The optional GEN_GAUSSLATS flag allows for the
+ ! generation of Gaussian latitudes. The generated grid
+ ! over-writes the values of IO_lats/IO_area passed by
+ ! the user.
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ class(ZonalAverage_t) :: this
+ real(r8) ,intent(inout):: IO_lats(:)
+ real(r8) ,intent(inout):: IO_area(:)
+ integer ,intent(in):: I_nlat
+ logical,optional,intent(in):: GEN_GAUSSLATS
+ !
+ ! Local Values
+ !--------------
+ real(r8),allocatable:: Clats (:)
+ real(r8),allocatable:: Glats (:,:)
+ real(r8),allocatable:: BinLat(:)
+ real(r8),allocatable:: Asum (:,:)
+ real(r8),allocatable:: Anorm (:)
+ real(r8):: area(pcols),rlat
+ integer :: nn,jj,ierr, astat
+ integer :: ncols,lchnk,cc,jlat
+ integer :: nlcols, count
+ logical :: generate_lats
+ character(len=*), parameter :: subname = 'init_ZonalAverage'
+
+ generate_lats = .false.
+
+ if (present(GEN_GAUSSLATS)) then
+ generate_lats = GEN_GAUSSLATS
+ end if
+
+ nlcols = get_nlcols_p()
+
+ ! Allocate space
+ !-----------------
+ if(allocated(this%area )) deallocate(this%area)
+ if(allocated(this%a_norm )) deallocate(this%a_norm)
+ if(allocated(this%area_g )) deallocate(this%area_g)
+ if(allocated(this%idx_map)) deallocate(this%idx_map)
+
+ this%nlat = I_nlat
+ allocate(this%area (I_nlat), stat=astat)
+ call handle_allocate_error(astat, subname, 'this%area')
+ allocate(this%a_norm (I_nlat), stat=astat)
+ call handle_allocate_error(astat, subname, 'this%a_norm')
+ allocate(this%area_g (pcols,begchunk:endchunk), stat=astat)
+ call handle_allocate_error(astat, subname, 'this%area_g')
+ allocate(this%idx_map(pcols,begchunk:endchunk), stat=astat)
+ call handle_allocate_error(astat, subname, 'this%idx_map')
+
+ allocate(Clats (I_nlat), stat=astat)
+ call handle_allocate_error(astat, subname, 'Clats')
+ allocate(BinLat(I_nlat+1), stat=astat)
+ call handle_allocate_error(astat, subname, 'BinLat')
+ allocate(Glats (pcols,begchunk:endchunk), stat=astat)
+ call handle_allocate_error(astat, subname, 'Glats')
+ allocate(Asum (nlcols,I_nlat), stat=astat)
+ call handle_allocate_error(astat, subname, 'Asum')
+ allocate(Anorm (I_nlat), stat=astat)
+ call handle_allocate_error(astat, subname, 'Anorm')
+
+ ! Optionally create the Latitude Gridpoints
+ ! and their associated area weights. Otherwise
+ ! they need to be supplied by the user.
+ !-----------------------------------------------
+ if(generate_lats) then
+
+ ! Create a Gaussin grid from SP to NP
+ !--------------------------------------
+ call sh_create_gaus_grid(this%nlat,Clats,IO_area,ierr)
+ if (ierr/=0) then
+ call endrun('init_ZonalAverage: Error creating Gaussian grid')
+ end if
+
+ ! Convert generated colatitudes SP->NP to Lats and convert
+ ! to degrees and scale the area for global 2D integrals
+ !-----------------------------------------------------------
+ do nn=1,this%nlat
+ IO_lats(nn) = (45._r8*Clats(nn)/qrtrPI) - 90._r8
+ IO_area(nn) = IO_area(nn)*twoPI
+ end do
+ else
+ ! Convert Latitudes to SP->NP colatitudes in radians
+ !----------------------------------------------------
+ do nn=1,this%nlat
+ Clats(nn) = (IO_lats(nn) + 90._r8)*qrtrPI/45._r8
+ end do
+ endif
+
+ ! Copy the Lat grid area weights to the data structure
+ !-----------------------------------------------------
+ this%area(1:this%nlat) = IO_area(1:this%nlat)
+
+ ! Save a copy of the area weights for each 2D gridpoint
+ ! and convert Latitudes to SP->NP colatitudes in radians
+ !-------------------------------------------------------
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ call get_wght_all_p(lchnk, ncols, area)
+ do cc = 1,ncols
+ rlat=get_rlat_p(lchnk,cc)
+ this%area_g(cc,lchnk) = area(cc)
+ Glats (cc,lchnk) = rlat + halfPI
+ end do
+ end do
+
+ ! Set boundaries for Latitude bins
+ !-----------------------------------
+ BinLat(1) = 0._r8
+ BinLat(this%nlat+1) = pi
+ do nn=2,this%nlat
+ BinLat(nn) = (Clats(nn-1)+Clats(nn))/2._r8
+ end do
+
+ ! Loop over 2D gridpoints and determine its lat bin index
+ !---------------------------------------------------------
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ do cc = 1,ncols
+ jlat = -1
+ if((Glats(cc,lchnk)<=BinLat(2)).and. &
+ (Glats(cc,lchnk)>=BinLat(1)) ) then
+ jlat = 1
+ elseif((Glats(cc,lchnk)>=BinLat(this%nlat) ).and. &
+ (Glats(cc,lchnk)<=BinLat(this%nlat+1)) ) then
+ jlat = this%nlat
+ else
+ do jj=2,(this%nlat-1)
+ if((Glats(cc,lchnk)>BinLat(jj )).and. &
+ (Glats(cc,lchnk)<=BinLat(jj+1)) ) then
+ jlat = jj
+ exit
+ endif
+ end do
+ endif
+ if (jlat<1) then
+ call endrun('ZonalAverage init ERROR: jlat not in range')
+ endif
+ this%idx_map(cc,lchnk) = jlat
+ end do
+ end do
+
+ ! Initialize 2D Area sums for each bin
+ !--------------------------------------
+ Asum(:,:) = 0._r8
+ Anorm(:) = 0._r8
+ count = 0
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ do cc = 1,ncols
+ jlat = this%idx_map(cc,lchnk)
+ count=count+1
+ Asum(count,jlat) = this%area_g(cc,lchnk)
+ end do
+ end do
+
+ call shr_reprosum_calc(Asum, Anorm, count, nlcols, I_nlat, gbl_count=ngcols_p, commid=mpicom)
+
+ this%a_norm = Anorm
+
+ if (.not.all(Anorm(:)>0._r8)) then
+ write(iulog,*) 'init_ZonalAverage -- ERROR in Anorm values: '
+ do jlat = 1,I_nlat
+ if (.not.Anorm(jlat)>0._r8) then
+ write(iulog,*) ' Anorm(',jlat,'): ', Anorm(jlat)
+ endif
+ end do
+ call endrun('init_ZonalAverage -- ERROR in Anorm values')
+ end if
+
+ ! End Routine
+ !------------
+ deallocate(Clats)
+ deallocate(BinLat)
+ deallocate(Glats)
+ deallocate(Asum)
+ deallocate(Anorm)
+
+end subroutine init_ZonalAverage
+!=======================================================================
+
+
+!=======================================================================
+subroutine calc_ZonalAverage_2DbinAvg(this,I_Gdata,O_Zdata)
+ !
+ ! calc_ZonalAverage_2DbinAvg: Given 2D data values for ncol gridpoints,
+ ! compute the nlat area weighted binAvg profile
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ class(ZonalAverage_t):: this
+ real(r8),intent(in ):: I_Gdata(pcols,begchunk:endchunk)
+ real(r8),intent(out):: O_Zdata(:)
+ !
+ ! Local Values
+ !--------------
+ real(r8),allocatable:: Asum (:,:)
+ integer:: nn,ncols,lchnk,cc,jlat
+ integer :: nlcols, count, astat
+ character(len=*), parameter :: subname = 'calc_ZonalAverage_2DbinAvg'
+
+ nlcols = get_nlcols_p()
+
+
+ ! Initialize Zonal profile
+ !---------------------------
+ allocate(Asum(nlcols,this%nlat), stat=astat)
+ call handle_allocate_error(astat, subname, 'Asum')
+ Asum(:,:) = 0._r8
+
+ O_Zdata(1:this%nlat) = 0._r8
+
+ ! Compute area-weighted sums
+ !-----------------------------
+ count = 0
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ do cc = 1,ncols
+ jlat = this%idx_map(cc,lchnk)
+ count=count+1
+ Asum(count,jlat) = I_Gdata(cc,lchnk)*this%area_g(cc,lchnk)
+ end do
+ end do
+
+ call shr_reprosum_calc(Asum,O_Zdata,count, nlcols, this%nlat,gbl_count=ngcols_p, commid=mpicom)
+
+ ! Divide by area norm to get the averages
+ !-----------------------------------------
+ do nn=1,this%nlat
+ O_Zdata(nn) = O_Zdata(nn)/this%a_norm(nn)
+ end do
+
+ deallocate(Asum)
+
+end subroutine calc_ZonalAverage_2DbinAvg
+!=======================================================================
+
+
+!=======================================================================
+subroutine calc_ZonalAverage_3DbinAvg(this,I_Gdata,O_Zdata)
+ !
+ ! calc_ZonalAverage_3DbinAvg: Given 3D data values for ncol,nlev gridpoints,
+ ! compute the nlat,nlev area weighted binAvg profile
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ class(ZonalAverage_t):: this
+ real(r8),intent(in ):: I_Gdata(:,:,begchunk:)
+ real(r8),intent(out):: O_Zdata(:,:)
+ !
+ ! Local Values
+ !--------------
+ real(r8),allocatable:: Gsum(:)
+ real(r8),allocatable:: Asum(:,:)
+ integer:: nn,ncols,lchnk,cc,jlat
+ integer:: Nsum,ilev,ns
+
+ integer :: nlev
+ integer :: nlcols, count, astat
+ character(len=*), parameter :: subname = 'calc_ZonalAverage_3DbinAvg'
+
+ nlev = size(I_Gdata,dim=2)
+ nlcols = get_nlcols_p()
+
+ ! Initialize Zonal profile
+ !---------------------------
+ Nsum = this%nlat*nlev
+ allocate(Gsum(Nsum), stat=astat)
+ call handle_allocate_error(astat, subname, 'Gsum')
+ allocate(Asum(nlcols,Nsum), stat=astat)
+ call handle_allocate_error(astat, subname, 'Asum')
+ Asum(:,:) = 0._r8
+
+ O_Zdata(1:this%nlat,1:nlev) = 0._r8
+
+ ! Compute area-weighted sums
+ !-----------------------------
+ do ilev = 1,nlev
+ count = 0
+ do lchnk=begchunk,endchunk
+ ncols = get_ncols_p(lchnk)
+ do cc = 1,ncols
+ jlat = this%idx_map(cc,lchnk)
+ ns = jlat + (ilev-1)*this%nlat
+ count=count+1
+ Asum(count,ns) = I_Gdata(cc,ilev,lchnk)*this%area_g(cc,lchnk)
+ end do
+ end do
+ end do
+
+ call shr_reprosum_calc(Asum,Gsum, count, nlcols, Nsum, gbl_count=ngcols_p, commid=mpicom)
+
+ ! Divide by area norm to get the averages
+ !-----------------------------------------
+ do ilev = 1,nlev
+ do nn = 1,this%nlat
+ ns = nn + (ilev-1)*this%nlat
+ O_Zdata(nn,ilev) = Gsum(ns)/this%a_norm(nn)
+ end do
+ end do
+
+ deallocate(Gsum)
+ deallocate(Asum)
+
+end subroutine calc_ZonalAverage_3DbinAvg
+!=======================================================================
+
+!=======================================================================
+subroutine final_ZonalAverage(this)
+ class(ZonalAverage_t) :: this
+
+ if(allocated(this%area )) deallocate(this%area)
+ if(allocated(this%a_norm )) deallocate(this%a_norm)
+ if(allocated(this%area_g )) deallocate(this%area_g)
+ if(allocated(this%idx_map)) deallocate(this%idx_map)
+
+end subroutine final_ZonalAverage
+!=======================================================================
+
+
+!=======================================================================
+subroutine Invert_Matrix(I_Mat,Nbas,O_InvMat)
+ !
+ ! Invert_Matrix: Given the NbasxNbas matrix, calculate and return
+ ! the inverse of the matrix.
+ !
+ ! Implemented with the LAPACK DGESV routine.
+ !
+ !====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ real(r8), intent(inout) :: I_Mat(:,:) ! input matrix contains P*L*U
+ ! decomposition on output
+ integer, intent(in) :: Nbas
+ real(r8), intent(out) :: O_InvMat(:,:)
+ !
+ ! Local Values
+ !-------------
+ integer, allocatable :: Indx(:) ! pivot indices
+ integer :: astat, ii
+ character(len=*), parameter :: subname = 'Invert_Matrix'
+ character(len=80) :: msg
+
+ external DGESV
+
+ ! Allocate work space
+ !---------------------
+ allocate(Indx(Nbas), stat=astat)
+ call handle_allocate_error(astat, subname, 'Indx')
+
+ ! Initialize the inverse array with the identity matrix
+ !-------------------------------------------------------
+ O_InvMat(:,:) = 0._r8
+ do ii=1,Nbas
+ O_InvMat(ii,ii) = 1._r8
+ end do
+
+ call DGESV(Nbas, Nbas, I_Mat, Nbas, Indx, O_InvMat, Nbas, astat)
+
+ if (astat < 0) then
+ write(msg, '(a, i1, a)') 'argument # ', abs(astat), ' has an illegal value'
+ call endrun(subname//': DGESV error return: '//msg)
+ else if (astat > 0) then
+ call endrun(subname//': DGESV error return: matrix is singular')
+ end if
+
+ deallocate(Indx)
+
+end subroutine Invert_Matrix
+!=======================================================================
+
+!=======================================================================
+! legacy spherepack routines
+!=======================================================================
+subroutine sh_gen_basis_coefs(nn,mm,cp)
+ !
+ ! spherepack alfk
+ !
+ ! dimension of real cp(nn/2 + 1)
+ ! arguments
+ !
+ ! purpose computes fourier coefficients in the trigonometric series
+ ! representation of the normalized associated
+ ! legendre function pbar(nn,mm,theta) for use by
+ ! sh_gen_basis_coefs in calculating pbar(nn,mm,theta).
+ !
+ ! first define the normalized associated
+ ! legendre functions
+ !
+ ! pbar(mm,nn,theta) = sqrt((2*nn+1)*factorial(nn-mm)
+ ! /(2*factorial(nn+mm)))*sin(theta)**mm/(2**nn*
+ ! factorial(nn)) times the (nn+mm)th derivative of
+ ! (x**2-1)**nn with respect to x=cos(theta)
+ !
+ ! where theta is colatitude.
+ !
+ ! then subroutine sh_gen_basis_coefs computes the coefficients
+ ! cp(k) in the following trigonometric
+ ! expansion of pbar(m,n,theta).
+ !
+ ! 1) for n even and m even, pbar(mm,nn,theta) =
+ ! .5*cp(1) plus the sum from k=1 to k=nn/2
+ ! of cp(k+1)*cos(2*k*th)
+ !
+ ! 2) for nn even and mm odd, pbar(mm,nn,theta) =
+ ! the sum from k=1 to k=nn/2 of
+ ! cp(k)*sin(2*k*th)
+ !
+ ! 3) for n odd and m even, pbar(mm,nn,theta) =
+ ! the sum from k=1 to k=(nn+1)/2 of
+ ! cp(k)*cos((2*k-1)*th)
+ !
+ ! 4) for nn odd and mm odd, pbar(mm,nn,theta) =
+ ! the sum from k=1 to k=(nn+1)/2 of
+ ! cp(k)*sin((2*k-1)*th)
+ !
+ ! arguments
+ !
+ ! on input nn
+ ! nonnegative integer specifying the degree of
+ ! pbar(nn,mm,theta)
+ !
+ ! mm
+ ! is the order of pbar(nn,mm,theta). mm can be
+ ! any integer however cp is computed such that
+ ! pbar(nn,mm,theta) = 0 if abs(m) is greater
+ ! than nn and pbar(nn,mm,theta) = (-1)**mm*
+ ! pbar(nn,-mm,theta) for negative mm.
+ !
+ ! on output cp
+ ! array of length (nn/2)+1
+ ! which contains the fourier coefficients in
+ ! the trigonometric series representation of
+ ! pbar(nn,mm,theta)
+ !
+ ! special conditions none
+ !
+ ! algorithm the highest order coefficient is determined in
+ ! closed form and the remainig coefficients are
+ ! determined as the solution of a backward
+ ! recurrence relation.
+ !
+ !=====================================================================
+ !
+ ! Passed Variables
+ !------------------
+ integer ,intent(in ):: nn
+ integer ,intent(in ):: mm
+ real(r8),intent(out):: cp(nn/2+1)
+ !
+ ! Local Values
+ !----------------
+ real(r8):: fnum,fnmh
+ real(r8):: pm1
+ real(r8):: t1,t2
+ real(r8):: fden
+ real(r8):: cp2
+ real(r8):: fnnp1
+ real(r8):: fnmsq
+ real(r8):: fk
+ real(r8):: a1,b1,C1
+ integer :: ma,nmms2,nex
+ integer :: ii,jj
+
+ real(r8),parameter:: SC10=1024._r8
+ real(r8),parameter:: SC20=SC10*SC10
+ real(r8),parameter:: SC40=SC20*SC20
+
+ cp(1) = 0._r8
+ ma = abs(mm)
+ if(ma>nn) return
+
+ if((nn-1)<0) then
+ cp(1) = sqrt(2._r8)
+ return
+ elseif((nn-1)==0) then
+ if(ma/=0) then
+ cp(1) = sqrt(.75_r8)
+ if(mm==-1) cp(1) = -cp(1)
+ else
+ cp(1) = sqrt(1.5_r8)
+ endif
+ return
+ else
+ if(mod(nn+ma,2)/=0) then
+ nmms2 = (nn-ma-1)/2
+ fnum = nn + ma + 2
+ fnmh = nn - ma + 2
+ pm1 = -1._r8
+ else
+ nmms2 = (nn-ma)/2
+ fnum = nn + ma + 1
+ fnmh = nn - ma + 1
+ pm1 = 1._r8
+ endif
+ endif
+
+ t1 = 1._r8/SC20
+ nex = 20
+ fden = 2._r8
+ if(nmms2>=1) then
+ do ii = 1,nmms2
+ t1 = fnum*t1/fden
+ if (t1>SC20) then
+ t1 = t1/SC40
+ nex = nex + 40
+ endif
+ fnum = fnum + 2._r8
+ fden = fden + 2._r8
+ end do
+ endif
+
+ if(mod(ma/2,2)/=0) then
+ t1 = -t1/2._r8**(nn-1-nex)
+ else
+ t1 = t1/2._r8**(nn-1-nex)
+ endif
+ t2 = 1._r8
+ if(ma/=0) then
+ do ii = 1,ma
+ t2 = fnmh*t2/ (fnmh+pm1)
+ fnmh = fnmh + 2._r8
+ end do
+ endif
+
+ cp2 = t1*sqrt((nn+.5_r8)*t2)
+ fnnp1 = nn*(nn+1)
+ fnmsq = fnnp1 - 2._r8*ma*ma
+
+ if((mod(nn,2)==0).and.(mod(ma,2)==0)) then
+ jj = 1+(nn+1)/2
+ else
+ jj = (nn+1)/2
+ endif
+
+ cp(jj) = cp2
+ if(mm<0) then
+ if(mod(ma,2)/=0) cp(jj) = -cp(jj)
+ endif
+ if(jj<=1) return
+
+ fk = nn
+ a1 = (fk-2._r8)*(fk-1._r8) - fnnp1
+ b1 = 2._r8* (fk*fk-fnmsq)
+ cp(jj-1) = b1*cp(jj)/a1
+
+ jj = jj - 1
+ do while(jj>1)
+ fk = fk - 2._r8
+ a1 = (fk-2._r8)*(fk-1._r8) - fnnp1
+ b1 = -2._r8*(fk*fk-fnmsq)
+ c1 = (fk+1._r8)*(fk+2._r8) - fnnp1
+ cp(jj-1) = -(b1*cp(jj)+c1*cp(jj+1))/a1
+ jj = jj - 1
+ end do
+
+end subroutine sh_gen_basis_coefs
+!=======================================================================
+
+!=======================================================================
+subroutine sh_create_basis(nn,mm,theta,cp,pb)
+ !
+ ! spherepack lfpt
+ !
+ ! dimension of
+ ! arguments
+ ! cp((nn/2)+1)
+ !
+ ! purpose routine sh_create_basis uses coefficients computed by
+ ! routine sh_gen_basis_coefs to compute the
+ ! normalized associated legendre function pbar(nn,mm,theta)
+ ! at colatitude theta.
+ !
+ ! arguments
+ !
+ ! on input nn
+ ! nonnegative integer specifying the degree of
+ ! pbar(nn,mm,theta)
+ ! mm
+ ! is the order of pbar(nn,mm,theta). mm can be
+ ! any integer however pbar(nn,mm,theta) = 0
+ ! if abs(mm) is greater than nn and
+ ! pbar(nn,mm,theta) = (-1)**mm*pbar(nn,-mm,theta)
+ ! for negative mm.
+ !
+ ! theta
+ ! colatitude in radians
+ !
+ ! cp
+ ! array of length (nn/2)+1
+ ! containing coefficients computed by routine
+ ! sh_gen_basis_coefs
+ !
+ ! on output pb
+ ! variable containing pbar(n,m,theta)
+ !
+ ! special conditions calls to routine sh_create_basis must be preceded by an
+ ! appropriate call to routine sh_gen_basis_coefs.
+ !
+ ! algorithm the trigonometric series formula used by
+ ! routine sh_create_basis to calculate pbar(nn,mm,theta) at
+ ! colatitude theta depends on mm and nn as follows:
+ !
+ ! 1) for nn even and mm even, the formula is
+ ! .5*cp(1) plus the sum from k=1 to k=n/2
+ ! of cp(k)*cos(2*k*theta)
+ ! 2) for nn even and mm odd. the formula is
+ ! the sum from k=1 to k=nn/2 of
+ ! cp(k)*sin(2*k*theta)
+ ! 3) for nn odd and mm even, the formula is
+ ! the sum from k=1 to k=(nn+1)/2 of
+ ! cp(k)*cos((2*k-1)*theta)
+ ! 4) for nn odd and mm odd, the formula is
+ ! the sum from k=1 to k=(nn+1)/2 of
+ ! cp(k)*sin((2*k-1)*theta)
+ !
+ !=====================================================================
+ integer, intent(in) :: nn,mm
+ real(r8), intent(in) :: theta
+ real(r8), intent(in) :: cp(:)
+ real(r8), intent(out) :: pb
+
+ real(r8) :: cdt
+ real(r8) :: sdt
+ real(r8) :: ct
+ real(r8) :: st
+ real(r8) :: summ
+ real(r8) :: cth
+
+ integer:: ma,nmod,mmod,kdo
+ integer:: kp1,kk
+
+ pb = 0._r8
+ ma = abs(mm)
+ if(ma>nn) return
+
+ if(nn<=0) then
+ if(ma<=0) then
+ pb = sqrt(.5_r8)
+ return
+ endif
+ endif
+
+ nmod = mod(nn,2)
+ mmod = mod(ma,2)
+
+ if(nmod<=0) then
+ if(mmod<=0) then
+ kdo = nn/2 + 1
+ cdt = cos(theta+theta)
+ sdt = sin(theta+theta)
+ ct = 1._r8
+ st = 0._r8
+ summ = .5_r8*cp(1)
+ do kp1 = 2,kdo
+ cth = cdt*ct - sdt*st
+ st = sdt*ct + cdt*st
+ ct = cth
+ summ = summ + cp(kp1)*ct
+ end do
+ pb = summ
+ return
+ endif
+ kdo = nn/2
+ cdt = cos(theta+theta)
+ sdt = sin(theta+theta)
+ ct = 1._r8
+ st = 0._r8
+ summ = 0._r8
+ do kk = 1,kdo
+ cth = cdt*ct - sdt*st
+ st = sdt*ct + cdt*st
+ ct = cth
+ summ = summ + cp(kk)*st
+ end do
+ pb = summ
+ return
+ endif
+
+ kdo = (nn+1)/2
+ if(mmod<=0) then
+ cdt = cos(theta+theta)
+ sdt = sin(theta+theta)
+ ct = cos(theta)
+ st = -sin(theta)
+ summ = 0._r8
+ do kk = 1,kdo
+ cth = cdt*ct - sdt*st
+ st = sdt*ct + cdt*st
+ ct = cth
+ summ = summ + cp(kk)*ct
+ end do
+ pb = summ
+ return
+ endif
+
+ cdt = cos(theta+theta)
+ sdt = sin(theta+theta)
+ ct = cos(theta)
+ st = -sin(theta)
+ summ = 0._r8
+ do kk = 1,kdo
+ cth = cdt*ct - sdt*st
+ st = sdt*ct + cdt*st
+ ct = cth
+ summ = summ + cp(kk)*st
+ end do
+ pb = summ
+
+end subroutine sh_create_basis
+!=======================================================================
+
+!=======================================================================
+subroutine sh_create_gaus_grid(nlat,theta,wts,ierr)
+ !
+ ! spherepack gaqd
+ ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ ! . .
+ ! . copyright (c) 2001 by ucar .
+ ! . .
+ ! . university corporation for atmospheric research .
+ ! . .
+ ! . all rights reserved .
+ ! . .
+ ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+ !
+ ! February 2002
+ !
+ ! gauss points and weights are computed using the fourier-newton
+ ! described in "on computing the points and weights for
+ ! gauss-legendre quadrature", paul n. swarztrauber, siam journal
+ ! on scientific computing (DOI 10.1137/S1064827500379690).
+ ! This routine is faster and more accurate than older program
+ ! with the same name.
+ !
+ ! computes the nlat gaussian colatitudes and weights
+ ! in double precision. the colatitudes are in radians and lie in the
+ ! in the interval (0,pi).
+ !
+ ! input parameters
+ !
+ ! nlat the number of gaussian colatitudes in the interval (0,pi)
+ ! (between the two poles). nlat must be greater than zero.
+ !
+ ! output parameters
+ !
+ ! theta a double precision array with length nlat
+ ! containing the gaussian colatitudes in
+ ! increasing radians on the interval (0,pi).
+ !
+ ! wts a double precision array with lenght nlat
+ ! containing the gaussian weights.
+ !
+ ! ierror = 0 no errors
+ ! = 1 if nlat<=0
+ !
+ !===================================================================
+ !
+ ! Passed variables
+ !-----------------
+ integer ,intent(in ) :: nlat
+ real(r8),intent(out) :: theta(nlat)
+ real(r8),intent(out) :: wts(nlat)
+ integer ,intent(out) :: ierr
+ !
+ ! Local Values
+ !-------------
+ real(r8):: sgnd
+ real(r8):: xx,dtheta,dthalf
+ real(r8):: cmax,zprev,zlast,zero,zhold,pb,dpb,dcor,summ,cz
+ integer :: mnlat,ns2,nhalf,nix,it,ii
+
+ real(r8), parameter :: eps = epsilon(1._r8)
+
+ ! check work space length
+ !------------------------
+ if(nlat<=0) then
+ ierr = 1
+ return
+ endif
+ ierr = 0
+
+ ! compute weights and points analytically when nlat=1,2
+ !-------------------------------------------------------
+ if(nlat==1) then
+ theta(1) = acos(0._r8)
+ wts (1) = 2._r8
+ return
+ elseif(nlat==2) then
+ xx = sqrt(1._r8/3._r8)
+ theta(1) = acos( xx)
+ theta(2) = acos(-xx)
+ wts (1) = 1._r8
+ wts (2) = 1._r8
+ return
+ endif
+
+ ! Proceed for nlat > 2
+ !----------------------
+ mnlat = mod(nlat,2)
+ ns2 = nlat/2
+ nhalf = (nlat+1)/2
+
+ call sh_fourier_coefs_dp(nlat,cz,theta(ns2+1),wts(ns2+1))
+
+ dtheta = halfPI/nhalf
+ dthalf = dtheta/2._r8
+ cmax = .2_r8*dtheta
+
+ ! estimate first point next to theta = pi/2
+ !-------------------------------------------
+ if(mnlat/=0) then
+ zero = halfPI - dtheta
+ zprev = halfPI
+ nix = nhalf - 1
+ else
+ zero = halfPI - dthalf
+ nix = nhalf
+ endif
+
+ do while(nix/=0)
+ dcor = huge(1._r8)
+ it = 0
+ do while (abs(dcor) > eps*abs(zero))
+ it = it + 1
+ ! newton iterations
+ !-----------------------
+ call sh_legp_dlegp_theta(nlat,zero,cz,theta(ns2+1),wts(ns2+1),pb,dpb)
+ dcor = pb/dpb
+ if(dcor.ne.0._r8) then
+ sgnd = dcor/abs(dcor)
+ else
+ sgnd = 1._r8
+ endif
+ dcor = sgnd*min(abs(dcor),cmax)
+ zero = zero - dcor
+ end do
+
+ theta(nix) = zero
+ zhold = zero
+
+ ! wts(nix) = (nlat+nlat+1)/(dpb*dpb)
+ ! yakimiw's formula permits using old pb and dpb
+ !--------------------------------------------------
+ wts(nix) = (nlat+nlat+1)/ (dpb+pb*dcos(zlast)/dsin(zlast))**2
+ nix = nix - 1
+ if(nix==nhalf-1) zero = 3._r8*zero - pi
+ if(nix0) then
+ cth = cdt
+ sth = sdt
+ do kk = 1,kdo
+ pb = pb + cp(kk)*cth
+ dpb = dpb - dcp(kk)*sth
+ chh = cdt*cth - sdt*sth
+ sth = sdt*cth + cdt*sth
+ cth = chh
+ end do
+ endif
+ else
+ ! n odd
+ !-----------
+ kdo = (nn+1)/2
+ pb = 0._r8
+ dpb = 0._r8
+ cth = dcos(theta)
+ sth = dsin(theta)
+ do kk = 1,kdo
+ pb = pb + cp(kk)*cth
+ dpb = dpb - dcp(kk)*sth
+ chh = cdt*cth - sdt*sth
+ sth = sdt*cth + cdt*sth
+ cth = chh
+ end do
+ endif
+
+end subroutine sh_legp_dlegp_theta
+!=======================================================================
+
+end module zonal_mean_mod
diff --git a/components/eam/src/physics/crm/crm_physics.F90 b/components/eam/src/physics/crm/crm_physics.F90
index cc65d559bb88..61ef03f8ca65 100644
--- a/components/eam/src/physics/crm/crm_physics.F90
+++ b/components/eam/src/physics/crm/crm_physics.F90
@@ -1302,14 +1302,23 @@ subroutine crm_physics_tend(ztodt, state, tend, ptend, pbuf2d, cam_in, cam_out,
call pam_mirror_array_readonly( 'input_tau00', crm_input%tau00 )
! call pam_mirror_array_readonly( 'input_ul_esmt', crm_input%ul_esmt )
! call pam_mirror_array_readonly( 'input_vl_esmt', crm_input%vl_esmt )
- ! call pam_mirror_array_readonly( 'input_t_vt', crm_input%t_vt )
- ! call pam_mirror_array_readonly( 'input_q_vt', crm_input%q_vt )
- ! call pam_mirror_array_readonly( 'input_u_vt', crm_input%u_vt )
-
call pam_mirror_array_readonly( 'input_nccn_prescribed',crm_input%nccn_prescribed )
call pam_mirror_array_readonly( 'input_nc_nuceat_tend', crm_input%nc_nuceat_tend )
call pam_mirror_array_readonly( 'input_ni_activated', crm_input%ni_activated )
+ ! Variance transport inputs and outputs
+ if (use_MMF_VT) then
+ call pam_mirror_array_readonly( 'input_vt_t', crm_input%t_vt )
+ call pam_mirror_array_readonly( 'input_vt_q', crm_input%q_vt )
+ call pam_mirror_array_readonly( 'input_vt_u', crm_input%u_vt )
+ call pam_mirror_array_readwrite( 'output_t_vt_tend', crm_output%t_vt_tend )
+ call pam_mirror_array_readwrite( 'output_q_vt_tend', crm_output%q_vt_tend )
+ call pam_mirror_array_readwrite( 'output_u_vt_tend', crm_output%u_vt_tend )
+ call pam_mirror_array_readwrite( 'output_t_vt_ls', crm_output%t_vt_ls )
+ call pam_mirror_array_readwrite( 'output_q_vt_ls', crm_output%q_vt_ls )
+ call pam_mirror_array_readwrite( 'output_u_vt_ls', crm_output%u_vt_ls )
+ end if
+
call pam_mirror_array_readwrite( 'state_u_wind', crm_state%u_wind )
call pam_mirror_array_readwrite( 'state_v_wind', crm_state%v_wind )
call pam_mirror_array_readwrite( 'state_w_wind', crm_state%w_wind )
@@ -1389,12 +1398,6 @@ subroutine crm_physics_tend(ztodt, state, tend, ptend, pbuf2d, cam_in, cam_out,
call pam_mirror_array_readwrite( 'output_qltend', crm_output%qltend, '' )
call pam_mirror_array_readwrite( 'output_qcltend', crm_output%qcltend, '' )
call pam_mirror_array_readwrite( 'output_qiltend', crm_output%qiltend, '' )
- ! call pam_mirror_array_readwrite( 'output_t_vt_tend', crm_output%t_vt_tend, '' )
- ! call pam_mirror_array_readwrite( 'output_q_vt_tend', crm_output%q_vt_tend, '' )
- ! call pam_mirror_array_readwrite( 'output_u_vt_tend', crm_output%u_vt_tend, '' )
- ! call pam_mirror_array_readwrite( 'output_t_vt_ls', crm_output%t_vt_ls, '' )
- ! call pam_mirror_array_readwrite( 'output_q_vt_ls', crm_output%q_vt_ls, '' )
- ! call pam_mirror_array_readwrite( 'output_u_vt_ls', crm_output%u_vt_ls, '' )
call pam_mirror_array_readwrite( 'output_ultend', crm_output%ultend, '' )
call pam_mirror_array_readwrite( 'output_vltend', crm_output%vltend, '' )
! call pam_mirror_array_readwrite( 'output_tk', crm_output%tk, '' )
@@ -1450,7 +1453,6 @@ subroutine crm_physics_tend(ztodt, state, tend, ptend, pbuf2d, cam_in, cam_out,
call pam_register_dimension('gcm_lev',pver)
call pam_set_option('use_MMF_VT', use_MMF_VT_tmp )
- call pam_set_option('MMF_VT_wn_max', MMF_VT_wn_max )
call pam_set_option('use_MMF_ESMT', use_MMF_ESMT_tmp )
call pam_set_option('use_crm_accel', use_crm_accel_tmp )
diff --git a/components/eam/src/physics/crm/pam/pam_driver.cpp b/components/eam/src/physics/crm/pam/pam_driver.cpp
index f131bbd44f09..bfba64696163 100644
--- a/components/eam/src/physics/crm/pam/pam_driver.cpp
+++ b/components/eam/src/physics/crm/pam/pam_driver.cpp
@@ -13,6 +13,7 @@
#include "pam_statistics.h"
#include "pam_output.h"
#include "pam_accelerate.h"
+#include "pam_variance_transport.h"
#include "sponge_layer.h"
#include "surface_friction.h"
#include "scream_cxx_interface_finalize.h"
@@ -46,6 +47,7 @@ extern "C" void pam_driver() {
auto is_first_step = coupler.get_option("is_first_step");
auto is_restart = coupler.get_option("is_restart");
bool use_crm_accel = coupler.get_option("use_crm_accel");
+ bool use_MMF_VT = coupler.get_option("use_MMF_VT");
bool enable_physics_tend_stats = coupler.get_option("enable_physics_tend_stats");
//------------------------------------------------------------------------------------------------
// set various coupler options
@@ -111,6 +113,11 @@ extern "C" void pam_driver() {
// initialize variables for CRM mean-state acceleration
if (use_crm_accel) { pam_accelerate_init(coupler); }
+ if (use_MMF_VT) {
+ pam_variance_transport_init(coupler);
+ pam_variance_transport_compute_forcing(coupler);
+ }
+
// initilize surface "psuedo-friction" (psuedo => doesn't match "real" GCM friction)
auto input_tau = dm_host.get("input_tau00").createDeviceCopy();
auto input_bflx = dm_host.get("input_bflxls").createDeviceCopy();
@@ -166,7 +173,8 @@ extern "C" void pam_driver() {
if (enable_check_state) { pam_debug_check_state(coupler, 1, nstep); }
- // run a PAM time step
+ // Apply forcing tendencies
+ if (use_MMF_VT) { pam_variance_transport_apply_forcing(coupler); }
coupler.run_module( "apply_gcm_forcing_tendencies" , modules::apply_gcm_forcing_tendencies );
coupler.run_module( "radiation" , [&] (pam::PamCoupler &coupler) {rad .timeStep(coupler);} );
if (enable_check_state) { pam_debug_check_state(coupler, 2, nstep); }
@@ -237,6 +245,11 @@ extern "C" void pam_driver() {
pam_statistics_compute_means(coupler);
pam_statistics_copy_to_host(coupler);
+ if (use_MMF_VT) {
+ pam_variance_transport_compute_feedback(coupler);
+ pam_variance_transport_copy_to_host(coupler);
+ }
+
//------------------------------------------------------------------------------------------------
// Finalize and clean up
micro .finalize(coupler);
diff --git a/components/eam/src/physics/crm/pam/pam_variance_transport.h b/components/eam/src/physics/crm/pam/pam_variance_transport.h
new file mode 100644
index 000000000000..b7067631203f
--- /dev/null
+++ b/components/eam/src/physics/crm/pam/pam_variance_transport.h
@@ -0,0 +1,267 @@
+#pragma once
+
+#include "pam_coupler.h"
+
+inline void pam_variance_transport_init( pam::PamCoupler &coupler ) {
+ using yakl::c::parallel_for;
+ using yakl::c::SimpleBounds;
+ using yakl::atomicAdd;
+ auto &dm_device = coupler.get_data_manager_device_readwrite();
+ auto nens = coupler.get_option("ncrms");
+ auto nz = coupler.get_option("crm_nz");
+ auto ny = coupler.get_option("crm_ny");
+ auto nx = coupler.get_option("crm_nx");
+ //------------------------------------------------------------------------------------------------
+ dm_device.register_and_allocate("vt_temp", "temperature variance", {nz,nens}, {"z","nens"} );
+ dm_device.register_and_allocate("vt_rhov", "water vapor variance", {nz,nens}, {"z","nens"} );
+ dm_device.register_and_allocate("vt_uvel", "u momentum variance", {nz,nens}, {"z","nens"} );
+ dm_device.register_and_allocate("vt_temp_pert", "temperature perturbation from horz mean", {nz,ny,nx,nens}, {"z","y","x","nens"} );
+ dm_device.register_and_allocate("vt_rhov_pert", "water vapor perturbation from horz mean", {nz,ny,nx,nens}, {"z","y","x","nens"} );
+ dm_device.register_and_allocate("vt_uvel_pert", "u momentum perturbation from horz mean", {nz,ny,nx,nens}, {"z","y","x","nens"} );
+ dm_device.register_and_allocate("vt_temp_forcing_tend", "temperature variance forcing tendency", {nz,nens}, {"z","nens"} );
+ dm_device.register_and_allocate("vt_rhov_forcing_tend", "water vapor variance forcing tendency", {nz,nens}, {"z","nens"} );
+ dm_device.register_and_allocate("vt_uvel_forcing_tend", "u momentum variance forcing tendency", {nz,nens}, {"z","nens"} );
+ //------------------------------------------------------------------------------------------------
+}
+
+inline void pam_variance_transport_diagnose( pam::PamCoupler &coupler ) {
+ using yakl::c::parallel_for;
+ using yakl::c::SimpleBounds;
+ using yakl::atomicAdd;
+ auto &dm_device = coupler.get_data_manager_device_readwrite();
+ auto nens = coupler.get_option("ncrms");
+ auto nz = coupler.get_option("crm_nz");
+ auto ny = coupler.get_option("crm_ny");
+ auto nx = coupler.get_option("crm_nx");
+ //------------------------------------------------------------------------------------------------
+ auto temp = dm_device.get("temp" );
+ auto rhov = dm_device.get("water_vapor");
+ auto uvel = dm_device.get("uvel" );
+ auto vt_temp = dm_device.get("vt_temp" );
+ auto vt_rhov = dm_device.get("vt_rhov" );
+ auto vt_uvel = dm_device.get("vt_uvel" );
+ auto vt_temp_pert = dm_device.get("vt_temp_pert" );
+ auto vt_rhov_pert = dm_device.get("vt_rhov_pert" );
+ auto vt_uvel_pert = dm_device.get("vt_uvel_pert" );
+ //------------------------------------------------------------------------------------------------
+ // local variables
+ real2d temp_mean("temp_mean", nz, nens);
+ real2d rhov_mean("rhov_mean", nz, nens);
+ real2d uvel_mean("uvel_mean", nz, nens);
+ //------------------------------------------------------------------------------------------------
+ // initialize variance and horizontal mean
+ parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k, int n) {
+ temp_mean(k,n) = 0.0;
+ rhov_mean(k,n) = 0.0;
+ uvel_mean(k,n) = 0.0;
+ vt_temp(k,n) = 0.0;
+ vt_rhov(k,n) = 0.0;
+ vt_uvel(k,n) = 0.0;
+ });
+ //------------------------------------------------------------------------------------------------
+ // calculate horizontal mean
+ real r_nx_ny = 1._fp/(nx*ny); // precompute reciprocal to avoid costly divisions
+ parallel_for(SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int n) {
+ yakl::atomicAdd( temp_mean(k,n), temp(k,j,i,n)*r_nx_ny );
+ yakl::atomicAdd( rhov_mean(k,n), rhov(k,j,i,n)*r_nx_ny );
+ yakl::atomicAdd( uvel_mean(k,n), uvel(k,j,i,n)*r_nx_ny );
+ });
+ //------------------------------------------------------------------------------------------------
+ // calculate fluctuations from horz mean
+ parallel_for(SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int n) {
+ vt_temp_pert(k,j,i,n) = temp(k,j,i,n) - temp_mean(k,n);
+ vt_rhov_pert(k,j,i,n) = rhov(k,j,i,n) - rhov_mean(k,n);
+ vt_uvel_pert(k,j,i,n) = uvel(k,j,i,n) - uvel_mean(k,n);
+ });
+ //------------------------------------------------------------------------------------------------
+ // calculate variance
+ parallel_for(SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int n) {
+ yakl::atomicAdd( vt_temp(k,n), ( vt_temp_pert(k,j,i,n) * vt_temp_pert(k,j,i,n) ) * r_nx_ny );
+ yakl::atomicAdd( vt_rhov(k,n), ( vt_rhov_pert(k,j,i,n) * vt_rhov_pert(k,j,i,n) ) * r_nx_ny );
+ yakl::atomicAdd( vt_uvel(k,n), ( vt_uvel_pert(k,j,i,n) * vt_uvel_pert(k,j,i,n) ) * r_nx_ny );
+ });
+ //------------------------------------------------------------------------------------------------
+}
+
+inline void pam_variance_transport_compute_forcing( pam::PamCoupler &coupler ) {
+ using yakl::c::parallel_for;
+ using yakl::c::SimpleBounds;
+ auto &dm_device = coupler.get_data_manager_device_readwrite();
+ auto &dm_host = coupler.get_data_manager_host_readwrite();
+ auto nens = coupler.get_option("ncrms");
+ auto nz = coupler.get_option("crm_nz");
+ auto ny = coupler.get_option("crm_ny");
+ auto nx = coupler.get_option("crm_nx");
+ auto gcm_nlev = coupler.get_option("gcm_nlev");
+ auto gcm_dt = coupler.get_option("gcm_dt");
+ //------------------------------------------------------------------------------------------------
+ // update CRM variance values
+ pam_variance_transport_diagnose(coupler);
+ //------------------------------------------------------------------------------------------------
+ auto temp = dm_device.get("temp" );
+ auto rhov = dm_device.get("water_vapor" );
+ auto uvel = dm_device.get("uvel" );
+ auto vt_temp = dm_device.get("vt_temp" );
+ auto vt_rhov = dm_device.get("vt_rhov" );
+ auto vt_uvel = dm_device.get("vt_uvel" );
+ auto vt_temp_forcing_tend = dm_device.get("vt_temp_forcing_tend");
+ auto vt_rhov_forcing_tend = dm_device.get("vt_rhov_forcing_tend");
+ auto vt_uvel_forcing_tend = dm_device.get("vt_uvel_forcing_tend");
+ auto gcm_vt_temp = dm_host.get("input_vt_t").createDeviceCopy();
+ auto gcm_vt_rhov = dm_host.get("input_vt_q").createDeviceCopy();
+ auto gcm_vt_uvel = dm_host.get("input_vt_u").createDeviceCopy();
+ //------------------------------------------------------------------------------------------------
+ // calculate variance transport forcing
+ parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k_crm, int n) {
+ int k_gcm = gcm_nlev-1-k_crm;
+ vt_temp_forcing_tend(k_crm,n) = ( gcm_vt_temp(k_gcm,n) - vt_temp(k_crm,n) ) * gcm_dt ;
+ vt_rhov_forcing_tend(k_crm,n) = ( gcm_vt_rhov(k_gcm,n) - vt_rhov(k_crm,n) ) * gcm_dt ;
+ vt_uvel_forcing_tend(k_crm,n) = ( gcm_vt_uvel(k_gcm,n) - vt_uvel(k_crm,n) ) * gcm_dt ;
+ });
+ //------------------------------------------------------------------------------------------------
+}
+
+inline void pam_variance_transport_apply_forcing( pam::PamCoupler &coupler ) {
+ using yakl::c::parallel_for;
+ using yakl::c::SimpleBounds;
+ auto &dm_device = coupler.get_data_manager_device_readwrite();
+ auto nens = coupler.get_option("ncrms");
+ auto nz = coupler.get_option("crm_nz");
+ auto ny = coupler.get_option("crm_ny");
+ auto nx = coupler.get_option("crm_nx");
+ auto crm_dt = coupler.get_option("crm_dt");
+ //------------------------------------------------------------------------------------------------
+ // min and max perturbation scaling values are used to limit the
+ // large-scale forcing from variance transport. This is meant to
+ // protect against creating unstable situations, although
+ // problematic scenarios were extremely rare in testing.
+ // A scaling limit of +/- 10% was found to be adequate.
+ real constexpr pert_scale_min = 1.0 - 0.005;
+ real constexpr pert_scale_max = 1.0 + 0.005;
+ //------------------------------------------------------------------------------------------------
+ auto temp = dm_device.get("temp" );
+ auto rhov = dm_device.get("water_vapor" );
+ auto uvel = dm_device.get("uvel" );
+ auto vt_temp = dm_device.get("vt_temp" );
+ auto vt_rhov = dm_device.get("vt_rhov" );
+ auto vt_uvel = dm_device.get("vt_uvel" );
+ auto vt_temp_pert = dm_device.get("vt_temp_pert" );
+ auto vt_rhov_pert = dm_device.get("vt_rhov_pert" );
+ auto vt_uvel_pert = dm_device.get("vt_uvel_pert" );
+ auto vt_temp_forcing_tend = dm_device.get("vt_temp_forcing_tend");
+ auto vt_rhov_forcing_tend = dm_device.get("vt_rhov_forcing_tend");
+ auto vt_uvel_forcing_tend = dm_device.get("vt_uvel_forcing_tend");
+ //------------------------------------------------------------------------------------------------
+ // local variables
+ real2d temp_pert_scale("temp_pert_scale", nz, nens);
+ real2d rhov_pert_scale("rhov_pert_scale", nz, nens);
+ real2d uvel_pert_scale("uvel_pert_scale", nz, nens);
+ //------------------------------------------------------------------------------------------------
+ // update CRM variance values
+ pam_variance_transport_diagnose(coupler);
+ //------------------------------------------------------------------------------------------------
+ // calculate scaling factor for local perturbations
+ parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k, int n) {
+ // initialize scaling factors to 1.0
+ temp_pert_scale(k,n) = 1.0;
+ rhov_pert_scale(k,n) = 1.0;
+ uvel_pert_scale(k,n) = 1.0;
+ // set scaling factors as long as there are perturbations to scale
+ if (vt_temp(k,n)>0.0) { temp_pert_scale(k,n) = sqrt( 1.0 + crm_dt * vt_temp_forcing_tend(k,n) / vt_temp(k,n) ); }
+ if (vt_rhov(k,n)>0.0) { rhov_pert_scale(k,n) = sqrt( 1.0 + crm_dt * vt_rhov_forcing_tend(k,n) / vt_rhov(k,n) ); }
+ if (vt_uvel(k,n)>0.0) { uvel_pert_scale(k,n) = sqrt( 1.0 + crm_dt * vt_uvel_forcing_tend(k,n) / vt_uvel(k,n) ); }
+ // enforce minimum scaling
+ temp_pert_scale(k,n) = std::max( temp_pert_scale(k,n), pert_scale_min );
+ rhov_pert_scale(k,n) = std::max( rhov_pert_scale(k,n), pert_scale_min );
+ uvel_pert_scale(k,n) = std::max( uvel_pert_scale(k,n), pert_scale_min );
+ // enforce maximum scaling
+ temp_pert_scale(k,n) = std::min( temp_pert_scale(k,n), pert_scale_max );
+ rhov_pert_scale(k,n) = std::min( rhov_pert_scale(k,n), pert_scale_max );
+ uvel_pert_scale(k,n) = std::min( uvel_pert_scale(k,n), pert_scale_max );
+ });
+ //------------------------------------------------------------------------------------------------
+ // apply variance forcing tendency
+ parallel_for(SimpleBounds<4>(nz,ny,nx,nens), YAKL_LAMBDA (int k, int j, int i, int n) {
+ real temp_tend_loc = ( temp_pert_scale(k,n) * vt_temp_pert(k,j,i,n) - vt_temp_pert(k,j,i,n) );
+ real rhov_tend_loc = ( rhov_pert_scale(k,n) * vt_rhov_pert(k,j,i,n) - vt_rhov_pert(k,j,i,n) );
+ real uvel_tend_loc = ( uvel_pert_scale(k,n) * vt_uvel_pert(k,j,i,n) - vt_uvel_pert(k,j,i,n) );
+ temp(k,j,i,n) = temp(k,j,i,n) + temp_tend_loc;
+ rhov(k,j,i,n) = rhov(k,j,i,n) + rhov_tend_loc;
+ uvel(k,j,i,n) = uvel(k,j,i,n) + uvel_tend_loc;
+ });
+ //------------------------------------------------------------------------------------------------
+}
+
+inline void pam_variance_transport_compute_feedback( pam::PamCoupler &coupler ) {
+ using yakl::c::parallel_for;
+ using yakl::c::SimpleBounds;
+ using yakl::atomicAdd;
+ auto &dm_device = coupler.get_data_manager_device_readwrite();
+ auto &dm_host = coupler.get_data_manager_host_readwrite();
+ auto nens = coupler.get_option("ncrms");
+ auto nz = coupler.get_option("crm_nz");
+ auto ny = coupler.get_option("crm_ny");
+ auto nx = coupler.get_option("crm_nx");
+ auto gcm_nlev = coupler.get_option("gcm_nlev");
+ auto gcm_dt = coupler.get_option("gcm_dt");
+ //------------------------------------------------------------------------------------------------
+ // update CRM variance values
+ pam_variance_transport_diagnose(coupler);
+ //------------------------------------------------------------------------------------------------
+ auto temp = dm_device.get("temp" );
+ auto rhov = dm_device.get("water_vapor");
+ auto uvel = dm_device.get("uvel" );
+ auto vt_temp = dm_device.get("vt_temp" );
+ auto vt_rhov = dm_device.get("vt_rhov" );
+ auto vt_uvel = dm_device.get("vt_uvel" );
+ auto gcm_vt_temp = dm_host.get("input_vt_t").createDeviceCopy();
+ auto gcm_vt_rhov = dm_host.get("input_vt_q").createDeviceCopy();
+ auto gcm_vt_uvel = dm_host.get("input_vt_u").createDeviceCopy();
+ //------------------------------------------------------------------------------------------------
+ dm_device.register_and_allocate("vt_temp_feedback_tend", "feedback tend of temp variance", {gcm_nlev,nens},{"gcm_lev","nens"});
+ dm_device.register_and_allocate("vt_rhov_feedback_tend", "feedback tend of rhov variance", {gcm_nlev,nens},{"gcm_lev","nens"});
+ dm_device.register_and_allocate("vt_uvel_feedback_tend", "feedback tend of uvel variance", {gcm_nlev,nens},{"gcm_lev","nens"});
+ auto vt_temp_feedback_tend = dm_device.get("vt_temp_feedback_tend" );
+ auto vt_rhov_feedback_tend = dm_device.get("vt_rhov_feedback_tend" );
+ auto vt_uvel_feedback_tend = dm_device.get("vt_uvel_feedback_tend" );
+ //------------------------------------------------------------------------------------------------
+ // calculate variance transport forcing
+ parallel_for( SimpleBounds<2>(nz,nens) , YAKL_LAMBDA (int k_crm, int n) {
+ int k_gcm = gcm_nlev-1-k_crm;
+ if (k_crm("vt_temp_feedback_tend" );
+ auto vt_rhov_feedback_tend = dm_device.get("vt_rhov_feedback_tend" );
+ auto vt_uvel_feedback_tend = dm_device.get("vt_uvel_feedback_tend" );
+ //------------------------------------------------------------------------------------------------
+ auto output_vt_temp_tend_host = dm_host.get("output_t_vt_tend" );
+ auto output_vt_rhov_tend_host = dm_host.get("output_q_vt_tend" );
+ auto output_vt_uvel_tend_host = dm_host.get("output_u_vt_tend" );
+ //------------------------------------------------------------------------------------------------
+ // Copy the data to host
+ vt_temp_feedback_tend.deep_copy_to(output_vt_temp_tend_host);
+ vt_rhov_feedback_tend.deep_copy_to(output_vt_rhov_tend_host);
+ vt_uvel_feedback_tend.deep_copy_to(output_vt_uvel_tend_host);
+ yakl::fence();
+ //------------------------------------------------------------------------------------------------
+}
+
diff --git a/components/eam/src/physics/p3/eam/micro_p3.F90 b/components/eam/src/physics/p3/eam/micro_p3.F90
index 730736a2dbf2..e668cbaa494c 100644
--- a/components/eam/src/physics/p3/eam/micro_p3.F90
+++ b/components/eam/src/physics/p3/eam/micro_p3.F90
@@ -56,7 +56,7 @@ module micro_p3
use phys_control, only: use_hetfrz_classnuc
! physical and mathematical constants
- use micro_p3_utils, only: rho_1000mb,rho_600mb,ar,br,f1r,f2r,rho_h2o,kr,kc,aimm,mi0,nccnst, &
+ use micro_p3_utils, only: rho_1000mb,rho_600mb,ar,br,f1r,f2r,rho_h2o,kr,kc,aimm,mi0, &
eci,eri,bcn,cpw,cons1,cons3,cons4,cons5,cons6,cons7, &
inv_rho_h2o,inv_dropmass,qsmall,nsmall,cp,g,rd,rv,ep_2,inv_cp, &
thrd,sxth,piov6,rho_rimeMin, &
@@ -441,7 +441,7 @@ SUBROUTINE p3_main_part1(kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribe
t_atm, rho, inv_rho, qv_sat_l, qv_sat_i, qv_supersat_i, rhofacr, rhofaci, acn, qv, th_atm, &
qc, nc, qr, nr, &
qi, ni, qm, bm, qc_incld, qr_incld, qi_incld, qm_incld, &
- nc_incld, nr_incld, ni_incld, bm_incld, is_nucleat_possible, is_hydromet_present)
+ nc_incld, nr_incld, ni_incld, bm_incld, is_nucleat_possible, is_hydromet_present, nccnst)
implicit none
@@ -449,7 +449,7 @@ SUBROUTINE p3_main_part1(kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribe
integer, intent(in) :: kts, kte, kbot, ktop, kdir
logical(btype), intent(in) :: do_predict_nc
- real(rtype), intent(in) :: dt
+ real(rtype), intent(in) :: dt, nccnst
real(rtype), intent(in), dimension(kts:kte) :: pres, dpres, dz, nc_nuceat_tend, exner, inv_exner, &
inv_cld_frac_l, inv_cld_frac_i, inv_cld_frac_r, latent_heat_vapor, latent_heat_sublim, latent_heat_fusion, nccn_prescribed
@@ -561,15 +561,15 @@ SUBROUTINE p3_main_part2(kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribe
qm, bm, latent_heat_vapor, latent_heat_sublim, latent_heat_fusion, qc_incld, qr_incld, qi_incld, qm_incld, nc_incld, nr_incld, &
ni_incld, bm_incld, mu_c, nu, lamc, cdist, cdist1, cdistr, mu_r, lamr, logn0r, qv2qi_depos_tend, precip_total_tend, &
nevapr, qr_evap_tend, vap_liq_exchange, vap_ice_exchange, liq_ice_exchange, pratot, &
- prctot, frzimm, frzcnt, frzdep, p3_tend_out, is_hydromet_present)
+ prctot, frzimm, frzcnt, frzdep, p3_tend_out, is_hydromet_present, do_precip_off, nccnst)
implicit none
! args
integer, intent(in) :: kts, kte, kbot, ktop, kdir
- logical(btype), intent(in) :: do_predict_nc, do_prescribed_CCN
- real(rtype), intent(in) :: dt, inv_dt
+ logical(btype), intent(in) :: do_predict_nc, do_prescribed_CCN, do_precip_off
+ real(rtype), intent(in) :: dt, inv_dt, nccnst
real(rtype), intent(in) :: p3_autocon_coeff, p3_accret_coeff, p3_qc_autocon_expon, p3_nc_autocon_expon, p3_qc_accret_expon, &
p3_wbf_coeff, p3_embryonic_rain_size, p3_max_mean_rain_size
@@ -875,7 +875,7 @@ SUBROUTINE p3_main_part2(kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribe
! NOTE: cloud_water_autoconversion must be called before droplet_self_collection
call cloud_water_autoconversion(rho(k),qc_incld(k),nc_incld(k),inv_qc_relvar(k),&
p3_autocon_coeff,p3_qc_autocon_expon,p3_nc_autocon_expon,p3_embryonic_rain_size,&
- qc2qr_autoconv_tend,nc2nr_autoconv_tend,ncautr)
+ do_precip_off,qc2qr_autoconv_tend,nc2nr_autoconv_tend,ncautr)
!............................
! self-collection of droplets
@@ -978,7 +978,7 @@ SUBROUTINE p3_main_part2(kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribe
!-- warm-phase only processes:
call update_prognostic_liquid(qc2qr_accret_tend, nc_accret_tend, qc2qr_autoconv_tend, nc2nr_autoconv_tend, ncautr, &
nc_selfcollect_tend, qr2qv_evap_tend, nr_evap_tend, nr_selfcollect_tend, &
- do_predict_nc, do_prescribed_CCN, inv_rho(k), exner(k), latent_heat_vapor(k), dt, &
+ do_predict_nc, nccnst, do_prescribed_CCN, inv_rho(k), exner(k), latent_heat_vapor(k), dt, &
th_atm(k), qv(k), qc(k), nc(k), qr(k), nr(k))
!==
@@ -1259,7 +1259,7 @@ SUBROUTINE p3_main(qc,nc,qr,nr,th_atm,qv,dt,qi,qm,ni,bm,
p3_wbf_coeff,p3_mincdnc,p3_max_mean_rain_size,p3_embryonic_rain_size, &
dpres,exner,qv2qi_depos_tend,precip_total_tend,nevapr,qr_evap_tend,precip_liq_flux,precip_ice_flux,rflx,sflx,cflx,cld_frac_r,cld_frac_l,cld_frac_i, &
p3_tend_out,mu_c,lamc,liq_ice_exchange,vap_liq_exchange, &
- vap_ice_exchange,qv_prev,t_prev,col_location,diag_equiv_reflectivity,diag_ze_rain,diag_ze_ice &
+ vap_ice_exchange,qv_prev,t_prev,col_location,do_precip_off,nccnst,diag_equiv_reflectivity,diag_ze_rain,diag_ze_ice &
#ifdef SCREAM_CONFIG_IS_CMAKE
,elapsed_s &
#endif
@@ -1337,6 +1337,10 @@ SUBROUTINE p3_main(qc,nc,qr,nr,th_atm,qv,dt,qi,qm,ni,bm,
! INPUT for prescribed CCN option
logical(btype), intent(in) :: do_prescribed_CCN
+ ! INPUT for idealization options
+ logical(btype), intent(in) :: do_precip_off
+ real(rtype), intent(in) :: nccnst
+
! INPUT for p3 tuning parameters
real(rtype), intent(in) :: p3_autocon_coeff ! autconversion coefficient
real(rtype), intent(in) :: p3_accret_coeff ! accretion coefficient
@@ -1517,7 +1521,7 @@ SUBROUTINE p3_main(qc,nc,qr,nr,th_atm,qv,dt,qi,qm,ni,bm,
rhofaci(i,:), acn(i,:), qv(i,:), th_atm(i,:), qc(i,:), nc(i,:), qr(i,:), nr(i,:), &
qi(i,:), ni(i,:), qm(i,:), bm(i,:), qc_incld(i,:), qr_incld(i,:), &
qi_incld(i,:), qm_incld(i,:), nc_incld(i,:), nr_incld(i,:), &
- ni_incld(i,:), bm_incld(i,:), is_nucleat_possible, is_hydromet_present)
+ ni_incld(i,:), bm_incld(i,:), is_nucleat_possible, is_hydromet_present, nccnst)
if (debug_ON) then
tmparr1(i,:) = th_atm(i,:)*inv_exner(i,:)!(pres(i,:)*1.e-5)**(rd*inv_cp)
@@ -1541,7 +1545,8 @@ SUBROUTINE p3_main(qc,nc,qr,nr,th_atm,qv,dt,qi,qm,ni,bm,
bm_incld(i,:), mu_c(i,:), nu(i,:), lamc(i,:), cdist(i,:), cdist1(i,:), &
cdistr(i,:), mu_r(i,:), lamr(i,:), logn0r(i,:), qv2qi_depos_tend(i,:), precip_total_tend(i,:), &
nevapr(i,:), qr_evap_tend(i,:), vap_liq_exchange(i,:), vap_ice_exchange(i,:), &
- liq_ice_exchange(i,:), pratot(i,:), prctot(i,:), frzimm(i,:), frzcnt(i,:), frzdep(i,:), p3_tend_out(i,:,:), is_hydromet_present)
+ liq_ice_exchange(i,:), pratot(i,:), prctot(i,:), frzimm(i,:), frzcnt(i,:), frzdep(i,:), p3_tend_out(i,:,:), is_hydromet_present, &
+ do_precip_off, nccnst)
! measure microphysics processes tendency output
@@ -2950,7 +2955,7 @@ end subroutine rain_self_collection
subroutine cloud_water_autoconversion(rho,qc_incld,nc_incld,inv_qc_relvar, &
p3_autocon_coeff,p3_qc_autocon_expon,p3_nc_autocon_expon,p3_embryonic_rain_size, &
- qc2qr_autoconv_tend,nc2nr_autoconv_tend,ncautr)
+ do_precip_off,qc2qr_autoconv_tend,nc2nr_autoconv_tend,ncautr)
implicit none
@@ -2963,6 +2968,8 @@ subroutine cloud_water_autoconversion(rho,qc_incld,nc_incld,inv_qc_relvar,
real(rtype), intent(in) :: p3_nc_autocon_expon
real(rtype), intent(in) :: p3_embryonic_rain_size
+ logical(btype), intent(in) :: do_precip_off
+
real(rtype), intent(out) :: qc2qr_autoconv_tend
real(rtype), intent(out) :: nc2nr_autoconv_tend
real(rtype), intent(out) :: ncautr
@@ -2981,8 +2988,9 @@ subroutine cloud_water_autoconversion(rho,qc_incld,nc_incld,inv_qc_relvar,
ncautr = qc2qr_autoconv_tend*cons3*(1._rtype/bfb_pow(p3_embryonic_rain_size,3._rtype))
nc2nr_autoconv_tend = qc2qr_autoconv_tend*nc_incld/qc_incld
- if (qc2qr_autoconv_tend .eq.0._rtype) nc2nr_autoconv_tend = 0._rtype
- if (nc2nr_autoconv_tend.eq.0._rtype) qc2qr_autoconv_tend = 0._rtype
+ if (qc2qr_autoconv_tend .eq.0._rtype .or. do_precip_off) nc2nr_autoconv_tend = 0._rtype
+ if (nc2nr_autoconv_tend.eq.0._rtype .or. do_precip_off) qc2qr_autoconv_tend = 0._rtype
+ if (do_precip_off) ncautr = 0._rtype
endif qc_not_small
@@ -3502,7 +3510,7 @@ end subroutine update_prognostic_ice
subroutine update_prognostic_liquid(qc2qr_accret_tend,nc_accret_tend,qc2qr_autoconv_tend,nc2nr_autoconv_tend, &
ncautr,nc_selfcollect_tend, qr2qv_evap_tend,nr_evap_tend,nr_selfcollect_tend, &
- do_predict_nc, do_prescribed_CCN, inv_rho,exner,latent_heat_vapor,dt, &
+ do_predict_nc, nccnst, do_prescribed_CCN, inv_rho,exner,latent_heat_vapor,dt, &
th_atm,qv,qc,nc,qr,nr)
!-- warm-phase only processes:
@@ -3520,6 +3528,7 @@ subroutine update_prognostic_liquid(qc2qr_accret_tend,nc_accret_tend,qc2qr_autoc
logical(btype), intent(in) :: do_predict_nc, do_prescribed_CCN
+ real(rtype), intent(in) :: nccnst
real(rtype), intent(in) :: inv_rho
real(rtype), intent(in) :: exner
real(rtype), intent(in) :: latent_heat_vapor
diff --git a/components/eam/src/physics/p3/eam/micro_p3_interface.F90 b/components/eam/src/physics/p3/eam/micro_p3_interface.F90
index 9d53e95fc17f..bb6e164b4a14 100644
--- a/components/eam/src/physics/p3/eam/micro_p3_interface.F90
+++ b/components/eam/src/physics/p3/eam/micro_p3_interface.F90
@@ -42,6 +42,7 @@ module micro_p3_interface
use ncdio_atm, only: infld
use ppgrid, only: begchunk, endchunk, pcols, pver, pverp,psubcols
use cam_history_support, only: add_hist_coord
+ use iop_data_mod, only: precip_off
implicit none
save
@@ -131,8 +132,8 @@ module micro_p3_interface
p3_wbf_coeff = huge(1.0_rtype), &
p3_mincdnc = huge(1.0_rtype), &
p3_max_mean_rain_size = huge(1.0_rtype), &
- p3_embryonic_rain_size = huge(1.0_rtype)
-
+ p3_embryonic_rain_size = huge(1.0_rtype), &
+ micro_nccons = huge(1.0_rtype)
integer :: ncnst
@@ -165,7 +166,7 @@ subroutine micro_p3_readnl(nlfile)
micro_p3_tableversion, micro_p3_lookup_dir, micro_aerosolactivation, micro_subgrid_cloud, &
micro_tend_output, p3_autocon_coeff, p3_qc_autocon_expon, p3_nc_autocon_expon, p3_accret_coeff, &
p3_qc_accret_expon, p3_wbf_coeff, p3_max_mean_rain_size, p3_embryonic_rain_size, &
- do_prescribed_CCN, do_Cooper_inP3, p3_mincdnc
+ do_prescribed_CCN, do_Cooper_inP3, p3_mincdnc, micro_nccons
!-----------------------------------------------------------------------------
@@ -220,6 +221,7 @@ subroutine micro_p3_readnl(nlfile)
call mpibcast(p3_embryonic_rain_size, 1 , mpir8, 0, mpicom)
call mpibcast(do_prescribed_CCN, 1, mpilog, 0, mpicom)
call mpibcast(do_Cooper_inP3, 1, mpilog, 0, mpicom)
+ call mpibcast(micro_nccons, 1, mpir8, 0, mpicom)
#endif
@@ -1363,6 +1365,8 @@ subroutine micro_p3_tend(state, ptend, dtime, pbuf)
qv_prev(its:ite,kts:kte), & ! IN qv at end of prev p3_main call kg kg-1
t_prev(its:ite,kts:kte), & ! IN t at end of prev p3_main call K
col_location(its:ite,:3), & ! IN column locations
+ precip_off, & ! IN Option to turn precip (liquid) off
+ micro_nccons, & ! IN Option for constant droplet concentration
diag_equiv_reflectivity(its:ite,kts:kte), & !OUT equivalent reflectivity (rain + ice) [dBz]
diag_ze_rain(its:ite,kts:kte),diag_ze_ice(its:ite,kts:kte)) !OUT equivalent reflectivity for rain and ice [dBz]
diff --git a/components/eam/src/physics/p3/eam/micro_p3_utils.F90 b/components/eam/src/physics/p3/eam/micro_p3_utils.F90
index dab1c4751323..c2182a14206c 100644
--- a/components/eam/src/physics/p3/eam/micro_p3_utils.F90
+++ b/components/eam/src/physics/p3/eam/micro_p3_utils.F90
@@ -33,9 +33,6 @@ module micro_p3_utils
! maximum total ice concentration (sum of all categories)
real(rtype), public, parameter :: max_total_ni = 500.e+3_rtype ! (m)
- ! droplet concentration (m-3)
- real(rtype), public, parameter :: nccnst = 200.e+6_rtype
-
! parameters for Seifert and Beheng (2001) autoconversion/accretion
real(rtype), public, parameter :: kc = 9.44e+9_rtype
real(rtype), public, parameter :: kr = 5.78e+3_rtype
diff --git a/components/eam/src/physics/p3/scream/micro_p3.F90 b/components/eam/src/physics/p3/scream/micro_p3.F90
index e59bcc08239c..f345e5abcf70 100644
--- a/components/eam/src/physics/p3/scream/micro_p3.F90
+++ b/components/eam/src/physics/p3/scream/micro_p3.F90
@@ -1846,7 +1846,8 @@ subroutine get_rain_dsd2(qr,nr,mu_r,lamr,cdistr,logn0r)
real(rtype), intent(out) :: lamr,mu_r,cdistr,logn0r
!local variables:
- real(rtype) :: inv_dum,lammax,lammin
+ real(rtype) :: lammax,lammin
+ real(rtype) :: mass_to_d3_factor
!--------------------------------------------------------------------------
@@ -1858,25 +1859,25 @@ subroutine get_rain_dsd2(qr,nr,mu_r,lamr,cdistr,logn0r)
! find spot in lookup table
! (scaled N/q for lookup table parameter space_
nr = max(nr,nsmall)
- inv_dum = bfb_cbrt(qr/(cons1*nr*6._rtype))
! Apply constant mu_r: Recall the switch to v4 tables means constant mu_r
mu_r = mu_r_constant
- lamr = bfb_cbrt(cons1*nr*(mu_r+3._rtype)*(mu_r+2._rtype)*(mu_r+1._rtype)/(qr)) ! recalculate slope based on mu_r
+ mass_to_d3_factor = cons1*(mu_r+3._rtype)*(mu_r+2._rtype)*(mu_r+1._rtype)
+ lamr = bfb_cbrt(mass_to_d3_factor*nr/qr) ! recalculate slope based on mu_r
lammax = (mu_r+1._rtype)*1.e+5_rtype ! check for slope
lammin = (mu_r+1._rtype)*500._rtype !500=1/(2mm) is inverse of max allowed number-weighted mean raindrop diameter
! apply lambda limiters for rain
if (lamr.lt.lammin) then
lamr = lammin
- nr = bfb_exp(3._rtype*bfb_log(lamr)+bfb_log(qr)+bfb_log(bfb_gamma(mu_r+1._rtype))-bfb_log(bfb_gamma(mu_r+4._rtype)))/(cons1)
+ nr = lamr * lamr * lamr * qr / mass_to_d3_factor
elseif (lamr.gt.lammax) then
lamr = lammax
- nr = bfb_exp(3._rtype*bfb_log(lamr)+bfb_log(qr)+bfb_log(bfb_gamma(mu_r+1._rtype))-bfb_log(bfb_gamma(mu_r+4._rtype)))/(cons1)
+ nr = lamr * lamr * lamr * qr / mass_to_d3_factor
endif
cdistr = nr/bfb_gamma(mu_r+1._rtype)
- logn0r = bfb_log10(nr)+(mu_r+1._rtype)*bfb_log10(lamr)-bfb_log10(bfb_gamma(mu_r+1._rtype)) !note: logn0r is calculated as log10(n0r)
+ logn0r = bfb_log10(cdistr)+(mu_r+1._rtype)*bfb_log10(lamr) !note: logn0r is calculated as log10(n0r)
else
diff --git a/components/eam/src/utils/cam_abortutils.F90 b/components/eam/src/utils/cam_abortutils.F90
index 59e5fece3f2e..6783a5753b3b 100644
--- a/components/eam/src/utils/cam_abortutils.F90
+++ b/components/eam/src/utils/cam_abortutils.F90
@@ -10,7 +10,7 @@ module cam_abortutils
!-----------------------------------------------------------------------
!- use statements ------------------------------------------------------
!-----------------------------------------------------------------------
- use shr_kind_mod, only: shr_kind_in
+ use shr_kind_mod, only: shr_kind_in, SHR_KIND_CL
use shr_sys_mod, only: shr_sys_abort
!-----------------------------------------------------------------------
@@ -24,6 +24,7 @@ module cam_abortutils
! Public interfaces ----------------------------------------------------
!-----------------------------------------------------------------------
public endrun
+ public handle_allocate_error
!-----------------------------------------------------------------------
! Subroutines and functions --------------------------------------------
@@ -63,4 +64,20 @@ subroutine endrun(string)
end subroutine
+ subroutine handle_allocate_error(retval, subname, fieldname)
+ ! if is not zero, generate an error message and abort
+ ! Dummy arguments
+ integer, intent(in) :: retval
+ character(len=*), intent(in) :: subname
+ character(len=*), intent(in) :: fieldname
+ ! Local variable
+ character(len=SHR_KIND_CL) :: errmsg
+
+ if (retval /= 0) then
+ write(errmsg, '(4a,i0)') trim(subname), ' error allocating ', &
+ trim(fieldname), ', error = ', retval
+ call endrun(errmsg)
+ end if
+ end subroutine handle_allocate_error
+
end module cam_abortutils
diff --git a/components/eam/src/utils/cam_grid_support.F90 b/components/eam/src/utils/cam_grid_support.F90
index 1a69ef07f9ce..bc147321b325 100644
--- a/components/eam/src/utils/cam_grid_support.F90
+++ b/components/eam/src/utils/cam_grid_support.F90
@@ -161,12 +161,14 @@ module cam_grid_support
logical :: unstructured ! Is this needed?
logical :: block_indexed ! .false. for lon/lat
logical :: attrs_defined = .false.
+ logical :: zonal_grid = .false.
type(cam_filemap_t), pointer :: map => null() ! global dim map (dof)
type(cam_grid_attr_ptr_t), pointer :: attributes => NULL()
contains
procedure :: print_cam_grid
procedure :: is_unstructured => cam_grid_unstructured
procedure :: is_block_indexed => cam_grid_block_indexed
+ procedure :: is_zonal_grid => cam_grid_zonal_grid
procedure :: coord_lengths => cam_grid_get_dims
procedure :: coord_names => cam_grid_coord_names
procedure :: dim_names => cam_grid_dim_names
@@ -205,9 +207,12 @@ module cam_grid_support
integer :: global_lon_size = 0 ! lon patch dim size
real(r8) :: lon_range(2)
real(r8) :: lat_range(2)
+ logical :: collected_columns ! Output unstructured
type(cam_filemap_t), pointer :: mask => null() ! map for active pts
integer(iMap), pointer :: latmap(:) => null() ! map for patch coords
integer(iMap), pointer :: lonmap(:) => null() ! map for patch coords
+ real(r8), pointer :: lonvals(:) => null() ! For collected output
+ real(r8), pointer :: latvals(:) => null() ! For collected output
contains
procedure :: gridid => cam_grid_patch_get_id
procedure :: get_axis_names => cam_grid_patch_get_axis_names
@@ -307,6 +312,7 @@ end subroutine print_attr_spec
public :: cam_grid_has_blocksize, cam_grid_get_block_count
public :: cam_grid_get_latvals, cam_grid_get_lonvals
public :: cam_grid_is_unstructured, cam_grid_is_block_indexed
+ public :: cam_grid_is_zonal
! Functions for dealing with patch masks
public :: cam_grid_compute_patch
@@ -322,6 +328,11 @@ end subroutine print_attr_spec
module procedure cam_grid_dimensions_name
end interface
+ interface cam_grid_get_dim_names
+ module procedure cam_grid_get_dim_names_id
+ module procedure cam_grid_get_dim_names_name
+ end interface
+
interface cam_grid_read_dist_array
module procedure cam_grid_read_dist_array_2d_int
module procedure cam_grid_read_dist_array_3d_int
@@ -739,7 +750,7 @@ integer function num_cam_grid_attrs(gridind)
end function num_cam_grid_attrs
subroutine cam_grid_register(name, id, lat_coord, lon_coord, map, &
- unstruct, block_indexed, src_in, dest_in)
+ unstruct, block_indexed, zonal_grid, src_in, dest_in)
! Dummy arguments
character(len=*), intent(in) :: name
integer, intent(in) :: id
@@ -748,6 +759,7 @@ subroutine cam_grid_register(name, id, lat_coord, lon_coord, map, &
integer(iMap), pointer, intent(in) :: map(:,:)
logical, optional, intent(in) :: unstruct
logical, optional, intent(in) :: block_indexed
+ logical, optional, intent(in) :: zonal_grid
integer, optional, intent(in) :: src_in(2)
integer, optional, intent(in) :: dest_in(2)
@@ -798,6 +810,16 @@ subroutine cam_grid_register(name, id, lat_coord, lon_coord, map, &
else
cam_grids(registeredhgrids)%block_indexed = cam_grids(registeredhgrids)%unstructured
end if
+ if (present(zonal_grid)) then
+ ! Check the size of the longitude coordinate
+ call lon_coord%get_coord_len(i)
+ if (i /= 1) then
+ call endrun(subname//': lon_coord is not of size 1 for a zonal grid')
+ end if
+ cam_grids(registeredhgrids)%zonal_grid = zonal_grid
+ else
+ cam_grids(registeredhgrids)%zonal_grid = .false.
+ end if
if (associated(cam_grids(registeredhgrids)%map)) then
write(errormsg, *)
call endrun(trim(subname)//": new grid map should not be associated")
@@ -837,7 +859,8 @@ subroutine print_cam_grid(this)
', lat coord = ', trim(this%lat_coord%name), &
', lon coord = ', trim(this%lon_coord%name), &
', unstruct = ', this%unstructured, &
- ', block_ind = ', this%block_indexed
+ ', block_ind = ', this%block_indexed, &
+ ', zonal_grid = ', this%zonal_grid
attrPtr => this%attributes
do while (associated(attrPtr))
!!XXgoldyXX: Is this not working in PGI?
@@ -1406,23 +1429,50 @@ subroutine cam_grid_get_coord_names(id, name1, name2)
end subroutine cam_grid_get_coord_names
- subroutine cam_grid_get_dim_names(id, name1, name2)
+ !---------------------------------------------------------------------------
+ !
+ ! cam_grid_get_dim_names: Return the names of the grid axes dimensions.
+ ! Note that these may be the same
+ !
+ !---------------------------------------------------------------------------
+ subroutine cam_grid_get_dim_names_id(id, name1, name2)
! Dummy arguments
integer, intent(in) :: id
character(len=*), intent(out) :: name1
character(len=*), intent(out) :: name2
-
+
! Local variables
integer :: gridid
gridid = get_cam_grid_index(id)
if (gridid > 0) then
call cam_grids(gridid)%dim_names(name1, name2)
else
- call endrun('cam_grid_get_dim_names: Bad grid ID')
+ call endrun('cam_grid_get_dim_names_id: Bad grid ID')
end if
- end subroutine cam_grid_get_dim_names
+ end subroutine cam_grid_get_dim_names_id
+
+ subroutine cam_grid_get_dim_names_name(gridname, name1, name2)
+
+ ! Dummy arguments
+ character(len=*), intent(in) :: gridname
+ character(len=*), intent(out) :: name1
+ character(len=*), intent(out) :: name2
+
+ ! Local variables
+ integer :: gridind
+ character(len=120) :: errormsg
+
+ gridind = get_cam_grid_index(trim(gridname))
+ if (gridind < 0) then
+ write(errormsg, *) 'No CAM grid with name = ', trim(gridname)
+ call endrun('cam_grid_get_dim_names_name: '//errormsg)
+ else
+ call cam_grids(gridind)%dim_names(name1, name2)
+ end if
+
+ end subroutine cam_grid_get_dim_names_name
logical function cam_grid_has_blocksize(id)
@@ -1534,8 +1584,23 @@ logical function cam_grid_is_block_indexed(id) result(block_indexed)
end if
end function cam_grid_is_block_indexed
+ logical function cam_grid_is_zonal(id) result(zonal)
+
+ ! Dummy arguments
+ integer, intent(in) :: id
+
+ ! Local variables
+ integer :: gridid
+ gridid = get_cam_grid_index(id)
+ if (gridid > 0) then
+ zonal = cam_grids(gridid)%is_zonal_grid()
+ else
+ call endrun('s: Bad grid ID')
+ end if
+ end function cam_grid_is_zonal
+
! Compute or update a grid patch mask
- subroutine cam_grid_compute_patch(id, patch, lonl, lonu, latl, latu)
+ subroutine cam_grid_compute_patch(id, patch, lonl, lonu, latl, latu, cco)
! Dummy arguments
integer, intent(in) :: id
@@ -1544,13 +1609,14 @@ subroutine cam_grid_compute_patch(id, patch, lonl, lonu, latl, latu)
real(r8), intent(in) :: lonu
real(r8), intent(in) :: latl
real(r8), intent(in) :: latu
+ logical, intent(in) :: cco ! Collect columns?
! Local variables
integer :: gridid
gridid = get_cam_grid_index(id)
if (gridid > 0) then
- call cam_grids(gridid)%get_patch_mask(lonl, lonu, latl, latu, patch)
+ call cam_grids(gridid)%get_patch_mask(lonl, lonu, latl, latu, patch, cco)
else
call endrun('cam_grid_compute_patch: Bad grid ID')
end if
@@ -2409,6 +2475,12 @@ logical function cam_grid_block_indexed(this)
cam_grid_block_indexed = this%block_indexed
end function cam_grid_block_indexed
+ logical function cam_grid_zonal_grid(this)
+ class(cam_grid_t) :: this
+
+ cam_grid_zonal_grid = this%zonal_grid
+ end function cam_grid_zonal_grid
+
logical function cam_grid_unstructured(this)
class(cam_grid_t) :: this
@@ -3197,7 +3269,7 @@ end subroutine cam_grid_write_darray_3d_real
! within the input patch.
!
!---------------------------------------------------------------------------
- subroutine cam_grid_get_patch_mask(this, lonl, lonu, latl, latu, patch)
+ subroutine cam_grid_get_patch_mask(this, lonl, lonu, latl, latu, patch, cco)
use spmd_utils, only: mpi_min, mpi_real8, mpicom
use physconst, only: pi
@@ -3206,6 +3278,7 @@ subroutine cam_grid_get_patch_mask(this, lonl, lonu, latl, latu, patch)
real(r8), intent(in) :: lonl, lonu ! Longitude bounds
real(r8), intent(in) :: latl, latu ! Latitude bounds
type(cam_grid_patch_t), intent(inout) :: patch
+ logical, intent(in) :: cco ! Collect columns?
! Local arguments
real(r8) :: mindist
@@ -3228,6 +3301,7 @@ subroutine cam_grid_get_patch_mask(this, lonl, lonu, latl, latu, patch)
real(r8), parameter :: maxangle = pi / 4.0_r8
real(r8), parameter :: deg2rad = pi / 180.0_r8
real(r8), parameter :: maxlat = 89.5_r8
+ character(len=*), parameter :: subname = 'cam_grid_get_patch_mask'
if (.not. associated(this%map)) then
call endrun('cam_grid_get_patch_mask: Grid, '//trim(this%name)//', has no map')
@@ -3243,6 +3317,9 @@ subroutine cam_grid_get_patch_mask(this, lonl, lonu, latl, latu, patch)
! NB: Compacting the mask must be done after all calls (for a
! particular mask) to this function.
end if
+ if (patch%collected_columns .neqv. cco) then
+ call endrun(subname//': collected_column mismatch')
+ end if
else
if (associated(patch%latmap)) then
call endrun('cam_grid_get_patch_mask: unallocated patch has latmap')
@@ -3257,17 +3334,29 @@ subroutine cam_grid_get_patch_mask(this, lonl, lonu, latl, latu, patch)
end if
call patch%mask%clear()
! Set up the lat/lon maps
- if (associated(this%lat_coord%values)) then
- allocate(patch%latmap(LBOUND(this%lat_coord%values, 1):UBOUND(this%lat_coord%values, 1)))
+ if (cco) then
+ ! For collected column output, we need to collect coordinates and values
+ allocate(patch%latmap(patch%mask%num_elem()))
patch%latmap = 0
- else
- nullify(patch%latmap)
- end if
- if (associated(this%lon_coord%values)) then
- allocate(patch%lonmap(LBOUND(this%lon_coord%values, 1):UBOUND(this%lon_coord%values, 1)))
+ allocate(patch%latvals(patch%mask%num_elem()))
+ patch%latvals = 91.0_r8
+ allocate(patch%lonmap(patch%mask%num_elem()))
patch%lonmap = 0
+ allocate(patch%lonvals(patch%mask%num_elem()))
+ patch%lonvals = 361.0_r8
else
- nullify(patch%lonmap)
+ if (associated(this%lat_coord%values)) then
+ allocate(patch%latmap(LBOUND(this%lat_coord%values, 1):UBOUND(this%lat_coord%values, 1)))
+ patch%latmap = 0
+ else
+ nullify(patch%latmap)
+ end if
+ if (associated(this%lon_coord%values)) then
+ allocate(patch%lonmap(LBOUND(this%lon_coord%values, 1):UBOUND(this%lon_coord%values, 1)))
+ patch%lonmap = 0
+ else
+ nullify(patch%lonmap)
+ end if
end if
end if
diff --git a/components/eam/src/utils/string_utils.F90 b/components/eam/src/utils/string_utils.F90
index 3a1bafe5a6c2..476e6f2319ae 100644
--- a/components/eam/src/utils/string_utils.F90
+++ b/components/eam/src/utils/string_utils.F90
@@ -10,7 +10,8 @@ module string_utils
to_upper, & ! Convert character string to upper case
to_lower, & ! Convert character string to lower case
INCSTR, & ! increments a string
- GLC ! Position of last significant character in string
+ GLC, & ! Position of last significant character in string
+ int2str ! convert integer to left justified string
contains
@@ -240,4 +241,11 @@ integer function GLC( cs )
end function GLC
+character(len=10) function int2str(n)
+ ! return default integer as a left justified string
+ integer, intent(in) :: n
+ !-----------------------------------------------------------------------
+ write(int2str,'(i0)') n
+end function int2str
+
end module string_utils
diff --git a/components/eamxx/CMakeLists.txt b/components/eamxx/CMakeLists.txt
index e2aae3e97b32..453b2d4be8a3 100644
--- a/components/eamxx/CMakeLists.txt
+++ b/components/eamxx/CMakeLists.txt
@@ -1,7 +1,18 @@
+####################################################################
+# Basic setup: version, cime debug, cmake paths,... #
+####################################################################
if (NOT DEFINED PROJECT_NAME)
- cmake_minimum_required(VERSION 3.3)
+ cmake_minimum_required(VERSION 3.14)
cmake_policy(SET CMP0057 NEW)
set(SCREAM_CIME_BUILD FALSE)
+
+ # Print the sha of the last commit (useful to double check which version was tested on CDash)
+ execute_process (COMMAND git rev-parse HEAD
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_VARIABLE LAST_GIT_COMMIT_SHA
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ set(EAMXX_GIT_VERSION ${LAST_GIT_COMMIT_SHA} CACHE STRING "The sha of the last git commit." FORCE)
+ message(STATUS "The sha of the last commit is ${EAMXX_GIT_VERSION}")
else()
set(SCREAM_CIME_BUILD TRUE)
endif()
@@ -20,6 +31,13 @@ if ($ENV{SCREAM_FORCE_CONFIG_FAIL})
message(FATAL_ERROR "Failed, as instructed by environment")
endif()
+string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_ci)
+if (CMAKE_BUILD_TYPE_ci STREQUAL "debug")
+ set (SCREAM_DEBUG TRUE)
+else ()
+ set (SCREAM_DEBUG FALSE)
+endif()
+
# Add the ./cmake folder to cmake path. Also add EKAT's cmake folder
set (EKAT_CMAKE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../externals/ekat/cmake)
list(APPEND CMAKE_MODULE_PATH
@@ -33,6 +51,26 @@ if (SCREAM_CIME_BUILD)
${CMAKE_CURRENT_SOURCE_DIR}/cmake/cime)
endif ()
+# We want to use C++17 in EAMxx
+set(CMAKE_CXX_STANDARD 17)
+
+if (NOT SCREAM_CIME_BUILD)
+ project(SCREAM CXX C Fortran)
+
+ if (SCREAM_CORI_HACK)
+ list(APPEND CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "ifcore")
+ list(REMOVE_ITEM CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "ifport")
+ endif()
+
+else()
+ # Ensure our languages are all enabled
+ enable_language(C CXX Fortran)
+endif()
+
+####################################################################
+# Kokkos/YAKL-related settings #
+####################################################################
+
if (Kokkos_ENABLE_CUDA)
if (Kokkos_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE)
if (Kokkos_ENABLE_DEBUG_BOUNDS_CHECK)
@@ -56,68 +94,6 @@ endif()
# to be on. For now, simply ensure Kokkos Serial is enabled
option (Kokkos_ENABLE_SERIAL "" ON)
-# We want to use C++17 in EAMxx
-set(CMAKE_CXX_STANDARD 17)
-
-if (NOT SCREAM_CIME_BUILD)
- project(SCREAM CXX C Fortran)
-
- if (SCREAM_CORI_HACK)
- list(APPEND CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "ifcore")
- list(REMOVE_ITEM CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "ifport")
- endif()
-
-else()
- # Ensure our languages are all enabled
- enable_language(C CXX Fortran)
-endif()
-
-# Print the sha of the last commit (useful to double check which version was tested on CDash)
-execute_process (COMMAND git rev-parse HEAD
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- OUTPUT_VARIABLE LAST_GIT_COMMIT_SHA
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-set(EAMXX_GIT_VERSION ${LAST_GIT_COMMIT_SHA} CACHE STRING "The sha of the last git commit.")
-message(STATUS "The sha of the last commit is ${EAMXX_GIT_VERSION}")
-
-set(SCREAM_DOUBLE_PRECISION TRUE CACHE BOOL "Set to double precision (default True)")
-
-# Set the scream base and src directory, to be used across subfolders
-set(SCREAM_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
-set(SCREAM_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
-set(SCREAM_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
-
-# Shortcut function, to print a variable
-function (print_var var)
- message ("${var}: ${${var}}")
-endfunction ()
-
-function (check_pack_size master_pack_size pack_size name)
- math (EXPR PACK_MODULO "${master_pack_size} % ${pack_size}")
- if ((pack_size GREATER master_pack_size) OR (NOT PACK_MODULO EQUAL 0))
- message (FATAL_ERROR "Invalid '${name}' size of ${pack_size}. Needs to be <= ${master_pack_size} and be a factor of it")
- endif()
-endfunction ()
-
-# Compute reasonable defaults. This needs to happen before the CACHE variables
-# are set.
-string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_ci)
-if (CMAKE_BUILD_TYPE_ci STREQUAL "debug")
- set (SCREAM_DEBUG TRUE)
-else ()
- set (SCREAM_DEBUG FALSE)
-endif()
-
-# Add RRTMGP debug checks. Note, we might consider also adding RRTMGP_EXPENSIVE_CHECKS
-# to turn on the RRTMGP internal checks here as well, via
-# option (RRTMGP_EXPENSIVE_CHECKS "Turn on internal RRTMGP error checking" ${SCREAM_DEBUG})
-# and then adding to scream_config.h:
-# #cmakedefine RRTMGP_EXPENSIVE_CHECKS
-option (SCREAM_RRTMGP_DEBUG "Turn on extra debug checks in RRTMGP" ${SCREAM_DEBUG})
-
-enable_testing()
-include(CTest)
-
set (EAMXX_ENABLE_GPU FALSE CACHE BOOL "")
set (CUDA_BUILD FALSE CACHE BOOL "") #needed for yakl if kokkos vars are not visible there?
set (HIP_BUILD FALSE CACHE BOOL "") #needed for yakl if kokkos vars are not visible there?
@@ -142,13 +118,16 @@ if( NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "[Cc]lang" )
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -cpp")
endif()
-### Scream default configuration options
+####################################################################
+# EAMxx main configuration options #
+####################################################################
+
+# First, Compute reasonable defaults. This needs to happen before the CACHE variables are set
set(DEFAULT_MAX_RANKS 4)
set(DEFAULT_MAX_THREADS 16)
set(DEFAULT_MIMIC_GPU FALSE)
set(DEFAULT_FPE FALSE)
set(DEFAULT_PACK_SIZE 16)
-set(DEFAULT_POSSIBLY_NO_PACK FALSE)
if (EAMXX_ENABLE_GPU)
# On the GPU, the pack size must be 1
set(DEFAULT_PACK_SIZE 1)
@@ -203,24 +182,122 @@ if (Kokkos_ENABLE_HIP)
set(DEFAULT_SMALL_KERNELS TRUE)
endif()
-### Set CACHE vars
+if (SCREAM_DEBUG)
+ set(DEFAULT_FPMODEL "strict")
+ if (SCREAM_PACK_SIZE EQUAL 1 AND NOT EAMXX_ENABLE_GPU)
+ set(DEFAULT_FPE TRUE)
+ endif ()
+endif()
+
+### Now that reasonable defaults have been computed, set CACHE vars
set(SCREAM_MIMIC_GPU ${DEFAULT_MIMIC_GPU} CACHE BOOL "Mimic GPU to correctness-test inter-column parallelism on non-GPU platform")
set(SCREAM_PACK_CHECK_BOUNDS FALSE CACHE BOOL "If defined, scream::pack objects check indices against bounds")
-set(SCREAM_TEST_DATA_DIR ${CMAKE_CURRENT_BINARY_DIR}/data CACHE PATH "Location of data files generated by tests")
set(SCREAM_LIB_ONLY ${DEFAULT_LIB_ONLY} CACHE BOOL "Only build libraries, no exes")
set(NetCDF_Fortran_PATH ${DEFAULT_NetCDF_Fortran_PATH} CACHE FILEPATH "Path to netcdf fortran installation")
set(NetCDF_C_PATH ${DEFAULT_NetCDF_C_PATH} CACHE FILEPATH "Path to netcdf C installation")
set(SCREAM_MACHINE ${DEFAULT_SCREAM_MACHINE} CACHE STRING "The CIME/SCREAM name for the current machine")
option(SCREAM_MPI_ON_DEVICE "Whether to use device pointers for MPI calls" ON)
-option(SCREAM_ENABLE_MAM "Whether to enable MAM aerosol support" OFF)
+option(SCREAM_ENABLE_MAM "Whether to enable MAM aerosol support" ON)
set(SCREAM_SMALL_KERNELS ${DEFAULT_SMALL_KERNELS} CACHE STRING "Use small, non-monolothic kokkos kernels")
if (NOT SCREAM_SMALL_KERNELS)
set(EKAT_DISABLE_WORKSPACE_SHARING TRUE CACHE STRING "")
endif()
+# Add RRTMGP debug checks. Note, we might consider also adding RRTMGP_EXPENSIVE_CHECKS
+# to turn on the RRTMGP internal checks here as well, via
+# option (RRTMGP_EXPENSIVE_CHECKS "Turn on internal RRTMGP error checking" ${SCREAM_DEBUG})
+# and then adding to scream_config.h:
+# #cmakedefine RRTMGP_EXPENSIVE_CHECKS
+option (SCREAM_RRTMGP_DEBUG "Turn on extra debug checks in RRTMGP" ${SCREAM_DEBUG})
+
+set(SCREAM_DOUBLE_PRECISION TRUE CACHE BOOL "Set to double precision (default True)")
+
# For now, only used in share/grid/remap/refining_remapper_rma.*pp
option (EAMXX_ENABLE_EXPERIMENTAL_CODE "Compile one-sided MPI for refining remappers" OFF)
+option (SCREAM_ENABLE_ML_CORRECTION "Whether to enable ML correction parametrization" OFF)
+
+# Set number of vertical levels
+set(SCREAM_NUM_VERTICAL_LEV ${DEFAULT_NUM_VERTICAL_LEV} CACHE STRING
+ "The number of levels used in the vertical grid."
+)
+option(SCREAM_HAS_LEAP_YEAR "Whether scream uses leap years or not" ON)
+
+set(SCREAM_FPMODEL ${DEFAULT_FPMODEL} CACHE STRING "Compiler floating point model")
+set(SCREAM_FPE ${DEFAULT_FPE} CACHE BOOL "Enable floating point error exception")
+
+# Whether to use XYZ as a method to detect memory usage.
+option (SCREAM_ENABLE_GETRUSAGE "Whether getrusage can be used to get memory usage." OFF)
+option (SCREAM_ENABLE_STATM "Whether /proc/self/statm can be used to get memory usage." OFF)
+
+# Whether to disable warnings from tpls.
+set (SCREAM_DISABLE_TPL_WARNINGS ON CACHE BOOL "")
+
+# Dycore settings
+set(DEFAULT_SCREAM_DYNAMICS_DYCORE "NONE")
+if (SCREAM_CIME_BUILD AND SCREAM_DYN_TARGET STREQUAL "theta-l_kokkos")
+ set (DEFAULT_SCREAM_DYNAMICS_DYCORE "Homme")
+endif()
+
+set(SCREAM_DYNAMICS_DYCORE ${DEFAULT_SCREAM_DYNAMICS_DYCORE} CACHE STRING
+ "The name of the dycore to be used for dynamics. If NONE, then any code/test requiring dynamics is disabled.")
+
+string(TOUPPER "${SCREAM_DYNAMICS_DYCORE}" SCREAM_DYNAMICS_DYCORE)
+if (NOT ${SCREAM_DOUBLE_PRECISION})
+ # Homme cannot handle single precision, for now. This causes tests to fail.
+ # Fixing this requires adding a config parameter to homme, to switch between
+ # single and double. That must be done in the upstream repo (E3SM), before
+ # we can support it here.
+ # So, for now, if Homme is the requested dyn dycore AND single precision is
+ # requested, we disable dynamics, printing a warning.
+ if ("${SCREAM_DYNAMICS_DYCORE}" STREQUAL "HOMME")
+ message("WARNING! Homme dycore cannot be used in a Single Precision build. Turning Homme off.")
+ set(SCREAM_DYNAMICS_DYCORE "NONE")
+ endif()
+endif()
+
+# Set the scream base and src directory, to be used across subfolders
+set(SCREAM_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(SCREAM_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
+set(SCREAM_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
+
+####################################################################
+# Packs-related settings #
+####################################################################
+
+# Determine the main pack size.
+set(SCREAM_PACK_SIZE ${DEFAULT_PACK_SIZE} CACHE STRING
+ "The number of scalars in a scream::pack::Pack and Mask. Larger packs have good performance on conditional-free loops due to improved caching.")
+
+# Besides the the main pack size, we have a couple of other pack sizes used across EAMxx
+# For some routines, SKX may have better performance with pack_size=1
+set(SCREAM_SMALL_PACK_SIZE ${SCREAM_PACK_SIZE} CACHE STRING
+ "The number of scalars in a scream::pack::SmallPack and SmallMask. Smaller packs can have better performance in loops with conditionals since more of the packs will have masks with uniform value.")
+set(SCREAM_POSSIBLY_NO_PACK "${Kokkos_ARCH_SKX}" CACHE BOOL
+ "Set possibly-no-pack to this value. You can set it to something else to restore packs on SKX for testing.")
+
+if (SCREAM_POSSIBLY_NO_PACK)
+ set (SCREAM_POSSIBLY_NO_PACK_SIZE 1)
+else()
+ set (SCREAM_POSSIBLY_NO_PACK_SIZE ${SCREAM_PACK_SIZE})
+endif ()
+
+function (check_pack_size master_pack_size pack_size name)
+ math (EXPR PACK_MODULO "${master_pack_size} % ${pack_size}")
+ if ((pack_size GREATER master_pack_size) OR (NOT PACK_MODULO EQUAL 0))
+ message (FATAL_ERROR "Invalid '${name}' size of ${pack_size}. Needs to be <= ${master_pack_size} and be a factor of it")
+ endif()
+endfunction ()
+
+# Checks on pack sizes relative to the master one:
+check_pack_size(${SCREAM_PACK_SIZE} ${SCREAM_SMALL_PACK_SIZE} "small pack")
+# This one is an internal check, as the user cannot set SCREAM_POSSIBLY_NO_PACK_SIZE now.
+check_pack_size(${SCREAM_PACK_SIZE} ${SCREAM_POSSIBLY_NO_PACK_SIZE} "possibly no pack")
+
+####################################################################
+# Input-data locations #
+####################################################################
+
# Handle input root
if (SCREAM_MACHINE AND NOT SCREAM_INPUT_ROOT)
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/query-cime ${SCREAM_MACHINE} DIN_LOC_ROOT
@@ -274,140 +351,172 @@ set (SCREAM_DATA_DIR ${SCREAM_INPUT_ROOT}/atm/scream CACHE PATH "" FORCE)
set (TOPO_DATA_DIR ${SCREAM_INPUT_ROOT}/atm/cam/topo CACHE PATH "" FORCE)
set (IOP_DATA_DIR ${SCREAM_INPUT_ROOT}/atm/cam/scam/iop CACHE PATH "" FORCE)
-#
-# Handle test level
-#
+####################################################################
+# Tests-related settings #
+####################################################################
+
+if (NOT SCREAM_LIB_ONLY)
+
+ # Assuming SCREAM_LIB_ONLY is FALSE (else, no exec is built at all), we need to decide
+ # wether to build baseline-related execs, and wether we are generating baselines or
+ # comparing against them. These options can help reducing a bit the code that is built
+ # when generating baselines or when running memory-check tests (no baselines needed there)
+ option(SCREAM_ONLY_GENERATE_BASELINES "Whether building only baselines-related executables" OFF)
+ option(SCREAM_ENABLE_BASELINE_TESTS "Whether to run baselines-related tests" ON)
+ if (SCREAM_ONLY_GENERATE_BASELINES AND NOT SCREAM_ENABLE_BASELINE_TESTS)
+ message (FATAL_ERROR
+ "Makes no sense to set SCREAM_ONLY_GENERATE_BASELINES=ON,\n"
+ "but set SCREAM_ENABLE_BASELINE_TESTS=OFF.")
+ endif()
-# Constants
-set(SCREAM_TEST_LEVEL_AT "0")
-set(SCREAM_TEST_LEVEL_NIGHTLY "1")
-set(SCREAM_TEST_LEVEL_EXPERIMENTAL "2")
+ set(SCREAM_BASELINES_DIR "UNSET" CACHE PATH "Folder containing baselines data")
+ if (SCREAM_ENABLE_BASELINE_TESTS)
+ if (NOT EXISTS ${SCREAM_BASELINES_DIR}/data OR NOT IS_DIRECTORY ${SCREAM_BASELINES_DIR}/data)
+ string (CONCAT msg
+ "Error! Baselines tests enabled, but baseline dir is invalid.\n"
+ " SCREAM_BASELINES_DIR: ${SCREAM_BASELINES_DIR}")
+ message ("${msg}")
+ message (FATAL_ERROR "Aborting...")
+ endif()
+ endif()
-set(SCREAM_TEST_LEVEL "AT" CACHE STRING "The test level to run. Default is AT. NIGHTLY will run additional tests but is not guaranteed to PASS. EXPERIMENTAL will run even more tests with failures being more likely")
+ # All baselines tests will add a line to the baseline_list file,
+ # specifyiing the full name of the baseline they generated.
+ # When test-all-scream has to generate new baselines, it will run
+ # ctest -L baseline_gen, and then read this file to find out all the
+ # baseline files to copy into the baseline directory
+ set (SCREAM_TEST_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/data)
+ file(MAKE_DIRECTORY ${SCREAM_TEST_OUTPUT_DIR})
+ file(TOUCH ${SCREAM_TEST_OUTPUT_DIR}/baseline_list)
+
+ set(SCREAM_TEST_LEVEL_AT "0")
+ set(SCREAM_TEST_LEVEL_NIGHTLY "1")
+ set(SCREAM_TEST_LEVEL_EXPERIMENTAL "2")
+
+ set(SCREAM_TEST_LEVEL "AT" CACHE STRING "The test level to run. Default is AT. NIGHTLY will run additional tests but is not guaranteed to PASS. EXPERIMENTAL will run even more tests with failures being more likely")
+
+ if (SCREAM_TEST_LEVEL STREQUAL "AT")
+ set(SCREAM_TEST_LEVEL ${SCREAM_TEST_LEVEL_AT})
+ elseif (SCREAM_TEST_LEVEL STREQUAL "NIGHTLY")
+ set(SCREAM_TEST_LEVEL ${SCREAM_TEST_LEVEL_NIGHTLY})
+ elseif (SCREAM_TEST_LEVEL STREQUAL "EXPERIMENTAL")
+ set(SCREAM_TEST_LEVEL ${SCREAM_TEST_LEVEL_EXPERIMENTAL})
+ else()
+ message(FATAL_ERROR "Unknown SCREAM_TEST_LEVEL '${SCREAM_TEST_LEVEL}'")
+ endif()
-if (SCREAM_TEST_LEVEL STREQUAL "AT")
- set(SCREAM_TEST_LEVEL ${SCREAM_TEST_LEVEL_AT})
-elseif (SCREAM_TEST_LEVEL STREQUAL "NIGHTLY")
- set(SCREAM_TEST_LEVEL ${SCREAM_TEST_LEVEL_NIGHTLY})
-elseif (SCREAM_TEST_LEVEL STREQUAL "EXPERIMENTAL")
- set(SCREAM_TEST_LEVEL ${SCREAM_TEST_LEVEL_EXPERIMENTAL})
-else()
- message(FATAL_ERROR "Unknown SCREAM_TEST_LEVEL '${SCREAM_TEST_LEVEL}'")
-endif()
+ set(SCREAM_TEST_MAX_THREADS ${DEFAULT_MAX_THREADS} CACHE STRING "Upper limit on threads per rank for threaded tests")
+ set(SCREAM_TEST_THREAD_INC 1 CACHE STRING "Thread count increment for threaded tests")
+ set(SCREAM_TEST_MAX_RANKS ${DEFAULT_MAX_RANKS} CACHE STRING "Upper limit on ranks for mpi tests")
+ math(EXPR DEFAULT_MAX_TOTAL_THREADS "${SCREAM_TEST_MAX_RANKS}*${SCREAM_TEST_MAX_THREADS}")
+ set(SCREAM_TEST_MAX_TOTAL_THREADS ${DEFAULT_MAX_TOTAL_THREADS} CACHE STRING "Upper limit on nranks*threads for threaded tests")
+
+ # Make sure SCREAM_TEST_MAX_RANKS and SCREAM_TEST_MAX_THREADS do not individually exceed SCREAM_TEST_MAX_TOTAL_THREADS
+ if (SCREAM_TEST_MAX_THREADS GREATER ${SCREAM_TEST_MAX_TOTAL_THREADS})
+ string(CONCAT msg
+ "The requested number of max threads/rank (${SCREAM_TEST_MAX_THREADS}) is larger "
+ "than the max total threads (${SCREAM_TEST_MAX_TOTAL_THREADS}). Setting "
+ "SCREAM_TEST_MAX_THREADS=${SCREAM_TEST_MAX_TOTAL_THREADS}")
+ message(STATUS "${msg}")
+ set (SCREAM_TEST_MAX_THREADS ${SCREAM_TEST_MAX_TOTAL_THREADS})
+ endif()
+ if (SCREAM_TEST_MAX_RANKS GREATER ${SCREAM_TEST_MAX_TOTAL_THREADS})
+ string(CONCAT msg
+ "The requested number of max ranks (${SCREAM_TEST_MAX_RANKS}) is larger "
+ "than the max total threads (${SCREAM_TEST_MAX_TOTAL_THREADS}). Setting "
+ "SCREAM_TEST_MAX_RANKS=${SCREAM_TEST_MAX_TOTAL_THREADS}")
+ message(STATUS "${msg}")
+ set (SCREAM_TEST_MAX_RANKS ${SCREAM_TEST_MAX_TOTAL_THREADS})
+ endif()
+ # This is a meta-variable, which individual tests can use to set *different* degrees
+ # of testing, in terms of resolutions. E.g., for SHORT use 3 timesteps, for MEDIUM use 10,
+ # for LONG use 100. It is *completely* up to the test to decide what short, medium, and long mean.
+ if (EKAT_ENABLE_COVERAGE OR EKAT_ENABLE_CUDA_MEMCHECK OR EKAT_ENABLE_VALGRIND OR EKAT_ENABLE_COMPUTE_SANITIZER)
+ set (SCREAM_TEST_SIZE_DEFAULT SHORT)
+ # also set thread_ing=$max_thread - 1, so we test at most 2 threading configurations
+ if (SCREAM_TEST_MAX_THREADS GREATER 1)
+ math (EXPR SCREAM_TEST_THREAD_INC ${SCREAM_TEST_MAX_THREADS}-1)
+ endif()
+ else()
+ set (SCREAM_TEST_SIZE_DEFAULT MEDIUM)
+ endif()
-# Assuming SCREAM_LIB_ONLY is FALSE (else, no exec is built at all), we provide the option
-# of building only baseline-related execs. By default, this option is off (menaing "build everything").
-# However, when generating baselines, this can be useful to reduce the amount of stuff compiled.
-set(SCREAM_BASELINES_ONLY FALSE CACHE BOOL "Whether building only baselines-related executables")
+ set(SCREAM_TEST_SIZE ${SCREAM_TEST_SIZE_DEFAULT} CACHE STRING "The kind of testing to perform: SHORT, MEDIUM, LONG. Only applies to certain tests and is generally used to reduce test length when valgrind/cuda-memcheck are on.")
+ set(SCREAM_TEST_VALID_SIZES "SHORT;MEDIUM;LONG" CACHE INTERNAL "List of valid values for SCREAM_TEST_SIZE")
-# Certain builds are not meant to compare against baselines. For instance, a valgrind build
-# has the sole purpose of detecting memory errors. For these builds, we can disable baselines tests
-set(SCREAM_ENABLE_BASELINE_TESTS TRUE CACHE BOOL "Whether to run baselines-related tests")
+ if (SCREAM_TEST_SIZE STREQUAL "SHORT")
+ add_definitions(-DSCREAM_SHORT_TESTS)
+ endif()
-if (SCREAM_BASELINES_ONLY AND NOT SCREAM_ENABLE_BASELINE_TESTS)
- message (FATAL_ERROR
- "Makes no sense to set SCREAM_BASELINES_ONLY=ON,\n"
- "but set SCREAM_ENABLE_BASELINE_TESTS=OFF.")
+ enable_testing()
+ include(CTest)
endif()
-# Set number of vertical levels
-set(SCREAM_NUM_VERTICAL_LEV ${DEFAULT_NUM_VERTICAL_LEV} CACHE STRING
- "The number of levels used in the vertical grid."
-)
-option(SCREAM_HAS_LEAP_YEAR "Whether scream uses leap years or not" ON)
+####################################################################
+# Configure all tpls and subfolders #
+####################################################################
+
+if (DEFINED ENV{SCREAM_FAKE_ONLY})
+ # We don't really need to build ekat, but we do need to configure the test-launcher
+
+ # Declare some vars that Ekat would have declared, and may be used later
+ option (EKAT_ENABLE_MPI "Whether EKAT requires MPI." ON)
+ option (EKAT_TEST_LAUNCHER_MANAGE_RESOURCES "Whether test-launcher should try to manage thread distribution. Requires a ctest resource file to be effective." OFF)
+ option (EKAT_ENABLE_VALGRIND "Whether to run tests with valgrind" OFF)
+ set(EKAT_VALGRIND_SUPPRESSION_FILE "" CACHE FILEPATH "Use this valgrind suppression file if valgrind is enabled.")
+ set (EKAT_ENABLE_GPU False)
+ if (Kokkos_ENABLE_CUDA OR Kokkos_ENABLE_HIP OR Kokkos_ENABLE_SYCL)
+ set (EKAT_ENABLE_GPU True)
+ endif ()
-## Work out pack sizes.
-# Determine the master pack size.
-set(SCREAM_PACK_SIZE ${DEFAULT_PACK_SIZE} CACHE STRING
- "The number of scalars in a scream::pack::Pack and Mask. Larger packs have good performance on conditional-free loops due to improved caching.")
-# With the master pack size determined, we have constraints on the others.
-set(DEFAULT_SMALL_PACK_SIZE ${SCREAM_PACK_SIZE})
-# For some routines, SKX may have better performance with pksize=1
-if (Kokkos_ARCH_SKX)
- set(DEFAULT_POSSIBLY_NO_PACK TRUE)
-endif ()
-set(SCREAM_SMALL_PACK_SIZE ${DEFAULT_SMALL_PACK_SIZE} CACHE STRING
- "The number of scalars in a scream::pack::SmallPack and SmallMask. Smaller packs can have better performance in loops with conditionals since more of the packs will have masks with uniform value.")
-set(SCREAM_POSSIBLY_NO_PACK ${DEFAULT_POSSIBLY_NO_PACK} CACHE BOOL
- "Set possibly-no-pack to this value. You can set it to something else to restore packs on SKX for testing.")
-set (DEFAULT_POSSIBLY_NO_PACK_SIZE ${SCREAM_PACK_SIZE})
+ if (EKAT_TEST_LAUNCHER_MANAGE_RESOURCES)
+ set (TEST_LAUNCHER_MANAGE_RESOURCES True)
+ else()
+ set (TEST_LAUNCHER_MANAGE_RESOURCES False)
+ endif()
+ if (EKAT_ENABLE_GPU)
+ set (TEST_LAUNCHER_ON_GPU True)
+ else()
+ set (TEST_LAUNCHER_ON_GPU False)
+ endif()
-if (SCREAM_POSSIBLY_NO_PACK)
- set (DEFAULT_POSSIBLY_NO_PACK_SIZE 1)
-endif ()
-set (SCREAM_POSSIBLY_NO_PACK_SIZE ${DEFAULT_POSSIBLY_NO_PACK_SIZE})
-# Checks on pack sizes relative to the master one:
-check_pack_size(${SCREAM_PACK_SIZE} ${SCREAM_SMALL_PACK_SIZE} "small pack")
-# This one is an internal check, as the user cannot set SCREAM_POSSIBLY_NO_PACK_SIZE now.
-check_pack_size(${SCREAM_PACK_SIZE} ${SCREAM_POSSIBLY_NO_PACK_SIZE} "possibly no pack")
+ set (EKAT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../externals/ekat)
-## Now we have pack sizes. Proceed with other config options that depend on
-## these.
+ if (EKAT_ENABLE_MPI)
+ find_package(MPI REQUIRED COMPONENTS C)
-if (SCREAM_DEBUG)
- set(DEFAULT_FPMODEL "strict")
- if (${SCREAM_PACK_SIZE} EQUAL 1 AND NOT ${EAMXX_ENABLE_GPU})
- set(DEFAULT_FPE TRUE)
- endif ()
-endif()
-set(SCREAM_FPMODEL ${DEFAULT_FPMODEL} CACHE STRING "Compiler floating point model")
-set(SCREAM_FPE ${DEFAULT_FPE} CACHE BOOL "Enable floating point error exception")
-### Experimental, under development
+
+ F20TR-SCREAMv1
+ 20TR_SCREAM_ELM%SPBC_CICE%PRES_DOCN%DOM_MOSART_SGLC_SWAV
+
+
+
+ F2010-SCREAMv1-DP-DYCOMSrf01
+ 2010_SCREAM_ELM%SPBC_CICE%PRES_DOCN%DOM_SROF_SGLC_SWAV_SIAC_SESP%DP-EAMxx%DYCOMSrf01
+ Experimental, under development
+
+
2016-08-01
2020-01-20
+ 1999-07-10
+
+
+
+
+
+
+ 864
+
+
+
+
+
+ TRUE
+
+
+
+
+
+ TRUE
+
+
+
+
+
+ 31.5
+
+
+
+
+
+ 238.5
+
+
+
+
+
+ 225
+
+
+
+
+
+ 1
+
+
+
+
+
+ 225
+
+
+
+
+
+ 1
diff --git a/components/eamxx/cime_config/eamxx_buildnml.py b/components/eamxx/cime_config/eamxx_buildnml.py
index db05bd2e20e1..0c7ed8e52aac 100644
--- a/components/eamxx/cime_config/eamxx_buildnml.py
+++ b/components/eamxx/cime_config/eamxx_buildnml.py
@@ -21,7 +21,7 @@
from utils import ensure_yaml # pylint: disable=no-name-in-module
ensure_yaml()
import yaml
-from yaml_utils import Bools,Ints,Floats,Strings,array_representer
+from yaml_utils import Bools,Ints,Floats,Strings,array_representer,array_constructor
_CIMEROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..","..","..","cime")
sys.path.append(os.path.join(_CIMEROOT, "CIME", "Tools"))
@@ -465,7 +465,18 @@ def expand_cime_vars(element, case):
child.text = do_cime_vars(child.text, case)
###############################################################################
-def _create_raw_xml_file_impl(case, xml):
+def write_pretty_xml(filepath, xml):
+###############################################################################
+ with open(filepath, "w") as fd:
+ # dom has better pretty printing than ET in older python versions < 3.9
+ dom = md.parseString(ET.tostring(xml, encoding="unicode"))
+ pretty_xml = dom.toprettyxml(indent=" ")
+ pretty_xml = os.linesep.join([s for s in pretty_xml.splitlines()
+ if s.strip()])
+ fd.write(pretty_xml)
+
+###############################################################################
+def _create_raw_xml_file_impl(case, xml, filepath=None):
###############################################################################
"""
On input, xml contains the parsed content of namelist_defaults_scream.xml.
@@ -610,32 +621,40 @@ def _create_raw_xml_file_impl(case, xml):
selectors = get_valid_selectors(xml)
# 1. Evaluate all selectors
- evaluate_selectors(xml, case, selectors)
+ try:
+ evaluate_selectors(xml, case, selectors)
- # 2. Apply all changes in the SCREAM_ATMCHANGE_BUFFER that may alter
- # which atm processes are used
- apply_atm_procs_list_changes_from_buffer (case,xml)
+ # 2. Apply all changes in the SCREAM_ATMCHANGE_BUFFER that may alter
+ # which atm processes are used
+ apply_atm_procs_list_changes_from_buffer (case,xml)
- # 3. Resolve all inheritances
- resolve_all_inheritances(xml)
+ # 3. Resolve all inheritances
+ resolve_all_inheritances(xml)
- # 4. Expand any CIME var that appears inside XML nodes text
- expand_cime_vars(xml,case)
+ # 4. Expand any CIME var that appears inside XML nodes text
+ expand_cime_vars(xml,case)
- # 5. Grab the atmosphere_processes macro list, with all the defaults
- atm_procs_defaults = get_child(xml,"atmosphere_processes_defaults",remove=True)
+ # 5. Grab the atmosphere_processes macro list, with all the defaults
+ atm_procs_defaults = get_child(xml,"atmosphere_processes_defaults",remove=True)
- # 6. Get atm procs list
- atm_procs_list = get_child(atm_procs_defaults,"atm_procs_list",remove=True)
+ # 6. Get atm procs list
+ atm_procs_list = get_child(atm_procs_defaults,"atm_procs_list",remove=True)
- # 7. Form the nested list of atm procs needed, append to atmosphere_driver section
- atm_procs = gen_atm_proc_group(atm_procs_list.text, atm_procs_defaults)
- atm_procs.tag = "atmosphere_processes"
- xml.append(atm_procs)
+ # 7. Form the nested list of atm procs needed, append to atmosphere_driver section
+ atm_procs = gen_atm_proc_group(atm_procs_list.text, atm_procs_defaults)
+ atm_procs.tag = "atmosphere_processes"
+ xml.append(atm_procs)
- # 8. Apply all changes in the SCREAM_ATMCHANGE_BUFFER that do not alter
- # which atm processes are used
- apply_non_atm_procs_list_changes_from_buffer (case,xml)
+ # 8. Apply all changes in the SCREAM_ATMCHANGE_BUFFER that do not alter
+ # which atm processes are used
+ apply_non_atm_procs_list_changes_from_buffer (case,xml)
+ except BaseException as e:
+ if filepath is not None:
+ dbg_xml_path = filepath.replace(".xml", ".dbg.xml")
+ write_pretty_xml(dbg_xml_path, xml)
+ print(f"Error during XML creation, writing {dbg_xml_path}")
+
+ raise e
perform_consistency_checks (case, xml)
@@ -666,17 +685,11 @@ def create_raw_xml_file(case, caseroot):
# be processed early by treating them as if they were made to the defaults file.
with open(src, "r") as fd:
defaults = ET.parse(fd).getroot()
- raw_xml = _create_raw_xml_file_impl(case, defaults)
+ raw_xml = _create_raw_xml_file_impl(case, defaults, filepath=raw_xml_file)
check_all_values(raw_xml)
- with open(raw_xml_file, "w") as fd:
- # dom has better pretty printing than ET in older python versions < 3.9
- dom = md.parseString(ET.tostring(raw_xml, encoding="unicode"))
- pretty_xml = dom.toprettyxml(indent=" ")
- pretty_xml = os.linesep.join([s for s in pretty_xml.splitlines()
- if s.strip()])
- fd.write(pretty_xml)
+ write_pretty_xml(raw_xml_file, raw_xml)
###############################################################################
def convert_to_dict(element):
@@ -877,6 +890,11 @@ def get_file_parameters(caseroot):
result = []
for item in raw_xml.findall('.//*[@type="file"]'):
+ # Certain configurations may not need a file (e.g., a remap
+ # file for SPA may not be needed if the model resolution
+ # matches the data file resolution
+ if item.text is None or item.text=="":
+ continue
result.append(item.text.strip())
for item in raw_xml.findall('.//*[@type="array(file)"]'):
@@ -886,7 +904,7 @@ def get_file_parameters(caseroot):
return list(OrderedDict.fromkeys(result))
###############################################################################
-def create_input_data_list_file(caseroot):
+def create_input_data_list_file(case,caseroot):
###############################################################################
"""
Create the scream.input_data_list file for this case. This will tell CIME
@@ -894,18 +912,51 @@ def create_input_data_list_file(caseroot):
"""
files_to_download = get_file_parameters(caseroot)
+ # Add array parsing knowledge to yaml loader
+ loader = yaml.SafeLoader
+ loader.add_constructor("!bools",array_constructor)
+ loader.add_constructor("!ints",array_constructor)
+ loader.add_constructor("!floats",array_constructor)
+ loader.add_constructor("!strings",array_constructor)
+
+ # Grab all the output yaml files, open them, and check if horiz_remap_file or vertical_remap_file is used
+ rundir = case.get_value("RUNDIR")
+ eamxx_xml_file = os.path.join(caseroot, "namelist_scream.xml")
+ with open(eamxx_xml_file, "r") as fd:
+ eamxx_xml = ET.parse(fd).getroot()
+
+ scorpio = get_child(eamxx_xml,'Scorpio')
+ out_files_xml = get_child(scorpio,"output_yaml_files",must_exist=False)
+ # out_files = out_files_xml.text.split(",") if (out_files_xml is not None and out_files_xml.text is not None) else []
+ # for fn in out_files:
+ if (out_files_xml is not None and out_files_xml.text is not None):
+ for fn in out_files_xml.text.split(","):
+ # Get full name
+ src_yaml = os.path.expanduser(os.path.join(fn.strip()))
+ dst_yaml = os.path.expanduser(os.path.join(rundir,'data',os.path.basename(src_yaml)))
+
+ # Load file, and look for the remap file entries
+ content = yaml.load(open(dst_yaml,"r"),Loader=loader)
+ if 'horiz_remap_file' in content.keys():
+ files_to_download += [content['horiz_remap_file']]
+ if 'vertical_remap_file' in content.keys():
+ files_to_download += [content['vertical_remap_file']]
+
input_data_list_file = "{}/Buildconf/scream.input_data_list".format(caseroot)
if os.path.exists(input_data_list_file):
os.remove(input_data_list_file)
+ din_loc_root = case.get_value("DIN_LOC_ROOT")
with open(input_data_list_file, "w") as fd:
- for idx, file_path in enumerate(files_to_download):
- fd.write("scream_dl_input_{} = {}\n".format(idx, file_path))
+ for idx, file_path in enumerate(list(set(files_to_download))):
+ # Only add files whose full path starts with the CIME's input data location
+ if file_path.startswith(din_loc_root):
+ fd.write("scream_dl_input_{} = {}\n".format(idx, file_path))
+
###############################################################################
def do_cime_vars_on_yaml_output_files(case, caseroot):
###############################################################################
- from yaml_utils import array_constructor
rundir = case.get_value("RUNDIR")
eamxx_xml_file = os.path.join(caseroot, "namelist_scream.xml")
@@ -956,14 +1007,15 @@ def do_cime_vars_on_yaml_output_files(case, caseroot):
# produces an output at t=0, which is not present in the restarted run, and
# which also causes different timestamp in the file name.
# Hence, change default output settings to perform a single AVERAGE step at the end of the run
- if case.get_value("TESTCASE") in ["ERP", "ERS"]:
- test_env = case.get_env('test')
- stop_n = int(test_env.get_value("STOP_N"))
- stop_opt = test_env.get_value("STOP_OPTION")
- content['output_control']['Frequency'] = stop_n
- content['output_control']['frequency_units'] = stop_opt
- content['Averaging Type'] = 'AVERAGE'
- print ("WARNING: ERS/ERP tests hard code output to consist of a single AVERAGE output step at the end of the run.")
+ if case.get_value("TESTCASE") in ["ERP", "ERS"] and content['Averaging Type'].upper()=="INSTANT":
+ hist_n = int(case.get_value("HIST_N",resolved=True))
+ hist_opt = case.get_value("HIST_OPTION",resolved=True)
+ content['output_control']['Frequency'] = hist_n
+ content['output_control']['frequency_units'] = hist_opt
+ content['output_control']['skip_t0_output'] = True
+ print ("ERS/ERP test with INSTANT output detected. Adjusting output control specs:\n")
+ print (" - setting skip_t0_output=true\n")
+ print (" - setting freq and freq_units to HIST_N and HIST_OPTION respectively\n")
ordered_dump(content, open(dst_yaml, "w"))
diff --git a/components/eamxx/cime_config/eamxx_buildnml_impl.py b/components/eamxx/cime_config/eamxx_buildnml_impl.py
index 2fa00b7f4a4b..e0ecab146246 100644
--- a/components/eamxx/cime_config/eamxx_buildnml_impl.py
+++ b/components/eamxx/cime_config/eamxx_buildnml_impl.py
@@ -162,11 +162,12 @@ def refine_type(entry, force_type=None):
>>> e = '1.0'
>>> refine_type(e,force_type='my_type')
Traceback (most recent call last):
- NameError: ERROR: Invalid/unsupported force type 'my_type'
+ CIME.utils.CIMEError: ERROR: Invalid/unsupported force type 'my_type'
>>> e = 'true,falsE'
>>> refine_type(e,'logical')
Traceback (most recent call last):
- ValueError: Could not refine 'true,falsE' as type 'logical'
+ CIME.utils.CIMEError: ERROR: Could not refine 'true,falsE' as type 'logical':
+ ERROR: For entry of type 'logical', expected 'true' or 'false', got 'true,falsE'
>>> refine_type(e,'array(logical)')
[True, False]
>>> refine_type('', 'array(string)')
@@ -176,15 +177,14 @@ def refine_type(entry, force_type=None):
>>> refine_type(None, 'array(real)')
[]
"""
-
- # If force type is unspecified, try to deduce it
+ # If force type is unspecified, try to deduce it
if force_type is None:
expect (entry is not None,
"If an entry is None, you must specify the force_type")
else:
elem_valid = ["logical","integer","real","string","file"]
valid = elem_valid + ["array("+e+")" for e in elem_valid]
- expect (force_type in valid, exc_type=NameError,
+ expect (force_type in valid,
error_msg=f"Invalid/unsupported force type '{force_type}'")
if is_array_type(force_type):
@@ -208,7 +208,8 @@ def refine_type(entry, force_type=None):
elif entry.upper() == "FALSE":
return False
else:
- return bool(int(entry))
+ expect(False, f"For entry of type 'logical', expected 'true' or 'false', got '{entry}'",
+ exc_type=ValueError)
elif elem_type == "integer":
tmp = float(entry)
@@ -220,7 +221,7 @@ def refine_type(entry, force_type=None):
return str(entry)
except ValueError as e:
- raise ValueError (f"Could not refine '{entry}' as type '{force_type}'") from e
+ expect(False, f"Could not refine '{entry}' as type '{force_type}':\n{e}")
# No force type provided. Try to infer from value
if entry.upper() == "TRUE":
@@ -273,7 +274,7 @@ def derive_type(entry):
elif isinstance(elem_value, str):
elem_type = "string"
else:
- raise RuntimeError("Couldn't derive type of '{}'".format(entry))
+ expect(False, "Couldn't derive type of '{}'".format(entry))
if isinstance(refined_value,list):
return "array(" + elem_type + ")"
@@ -293,7 +294,8 @@ def check_value(elem, value):
>>> root = ET.fromstring(xml)
>>> check_value(root,'1.5')
Traceback (most recent call last):
- ValueError: Could not refine '1.5' as type 'integer'
+ CIME.utils.CIMEError: ERROR: Could not refine '1.5' as type 'integer':
+ ERROR: Cannot interpret 1.5 as int
>>> check_value(root,'3')
Traceback (most recent call last):
CIME.utils.CIMEError: ERROR: Invalid value '3' for element 'a'. Value not in the valid list ('[1, 2]')
diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml
index 71c1bfd4f828..07ef2793f38c 100644
--- a/components/eamxx/cime_config/namelist_defaults_scream.xml
+++ b/components/eamxx/cime_config/namelist_defaults_scream.xml
@@ -48,7 +48,7 @@ be lost if SCREAM_HACK_XML is not enabled.
ctl_nl
- driver_options,atmosphere_processes,grids_manager,initial_conditions,Scorpio,e3sm_parameters
+ driver_options,iop_options,atmosphere_processes,grids_manager,initial_conditions,Scorpio,e3sm_parameters
@@ -119,9 +119,8 @@ be lost if SCREAM_HACK_XML is not enabled.
for the atmosphere processes section(s).
11) The attribute 'locked="true"' is to be used for entries that cannot be changed
- via atmchange (see scripts/atmchange). For instance, the overall list of atm procs cannot be changed,
- since it would require to re-parse the defaults, to re-generate the correct
- defaults for the (possibly) new atm procs.
+ via atmchange (see scripts/atmchange). If an element is locked, then all children
+ will be locked as well.
12) The attribute 'constraints' allows to specify constraints on values. Valid constraints
are lt, le, ne, gt, ge, and mod. Except the latter (which has slightly different syntax,
@@ -203,6 +202,18 @@ be lost if SCREAM_HACK_XML is not enabled.
${DIN_LOC_ROOT}/atm/scream/tables/vn_table_vals.dat8,
${DIN_LOC_ROOT}/atm/scream/tables/vm_table_vals.dat8
+ 1350.0
+ 1.0
+ 1.0
+ 67.0
+ 0.5
+ 1.0
+ 50.0
+ 900.0
+ 0.65
+ 0.304
+ 1.0
+ 0.00028
@@ -226,20 +237,38 @@ be lost if SCREAM_HACK_XML is not enabled.
+
+
+
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/physprops/mam4_mode1_rrtmg_aeronetdust_c20240206.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/physprops/mam4_mode2_rrtmg_c20240206.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/physprops/mam4_mode3_rrtmg_aeronetdust_c20240206.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/physprops/mam4_mode4_rrtmg_c20240206.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/physprops/water_refindex_rrtmg_c20240206.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/physprops/ocphi_rrtmg_c20240206.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/physprops/dust_aeronet_rrtmg_c20240206.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/physprops/ssam_rrtmg_c20240206.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/physprops/sulfate_rrtmg_c20240206.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/physprops/ocpho_rrtmg_c20240206.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/physprops/bcpho_rrtmg_c20240206.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/physprops/poly_rrtmg_c20240206.nc
+
+
-
+
0
false
- false
+ TIME_DEPENDENT_3D_PROFILE
-
+
- UNSET
- ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30_to_ne4_mono_20220502.nc
- ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30np4_to_ne4pg2_mono.20220714.nc
- none
- ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30np4_to_ne30pg2_mono.20220714.nc
+
${DIN_LOC_ROOT}/atm/scream/maps/map_ne30np4_to_ne120np4_mono_20220502.nc
- ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30np4_to_ne512np4_mono_20220506.nc
- ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30np4_to_ne120pg2_intbilin_20221012.nc
- ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30np4_to_ne256pg2_intbilin_20221011.nc
- ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30np4_to_ne512pg2_intbilin_20221012.nc
- ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30np4_to_ne1024pg2_intbilin_20221012.nc
-
- ${DIN_LOC_ROOT}/atm/scream/init/spa_file_unified_and_complete_ne30_20220428.nc
+ ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30pg2_to_ne120pg2_20231201.nc
+ ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30pg2_to_ne256pg2_20231201.nc
+ ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30pg2_to_ne512pg2_20231201.nc
+ ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30pg2_to_ne1024pg2_20231201.nc
+
+
+
+ ${DIN_LOC_ROOT}/atm/scream/init/spa_file_unified_and_complete_ne30_20220428.nc
+ ${DIN_LOC_ROOT}/atm/scream/init/spa_file_unified_and_complete_ne30pg2_20240111.nc
+ ${DIN_LOC_ROOT}/atm/scream/init/spa_file_unified_and_complete_ne4_20220428.nc
+ ${DIN_LOC_ROOT}/atm/scream/init/spa_file_unified_and_complete_ne4pg2_20231222.nc
@@ -327,6 +356,7 @@ be lost if SCREAM_HACK_XML is not enabled.
3
3
3
+ 3
4
true
false
@@ -343,6 +373,9 @@ be lost if SCREAM_HACK_XML is not enabled.
>
false
+
+ true
+
@@ -356,11 +389,15 @@ be lost if SCREAM_HACK_XML is not enabled.
6
2
1
+ 1
5
- 10
+ 10
+ 1
+ 1
+ 1
1
hours
@@ -397,10 +434,8 @@ be lost if SCREAM_HACK_XML is not enabled.
${DIN_LOC_ROOT}/atm/scream/init/screami_ne256np4L128_ifs-20200120_20220914.nc
${DIN_LOC_ROOT}/atm/scream/init/screami_ne512np4L128_20220823.nc
${DIN_LOC_ROOT}/atm/scream/init/screami_ne1024np4L128_era5-20131001-topoadj-16x_20220914.nc
- ${DIN_LOC_ROOT}/atm/scream/init/screami_ne1024np4L128_ifs-20160801-topoadjx6t_20221011.nc
${DIN_LOC_ROOT}/atm/scream/init/screami_ne1024np4L128_ifs-20200120-topoadjx6t_20221011.nc
${DIN_LOC_ROOT}/atm/scream/init/screami_aquaplanet_ne4np4L72_20220823.nc
- ${DIN_LOC_ROOT}/atm/scream/init/screami_aquaplanet_ne30np4L128_20220823.nc
${DIN_LOC_ROOT}/atm/scream/init/screami_conusx4v1np4L72-topo12x_013023.nc
@@ -453,11 +488,19 @@ be lost if SCREAM_HACK_XML is not enabled.
0.0
0.0
0.0
+
+
+
+ T_mid
+ false
+ 0
+ 0.001
+ 900.0
- ${SRCROOT}/components/eamxx/data/scream_default_output.yaml
+
./${CASE}.scream
@@ -475,12 +518,19 @@ be lost if SCREAM_HACK_XML is not enabled.
doc="Verbosity level for the atm logger">
info
+
+ warn
+
false
1e-10
1e-14
Warning
true
phis,landfrac
+ false
+ true
@@ -488,11 +538,28 @@ be lost if SCREAM_HACK_XML is not enabled.
${CASE}
+
+
+ true
+ UNSET
+ ${DIN_LOC_ROOT}/atm/cam/scam/iop/DYCOMSrf01_iopfile_4scam.nc
+ -999
+ 31.5
+ -999
+ 238.5
+ false
+ true
+ false
+ true
+
+
0
+ 2
False
2
+ 1
1
6
0
@@ -506,6 +573,7 @@ be lost if SCREAM_HACK_XML is not enabled.
1
1
3.4e-08
+ 0.216784
UNSET
250000.0
250000.0
@@ -513,6 +581,7 @@ be lost if SCREAM_HACK_XML is not enabled.
4.0e4
2.0e4
1.0e4
+ 1.0e4
100000.0
1
0
@@ -522,6 +591,7 @@ be lost if SCREAM_HACK_XML is not enabled.
0
0
sphere
+ plane
9
UNSET
4
@@ -530,19 +600,28 @@ be lost if SCREAM_HACK_XML is not enabled.
256
512
1024
+ 1024
0
0
+ 5
0
+ 5
+ 0
+ 50000
+ 0
+ 50000
-1
4
cube
- UNSET
+ plane
+ UNSET
600
300
75
33.33333333333
16.6666666666666
8.3333333333333
+ 8.3333333333333
75
9999
1
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/internal_diagnostics_level/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/internal_diagnostics_level/shell_commands
index d3a4a39b668a..cf3ca97f6dd3 100644
--- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/internal_diagnostics_level/shell_commands
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/internal_diagnostics_level/shell_commands
@@ -1,2 +1,2 @@
$CIMEROOT/../components/eamxx/scripts/atmchange --all internal_diagnostics_level=1 atmosphere_processes::internal_diagnostics_level=0 -b
-./xmlchange POSTRUN_SCRIPT="$CIMEROOT/../components/eamxx/tests/postrun/check_hashes_ers.py"
+./xmlchange POSTRUN_SCRIPT="$CIMEROOT/../components/eamxx/scripts/check-hashes-ers"
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/optics/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/optics/shell_commands
new file mode 100644
index 000000000000..1c22bd9ee454
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/optics/shell_commands
@@ -0,0 +1,9 @@
+
+#Default scream has 10 tracers, MAM4xx adds another 31 making a total of 41 tracer
+#Set total number of tracers to 41. We are using append here as last entry wins while parsing xml options
+./xmlchange --append SCREAM_CMAKE_OPTIONS="SCREAM_NUM_TRACERS 41"
+
+$CIMEROOT/../components/eamxx/scripts/atmchange initial_conditions::Filename='$DIN_LOC_ROOT/atm/scream/init/screami_mam4xx_ne4np4L72_c20240208.nc' -b
+$CIMEROOT/../components/eamxx/scripts/atmchange physics::atm_procs_list="mac_aero_mic,mam4_optics,rrtmgp" -b
+
+
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/README b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/README
new file mode 100644
index 000000000000..5d33c71fed37
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/README
@@ -0,0 +1,9 @@
+The testmods in this folder contain different configuration
+of output to request to eamxx. All the presets create a single
+output file, all with a different name, which means one can
+use 2+ presets at the same time.
+
+
+Each preset does basically two things:
+ 1. create a yaml file in the case folder
+ 2. add the yaml file to the yaml_output_files xml setting of eamxx
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/diags/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/diags/shell_commands
new file mode 100644
index 000000000000..904f46b580f2
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/diags/shell_commands
@@ -0,0 +1,37 @@
+# This script generates a (single) yaml file for EAMxx output.
+# The output will be INSTANT, with only some diags fields as ouput
+
+CASEROOT=$(./xmlquery --value CASEROOT)
+CASE=$(./xmlquery --value CASE)
+
+# Scripts location
+YAML_EDIT_SCRIPT=$CIMEROOT/../components/eamxx/scripts/edit-output-stream
+ATMCHANGE=$CIMEROOT/../components/eamxx/scripts/atmchange
+YAML_FILE=$CASEROOT/eamxx_diags_output.yaml
+
+# Figure out the suffix for the physics grid
+ATM_GRID=$(./xmlquery --value ATM_GRID)
+if [[ $ATM_GRID == *"pg2"* ]]; then
+ PGTYPE="PG2"
+else
+ PGTYPE="GLL"
+fi
+
+# List of output fields
+FIELDS='Exner LiqWaterPath dz geopotential_int PotentialTemperature'
+FIELDS+=' precip_liq_surf_mass_flux wind_speed ShortwaveCloudForcing'
+FIELDS+=' T_mid_at_model_bot T_mid_at_900hPa'
+FIELDS+=' horiz_winds_at_100m_above_surface horiz_winds_at_100m_above_sealevel'
+
+# Generate the file
+$YAML_EDIT_SCRIPT -g \
+ -f $YAML_FILE \
+ --avg-type INSTANT \
+ --freq HIST_N \
+ --freq-units HIST_OPTION \
+ --prefix ${CASE}.scream.diags.hi \
+ --grid "Physics ${PGTYPE}" \
+ --fields ${FIELDS}
+
+# Add this output yaml file to the list of eamxx output streams
+$ATMCHANGE output_yaml_files+=$YAML_FILE -b
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/hremap_to_ne4/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/hremap_to_ne4/shell_commands
new file mode 100644
index 000000000000..99289d5e411b
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/hremap_to_ne4/shell_commands
@@ -0,0 +1,15 @@
+# Look for all the eamxx_***_output.yaml files in the case folder and
+# sets horiz remap if atm grid is ne30pg2
+
+CASEROOT=$(./xmlquery --value CASEROOT)
+YAML_EDIT_SCRIPT=$CIMEROOT/../components/eamxx/scripts/edit-output-stream
+ATM_GRID=$(./xmlquery --value ATM_GRID)
+
+if [[ $ATM_GRID = "ne30np4.pg2" ]];then
+ YAML_FILES=$(ls -1 | grep 'eamxx_.*_output.yaml')
+ for fname in ${YAML_FILES}; do
+ $YAML_EDIT_SCRIPT -f $fname --horiz-remap-file \${DIN_LOC_ROOT}/atm/scream/maps/map_ne30pg2_to_ne4pg2_20231201.nc
+ done
+else
+ echo "Note: testmod 'hremap_to_ne4' only works for ne30pg2 atm grid"
+fi
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/phys/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/phys/shell_commands
new file mode 100644
index 000000000000..116cdf111b43
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/phys/shell_commands
@@ -0,0 +1,34 @@
+# This script generates a (single) yaml file for EAMxx output.
+# The output will be INSTANT, with only a few state vars
+
+CASEROOT=$(./xmlquery --value CASEROOT)
+CASE=$(./xmlquery --value CASE)
+
+# Scripts location
+YAML_EDIT_SCRIPT=$CIMEROOT/../components/eamxx/scripts/edit-output-stream
+ATMCHANGE=$CIMEROOT/../components/eamxx/scripts/atmchange
+YAML_FILE=$CASEROOT/eamxx_phys_output.yaml
+
+# Figure out the suffix for the physics grid
+ATM_GRID=$(./xmlquery --value ATM_GRID)
+if [[ $ATM_GRID == *"pg2"* ]]; then
+ PGTYPE="PG2"
+else
+ PGTYPE="GLL"
+fi
+
+# List of output fields
+FIELDS='horiz_winds T_mid tracers pseudo_density p_mid p_int'
+
+# Generate the file
+$YAML_EDIT_SCRIPT -g \
+ -f $YAML_FILE \
+ --avg-type INSTANT \
+ --freq HIST_N \
+ --freq-units HIST_OPTION \
+ --prefix ${CASE}.scream.phys.hi \
+ --grid "Physics ${PGTYPE}" \
+ --fields ${FIELDS}
+
+# Add this output yaml file to the list of eamxx output streams
+$ATMCHANGE output_yaml_files+=$YAML_FILE -b
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/phys_dyn/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/phys_dyn/shell_commands
new file mode 100644
index 000000000000..0952b4afe3f9
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/phys_dyn/shell_commands
@@ -0,0 +1,41 @@
+# This script generates a (single) yaml file for EAMxx output.
+# The output will be INSTANT, with only dyn state vars
+
+CASEROOT=$(./xmlquery --value CASEROOT)
+CASE=$(./xmlquery --value CASE)
+
+# Scripts location
+YAML_EDIT_SCRIPT=$CIMEROOT/../components/eamxx/scripts/edit-output-stream
+ATMCHANGE=$CIMEROOT/../components/eamxx/scripts/atmchange
+YAML_FILE=$CASEROOT/eamxx_dyn_output.yaml
+
+# Figure out the suffix for the physics grid
+ATM_GRID=$(./xmlquery --value ATM_GRID)
+if [[ $ATM_GRID == *"pg2"* ]]; then
+ PGTYPE="PG2"
+else
+ PGTYPE="GLL"
+fi
+
+# List of output fields
+FIELDS='v_dyn vtheta_dp_dyn dp3d_dyn w_int_dyn phis_dyn phi_int_dyn ps_dyn omega_dyn Qdp_dyn'
+
+# Generate the file
+$YAML_EDIT_SCRIPT -g \
+ -f $YAML_FILE \
+ --avg-type INSTANT \
+ --freq HIST_N \
+ --freq-units HIST_OPTION \
+ --prefix ${CASE}.scream.phys_dyn.hi \
+ --grid Dynamics \
+ --io-grid 'Physics GLL' \
+ --fields ${FIELDS}
+
+# Add also a couple of fields on the phys grid, to trigger 2-grid in same stream
+$YAML_EDIT_SCRIPT \
+ -f $YAML_FILE \
+ --grid "Physics ${PGTYPE}" \
+ --fields T_mid horiz_winds
+
+# Add this output yaml file to the list of eamxx output streams
+$ATMCHANGE output_yaml_files+=$YAML_FILE -b
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/1/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/1/shell_commands
new file mode 100644
index 000000000000..74bd2a4d0213
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/1/shell_commands
@@ -0,0 +1,9 @@
+# This preset uses the three output streams (phys_dyn, phys, and diags)
+# It does not add remap, and uses INSTANT output
+
+SCRIPTS_DIR=$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/output
+
+# Add the three streams
+. $SCRIPTS_DIR/phys/shell_commands
+. $SCRIPTS_DIR/phys_dyn/shell_commands
+. $SCRIPTS_DIR/diags/shell_commands
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/2/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/2/shell_commands
new file mode 100644
index 000000000000..aea7feb5bbd6
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/2/shell_commands
@@ -0,0 +1,12 @@
+# This preset uses the three output streams (phys_dyn, phys, and diags)
+# It does not add remap, and uses AVERAGE output
+
+SCRIPTS_DIR=$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/output
+
+# Add the three streams
+. $SCRIPTS_DIR/phys/shell_commands
+. $SCRIPTS_DIR/phys_dyn/shell_commands
+. $SCRIPTS_DIR/diags/shell_commands
+
+# Change avg-type to AVERAGE for all streams
+. $SCRIPTS_DIR/set_avg/shell_commands
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/3/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/3/shell_commands
new file mode 100644
index 000000000000..da1d02dc5de1
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/3/shell_commands
@@ -0,0 +1,11 @@
+# This preset uses the three output streams (phys, and diags)
+# It adds horiz remap, and uses INSTANT output
+
+SCRIPTS_DIR=$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/output
+
+# Add the phys/diags streams (cannot add phys_dyn, b/c we use horiz remap)
+. $SCRIPTS_DIR/phys/shell_commands
+. $SCRIPTS_DIR/diags/shell_commands
+
+# Add horiz remap
+. $SCRIPTS_DIR/hremap_to_ne4/shell_commands
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/4/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/4/shell_commands
new file mode 100644
index 000000000000..521ada7f5082
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/4/shell_commands
@@ -0,0 +1,14 @@
+# This preset uses the three output streams (phys, and diags)
+# It adds horizontal remap, and uses AVERAGE output
+
+SCRIPTS_DIR=$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/output
+
+# Add the phys/diags streams (cannot add phys_dyn, b/c we use horiz remap)
+. $SCRIPTS_DIR/phys/shell_commands
+. $SCRIPTS_DIR/diags/shell_commands
+
+# Add horiz remap
+. $SCRIPTS_DIR/hremap_to_ne4/shell_commands
+
+# Use AVERAGE
+. $SCRIPTS_DIR/set_avg/shell_commands
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/5/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/5/shell_commands
new file mode 100644
index 000000000000..bd60a0472a87
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/5/shell_commands
@@ -0,0 +1,15 @@
+# This preset uses the three output streams (phys_dyn, phys, and diags)
+# It adds vertical remap, and uses AVERAGE output
+
+SCRIPTS_DIR=$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/output
+
+# Add the phys/dyn/diags streams
+. $SCRIPTS_DIR/phys/shell_commands
+. $SCRIPTS_DIR/phys_dyn/shell_commands
+. $SCRIPTS_DIR/diags/shell_commands
+
+# Add vertical remap
+. $SCRIPTS_DIR/vremap/shell_commands
+
+# Use AVERAGE
+. $SCRIPTS_DIR/set_avg/shell_commands
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/6/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/6/shell_commands
new file mode 100644
index 000000000000..937d16468516
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/preset/6/shell_commands
@@ -0,0 +1,17 @@
+# This preset uses the three output streams (phys, and diags)
+# It adds horizontal and remap, and uses AVERAGE output
+
+SCRIPTS_DIR=$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/output
+
+# Add the phys/diags streams (cannot add phys_dyn, b/c we use horiz remap)
+. $SCRIPTS_DIR/phys/shell_commands
+. $SCRIPTS_DIR/diags/shell_commands
+
+# Add horiz remap
+. $SCRIPTS_DIR/hremap_to_ne4/shell_commands
+
+# Add vert remap
+. $SCRIPTS_DIR/vremap/shell_commands
+
+# Use AVERAGE
+. $SCRIPTS_DIR/set_avg/shell_commands
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/set_avg/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/set_avg/shell_commands
new file mode 100644
index 000000000000..dc58bc6301a7
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/set_avg/shell_commands
@@ -0,0 +1,10 @@
+# Look for all the eamxx_***_output.yaml files in the case folder and
+# change the avg type to average.
+
+CASEROOT=$(./xmlquery --value CASEROOT)
+YAML_EDIT_SCRIPT=$CIMEROOT/../components/eamxx/scripts/edit-output-stream
+
+YAML_FILES=$(ls -1 | grep 'eamxx_.*_output.yaml')
+for fname in ${YAML_FILES}; do
+ $YAML_EDIT_SCRIPT -f $fname --avg-type average
+done
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/vremap/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/vremap/shell_commands
new file mode 100644
index 000000000000..151928669d1a
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/output/vremap/shell_commands
@@ -0,0 +1,10 @@
+# Look for all the eamxx_***_output.yaml files in the case folder and
+# sets vertical remap
+
+CASEROOT=$(./xmlquery --value CASEROOT)
+YAML_EDIT_SCRIPT=$CIMEROOT/../components/eamxx/scripts/edit-output-stream
+
+YAML_FILES=$(ls -1 | grep 'eamxx_.*_output.yaml')
+for fname in ${YAML_FILES}; do
+ $YAML_EDIT_SCRIPT -f $fname --vertical-remap-file \${DIN_LOC_ROOT}/atm/scream/maps/vrt_remapping_p_levs_20230926.nc
+done
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/perf_test/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/perf_test/shell_commands
new file mode 100644
index 000000000000..d4e7c2a95377
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/perf_test/shell_commands
@@ -0,0 +1,5 @@
+
+# Force us to use 1 node to eliminate network noise
+if [ `./xmlquery --value MACH` == frontier-scream-gpu ]; then
+ ./xmlchange NTASKS=8
+fi
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/small_kernels/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/small_kernels/shell_commands
index 04989a22796a..e6773dce4199 100644
--- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/small_kernels/shell_commands
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/small_kernels/shell_commands
@@ -1,7 +1,2 @@
./xmlchange --append SCREAM_CMAKE_OPTIONS='SCREAM_SMALL_KERNELS On'
$CIMEROOT/../components/eamxx/scripts/atmchange --all internal_diagnostics_level=1 atmosphere_processes::internal_diagnostics_level=0 -b
-
-f=$(./xmlquery --value MACH)
-if [ $f == chrysalis ]; then
- ./xmlchange BATCH_COMMAND_FLAGS="--time 00:30:00 -p debug --account e3sm --exclude=chr-0512"
-fi
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/spa_remap/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/spa_remap/shell_commands
new file mode 100644
index 000000000000..5a07fb378464
--- /dev/null
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/spa_remap/shell_commands
@@ -0,0 +1,2 @@
+$CIMEROOT/../components/eamxx/scripts/atmchange -b spa_data_file='${DIN_LOC_ROOT}'/atm/scream/init/spa_file_unified_and_complete_ne4pg2_20231222.nc
+$CIMEROOT/../components/eamxx/scripts/atmchange -b spa_remap_file='${DIN_LOC_ROOT}'/atm/scream/maps/map_ne4pg2_to_ne30pg2_20231201.nc
diff --git a/components/eamxx/cime_config/tests/eamxx_default_files.py b/components/eamxx/cime_config/tests/eamxx_default_files.py
new file mode 100644
index 000000000000..b39d2d5c1553
--- /dev/null
+++ b/components/eamxx/cime_config/tests/eamxx_default_files.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python3
+
+import os
+import http
+import pathlib
+import unittest
+import urllib.request
+import xml.etree.ElementTree as ET
+
+
+class testNamelistDefaultsScream(unittest.TestCase):
+ def setUp(self):
+ """
+ Set up the environment for the test by setting the DIN_LOC_ROOT
+ environment variable. Parse the 'namelist_defaults_scream.xml'
+ file and extract the files of interest based on the DIN_LOC_ROOT
+ variable or the array(file) type. Assign the extracted files
+ to the 'my_files' attribute of the test instance.
+ """
+
+ os.environ["DIN_LOC_ROOT"] = "https://web.lcrc.anl.gov/public/e3sm/inputdata/"
+
+ scream_defaults_path = pathlib.Path(__file__)
+ tree = ET.parse(f"{scream_defaults_path.parent.parent}/namelist_defaults_scream.xml")
+ root = tree.getroot()
+
+ files_of_interest = [
+ child.text for child in root.findall(".//")
+ if child.text and child.text.startswith("${DIN_LOC_ROOT}")
+ ]
+
+ more_files_of_interest = [
+ child.text for child in root.findall(".//")
+ if child.text and "type" in child.attrib.keys() and child.attrib["type"]=="array(file)"
+ ]
+
+ files_of_interest.extend(
+ text.strip() for text_list in more_files_of_interest for text in text_list.split(",")
+ if text.strip().startswith("${DIN_LOC_ROOT}")
+ )
+
+ self.my_files = [
+ file.replace("${DIN_LOC_ROOT}/", "")
+ for file in files_of_interest
+ ]
+
+ self.my_lines = []
+ with open(
+ f"{scream_defaults_path.parent.parent}/namelist_defaults_scream.xml",
+ "r"
+ ) as the_file:
+ for a_line in the_file:
+ self.my_lines.append(a_line)
+
+ def test_ascii_lines(self):
+ """
+ Test that all lines are ASCII
+ """
+
+ for i_line, a_line in enumerate(self.my_lines):
+ with self.subTest(i_line=i_line):
+ self.assertTrue(
+ a_line.isascii(),
+ msg=f"\nERROR! This line is not ASCII!\n{a_line}"
+ )
+
+ def test_opening_files(self):
+ """
+ Test the opening of files from the inputdata server.
+ """
+
+ for i_file in range(len(self.my_files)):
+ with self.subTest(i_file=i_file):
+ try:
+ request_return = urllib.request.urlopen(
+ f"{os.environ['DIN_LOC_ROOT']}{self.my_files[i_file]}"
+ )
+ self.assertIsInstance(request_return, http.client.HTTPResponse)
+ except urllib.error.HTTPError:
+ file_name = f"{os.environ['DIN_LOC_ROOT']}{self.my_files[i_file]}"
+ self.assertTrue(
+ False,
+ msg=f"\nERROR! This file doesn't exist!\n{file_name}"
+ )
+
+ def test_expected_fail(self):
+ """
+ Test an expected failure by manipulating the file name.
+ """
+
+ with self.assertRaises(urllib.error.HTTPError):
+ some_phony_file = f"{self.my_files[5][:-5]}some_phony_file.nc"
+ urllib.request.urlopen(
+ f"{os.environ['DIN_LOC_ROOT']}{some_phony_file}"
+ )
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/components/eamxx/cmake/machine-files/lassen.cmake b/components/eamxx/cmake/machine-files/lassen.cmake
deleted file mode 100644
index 36b69c7f0253..000000000000
--- a/components/eamxx/cmake/machine-files/lassen.cmake
+++ /dev/null
@@ -1,9 +0,0 @@
-include(${CMAKE_CURRENT_LIST_DIR}/common.cmake)
-common_setup()
-
-set(NetCDF_PATH /usr/gdata/climdat/netcdf CACHE STRING "")
-set(NetCDF_Fortran_PATH /usr/gdata/climdat/netcdf CACHE STRING "")
-set(LAPACK_LIBRARIES /usr/lib64/liblapack.so CACHE STRING "")
-set(CMAKE_CXX_FLAGS "-DTHRUST_IGNORE_CUB_VERSION_CHECK" CACHE STRING "" FORCE)
-
-set(SCREAM_INPUT_ROOT "/usr/gdata/climdat/ccsm3data/inputdata/" CACHE STRING "")
diff --git a/components/eamxx/cmake/machine-files/mappy.cmake b/components/eamxx/cmake/machine-files/mappy.cmake
index 7c1fc8cf25ea..29fb2e74b8a1 100644
--- a/components/eamxx/cmake/machine-files/mappy.cmake
+++ b/components/eamxx/cmake/machine-files/mappy.cmake
@@ -1,3 +1,5 @@
include(${CMAKE_CURRENT_LIST_DIR}/common.cmake)
common_setup()
-set(PYTHON_EXECUTABLE "/ascldap/users/jgfouca/packages/Python-3.8.5/bin/python3.8" CACHE STRING "" FORCE)
\ No newline at end of file
+set(PYTHON_EXECUTABLE "/ascldap/users/jgfouca/packages/Python-3.8.5/bin/python3.8" CACHE STRING "" FORCE)
+
+set(CMAKE_Fortran_FLAGS "-fallow-argument-mismatch" CACHE STRING "" FORCE)
diff --git a/components/eamxx/cmake/machine-files/quartz-intel.cmake b/components/eamxx/cmake/machine-files/quartz-intel.cmake
index 753c782702db..defd8cbb2d33 100644
--- a/components/eamxx/cmake/machine-files/quartz-intel.cmake
+++ b/components/eamxx/cmake/machine-files/quartz-intel.cmake
@@ -4,4 +4,4 @@ set(PYTHON_EXECUTABLE "/usr/tce/packages/python/python-3.9.12/bin/python3" CACHE
set(PYTHON_LIBRARIES "/usr/lib64/libpython3.9.so.1.0" CACHE STRING "" FORCE)
option (SCREAM_ENABLE_ML_CORRECTION "Whether to enable ML correction parametrization" ON)
set(HDF5_DISABLE_VERSION_CHECK 1 CACHE STRING "" FORCE)
-execute_process(COMMAND source /usr/WS1/climdat/python_venv/3.9.2/screamML/bin/activate)
+execute_process(COMMAND source /usr/WS1/e3sm/python_venv/3.9.2/screamML/bin/activate)
diff --git a/components/eamxx/cmake/machine-files/quartz.cmake b/components/eamxx/cmake/machine-files/quartz.cmake
index ee9a3dcbffd3..e4b4fcbd8a57 100644
--- a/components/eamxx/cmake/machine-files/quartz.cmake
+++ b/components/eamxx/cmake/machine-files/quartz.cmake
@@ -16,4 +16,4 @@ elseif ("${COMPILER}" STREQUAL "gnu")
set(CMAKE_EXE_LINKER_FLAGS "-L/usr/tce/packages/gcc/gcc-8.3.1/rh/lib/gcc/x86_64-redhat-linux/8/" CACHE STRING "" FORCE)
endif()
-set(SCREAM_INPUT_ROOT "/usr/gdata/climdat/ccsm3data/inputdata" CACHE STRING "")
+set(SCREAM_INPUT_ROOT "/usr/gdata/e3sm/ccsm3data/inputdata" CACHE STRING "")
diff --git a/components/eamxx/cmake/machine-files/ruby-intel.cmake b/components/eamxx/cmake/machine-files/ruby-intel.cmake
index 63fff478fdaf..9c6318da4952 100644
--- a/components/eamxx/cmake/machine-files/ruby-intel.cmake
+++ b/components/eamxx/cmake/machine-files/ruby-intel.cmake
@@ -4,4 +4,4 @@ set(PYTHON_EXECUTABLE "/usr/tce/packages/python/python-3.9.12/bin/python3" CACHE
set(PYTHON_LIBRARIES "/usr/lib64/libpython3.9.so.1.0" CACHE STRING "" FORCE)
option (SCREAM_ENABLE_ML_CORRECTION "Whether to enable ML correction parametrization" ON)
set(HDF5_DISABLE_VERSION_CHECK 1 CACHE STRING "" FORCE)
-execute_process(COMMAND source /usr/WS1/climdat/python_venv/3.9.2/screamML/bin/activate)
+execute_process(COMMAND source /usr/WS1/e3sm/python_venv/3.9.2/screamML/bin/activate)
diff --git a/components/eamxx/cmake/machine-files/ruby.cmake b/components/eamxx/cmake/machine-files/ruby.cmake
index d0a9de4baf4b..77d6e6618c71 100644
--- a/components/eamxx/cmake/machine-files/ruby.cmake
+++ b/components/eamxx/cmake/machine-files/ruby.cmake
@@ -12,4 +12,4 @@ include (${EKAT_MACH_FILES_PATH}/kokkos/openmp.cmake)
include (${EKAT_MACH_FILES_PATH}/mpi/srun.cmake)
-set(SCREAM_INPUT_ROOT "/usr/gdata/climdat/ccsm3data/inputdata" CACHE STRING "")
+set(SCREAM_INPUT_ROOT "/usr/gdata/e3sm/ccsm3data/inputdata" CACHE STRING "")
diff --git a/components/eamxx/cmake/machine-files/syrah.cmake b/components/eamxx/cmake/machine-files/syrah.cmake
deleted file mode 100644
index f03fc1e9d469..000000000000
--- a/components/eamxx/cmake/machine-files/syrah.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-include(${CMAKE_CURRENT_LIST_DIR}/common.cmake)
-common_setup()
-
-include (${EKAT_MACH_FILES_PATH}/kokkos/openmp.cmake)
-include (${EKAT_MACH_FILES_PATH}/mpi/srun.cmake)
-
-# Enable Sandy Bridge arch in Kokkos
-option(Kokkos_ARCH_SNB "" ON)
-
-set(CMAKE_CXX_FLAGS "-w -cxxlib=/usr/tce/packages/gcc/gcc-8.3.1/rh" CACHE STRING "" FORCE)
-set(CMAKE_EXE_LINKER_FLAGS "-L/usr/tce/packages/gcc/gcc-8.3.1/rh/lib/gcc/x86_64-redhat-linux/8/ -mkl" CACHE STRING "" FORCE)
-
-set(SCREAM_INPUT_ROOT "/usr/gdata/climdat/ccsm3data/inputdata/" CACHE STRING "")
diff --git a/components/eamxx/data/SCREAM_YAML_README b/components/eamxx/data/SCREAM_YAML_README
deleted file mode 100644
index daf425845e31..000000000000
--- a/components/eamxx/data/SCREAM_YAML_README
+++ /dev/null
@@ -1,52 +0,0 @@
-
-INTRO:
-
-The scream_input.yaml is the key file for configuring a SCREAM run. This file will be
-processed and copied to $case/run/scream_input.yaml by scream's buidnml script, which
-is called during case.setup. Note, this is for runtime coniguration
-only. Cmake/build-time configuration should be done through SCREAM_CMAKE_OPTIONS.
-
-For inline comments, see the version of scream_input.yaml that lives in the repo
-(components/eamxx/data/scream_input.yaml)
-
-Note, the $case/run/scream_input.yaml will NEVER be overwritten by subsequent
-calls to case.setup/buildnml in order to avoid blowing away potential local
-modifications. To force a regeneration of this file, it should be removed from the
-case and `./case.setup --reset` should be called.
-
-SECTIONS:
-
- Atmosphere Driver: Contains settings for the AD. Can turn off processes by editing "Number of Entries" and
- changing the Process N list.
-
- SCREAM: For general SCREAM settings
-
- HOMME: For HOMME settings. These settings will be translated into data/namelist.nl
-
-SYNTAX:
-
-This file supports some special syntax in addition to basic YAML:
-'${VAR}' will be used to refer to env variables in the CIME case
-
-' val1 : key2 => val2 : elseval>' will be used to express conditional
-statements. If switch_val matches key1, then the expression evaluates to val1; if switch_val
-matches key2, then the expression evaluates to val2; if it matches neither, then
-the expression evaluates to elseval. The elseval component of this expression is optional.
-You can have any number (N>=1) of key => val sections.
-
-Example, if you wanted tstep to depend on atm grid resolution:
-
- tstep: "<${ATM_GRID} : ne4np4 => 300 : 30>"
-
-This would give all ne4 cases a timestep of 300, otherwise it would be 30.
-
-You could specify multiple grid->timestep relationships this way:
-
- tstep: "<${ATM_GRID} : ne4np4 => 300 : ne30np4 => 100 : 30>"
-
-Regex matching is supported:
-
- tstep: "<${ATM_GRID} : .*ne4.* => 300 : .*ne30.* => 100 : 30>"
-
-Note: none of this special syntax will be automatically reprocessed if the case XML values
-are changed. Regenerating this file is necessary if relevant case XML values are modified.
diff --git a/components/eamxx/data/scream_default_output.yaml b/components/eamxx/data/scream_default_output.yaml
deleted file mode 100644
index 7e0a45f12d6a..000000000000
--- a/components/eamxx/data/scream_default_output.yaml
+++ /dev/null
@@ -1,75 +0,0 @@
-%YAML 1.1
----
-filename_prefix: ${CASE}.scream.hi
-# WARNING: ERS/ERP tets will override this with AVERAGE
-Averaging Type: Instant
-# One output every 31 days if output frequency is set to once per hour
-Max Snapshots Per File: 744
-Fields:
- Physics ${PHYSICS_GRID_TYPE}:
- Field Names:
- # HOMME
- - ps
- - pseudo_density
- - omega
- - p_int
- - p_mid
- # SHOC + HOMME
- - horiz_winds
- # SHOC
- - cldfrac_liq
- - eddy_diff_mom
- - sgs_buoy_flux
- - tke
- - pbl_height
- # CLD
- - cldfrac_ice_for_analysis
- - cldfrac_tot_for_analysis
- # P3
- - bm
- - nc
- - ni
- - nr
- - qi
- - qm
- - qr
- - eff_radius_qc
- - eff_radius_qi
- - eff_radius_qr
- - precip_ice_surf_mass
- - precip_liq_surf_mass
- - rainfrac
- # SHOC + P3
- - qc
- - qv
- # SHOC + P3 + RRTMGP + HOMME
- - T_mid
- # RRTMGP
- - sfc_alb_dir_vis
- - LW_flux_dn
- - LW_flux_up
- - SW_flux_dn
- - SW_flux_up
- - sfc_flux_lw_dn
- - sfc_flux_sw_net
- - cldtot
- - cldlow
- - cldmed
- - cldhgh
- # Surface Fluxes
- - surf_evap
- - surf_sens_flux
- # Diagnostics
- - PotentialTemperature
- # GLL output for homme states.
- Dynamics:
- Field Names:
- - ps_dyn
- - dp3d_dyn
- - omega_dyn
- IO Grid Name: Physics GLL
-output_control:
-# WARNING: ERS/ERP tets will override this with STOP_N/STOP_OPTION
- Frequency: ${HIST_N}
- frequency_units: ${HIST_OPTION}
-...
diff --git a/components/eamxx/data/scream_default_remap.yaml b/components/eamxx/data/scream_default_remap.yaml
deleted file mode 100644
index 8bf47386c76d..000000000000
--- a/components/eamxx/data/scream_default_remap.yaml
+++ /dev/null
@@ -1,67 +0,0 @@
-%YAML 1.1
----
-filename_prefix: ${CASE}.scream.arm_sites.hi
-Averaging Type: Instant
-Max Snapshots Per File: 744 # One output every 31 days
-#remap_file: /g/g17/donahue5/Code/e3sm/scream-docs/regional_output_sites/20221123_ARM_sites_map.nc
-remap_file: /usr/gdata/climdat/ccsm3data/inputdata/atm/scream/maps/map_ne30np4_to_ne4pg2_mono.20220714.nc
-Fields:
- Physics ${PHYSICS_GRID_TYPE}:
- Field Names:
- # HOMME
- - ps
- - pseudo_density
- - omega
- - p_int
- - p_mid
- # SHOC + HOMME
- - horiz_winds
- # SHOC
- - cldfrac_liq
- - eddy_diff_mom
- - sgs_buoy_flux
- - tke
- - pbl_height
- # CLD
- - cldfrac_ice
- - cldfrac_tot
- # P3
- - bm
- - nc
- - ni
- - nr
- - qi
- - qm
- - qr
- - eff_radius_qc
- - eff_radius_qi
- - eff_radius_qr
- - precip_ice_surf_mass
- - precip_liq_surf_mass
- - rainfrac
- # SHOC + P3
- - qc
- - qv
- # SHOC + P3 + RRTMGP + HOMME
- - T_mid
- # RRTMGP
- - sfc_alb_dir_vis
- - LW_flux_dn
- - LW_flux_up
- - SW_flux_dn
- - SW_flux_up
- - sfc_flux_lw_dn
- - sfc_flux_sw_net
- - cldtot
- - cldlow
- - cldmed
- - cldhgh
- # Surface Fluxes
- - surf_evap
- - surf_sens_flux
- # Diagnostics
-# - PotentialTemperature
-output_control:
- Frequency: ${HIST_N}
- frequency_units: ${HIST_OPTION}
-...
diff --git a/components/eamxx/docs/developer/standalone_testing.md b/components/eamxx/docs/developer/standalone_testing.md
index aedb7b2cbaad..63ea01fc612e 100644
--- a/components/eamxx/docs/developer/standalone_testing.md
+++ b/components/eamxx/docs/developer/standalone_testing.md
@@ -33,9 +33,9 @@ make baseline
```
The tests will run, automatically using the baseline file, which is located in
-the CMake-configurable path `${SCREAM_TEST_DATA_DIR}`. By default, this path is
-set to `data/` within your build directory (which is `$RUN_ROOT_DIR`, in
-our case).
+the CMake-configurable path `${SCREAM_BASELINES_DIR}`. By default, this path is
+set to an invalid string. If baselines tests are enabled, we check that a valid
+path has been provided.
To run all of SCREAM's tests, make sure you're in `$RUN_ROOT_DIR` and type
diff --git a/components/eamxx/docs/user/coarse_nudging.md b/components/eamxx/docs/user/coarse_nudging.md
index c52ce9a0eb24..3d7309c42aaa 100644
--- a/components/eamxx/docs/user/coarse_nudging.md
+++ b/components/eamxx/docs/user/coarse_nudging.md
@@ -20,6 +20,6 @@ In other words, the following options are needed:
```shell
./atmchange atm_procs_list=(sc_import,nudging,homme,physics,sc_export)
./atmchange nudging_fields=U,V
-./atmchange nudging_filename=/path/to/nudging_data_ne4pg2_L72.nc
+./atmchange nudging_filenames_patterns=/path/to/nudging_data_ne4pg2_L72.nc
./atmchange nudging_refine_remap_mapfile=/another/path/to/mapping_file_ne4pg2_to_ne120pg2.nc
```
diff --git a/components/eamxx/mkdocs.yml b/components/eamxx/mkdocs.yaml
similarity index 100%
rename from components/eamxx/mkdocs.yml
rename to components/eamxx/mkdocs.yaml
diff --git a/components/eamxx/scripts/atm_manip.py b/components/eamxx/scripts/atm_manip.py
index 2a763bc1990d..fbd8381e1727 100755
--- a/components/eamxx/scripts/atm_manip.py
+++ b/components/eamxx/scripts/atm_manip.py
@@ -170,7 +170,7 @@ def modify_ap_list(xml_root, group, ap_list_str, append_this):
'p1,p2,p1'
>>> modify_ap_list(tree,node,"p1,p3",False)
Traceback (most recent call last):
- ValueError: ERROR: Unrecognized atm proc name 'p3'. To declare a new group, prepend and append '_' to the name.
+ SystemExit: ERROR: Unrecognized atm proc name 'p3'. To declare a new group, prepend and append '_' to the name.
>>> modify_ap_list(tree,node,"p1,_my_group_",False)
True
>>> get_child(node,"atm_procs_list").text
@@ -203,11 +203,11 @@ def modify_ap_list(xml_root, group, ap_list_str, append_this):
new_aps = [n for n in add_aps if find_node(ap_defaults,n) is None]
for ap in new_aps:
- expect (ap[0]=="_" and ap[-1]=="_" and len(ap)>2, exc_type=ValueError,
- error_msg=f"Unrecognized atm proc name '{ap}'. To declare a new group, prepend and append '_' to the name.")
+ expect (ap[0]=="_" and ap[-1]=="_" and len(ap)>2,
+ f"Unrecognized atm proc name '{ap}'. To declare a new group, prepend and append '_' to the name.")
group = gen_atm_proc_group("", ap_defaults)
group.tag = ap
-
+
ap_defaults.append(group)
# Update the 'atm_procs_list' in this node
@@ -217,6 +217,25 @@ def modify_ap_list(xml_root, group, ap_list_str, append_this):
curr_apl.text = ','.join(ap_list)
return True
+###############################################################################
+def is_locked_impl(node):
+###############################################################################
+ return "locked" in node.attrib.keys() and str(node.attrib["locked"]).upper() == "TRUE"
+
+###############################################################################
+def is_locked(xml_root, node):
+###############################################################################
+ if is_locked_impl(node):
+ return True
+ else:
+ parent_map = create_parent_map(xml_root)
+ parents = get_parents(node, parent_map)
+ for parent in parents:
+ if is_locked_impl(parent):
+ return True
+
+ return False
+
###############################################################################
def apply_change(xml_root, node, new_value, append_this):
###############################################################################
@@ -231,6 +250,7 @@ def apply_change(xml_root, node, new_value, append_this):
if append_this:
+ expect (not is_locked(xml_root, node), f"Cannot change {node.tag}, it is locked")
expect ("type" in node.attrib.keys(),
f"Error! Missing type information for {node.tag}")
type_ = node.attrib["type"]
@@ -238,7 +258,11 @@ def apply_change(xml_root, node, new_value, append_this):
"Error! Can only append with array and string types.\n"
f" - name: {node.tag}\n"
f" - type: {type_}")
- if is_array_type(type_):
+
+ if node.text is None:
+ node.text = ""
+
+ if is_array_type(type_) and node.text!="":
node.text += ", " + new_value
else:
node.text += new_value
@@ -246,6 +270,7 @@ def apply_change(xml_root, node, new_value, append_this):
any_change = True
elif node.text != new_value:
+ expect (not is_locked(xml_root, node), f"Cannot change {node.tag}, it is locked")
check_value(node,new_value)
node.text = new_value
any_change = True
@@ -283,16 +308,37 @@ def atm_config_chg_impl(xml_root, change, all_matches=False):
"""
>>> xml = '''
...
- ... 1,2,3
- ... 1
- ... 1
- ... one
- ... one
- ... one
- ...
- ... two
- ... 2
- ...
+ ... 1,2,3
+ ... 1
+ ... 1
+ ... one
+ ... one
+ ... one
+ ...
+ ... two
+ ... 2
+ ...
+ ...
+ ...
+ ...
+ ... hi
+ ...
+ ...
+ ...
+ ...
+ ...
+ ...
+ ... hi
+ ...
+ ...
+ ...
+ ...
+ ...
+ ...
+ ... hi
+ ...
+ ...
+ ...
...
... '''
>>> import xml.etree.ElementTree as ET
@@ -306,7 +352,8 @@ def atm_config_chg_impl(xml_root, change, all_matches=False):
>>> ################ INVALID TYPE #######################
>>> atm_config_chg_impl(tree,'prop2=two')
Traceback (most recent call last):
- ValueError: Could not refine 'two' as type 'integer'
+ CIME.utils.CIMEError: ERROR: Could not refine 'two' as type 'integer':
+ could not convert string to float: 'two'
>>> ################ INVALID VALUE #######################
>>> atm_config_chg_impl(tree,'prop2=3')
Traceback (most recent call last):
@@ -350,6 +397,16 @@ def atm_config_chg_impl(xml_root, change, all_matches=False):
True
>>> get_xml_nodes(tree,'e')[0].text
'one, two'
+ >>> ################ Test locked ##################
+ >>> atm_config_chg_impl(tree, 'lprop2=yo')
+ Traceback (most recent call last):
+ SystemExit: ERROR: Cannot change lprop2, it is locked
+ >>> atm_config_chg_impl(tree, 'lprop3=yo')
+ Traceback (most recent call last):
+ SystemExit: ERROR: Cannot change lprop3, it is locked
+ >>> atm_config_chg_impl(tree, 'lprop4=yo')
+ Traceback (most recent call last):
+ SystemExit: ERROR: Cannot change lprop4, it is locked
"""
node_name, new_value, append_this = parse_change(change)
matches = get_xml_nodes(xml_root, node_name)
diff --git a/components/eamxx/scripts/change-param-pattern b/components/eamxx/scripts/change-param-pattern
index 5ab26a64df3b..a54c7292d246 100755
--- a/components/eamxx/scripts/change-param-pattern
+++ b/components/eamxx/scripts/change-param-pattern
@@ -35,4 +35,4 @@ for bad_name_under in bad_name_unders:
run_cmd_no_fail(f"sed -i -e 's/{bad_name_ws}/{good_name}/g' $(git grep -l '{bad_name_ws}')")
run_cmd_no_fail(f"git commit -a -m '{bad_name_ws} -> {good_name}'")
print(" Testing")
- run_cmd_no_fail("./create_test ERS_D_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1 --compiler=gnu9", from_dir="../../cime/scripts")
+ run_cmd_no_fail("./create_test ERS_D_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1", from_dir="../../cime/scripts")
diff --git a/components/eamxx/scripts/check-hashes-ers b/components/eamxx/scripts/check-hashes-ers
new file mode 100755
index 000000000000..6d9da4b2f98e
--- /dev/null
+++ b/components/eamxx/scripts/check-hashes-ers
@@ -0,0 +1,171 @@
+#!/usr/bin/env python3
+
+"""
+See https://acme-climate.atlassian.net/wiki/spaces/NGDNA/pages/3831923056/EAMxx+BFB+hashing
+for full explanation.
+
+This script is used by the scream-internal_diagnostics_level testmod to check
+hash output after a test has run.
+"""
+
+import sys, re, glob, pathlib, argparse
+
+from utils import run_cmd_no_fail, expect
+
+###############################################################################
+def parse_command_line(args, description):
+###############################################################################
+ parser = argparse.ArgumentParser(
+ usage="""\n{0} [=] ...
+OR
+{0} --help
+
+\033[1mEXAMPLES:\033[0m
+ \033[1;32m# Run hash checker on /my/case/dir \033[0m
+ > {0} /my/case/dir
+""".format(pathlib.Path(args[0]).name),
+ description=description,
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter
+ )
+
+ parser.add_argument(
+ "case_dir",
+ help="The test case you want to check"
+ )
+
+ return parser.parse_args(args[1:])
+
+###############################################################################
+def readall(fn):
+###############################################################################
+ with open(fn,'r') as f:
+ txt = f.read()
+ return txt
+
+###############################################################################
+def greptxt(pattern, txt):
+###############################################################################
+ return re.findall('(?:' + pattern + ').*', txt, flags=re.MULTILINE)
+
+###############################################################################
+def grep(pattern, fn):
+###############################################################################
+ txt = readall(fn)
+ return greptxt(pattern, txt)
+
+###############################################################################
+def get_log_glob_from_atm_modelio(case_dir):
+###############################################################################
+ filename = case_dir / 'CaseDocs' / 'atm_modelio.nml'
+ ln = grep('diro = ', filename)[0]
+ run_dir = pathlib.Path(ln.split()[2].split('"')[1])
+ ln = grep('logfile = ', filename)[0]
+ atm_log_fn = ln.split()[2].split('"')[1]
+ id_ = atm_log_fn.split('.')[2]
+ return str(run_dir / '**' / f'e3sm.log.{id_}*')
+
+###############################################################################
+def get_hash_lines(fn):
+###############################################################################
+ rlns = run_cmd_no_fail(f'zgrep exxhash {fn}').splitlines()
+ lns = []
+ if len(rlns) == 0: return lns
+ for rln in rlns:
+ pos = rln.find('exxhash')
+ lns.append(rln[pos:])
+ return lns
+
+###############################################################################
+def parse_time(hash_ln):
+###############################################################################
+ return hash_ln.split()[1:3]
+
+###############################################################################
+def all_equal(t1, t2):
+###############################################################################
+ if len(t1) != len(t2): return False
+ for i in range(len(t1)):
+ if t1[i] != t2[i]: return False
+ return True
+
+###############################################################################
+def find_first_index_at_time(lns, time):
+###############################################################################
+ for i, ln in enumerate(lns):
+ t = parse_time(ln)
+ if all_equal(time, t): return i
+ return None
+
+###############################################################################
+def diff(l1, l2):
+###############################################################################
+ diffs = []
+ for i in range(len(l1)):
+ if l1[i] != l2[i]:
+ diffs.append((l1[i], l2[i]))
+ return diffs
+
+###############################################################################
+def check_hashes_ers(case_dir):
+###############################################################################
+ case_dir_p = pathlib.Path(case_dir)
+ expect(case_dir_p.is_dir(), f"{case_dir} is not a dir")
+
+ # Look for the two e3sm.log files.
+ glob_pat = get_log_glob_from_atm_modelio(case_dir_p)
+ e3sm_fns = glob.glob(glob_pat, recursive=True)
+ if len(e3sm_fns) == 0:
+ print('Could not find e3sm.log files with glob string {}'.format(glob_pat))
+ return False
+ e3sm_fns.sort()
+ if len(e3sm_fns) == 1:
+ # This is the first run. Exit and wait for the second
+ # run. (POSTRUN_SCRIPT is called after each of the two runs.)
+ print('Exiting on first run.')
+ return True
+ print('Diffing base {} and restart {}'.format(e3sm_fns[0], e3sm_fns[1]))
+
+ # Because of the prefixed 1: and 2: on some systems, we can't just use
+ # zdiff.
+ lns = []
+ for f in e3sm_fns:
+ lns.append(get_hash_lines(f))
+ time = parse_time(lns[1][0])
+ time_idx = find_first_index_at_time(lns[0], time)
+ if time_idx is None:
+ print('Could not find a start time.')
+ return False
+ lns[0] = lns[0][time_idx:]
+ if len(lns[0]) != len(lns[1]):
+ print('Number of hash lines starting at restart time do not agree.')
+ return False
+ diffs = diff(lns[0], lns[1])
+
+ # Flushed prints to e3sm.log can sometimes conflict with other
+ # output. Permit up to 'thr' diffs so we don't fail due to badly printed
+ # lines. This isn't a big loss in checking because an ERS_Ln22 second run
+ # writes > 1000 hash lines, and a true loss of BFBness is nearly certain to
+ # propagate to a large number of subsequent hashes.
+ thr = 5
+ if len(lns[0]) < 100: thr = 0
+
+ ok = True
+ if len(diffs) > thr:
+ print('DIFF')
+ print(diffs[-10:])
+ ok = False
+ else:
+ print('OK')
+
+ return ok
+
+###############################################################################
+def _main_func(description):
+###############################################################################
+ success = check_hashes_ers(**vars(parse_command_line(sys.argv, description)))
+ sys.exit(0 if success else 1)
+
+###############################################################################
+
+if (__name__ == "__main__"):
+ _main_func(__doc__)
diff --git a/components/eamxx/scripts/cime-nml-tests b/components/eamxx/scripts/cime-nml-tests
index 0a60376bd45f..b128121cf95f 100755
--- a/components/eamxx/scripts/cime-nml-tests
+++ b/components/eamxx/scripts/cime-nml-tests
@@ -222,9 +222,10 @@ class TestBuildnml(unittest.TestCase):
# Append to an existing entry
name = 'output_yaml_files'
out = run_cmd_no_fail(f"./atmchange {name}+=a.yaml", from_dir=case)
+ out = run_cmd_no_fail(f"./atmchange {name}+=b.yaml", from_dir=case)
# Get the yaml files
- expected =f'{EAMXX_DIR / "data/scream_default_output.yaml"}, a.yaml'
+ expected =f'a.yaml, b.yaml'
self._get_values(case, name, value=expected, expect_equal=True)
###########################################################################
diff --git a/components/eamxx/scripts/eamxx-params-docs-autogen b/components/eamxx/scripts/eamxx-params-docs-autogen
index 3024677d96b0..9bea5242d5a9 100755
--- a/components/eamxx/scripts/eamxx-params-docs-autogen
+++ b/components/eamxx/scripts/eamxx-params-docs-autogen
@@ -20,6 +20,7 @@ from mdutils import Html
sys.path.append(os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "cime_config"))
from eamxx_buildnml_impl import resolve_all_inheritances, get_valid_selectors
+from atm_manip import is_locked_impl
###############################################################################
def parse_command_line(args, description):
@@ -34,14 +35,15 @@ def parse_command_line(args, description):
return parser.parse_args(args[1:])
###########################################################################
-def add_param(docs,scope,item):
+def add_param(docs, scope, item):
###########################################################################
# Locked parameters are not to be configured at runtime, so don't even bother
# E.g, a locked param is something we need to get in the input file, like
# the restart write frequency, but we don't want the user to modify it
# via atmchange
- if "locked" in item.attrib.keys():
+ if is_locked_impl(item):
return
+
docs.new_line(f"* {scope}{item.tag}:")
pdoc = item.attrib['doc'] if 'doc' in item.attrib.keys() else "**MISSING**"
@@ -53,21 +55,23 @@ def add_param(docs,scope,item):
pvalid = item.attrib['valid_values'] if 'valid_values' in item.attrib.keys() else None
if pvalid is not None:
docs.new_line(f" - valid values: {pvalid}")
+
pconstr = item.attrib['constraints'] if 'constraints' in item.attrib.keys() else None
if pconstr is not None:
docs.new_line(f" - constraints: {pconstr}")
###########################################################################
-def add_children(docs,xml,scope=""):
+def add_children(docs, elem, scope=""):
###########################################################################
done = []
# Locked parameters are not to be configured at runtime, so don't even bother
# E.g, a locked param is something we need to get in the input file, like
# the restart write frequency, but we don't want the user to modify it
# via atmchange
- if "locked" in xml.attrib.keys():
+ if is_locked_impl(elem):
return
- for item in xml:
+
+ for item in elem:
# The same entry may appear multiple times in the XML defaults file,
# each time with different selectors. We don't want to generate the
# same documentation twice.
@@ -75,9 +79,10 @@ def add_children(docs,xml,scope=""):
continue
done.append(item.tag)
if len(item)>0:
- add_children (docs,item,f"{scope}{xml.tag}::")
+ add_children (docs,item,f"{scope}{elem.tag}::")
else:
- add_param(docs,f"{scope}{xml.tag}::",item)
+ add_param(docs,f"{scope}{elem.tag}::",item)
+
docs.new_line()
###########################################################################
@@ -107,7 +112,7 @@ def generate_params_docs():
continue
docs.new_header(level=2,title=ap.tag)
add_children(docs,ap)
-
+
ic = xml_defaults.find('initial_conditions')
docs.new_header(level=1,title="Initial Conditions Parameters")
add_children(docs,ic)
@@ -123,6 +128,7 @@ def generate_params_docs():
homme = xml_defaults.find('ctl_nl')
docs.new_header(level=1,title='Homme namelist')
add_children(docs,homme)
+
docs.create_md_file()
print("Generating eamxx params documentation ... SUCCESS!")
diff --git a/components/eamxx/scripts/edit-output-stream b/components/eamxx/scripts/edit-output-stream
new file mode 100755
index 000000000000..76c88e69ca39
--- /dev/null
+++ b/components/eamxx/scripts/edit-output-stream
@@ -0,0 +1,149 @@
+#!/usr/bin/env python3
+
+"""
+Edit (or create) an output stream yaml file
+"""
+
+import argparse, sys, pathlib
+
+from edit_output_stream import edit_output_stream_impl
+
+###############################################################################
+def parse_command_line(args, description):
+###############################################################################
+ parser = argparse.ArgumentParser(
+ usage="""\n{0} = [=] ...
+OR
+{0} --help
+
+\033[1mEXAMPLES:\033[0m
+ \033[1;32m# Generate empty file (with invalid options)'\033[0m
+ > {0} -g -f my_output.yaml
+
+ \033[1;32m# Generate empty file (with invalid options), overwrite if existing'\033[0m
+ > {0} -g -O -f my_output.yaml
+
+ \033[1;32m# Change avg type to Instant, output frequency to 1 day\033[0m
+ > {0} -f my_output.yaml --avg-type instant --freq 1 --freq-units ndays
+
+ \033[1;32m# Set horiz remaping\033[0m
+ > {0} -f my_output.yaml --horiz-map-file /path/to/map.nc
+""".format(pathlib.Path(args[0]).name),
+ description=description,
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter
+ )
+
+ parser.add_argument(
+ "-f","--filename",
+ required=True,
+ type=str,
+ help="The name of the yaml file to be configured",
+ )
+
+ parser.add_argument(
+ "--prefix",
+ type=str,
+ help="The prefix of the output files",
+ )
+
+ parser.add_argument(
+ "-g", "--generate",
+ default=False,
+ dest="generate",
+ action="store_true",
+ help="Generate a new file",
+ )
+ parser.add_argument(
+ "-O", "--overwrite",
+ default=False,
+ action="store_true",
+ help="When generating a new file, overwrite existing file (if any)",
+ )
+
+ parser.add_argument(
+ "-r","--reset",
+ default=None,
+ nargs="+",
+ type=str,
+ help="List of options to remove (or reset to default values) BEFORE doing any other edit"
+ )
+
+ parser.add_argument(
+ "--avg-type",
+ default=None,
+ type=str.lower,
+ help="Set the averaging type",
+ choices=['instant','average','max','min'],
+ )
+
+ parser.add_argument(
+ "--skip-t0-output",
+ action="store_true",
+ help="Skip t=case_t0 output (only relevant for INSTANT avg)"
+ )
+
+ parser.add_argument(
+ "--freq-units",
+ default=None,
+ type=str.lower,
+ help="Set the output frequency units",
+ )
+
+ parser.add_argument(
+ "--freq",
+ type=str.lower,
+ default=None,
+ help="Set the output frequency",
+ )
+
+ parser.add_argument(
+ "--grid",
+ default=None,
+ type=str,
+ help="Specify grid for which --fields/--io-grid options apply to",
+ )
+
+ parser.add_argument(
+ "--fields",
+ default=[],
+ nargs="+",
+ help="Fields to add to output",
+ )
+
+ parser.add_argument(
+ "--io-grid",
+ default=None,
+ type=str,
+ help="Name of grid onto which to remap fields before outputing them",
+ )
+
+ parser.add_argument(
+ "--horiz-remap-file",
+ default=None,
+ help="Map file to use for horizontal remap",
+ )
+
+ parser.add_argument(
+ "--vertical-remap-file",
+ default=None,
+ help="Map file to use for horizontal remap",
+ )
+
+ return parser.parse_args(args[1:])
+
+###############################################################################
+def _main_func(description):
+###############################################################################
+ if "--test" in sys.argv:
+ from doctest import testmod
+ import edit_output_stream
+ testmod()
+ testmod(m=edit_output_stream)
+ else:
+ edit_output_stream_impl(**vars(parse_command_line(sys.argv, description)))
+ sys.exit(0)
+
+###############################################################################
+
+if (__name__ == "__main__"):
+ _main_func(__doc__)
diff --git a/components/eamxx/scripts/edit_output_stream.py b/components/eamxx/scripts/edit_output_stream.py
new file mode 100644
index 000000000000..8ca194a47f98
--- /dev/null
+++ b/components/eamxx/scripts/edit_output_stream.py
@@ -0,0 +1,223 @@
+import pathlib
+
+from utils import expect, ensure_yaml
+
+ensure_yaml()
+import yaml
+
+###############################################################################
+def generate_empty_yaml(filename,overwrite):
+###############################################################################
+ """
+ Generate a yaml file with basic fields set, but containing empty or invalid values
+ >>> fname = "__test__.yaml"
+ >>> generate_empty_yaml(fname,False)
+ >>> generate_empty_yaml(fname,False)
+ Traceback (most recent call last):
+ SystemExit: ERROR: YAML file already exist. Re-run with -O/--overwrite to overwrite existing file
+ >>> generate_empty_yaml(fname,True)
+ >>> data = yaml.load(open(fname,'r'),Loader=yaml.SafeLoader)
+ >>> len(data)
+ 4
+ >>> data["filename_prefix"]
+ 'UNSET'
+ >>> data["Averaging Type"]
+ 'INVALID'
+ >>> len(data["Fields"])
+ 0
+ >>> oc = data["output_control"]
+ >>> len(oc)
+ 2
+ >>> oc["Frequency"]
+ -1
+ >>> oc["frequency_units"]
+ 'never'
+ >>> # Clean up the file
+ >>> pathlib.Path(fname).unlink()
+ """
+ file = pathlib.Path(filename).resolve()
+
+ expect (overwrite or not file.exists(),
+ "YAML file already exist. Re-run with -O/--overwrite to overwrite existing file")
+
+ if file.exists():
+ file.unlink()
+
+ data = {}
+ data["filename_prefix"] = "UNSET"
+ data["Averaging Type"] = "INVALID"
+ data["Fields"] = {}
+ data["output_control"] = {}
+ data["output_control"]["skip_t0_output"] = "false"
+ data["output_control"]["Frequency"] = -1
+ data["output_control"]["frequency_units"] = "never"
+
+ with open(file,'w') as fd:
+ yaml.dump(data,fd,Dumper=yaml.SafeDumper,explicit_start=True,explicit_end=True,version=(1,2))
+
+###############################################################################
+def edit_output_stream_impl(filename,prefix=None,generate=False,overwrite=False,
+ avg_type=None,skip_t0_output=False,freq_units=None,freq=None,
+ grid=None,fields=[],reset=None,io_grid=None,
+ horiz_remap_file=None,vertical_remap_file=None):
+###############################################################################
+ """
+ Apply the requested changes to the output stream yaml file
+ >>> fname = '__test__.yaml'
+ >>> # Create the file
+ >>> edit_output_stream_impl(fname,generate=True,prefix='foo')
+ >>> # Set some basic options, and then check
+ >>> edit_output_stream_impl(fname,avg_type='max',freq_units='ndays',freq=10)
+ >>> data = yaml.load(open(fname,'r'),Loader=yaml.SafeLoader)
+ >>> data['filename_prefix']
+ 'foo'
+ >>> data['Averaging Type']
+ 'max'
+ >>> data['output_control']['Frequency']
+ 10
+ >>> data['output_control']['frequency_units']
+ 'ndays'
+ >>> # Set fields options, and then check
+ >>> edit_output_stream_impl(fname,fields=['a','b'],grid='my_grid',io_grid='other_grid')
+ >>> data = yaml.load(open(fname,'r'),Loader=yaml.SafeLoader)
+ >>> f = data['Fields']['my_grid']['Field Names']
+ >>> f.sort()
+ >>> f
+ ['a', 'b']
+ >>> data['Fields']['my_grid']['IO Grid Name']
+ 'other_grid'
+ >>> # No remap if online remap (IO Grid Name) is set
+ >>> edit_output_stream_impl(fname,horiz_remap_file='blah')
+ Traceback (most recent call last):
+ SystemExit: ERROR: Cannot use online remap and horiz/vert remap at the same time.
+ >>> edit_output_stream_impl(fname,vertical_remap_file='blah')
+ Traceback (most recent call last):
+ SystemExit: ERROR: Cannot use online remap and horiz/vert remap at the same time.
+ >>> # Remove io grid and fields
+ >>> edit_output_stream_impl(fname,reset=['fields','io-grid'])
+ Traceback (most recent call last):
+ SystemExit: ERROR: Fields reset requested, but no grid name provided. Re-run with --grid GRID_NAME
+ >>> edit_output_stream_impl(fname,reset=['fields','io-grid'],grid='my_grid')
+ >>> data = yaml.load(open(fname,'r'),Loader=yaml.SafeLoader)
+ >>> 'my_grid' in data['Fields'].keys()
+ False
+ >>> # Set remap options, and then check
+ >>> edit_output_stream_impl(fname,horiz_remap_file='blah1',vertical_remap_file='blah2')
+ >>> data = yaml.load(open(fname,'r'),Loader=yaml.SafeLoader)
+ >>> data['horiz_remap_file']
+ 'blah1'
+ >>> data['vertical_remap_file']
+ 'blah2'
+ >>> # Clean up the file
+ >>> pathlib.Path(fname).unlink()
+ """
+
+ if generate:
+ generate_empty_yaml(filename,overwrite)
+
+ file = pathlib.Path(filename).resolve()
+
+ expect (file.exists(),
+ "YAML file does not exist. Re-run with -g/--generate to create")
+
+ data = yaml.load(open(file,"r"),Loader=yaml.SafeLoader)
+
+ # Before adding new options, process all the reset requests
+ if reset is not None:
+ for s in reset:
+ if s=="avg-type":
+ data["Averaging Type"] = "INVALID"
+ elif s=="skip_t0_output":
+ data["skip_t0_output"] = "false"
+ elif s=="preifx":
+ data["filename_prefix"] = "UNSET"
+ elif s=="freq":
+ data["output_control"]["Frequency"] = -1
+ elif s=="freq_units":
+ data["output_control"]["frequency_units"] = "never"
+ elif s=="horiz_remap_file":
+ del data["horiz_remap_file"]
+ elif s=="vert_remap_file":
+ del data["vert_remap_file"]
+ elif s=="fields":
+ expect (grid is not None,
+ "Fields reset requested, but no grid name provided. Re-run with --grid GRID_NAME")
+ if grid in data["Fields"].keys():
+ data["Fields"][grid]["Field Names"] = []
+
+ # Remove this grid if there are no other options set
+ if len(data["Fields"][grid])==1:
+ del data["Fields"][grid]
+ elif s=="io-grid":
+ expect (grid is not None,
+ "IO grid reset requested, but no grid name provided. Re-run with --grid GRID_NAME")
+ if grid in data["Fields"].keys():
+ del data["Fields"][grid]["IO Grid Name"]
+
+ # Remove this grid if there's not other options set other than
+ # fields names, and field names is an empty list
+ if len(data["Fields"][grid])==1 and len(data["Fields"][grid]["Field Names"])==0:
+ del data["Fields"][grid]
+
+ if prefix is not None:
+ data["filename_prefix"] = prefix
+
+ if avg_type is not None:
+ data["Averaging Type"] = avg_type
+
+ if skip_t0_output is not None:
+ data["skip_t0_output"] = skip_t0_output
+
+ if freq is not None:
+ expect (freq.lstrip('-+').isnumeric() or freq=='hist_n',
+ f"Invalid value '{freq}' for --freq. Valid options are\n"
+ " - an integer\n"
+ " - HIST_N\n")
+ data["output_control"]["Frequency"] = int(freq) if freq.lstrip('-+').isnumeric() else f"${{{freq.upper()}}}"
+
+ if freq_units is not None:
+ explicit = ['nsteps','nsecs','nmins','nhours','ndays','nmonths','nyears']
+ expect (freq_units in explicit or freq_units=='hist_option',
+ f"Invalid value '{freq_units}' for --freq-units. Valid options are (case insensitive)\n"
+ " - explicit values: 'nsteps','nsecs','nmins','nhours','ndays','nmonths','nyears'\n"
+ " - CIME variables : 'HIST_OPTION'\n")
+
+ data["output_control"]["frequency_units"] = freq_units if freq_units in explicit else f"${{{freq_units.upper()}}}"
+
+ if horiz_remap_file is not None:
+ data["horiz_remap_file"] = horiz_remap_file
+
+ if vertical_remap_file is not None:
+ data["vertical_remap_file"] = vertical_remap_file
+
+ if len(fields)>0 or io_grid is not None:
+ expect (grid is not None,
+ "Fields list specified, but no grid name provided. Re-run with --grid GRID_NAME")
+
+ section = data["Fields"].setdefault(grid,{})
+ if "Field Names" not in section.keys():
+ section["Field Names"] = []
+
+ fnames = section["Field Names"]
+ fnames += fields
+ fnames = list(set(fnames))
+ section["Field Names"] = fnames
+
+ if io_grid is not None:
+ section["IO Grid Name"] = io_grid
+ # If not already present, add an empty list of field names
+ section.setdefault("Field Names",[])
+
+ data["Fields"][grid] = section
+
+ # We cannot do online remap (typically dyn->physGLL) if horiz or vert remap is used
+ has_online_remap = False
+ for k,v in data["Fields"].items():
+ has_online_remap = has_online_remap or "IO Grid Name" in v.keys();
+ has_vert_remap = "vertical_remap_file" in data.keys()
+ has_horiz_remap = "horiz_remap_file" in data.keys()
+ expect (not has_online_remap or (not has_vert_remap and not has_horiz_remap),
+ "Cannot use online remap and horiz/vert remap at the same time.")
+
+ with open(file,'w') as fd:
+ yaml.dump(dict(data),fd,Dumper=yaml.SafeDumper,explicit_start=True,explicit_end=True,version=(1,2))
diff --git a/components/eamxx/scripts/git_utils.py b/components/eamxx/scripts/git_utils.py
index e3aa70025398..a7202bfbfaba 100644
--- a/components/eamxx/scripts/git_utils.py
+++ b/components/eamxx/scripts/git_utils.py
@@ -55,7 +55,7 @@ def get_current_head(repo=None):
return branch
###############################################################################
-def git_refs_difference (cmp_ref, head="HEAD", repo=None):
+def git_refs_difference(cmp_ref, head="HEAD", repo=None):
###############################################################################
"""
Return the difference in commits between cmp_ref and head.
@@ -136,6 +136,17 @@ def merge_git_ref(git_ref, repo=None, verbose=False, dry_run=False):
print ("git ref {} successfully merged.".format(git_ref))
print_last_commit()
+###############################################################################
+def create_backup_commit (repo=None, dry_run=False):
+###############################################################################
+
+ bkp_cmd = "git add -A && git commit -m 'WARNING: test-all-scream backup commit'"
+ if dry_run:
+ print (f"Would run: {bkp_cmd}")
+ else:
+ run_cmd_no_fail(bkp_cmd, from_dir=repo)
+ expect(is_repo_clean(repo=repo), "Something went wrong while performing the backup commit")
+
###############################################################################
def print_last_commit(git_ref=None, repo=None, dry_run=False):
###############################################################################
@@ -182,7 +193,7 @@ def get_git_toplevel_dir(repo=None):
return output if stat == 0 else None
###############################################################################
-def cleanup_repo(orig_branch, orig_commit, repo=None, dry_run=False):
+def cleanup_repo(orig_branch, orig_commit, has_backup_commit=False, repo=None, dry_run=False):
###############################################################################
"""
Discards all unstaged changes, as well as untracked files
@@ -206,4 +217,10 @@ def cleanup_repo(orig_branch, orig_commit, repo=None, dry_run=False):
# NOTE: if you reset the branch, don't forget to re-update the modules!!
if curr_commit != orig_commit and not dry_run:
run_cmd_no_fail("git reset --hard {}".format(orig_commit), from_dir=repo)
+ if has_backup_commit:
+ # This can happen if we ran an integration test with a dirty repo.
+ # test_all_scream will create a temporary backup commit, which we
+ # need to undo, but leaving the changed files in the workspace.
+ # So DON'T add --hard to this call!
+ run_cmd_no_fail("git reset {HEAD~1}", from_dir=repo)
update_submodules(repo=repo)
diff --git a/components/eamxx/scripts/jenkins/jenkins_cleanup_impl.sh b/components/eamxx/scripts/jenkins/jenkins_cleanup_impl.sh
index 942be64d8df6..3282f86e7158 100755
--- a/components/eamxx/scripts/jenkins/jenkins_cleanup_impl.sh
+++ b/components/eamxx/scripts/jenkins/jenkins_cleanup_impl.sh
@@ -1,11 +1,10 @@
#!/bin/bash -xe
-# Adjust this number to keep more/less builds
-echo "WORKSPACE: ${WORKSPACE}, BUILD_ID: ${BUILD_ID}"
+echo "RUNNING CLEANUP FOR WORKSPACE: ${WORKSPACE}, BUILD_ID: ${BUILD_ID}"
cd ${WORKSPACE}
-NUM_KEEP=30
+NUM_KEEP=12 # Adjust this number to keep more/fewer builds
KEEP_LAST=${BUILD_ID}
KEEP_FIRST=$((${BUILD_ID}-${NUM_KEEP}))
KEEP="$(seq ${KEEP_FIRST} 1 ${KEEP_LAST})"
@@ -15,3 +14,11 @@ REMOVE_THESE="$(ls -1 | grep -vF "${KEEP}")"
echo "Purging old builds: ${REMOVE_THESE}."
/bin/rm -rf $REMOVE_THESE
+
+# Now clean up the scratch area
+if [[ "$NODE_NAME" == "mappy" ]]; then
+ # Ensure we have a newer python
+ source $JENKINS_SCRIPT_DIR/${NODE_NAME}_setup
+
+ $JENKINS_SCRIPT_DIR/scratch_cleanup.py
+fi
diff --git a/components/eamxx/scripts/jenkins/jenkins_common_impl.sh b/components/eamxx/scripts/jenkins/jenkins_common_impl.sh
index fe293debe446..664c911585e2 100755
--- a/components/eamxx/scripts/jenkins/jenkins_common_impl.sh
+++ b/components/eamxx/scripts/jenkins/jenkins_common_impl.sh
@@ -72,7 +72,12 @@ if [ $skip_testing -eq 0 ]; then
# IF such dir is not found, then the default (ctest-build/baselines) is used
BASELINES_DIR=AUTO
- TAS_ARGS="--baseline-dir $BASELINES_DIR \$compiler -c EKAT_DISABLE_TPL_WARNINGS=ON -p -i -m \$machine"
+ TAS_ARGS="--baseline-dir $BASELINES_DIR \$compiler -p -c EKAT_DISABLE_TPL_WARNINGS=ON -i -m \$machine"
+ # pm-gpu needs to do work in scratch area in order not to fill home quota
+ if [[ "$SCREAM_MACHINE" == "pm-gpu" ]]; then
+ TAS_ARGS="${TAS_ARGS} -w /pscratch/sd/e/e3smtest/e3sm_scratch/pm-gpu/ctest-build"
+ fi
+
# Now that we are starting to run things that we expect could fail, we
# do not want the script to exit on any fail since this will prevent
# later tests from running.
@@ -120,7 +125,9 @@ if [ $skip_testing -eq 0 ]; then
fi
fi
- if [[ "$SCREAM_MACHINE" == "weaver" ]]; then
+ if [[ -z "$SCREAM_FAKE_ONLY" && "$SCREAM_MACHINE" == "weaver" ]]; then
+ # The fake-only tests don't launch any kernels which will cause all
+ # the compute-sanitizer runs to fail.
./scripts/gather-all-data "./scripts/test-all-scream -t csm -t csr -t csi -t css ${TAS_ARGS}" -l -m $SCREAM_MACHINE
if [[ $? != 0 ]]; then
fails=$fails+1;
@@ -138,20 +145,6 @@ if [ $skip_testing -eq 0 ]; then
# Run scripts-tests
if [[ $test_scripts == 1 ]]; then
- # JGF: I'm not sure there's much value in these dry-run comparisons
- # since we aren't changing HEADs
- ./scripts/scripts-tests -g -m $SCREAM_MACHINE
- if [[ $? != 0 ]]; then
- fails=$fails+1;
- scripts_fail=1
- fi
-
- ./scripts/scripts-tests -c -m $SCREAM_MACHINE
- if [[ $? != 0 ]]; then
- fails=$fails+1;
- scripts_fail=1
- fi
-
./scripts/scripts-tests -f -m $SCREAM_MACHINE
if [[ $? != 0 ]]; then
fails=$fails+1;
@@ -195,7 +188,7 @@ if [ $skip_testing -eq 0 ]; then
if [[ $test_v1 == 1 ]]; then
# AT runs should be fast. => run only low resolution
- this_output=$(../../cime/scripts/create_test e3sm_scream_v1_at --compiler=gnu9 -c -b master --wait)
+ this_output=$(../../cime/scripts/create_test e3sm_scream_v1_at -c -b master --wait)
if [[ $? != 0 ]]; then
fails=$fails+1;
v1_fail=1
diff --git a/components/eamxx/scripts/jenkins/pm-gpu_setup b/components/eamxx/scripts/jenkins/pm-gpu_setup
new file mode 100644
index 000000000000..7bc04f72f9da
--- /dev/null
+++ b/components/eamxx/scripts/jenkins/pm-gpu_setup
@@ -0,0 +1,2 @@
+source /global/common/software/e3sm/anaconda_envs/load_latest_cime_env.sh
+SCREAM_MACHINE=pm-gpu
diff --git a/components/eamxx/scripts/jenkins/scratch_cleanup.py b/components/eamxx/scripts/jenkins/scratch_cleanup.py
new file mode 100755
index 000000000000..0195195a157e
--- /dev/null
+++ b/components/eamxx/scripts/jenkins/scratch_cleanup.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+
+"""
+Clean up old files in the scratch area for mappy.
+"""
+
+from pathlib import Path
+import re, time, shutil, sys, argparse
+
+###############################################################################
+def parse_command_line(args, description):
+###############################################################################
+ parser = argparse.ArgumentParser(
+ usage="""\n{0} [-c HOURS]
+OR
+{0} --help
+
+\033[1mEXAMPLES:\033[0m
+ \033[1;32m# Purge files older than 20 hours \033[0m
+ > {0} -c 20
+""".format(Path(args[0]).name),
+ description=description,
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter
+ )
+
+ parser.add_argument("-c", "--cutoff", type=int, default=30, help="The cutoff age for purging in hours")
+
+ parser.add_argument("-d", "--dry-run", action="store_true", help="Do a dry run, don't actually remove files")
+
+ args = parser.parse_args(args[1:])
+
+ return args
+
+###############################################################################
+def scratch_cleanup(cutoff, dry_run):
+###############################################################################
+ scratch = Path('/ascldap/users/e3sm-jenkins/acme/scratch')
+
+ timestamp_re = re.compile(r'.*(20[0-9]{6}_[0-9]{6}).*')
+ timestamps = set()
+ for item in scratch.iterdir():
+ basename = item.name
+ re_match = timestamp_re.match(basename)
+ if re_match:
+ timestamps.add(re_match.groups()[0])
+
+ tformat = "%Y%m%d_%H%M%S"
+ curr_time = time.time()
+
+ for timestamp in timestamps:
+ timestamp_time = time.mktime(time.strptime(timestamp, tformat))
+ age_in_hours = (curr_time - timestamp_time) / 3600
+ if age_in_hours > cutoff:
+ print(f"Timestamp {timestamp} is {age_in_hours} hours old and corresponding files will be removed")
+ files_to_remove = scratch.glob(f"*{timestamp}*")
+ for file_to_remove in files_to_remove:
+ print(f" Removing {file_to_remove}")
+ if not dry_run:
+ if file_to_remove.is_dir():
+ shutil.rmtree(file_to_remove)
+ else:
+ file_to_remove.unlink()
+
+ return True
+
+###############################################################################
+def _main_func(description):
+###############################################################################
+ success = scratch_cleanup(**vars(parse_command_line(sys.argv, description)))
+
+ sys.exit(0 if success else 1)
+
+###############################################################################
+
+if __name__ == "__main__":
+ _main_func(__doc__)
diff --git a/components/eamxx/scripts/machines_specs.py b/components/eamxx/scripts/machines_specs.py
index cd717cba6b97..df89ae7b5add 100644
--- a/components/eamxx/scripts/machines_specs.py
+++ b/components/eamxx/scripts/machines_specs.py
@@ -4,6 +4,8 @@
ensure_psutil()
import psutil
+CIMEROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..","..","..","cime")
+
# MACHINE -> (env_setup, # list of shell commands to set up scream-approved env
# compilers, # list of compilers [CXX, F90, C]
# batch submit prefix, # string shell commmand prefix
@@ -26,22 +28,22 @@
["mpicxx","mpifort","mpicc"],
"bsub -I -q rhel8 -n 4 -gpu num=4",
"/home/projects/e3sm/scream/pr-autotester/master-baselines/weaver/"),
- "mappy" : (["module purge", "module load sems-archive-env acme-env acme-cmake/3.26.3 sems-archive-gcc/9.2.0 sems-archive-git/2.10.1 acme-openmpi/4.0.7 acme-netcdf/4.7.4/acme"],
+ "mappy" : (["module purge", "module load sems-archive-env acme-env acme-cmake/3.26.3 acme-gcc/11.2.0 sems-archive-git/2.10.1 acme-openmpi/4.1.4 acme-netcdf/4.7.4/acme", "export GATOR_INITIAL_MB=4000MB"],
["mpicxx","mpifort","mpicc"],
"",
"/sems-data-store/ACME/baselines/scream/master-baselines"),
"lassen" : (["module --force purge", "module load git gcc/8.3.1 cuda/11.8.0 cmake/3.16.8 spectrum-mpi python/3.7.2", "export LLNL_USE_OMPI_VARS='y'",
- "export PATH=/usr/gdata/climdat/netcdf/bin:$PATH",
- "export LD_LIBRARY_PATH=/usr/gdata/climdat/netcdf/lib:$LD_LIBRARY_PATH",
+ "export PATH=/usr/gdata/e3sm/netcdf/bin:$PATH",
+ "export LD_LIBRARY_PATH=/usr/gdata/e3sm/netcdf/lib:$LD_LIBRARY_PATH",
],
["mpicxx","mpifort","mpicc"],
"bsub -Ip -qpdebug",
""),
- "ruby-intel" : (["module --force purge", "module use --append /usr/gdata/climdat/install/quartz/modulefiles", "module load StdEnv cmake/3.19.2 mkl/2022.1.0 intel-classic/2021.6.0-magic mvapich2/2.3.7 hdf5/1.12.2 netcdf-c/4.9.0 netcdf-fortran/4.6.0 parallel-netcdf/1.12.3 python/3.9.12 screamML-venv/0.0.1"],
+ "ruby-intel" : (["module --force purge", "module use --append /usr/gdata/e3sm/install/quartz/modulefiles", "module load StdEnv cmake/3.19.2 mkl/2022.1.0 intel-classic/2021.6.0-magic mvapich2/2.3.7 hdf5/1.12.2 netcdf-c/4.9.0 netcdf-fortran/4.6.0 parallel-netcdf/1.12.3 python/3.9.12 screamML-venv/0.0.1"],
["mpicxx","mpifort","mpicc"],
"salloc --partition=pdebug",
""),
- "quartz-intel" : (["module --force purge", "module use --append /usr/gdata/climdat/install/quartz/modulefiles", "module load StdEnv cmake/3.19.2 mkl/2022.1.0 intel-classic/2021.6.0-magic mvapich2/2.3.7 hdf5/1.12.2 netcdf-c/4.9.0 netcdf-fortran/4.6.0 parallel-netcdf/1.12.3 python/3.9.12 screamML-venv/0.0.1"],
+ "quartz-intel" : (["module --force purge", "module use --append /usr/gdata/e3sm/install/quartz/modulefiles", "module load StdEnv cmake/3.19.2 mkl/2022.1.0 intel-classic/2021.6.0-magic mvapich2/2.3.7 hdf5/1.12.2 netcdf-c/4.9.0 netcdf-fortran/4.6.0 parallel-netcdf/1.12.3 python/3.9.12 screamML-venv/0.0.1"],
["mpicxx","mpifort","mpicc"],
"salloc --partition=pdebug",
""),
@@ -57,15 +59,19 @@
["mpicxx","mpifort","mpicc"],
"bsub -I -q batch -W 0:30 -P cli115 -nnodes 1",
"/gpfs/alpine/cli115/proj-shared/scream/master-baselines"),
- "pm-gpu" : (["module load PrgEnv-gnu gcc/10.3.0 cudatoolkit craype-accel-nvidia80 cray-libsci craype cray-mpich cray-hdf5-parallel cray-netcdf-hdf5parallel cray-parallel-netcdf cmake evp-patch","module unload craype-accel-host perftools-base perftools darshan", "export NVCC_WRAPPER_DEFAULT_COMPILER=CC", "export NVCC_WRAPPER_DEFAULT_ARCH=sm_80"],
+ "pm-cpu" : ([f"eval $({CIMEROOT}/CIME/Tools/get_case_env -c SMS.ne4pg2_ne4pg2.F2010-SCREAMv1.pm-cpu_gnu)"],
+ ["CC","ftn","cc"],
+ "salloc --time 00:30:00 --nodes=1 --constraint=cpu -q debug --account e3sm_g",
+ "/global/cfs/cdirs/e3sm/baselines/gnu/scream/pm-cpu"),
+ "pm-gpu" : ([f"eval $({CIMEROOT}/CIME/Tools/get_case_env -c SMS.ne4pg2_ne4pg2.F2010-SCREAMv1.pm-gpu_gnugpu)", "echo cuda=true"],
["CC","ftn","cc"],
- "srun --time 00:30:00 --nodes=1 --constraint=gpu --exclusive -q regular --account e3sm_g",
- ""),
+ "salloc --time 02:00:00 --nodes=4 --constraint=gpu --gpus-per-node=4 --gpu-bind=none --exclusive -q regular --account e3sm_g",
+ "/global/cfs/cdirs/e3sm/baselines/gnugpu/scream/pm-gpu"),
"compy" : (["module purge", "module load cmake/3.19.6 gcc/8.1.0 mvapich2/2.3.1 python/3.7.3"],
["mpicxx","mpifort","mpicc"],
"srun --time 02:00:00 --nodes=1 -p short --exclusive --account e3sm",
""),
- "chrysalis" : (["eval $(../../cime/CIME/Tools/get_case_env)", "export OMP_NUM_THREADS=1"],
+ "chrysalis" : ([f"eval $({CIMEROOT}/CIME/Tools/get_case_env)", "export OMP_NUM_THREADS=1"],
["mpic++","mpif90","mpicc"],
"srun --mpi=pmi2 -l -N 1 --kill-on-bad-exit --cpu_bind=cores",
"/lcrc/group/e3sm/baselines/chrys/intel/scream"),
@@ -193,10 +199,20 @@ def get_mach_testing_resources(machine):
of jobs across cores.
"""
if is_cuda_machine(machine):
- return int(run_cmd_no_fail("nvidia-smi -L | wc -l"))
+ prefix = "srun " if is_salloc(machine) else ""
+ return int(run_cmd_no_fail(f"{prefix}nvidia-smi -L | wc -l"))
else:
return get_available_cpu_count()
+###############################################################################
+def is_salloc(machine):
+###############################################################################
+ """
+ Return true if we are running on an salloc'd job.
+ """
+ bcmd = get_mach_batch_command(machine)
+ return "salloc" in bcmd and "srun" not in bcmd
+
###############################################################################
def is_cuda_machine(machine):
###############################################################################
diff --git a/components/eamxx/scripts/scripts-tests b/components/eamxx/scripts/scripts-tests
index b70a697a7d55..b5af87320243 100755
--- a/components/eamxx/scripts/scripts-tests
+++ b/components/eamxx/scripts/scripts-tests
@@ -3,14 +3,7 @@
"""
Script containing python test suite for SCREAM test
infrastructure. This suite should be run to confirm overall
-correctness. You should run this test once in generation mode to
-generate baseline results using your reference commit (common
-ancestor) and once in comparison mode to compare against these
-baselines using your development commit. Baseline and compare runs
-will use dry-run modes so we are only comparing hypothetical shell
-commands, not actually running them.
-
-You can also do a full run which will actually execute the commands.
+correctness.
If you are on a batch machine, it is expected that you are on a compute node.
@@ -26,43 +19,17 @@ from machines_specs import is_machine_supported, is_cuda_machine
from git_utils import get_current_branch, get_current_commit, get_current_head, git_refs_difference, \
is_repo_clean, get_common_ancestor, checkout_git_ref, get_git_toplevel_dir
-import unittest, argparse, sys, difflib, shutil, os
+import unittest, argparse, sys, shutil, os
from pathlib import Path
# Globals
TEST_DIR = Path(__file__).resolve().parent
CONFIG = {
"machine" : None,
- "compare" : False,
- "generate" : False,
"full" : False,
"jenkins" : False
}
-###############################################################################
-def run_cmd_store_output(test_obj, cmd, output_file):
-###############################################################################
- output_file.parent.mkdir(parents=True, exist_ok=True)
- output = run_cmd_assert_result(test_obj, cmd, from_dir=TEST_DIR)
- head = get_current_head()
- output = output.replace(head, "CURRENT_HEAD_NORMALIZED")
- output_file.write_text(output)
-
-###############################################################################
-def run_cmd_check_baseline(test_obj, cmd, baseline_path):
-###############################################################################
- test_obj.assertTrue(baseline_path.is_file(), msg="Missing baseline {}".format(baseline_path))
- output = run_cmd_assert_result(test_obj, cmd, from_dir=TEST_DIR)
- head = get_current_head()
- output = output.replace(head, "CURRENT_HEAD_NORMALIZED")
- diff = difflib.unified_diff(
- baseline_path.read_text().splitlines(),
- output.splitlines(),
- fromfile=str(baseline_path),
- tofile=cmd)
- diff_output = "\n".join(diff)
- test_obj.assertEqual("", diff_output, msg=diff_output)
-
###############################################################################
def test_cmake_cache_contents(test_obj, build_name, cache_var, expected_value):
###############################################################################
@@ -150,8 +117,6 @@ class TestBaseOuter: # Hides the TestBase class from test scanner
self._source_file = source_file
self._cmds = list(cmds)
self._machine = CONFIG["machine"]
- self._compare = CONFIG["compare"]
- self._generate = CONFIG["generate"]
self._full = CONFIG["full"]
self._jenkins = CONFIG["jenkins"]
@@ -160,42 +125,20 @@ class TestBaseOuter: # Hides the TestBase class from test scanner
self._results = TEST_DIR.joinpath("results")
self._results.mkdir(parents=True, exist_ok=True) # pylint: disable=no-member
- def get_baseline(self, cmd, machine):
- return self._results.joinpath(self._source_file).with_suffix("").\
- joinpath(machine, self.get_cmd(cmd, machine, dry_run=False).translate(str.maketrans(" /='", "____")))
-
- def get_cmd(self, cmd, machine, dry_run=True):
- return "{}{}".format(cmd.replace("$machine", machine).replace("$results", str(self._results)),
- " --dry-run" if (dry_run and "--dry-run" not in cmd) else "")
+ def get_cmd(self, cmd, machine):
+ return cmd.replace("$machine", machine).replace("$results", str(self._results))
def test_doctests(self):
run_cmd_assert_result(self, "python3 -m doctest {}".format(self._source_file), from_dir=TEST_DIR)
def test_pylint(self):
ensure_pylint()
- run_cmd_assert_result(self, "python3 -m pylint --disable C --disable R {}".format(self._source_file), from_dir=TEST_DIR, verbose=True)
-
- def test_gen_baseline(self):
- if self._generate:
- for cmd in self._cmds:
- run_cmd_store_output(self, self.get_cmd(cmd, self._machine), self.get_baseline(cmd, self._machine))
- else:
- self.skipTest("Skipping dry run baseline generation")
-
- def test_cmp_baseline(self):
- if self._compare:
- for cmd in self._cmds:
- if "-p" in cmd:
- # Parallel builds can generate scrambled output. Skip them.
- continue
- run_cmd_check_baseline(self, self.get_cmd(cmd, self._machine), self.get_baseline(cmd, self._machine))
- else:
- self.skipTest("Skipping dry run baseline comparison")
+ run_cmd_assert_result(self, "python3 -m pylint --disable C --disable R {}".format(self._source_file), from_dir=TEST_DIR)
def test_full(self):
if self._full:
for cmd in self._cmds:
- run_cmd_assert_result(self, self.get_cmd(cmd, self._machine, dry_run=False), from_dir=TEST_DIR)
+ run_cmd_assert_result(self, self.get_cmd(cmd, self._machine), from_dir=TEST_DIR)
else:
self.skipTest("Skipping full run")
@@ -271,9 +214,8 @@ class TestTestAllScream(TestBaseOuter.TestBase):
###############################################################################
CMDS_TO_TEST = [
- "./test-all-scream -m $machine -b HEAD -k -p",
- "./test-all-scream -m $machine -b HEAD -k -t dbg",
- "./test-all-scream --baseline-dir $results -p -c EKAT_DISABLE_TPL_WARNINGS=ON -i -m $machine --submit --dry-run", # always dry run
+ "./test-all-scream -m $machine -p -i -c EKAT_DISABLE_TPL_WARNINGS=ON",
+ "./test-all-scream -m $machine -t dbg",
]
def __init__(self, *internal_args):
@@ -288,9 +230,9 @@ class TestTestAllScream(TestBaseOuter.TestBase):
Test the 'dbg' test in test-all-scream. It should set certain CMake values
"""
if not self._jenkins:
- options = "-b HEAD -k -t dbg --config-only"
+ options = "-t dbg --config-only"
cmd = self.get_cmd("./test-all-scream -m $machine {}".format(options),
- self._machine, dry_run=False)
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_cmake_cache_contents(self, "full_debug", "CMAKE_BUILD_TYPE", "Debug")
test_cmake_cache_contents(self, "full_debug", "SCREAM_DOUBLE_PRECISION", "TRUE")
@@ -307,9 +249,9 @@ class TestTestAllScream(TestBaseOuter.TestBase):
Test the 'sp' test in test-all-scream. It should set certain CMake values
"""
if not self._jenkins:
- options = "-b HEAD -k -t sp --config-only"
+ options = "-t sp --config-only"
cmd = self.get_cmd("./test-all-scream -m $machine {}".format(options),
- self._machine, dry_run=False)
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_cmake_cache_contents(self, "full_sp_debug", "CMAKE_BUILD_TYPE", "Debug")
test_cmake_cache_contents(self, "full_sp_debug", "SCREAM_DOUBLE_PRECISION", "FALSE")
@@ -329,9 +271,9 @@ class TestTestAllScream(TestBaseOuter.TestBase):
if is_cuda_machine(self._machine):
self.skipTest("Skipping FPE check on cuda")
else:
- options = "-b HEAD -k -t fpe --config-only"
+ options = "-t fpe --config-only"
cmd = self.get_cmd("./test-all-scream -m $machine {}".format(options),
- self._machine, dry_run=False)
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_cmake_cache_contents(self, "debug_nopack_fpe", "CMAKE_BUILD_TYPE", "Debug")
test_cmake_cache_contents(self, "debug_nopack_fpe", "SCREAM_DOUBLE_PRECISION", "TRUE")
@@ -345,9 +287,9 @@ class TestTestAllScream(TestBaseOuter.TestBase):
Test the mem (default mem-check build) in test-all-scream. It should set certain CMake values
"""
if not self._jenkins:
- options = "-b HEAD -k -t mem --config-only"
+ options = "-t mem --config-only"
cmd = self.get_cmd("./test-all-scream -m $machine {}".format(options),
- self._machine, dry_run=False)
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
builddir = "compute_sanitizer_memcheck" if is_cuda_machine(self._machine) else "valgrind"
test_cmake_cache_contents(self, builddir, "CMAKE_BUILD_TYPE", "Debug")
@@ -365,9 +307,9 @@ class TestTestAllScream(TestBaseOuter.TestBase):
Test the 'opt' test in test-all-scream. It should set certain CMake values
"""
if not self._jenkins:
- options = "-b HEAD -k -t opt --config-only"
+ options = "-t opt --config-only"
cmd = self.get_cmd("./test-all-scream -m $machine {}".format(options),
- self._machine, dry_run=False)
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_cmake_cache_contents(self, "release", "CMAKE_BUILD_TYPE", "Release")
else:
@@ -379,7 +321,7 @@ class TestTestAllScream(TestBaseOuter.TestBase):
Test that the 'dbg' test in test-all-scream detects and returns non-zero if there's a cmake configure error
"""
if self._full:
- cmd = self.get_cmd("./test-all-scream -e SCREAM_FORCE_CONFIG_FAIL=True -m $machine -b HEAD -k -t dbg", self._machine, dry_run=False)
+ cmd = self.get_cmd("./test-all-scream -e SCREAM_FORCE_CONFIG_FAIL=True -m $machine -t dbg", self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR, expect_works=False)
else:
self.skipTest("Skipping full run")
@@ -389,7 +331,7 @@ class TestTestAllScream(TestBaseOuter.TestBase):
Test that the 'dbg' test in test-all-scream detects and returns non-zero if there's a build error
"""
if self._full:
- cmd = self.get_cmd("./test-all-scream -e SCREAM_FORCE_BUILD_FAIL=True -m $machine -b HEAD -k -t dbg", self._machine, dry_run=False)
+ cmd = self.get_cmd("./test-all-scream -e SCREAM_FORCE_BUILD_FAIL=True -m $machine -t dbg", self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR, expect_works=False)
else:
self.skipTest("Skipping full run")
@@ -399,7 +341,7 @@ class TestTestAllScream(TestBaseOuter.TestBase):
Test that a failure from ctest in the testing phase is caught by test-all-scream
"""
if self._full:
- cmd = self.get_cmd("./test-all-scream -e SCREAM_FORCE_RUN_FAIL=True -m $machine -b HEAD -k -t dbg", self._machine, dry_run=False)
+ cmd = self.get_cmd("./test-all-scream -e SCREAM_FORCE_RUN_FAIL=True -m $machine -t dbg", self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR, expect_works=False)
else:
self.skipTest("Skipping full run")
@@ -409,7 +351,7 @@ class TestTestAllScream(TestBaseOuter.TestBase):
Test that the at test level works
"""
if self._full:
- cmd = self.get_cmd("./test-all-scream -x -m $machine -b HEAD -k -t dbg", self._machine, dry_run=False)
+ cmd = self.get_cmd("./test-all-scream -x -m $machine -t dbg", self._machine)
output = run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_test_levels_were_run(self, output, ["AT"], ["NIGHTLY", "EXPERIMENTAL"])
else:
@@ -420,7 +362,7 @@ class TestTestAllScream(TestBaseOuter.TestBase):
Test that the nightly test level works
"""
if self._full:
- cmd = self.get_cmd("./test-all-scream -x --test-level=nightly -m $machine -b HEAD -k -t dbg", self._machine, dry_run=False)
+ cmd = self.get_cmd("./test-all-scream -x --test-level=nightly -m $machine -t dbg", self._machine)
output = run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_test_levels_were_run(self, output, ["AT", "NIGHTLY"], ["EXPERIMENTAL"])
else:
@@ -431,7 +373,7 @@ class TestTestAllScream(TestBaseOuter.TestBase):
Test that the experimental test level works
"""
if self._full:
- cmd = self.get_cmd("./test-all-scream -x --test-level=experimental -m $machine -b HEAD -k -t dbg", self._machine, dry_run=False)
+ cmd = self.get_cmd("./test-all-scream -x --test-level=experimental -m $machine -t dbg", self._machine)
output = run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_test_levels_were_run(self, output, ["AT", "NIGHTLY", "EXPERIMENTAL"], [])
else:
@@ -445,13 +387,12 @@ class TestTestAllScream(TestBaseOuter.TestBase):
So set SCREAM_FAKE_ONLY=ON, to lower the build time
"""
if self._full:
- baseline_dir = TEST_DIR.parent/"ctest-build"/"baselines"
- # Start a couple new tests, baselines will be generated
+ # Start a couple new tests, baselines will be generated in ctest-build/baselines
env = "SCREAM_FAKE_ONLY=ON SCREAM_FAKE_GIT_HEAD=FAKE1"
- opts = "-b HEAD -k -t dbg -t sp --no-tests"
- cmd = self.get_cmd("{} ./test-all-scream -m $machine {}".format(env,opts),
- self._machine, dry_run=False)
+ opts = " -g -t dbg -t sp --no-tests"
+ cmd = self.get_cmd(f"{env} ./test-all-scream -m $machine {opts}",
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_baseline_has_sha(self, TEST_DIR, "full_debug", "FAKE1")
@@ -459,39 +400,42 @@ class TestTestAllScream(TestBaseOuter.TestBase):
# Re-run reusing baselines from above
env = "SCREAM_FAKE_ONLY=ON SCREAM_FAKE_GIT_HEAD=FAKE2"
- opts = "--baseline-dir={} -b HEAD -k -t dbg -t sp --no-tests".format(baseline_dir)
- cmd = self.get_cmd("{} ./test-all-scream -m $machine {}".format(env,opts),
- self._machine, dry_run=False)
+ opts = "--baseline-dir LOCAL -t dbg -t sp --no-tests"
+ cmd = self.get_cmd(f"{env} ./test-all-scream -m $machine {opts}",
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_baseline_has_sha(self, TEST_DIR, "full_debug", "FAKE1")
test_baseline_has_sha(self, TEST_DIR, "full_sp_debug", "FAKE1")
# Re-run dbg reusing baselines from above with a fake commit that's not ahead
+ # The flag -u implies -g, but nothing should happen, since SCREAM_FAKE_AHEAD=0
env = "SCREAM_FAKE_ONLY=ON SCREAM_FAKE_AHEAD=0 SCREAM_FAKE_GIT_HEAD=FAKE2"
- opts = "--baseline-dir={} -b HEAD -k -t dbg -u --no-tests".format(baseline_dir)
- cmd = self.get_cmd("{} ./test-all-scream -m $machine {}".format(env,opts),
- self._machine, dry_run=False)
+ opts = "--baseline-dir LOCAL -t dbg -u --no-tests"
+ cmd = self.get_cmd(f"{env} ./test-all-scream -m $machine {opts}",
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_baseline_has_sha(self, TEST_DIR, "full_debug", "FAKE1")
test_baseline_has_sha(self, TEST_DIR, "full_sp_debug", "FAKE1")
# Re-run dbg reusing baselines from above but expire them
+ # The flag -u implies -g, and since SCREAM_FAKE_AHEAD=1, baseline should be regenerated
env = "SCREAM_FAKE_ONLY=ON SCREAM_FAKE_AHEAD=1 SCREAM_FAKE_GIT_HEAD=FAKE2"
- opts = "--baseline-dir={} -b HEAD -k -t dbg -u --no-tests".format(baseline_dir)
- cmd = self.get_cmd("{} ./test-all-scream -m $machine {}".format(env,opts),
- self._machine, dry_run=False)
+ opts = "--baseline-dir LOCAL -t dbg -u --no-tests"
+ cmd = self.get_cmd(f"{env} ./test-all-scream -m $machine {opts}",
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_baseline_has_sha(self, TEST_DIR, "full_debug", "FAKE2")
test_baseline_has_sha(self, TEST_DIR, "full_sp_debug", "FAKE1")
# Re-run reusing some baselines and expiring others
+ # The dbg baselines were generated in the prev step, so this should only gen the sp baselines
env = "SCREAM_FAKE_ONLY=ON SCREAM_FAKE_AHEAD=1 SCREAM_FAKE_GIT_HEAD=FAKE2"
- opts = "--baseline-dir={} -b HEAD -k -t dbg -t sp -u --no-tests".format(baseline_dir)
- cmd = self.get_cmd("{} ./test-all-scream -m $machine {}".format(env,opts),
- self._machine, dry_run=False)
+ opts = "--baseline-dir LOCAL -t dbg -t sp -u --no-tests"
+ cmd = self.get_cmd(f"{env} ./test-all-scream -m $machine {opts}",
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_baseline_has_sha(self, TEST_DIR, "full_debug", "FAKE2")
@@ -499,9 +443,9 @@ class TestTestAllScream(TestBaseOuter.TestBase):
# Re-run without reusing baselines, should force regeneration
env = "SCREAM_FAKE_ONLY=ON SCREAM_FAKE_GIT_HEAD=FAKE3"
- opts = "-b HEAD -k -t dbg -t sp --no-tests"
- cmd = self.get_cmd("{} ./test-all-scream -m $machine {}".format(env,opts),
- self._machine, dry_run=False)
+ opts = "-g -t dbg -t sp --no-tests"
+ cmd = self.get_cmd(f"{env} ./test-all-scream -m $machine {opts}",
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_baseline_has_sha(self, TEST_DIR, "full_debug", "FAKE3")
@@ -518,21 +462,13 @@ class TestTestAllScream(TestBaseOuter.TestBase):
can manage resources correctly.
"""
if self._full and self._machine == "mappy":
- spread_test_opts = "-x -e SCREAM_TEST_THREAD_SPREAD=True -c EKAT_TEST_LAUNCHER_MANAGE_RESOURCES=True -c EKAT_MPIRUN_EXE=mpiexec -c EKAT_MPI_EXTRA_ARGS='-bind-to core' -c EKAT_MPI_NP_FLAG='--map-by' -c EKAT_MPI_THREAD_FLAG='' -m $machine -b HEAD -k -t dbg"
+ spread_test_opts = "-x -e SCREAM_TEST_THREAD_SPREAD=True -e SCREAM_TEST_RANK_SPREAD=True -c EKAT_TEST_LAUNCHER_MANAGE_RESOURCES=True -c EKAT_MPIRUN_EXE=mpiexec -c EKAT_MPI_EXTRA_ARGS='-bind-to core' -c EKAT_MPI_NP_FLAG='--map-by' -c EKAT_MPI_THREAD_FLAG='' -m $machine -t dbg"
- cmd = self.get_cmd(f"./test-all-scream {spread_test_opts} --ctest-parallel-level=40 ", self._machine, dry_run=False)
+ cmd = self.get_cmd(f"./test-all-scream {spread_test_opts} --ctest-parallel-level=40 ", self._machine)
output = run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_omp_spread(self, output, 40)
- cmd = self.get_cmd(f"./test-all-scream {spread_test_opts} --ctest-parallel-level=40 ", self._machine, dry_run=False)
- output = run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
- test_omp_spread(self, output, 40)
-
- cmd = self.get_cmd(f"taskset -c 8-47 ./test-all-scream {spread_test_opts} --ctest-parallel-level=40 ", self._machine, dry_run=False)
- output = run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
- test_omp_spread(self, output, 48, begin=8)
-
- cmd = self.get_cmd(f"taskset -c 8-47 ./test-all-scream {spread_test_opts} --ctest-parallel-level=40 ", self._machine, dry_run=False)
+ cmd = self.get_cmd(f"taskset -c 8-47 ./test-all-scream {spread_test_opts} --ctest-parallel-level=40 ", self._machine)
output = run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
test_omp_spread(self, output, 48, begin=8)
@@ -547,7 +483,7 @@ class TestTestAllScream(TestBaseOuter.TestBase):
# We set PULLREQUESTNUM to block dashboard submission
# We set SCREAM_FAKE_AUTO to not interere with real baselines
cmd = self.get_cmd("PR_LABELS= NODE_NAME={} SCREAM_FAKE_AUTO=TRUE PULLREQUESTNUM=42 ./jenkins/jenkins_common.sh".format(self._machine),
- self._machine, dry_run=False)
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
else:
@@ -561,7 +497,7 @@ class TestTestAllScream(TestBaseOuter.TestBase):
# We set PULLREQUESTNUM to block dashboard submission
# We set SCREAM_FAKE_AUTO to not interere with real baselines
cmd = self.get_cmd("PR_LABELS= NODE_NAME={} SCREAM_FAKE_AUTO=TRUE PULLREQUESTNUM= ./jenkins/jenkins_common.sh".format(self._machine),
- self._machine, dry_run=False)
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR)
else:
@@ -574,7 +510,7 @@ class TestTestAllScream(TestBaseOuter.TestBase):
if self._jenkins:
# Any fail will do, we already checked test-all-scream captures all the fail types
cmd = self.get_cmd("PR_LABELS= SCREAM_FORCE_CONFIG_FAIL=True NODE_NAME={} SCREAM_FAKE_AUTO=TRUE PULLREQUESTNUM=42 ./jenkins/jenkins_common.sh".format(self._machine),
- self._machine, dry_run=False)
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR, expect_works=False)
else:
@@ -587,7 +523,7 @@ class TestTestAllScream(TestBaseOuter.TestBase):
if self._jenkins:
# Any fail will do, we already checked test-all-scream captures all the fail types
cmd = self.get_cmd("PR_LABELS= SCREAM_FORCE_CONFIG_FAIL=True NODE_NAME={} SCREAM_FAKE_AUTO=TRUE PULLREQUESTNUM= ./jenkins/jenkins_common.sh".format(self._machine),
- self._machine, dry_run=False)
+ self._machine)
run_cmd_assert_result(self, cmd, from_dir=TEST_DIR, expect_works=False)
else:
@@ -598,7 +534,7 @@ class TestGatherAllData(TestBaseOuter.TestBase):
###############################################################################
CMDS_TO_TEST = [
- "./gather-all-data './scripts/test-all-scream -m $machine -b HEAD -k' -l -m $machine",
+ "./gather-all-data 'echo -m $machine' -l -m $machine",
]
def __init__(self, *internal_args):
@@ -637,27 +573,10 @@ OR
\033[1;32m# Run pylint tests for test_all_scream \033[0m
> {0} TestTestAllScream.test_pylint
- \033[1;32m# Do a dry-run generation for test_all_scream \033[0m
- > {0} -g TestTestAllScream -m $machine
-
- \033[1;32m# Do a dry-run comparison for test_all_scream \033[0m
- > {0} -c TestTestAllScream -m $machine
-
\033[1;32m# Do a full test run of test_all_scream \033[0m
> {0} -f -m $machine TestTestAllScream
- \033[1;32m# Do a full test run of everything \033[0m
- > {0} -f -m $machine
-
- \033[1;32m# Do a dry-run generation for everything \033[0m
- > {0} -g -m $machine
-
- \033[1;32m# Do a dry-run comparison for comparison \033[0m
- > {0} -c -m $machine
-
\033[1;32m# Run every possible test. This should be done before a PR is issued \033[0m
- > {0} -g -m $machine # You likely want to do this for a reference commit
- > {0} -c -m $machine
> {0} -f -m $machine
\033[1;32m# Test Jenkins script \033[0m
@@ -673,12 +592,6 @@ OR
parser.add_argument("-m", "--machine",
help="Provide machine name. This is required for full (not dry) runs")
- parser.add_argument("-g", "--generate", action="store_true",
- help="Do a dry run with baseline generation")
-
- parser.add_argument("-c", "--compare", action="store_true",
- help="Do a dry run with baseline comparison")
-
parser.add_argument("-f", "--full", action="store_true",
help="Do a full (not dry) run")
@@ -691,7 +604,7 @@ OR
return args
###############################################################################
-def scripts_tests(machine=None, generate=False, compare=False, full=False, jenkins=False):
+def scripts_tests(machine=None, full=False, jenkins=False):
###############################################################################
os.environ["SCREAM_FAKE_ONLY"] = "True"
@@ -700,9 +613,6 @@ def scripts_tests(machine=None, generate=False, compare=False, full=False, jenki
expect(is_machine_supported(machine), "Machine {} is not supported".format(machine))
CONFIG["machine"] = machine
- expect(not (generate and compare), "Cannot do generate and compare in the same run")
- CONFIG["compare"] = compare
- CONFIG["generate"] = generate
CONFIG["jenkins"] = jenkins
if full:
diff --git a/components/eamxx/scripts/test-all-scream b/components/eamxx/scripts/test-all-scream
index 4a6d0710b4e3..bb55ad23c216 100755
--- a/components/eamxx/scripts/test-all-scream
+++ b/components/eamxx/scripts/test-all-scream
@@ -16,6 +16,7 @@ check_minimum_python_version(3, 4)
import argparse, sys, pathlib
+from test_factory import get_test_name_dict
from test_all_scream import TestAllScream
###############################################################################
@@ -35,10 +36,6 @@ OR
> cd $scream_repo/components/eamxx
> ./scripts/{0} --preserve-env -m melvin
- \033[1;32m# Run all tests on current machine with default behavior except using a custom ref for baseline generation\033[0m
- > cd $scream_repo/components/eamxx
- > ./scripts/{0} -m melvin -b BASELINE_REF
-
\033[1;32m# Run all tests on current machine with default behavior except using pre-existing baselines (skips baseline generation) \033[0m
> cd $scream_repo/components/eamxx
> ./scripts/{0} -m melvin --baseline-dir=PATH_TO_BASELINES
@@ -49,7 +46,7 @@ OR
\033[1;32m# Run all tests on current machine with default behavior on a repo with uncommitted changes\033[0m
> cd $scream_repo/components/eamxx
- > ./scripts/{0} -m melvin -k -b HEAD
+ > ./scripts/{0} -m melvin -k -b AUTO
""".format(pathlib.Path(args[0]).name),
description=description,
formatter_class=argparse.ArgumentDefaultsHelpFormatter
@@ -63,17 +60,14 @@ OR
parser.add_argument("-p", "--parallel", action="store_true",
help="Launch the different build types stacks in parallel")
- parser.add_argument("-f", "--fast-fail", action="store_true",
- help="Stop testing when the first failure is detected")
-
- parser.add_argument("-b", "--baseline-ref", default=None, # default will be computed later
- help="What commit to use to generate baselines. Default is merge-base of current commit and origin/master (or HEAD if --keep-tree)")
+ parser.add_argument("-g", "--generate", action="store_true",
+ help="Instruct test-all-scream to generate baselines from current commit. Skips tests")
- parser.add_argument("--baseline-dir", default=None,
- help="Use baselines from the given directory, skip baseline creation.")
+ parser.add_argument("-b", "--baseline-dir", default=None,
+ help="Directory where baselines should be read from (or written to, if -g/-i is used)")
parser.add_argument("-u", "--update-expired-baselines", action="store_true",
- help="Update baselines that appear to be expired.")
+ help="Update baselines that appear to be expired (only used with -g)")
parser.add_argument("-m", "--machine",
help="Provide machine name. This is *always* required. It can, but does not"
@@ -86,9 +80,6 @@ OR
parser.add_argument("--config-only", action="store_true",
help="In the testing phase, only run config step, skip build and tests")
- parser.add_argument("-k", "--keep-tree", action="store_true",
- help="Allow to keep the current work tree when testing against HEAD (only valid with `-b HEAD`)")
-
parser.add_argument("-c", "--custom-cmake-opts", action="append", default=[],
help="Extra custom options to pass to cmake. Can use multiple times for multiple cmake options. The -D is added for you")
@@ -100,12 +91,12 @@ OR
parser.add_argument("--preserve-env", action="store_true",
help="Whether to skip machine env setup, and preserve the current user env (useful to manually test new modules)")
- choices_doc = ", ".join(["'{}' ({})".format(k, v) for k, v in TestAllScream.get_test_name_desc().items()])
+ choices_doc = ", ".join(["'{}' ({})".format(k, v) for k, v in get_test_name_dict().items()])
parser.add_argument("-t", "--test", dest="tests", action="append", default=[],
help=f"Only run specific test configurations, choices={choices_doc}")
parser.add_argument("-i", "--integration-test", action="store_true",
- help="Merge origin/master into this branch before testing.")
+ help="Merge origin/master into this branch before testing (implies -u).")
parser.add_argument("-l", "--local", action="store_true",
help="Allow to not specify a machine name, and have test-all-scream to look"
@@ -123,9 +114,6 @@ OR
parser.add_argument("--quick-rerun-failed", action="store_true",
help="Do not clean the build dir, and do not reconfigure. Just (incremental) build and retest failed tests only.")
- parser.add_argument("-d", "--dry-run", action="store_true",
- help="Do a dry run, commands will be printed but not executed")
-
parser.add_argument("--make-parallel-level", action="store", type=int, default=0,
help="Max number of jobs to be created during compilation. If not provided, use default for given machine.")
diff --git a/components/eamxx/scripts/test_all_scream.py b/components/eamxx/scripts/test_all_scream.py
index dfade8beda0d..ffbe70e94f68 100644
--- a/components/eamxx/scripts/test_all_scream.py
+++ b/components/eamxx/scripts/test_all_scream.py
@@ -1,6 +1,10 @@
-from utils import run_cmd, run_cmd_no_fail, expect, check_minimum_python_version, ensure_psutil
+from utils import run_cmd, run_cmd_no_fail, expect, check_minimum_python_version, ensure_psutil, \
+ SharedArea, safe_copy
from git_utils import get_current_head, get_current_commit, get_current_branch, is_repo_clean, \
- cleanup_repo, merge_git_ref, checkout_git_ref, git_refs_difference, print_last_commit
+ cleanup_repo, merge_git_ref, git_refs_difference, print_last_commit, \
+ create_backup_commit, checkout_git_ref
+
+from test_factory import create_tests, COV
from machines_specs import get_mach_compilation_resources, get_mach_testing_resources, \
get_mach_baseline_root_dir, setup_mach_env, is_cuda_machine, \
@@ -18,270 +22,19 @@
import psutil
import re
-from collections import OrderedDict
from pathlib import Path
-###############################################################################
-class TestProperty(object):
-###############################################################################
-
- """
- Parent class of predefined test types for SCREAM standalone. test-all-scream
- offers a number of customization points, but you may need to just use
- cmake if you need maximal customization. You can run test-all-scream --dry-run
- to get the corresponding cmake command which can then be used as a starting
- point for making your own cmake command.
- """
-
- def __init__(self, longname, description, cmake_args,
- uses_baselines=True, on_by_default=True, default_test_len=None):
- # What the user uses to select tests via test-all-scream CLI.
- # Should also match the class name when converted to caps
- self.shortname = type(self).__name__.lower()
-
- # A longer name used to name baseline and test directories for a test.
- # Also used in output/error messages to refer to the test
- self.longname = longname
-
- # A longer decription of the test
- self.description = description
-
- # Cmake config args for this test. Check that quoting is done with
- # single quotes.
- self.cmake_args = cmake_args
- for name, arg in self.cmake_args:
- expect('"' not in arg,
- f"In test definition for {longname}, found cmake args with double quotes {name}='{arg}'"
- "Please use single quotes if quotes are needed.")
-
- # Does the test do baseline testing
- self.uses_baselines = uses_baselines
-
- # Should this test be run if the user did not specify tests at all?
- self.on_by_default = on_by_default
-
- # Should this test have a default test size
- self.default_test_len = default_test_len
-
- #
- # Properties not set by constructor (Set by the main TestAllScream object)
- #
-
- # Resources used by this test.
- self.compile_res_count = None
- self.testing_res_count = None
-
- # Does this test need baselines
- self.missing_baselines = False
-
- #
- # Common
- #
-
- if not self.uses_baselines:
- self.cmake_args += [("SCREAM_ENABLE_BASELINE_TESTS", "False")]
-
- def disable_baselines(self):
- if self.uses_baselines:
- self.uses_baselines = False
- self.cmake_args += [("SCREAM_ENABLE_BASELINE_TESTS", "False")]
-
- # Tests will generally be referred to via their longname
- def __str__(self):
- return self.longname
-
-###############################################################################
-class DBG(TestProperty):
-###############################################################################
-
- CMAKE_ARGS = [("CMAKE_BUILD_TYPE", "Debug"), ("EKAT_DEFAULT_BFB", "True")]
-
- def __init__(self, _):
- TestProperty.__init__(
- self,
- "full_debug",
- "debug",
- self.CMAKE_ARGS,
- )
-
-###############################################################################
-class SP(TestProperty):
-###############################################################################
-
- def __init__(self, _):
- TestProperty.__init__(
- self,
- "full_sp_debug",
- "debug single precision",
- DBG.CMAKE_ARGS + [("SCREAM_DOUBLE_PRECISION", "False")],
- )
-
-###############################################################################
-class FPE(TestProperty):
-###############################################################################
-
- def __init__(self, tas):
- TestProperty.__init__(
- self,
- "debug_nopack_fpe",
- "debug pksize=1 floating point exceptions on",
- DBG.CMAKE_ARGS + [("SCREAM_PACK_SIZE", "1"), ("SCREAM_FPE","True")],
- uses_baselines=False,
- on_by_default=(tas is not None and not tas.on_cuda())
- )
-
-###############################################################################
-class OPT(TestProperty):
-###############################################################################
-
- def __init__(self, _):
- TestProperty.__init__(
- self,
- "release",
- "release",
- [("CMAKE_BUILD_TYPE", "Release")],
- )
-
-###############################################################################
-class COV(TestProperty):
-###############################################################################
-
- def __init__(self, _):
- TestProperty.__init__(
- self,
- "coverage",
- "debug coverage",
- [("CMAKE_BUILD_TYPE", "Debug"), ("EKAT_ENABLE_COVERAGE", "True")],
- uses_baselines=False,
- on_by_default=False,
- default_test_len="short"
- )
-
-###############################################################################
-class VALG(TestProperty):
-###############################################################################
-
- def __init__(self, tas):
- TestProperty.__init__(
- self,
- "valgrind",
- "debug with valgrind",
- [("CMAKE_BUILD_TYPE", "Debug"), ("EKAT_ENABLE_VALGRIND", "True")],
- uses_baselines=False,
- on_by_default=False,
- default_test_len="short"
- )
- if tas is not None:
- # If a stored suppression file exists for this machine, use it
- persistent_supp_file = tas.get_root_dir() / "scripts" / "jenkins" / "valgrind" / f"{tas.get_machine()}.supp"
- if persistent_supp_file.exists():
- self.cmake_args.append( ("EKAT_VALGRIND_SUPPRESSION_FILE", str(persistent_supp_file)) )
-
-###############################################################################
-class CSM(TestProperty):
-###############################################################################
-
- def __init__(self, _):
- TestProperty.__init__(
- self,
- "compute_sanitizer_memcheck",
- "debug with compute sanitizer memcheck",
- [("CMAKE_BUILD_TYPE", "Debug"),
- ("EKAT_ENABLE_COMPUTE_SANITIZER", "True"),
- ("EKAT_COMPUTE_SANITIZER_OPTIONS", "--tool=memcheck")],
- uses_baselines=False,
- on_by_default=False,
- default_test_len="short"
- )
-
-###############################################################################
-class CSR(TestProperty):
-###############################################################################
-
- def __init__(self, _):
- TestProperty.__init__(
- self,
- "compute_sanitizer_racecheck",
- "debug with compute sanitizer racecheck",
- [("CMAKE_BUILD_TYPE", "Debug"),
- ("EKAT_ENABLE_COMPUTE_SANITIZER", "True"),
- ("EKAT_COMPUTE_SANITIZER_OPTIONS", "'--tool=racecheck --racecheck-detect-level=error'")],
- uses_baselines=False,
- on_by_default=False,
- default_test_len="short"
- )
-
-###############################################################################
-class CSI(TestProperty):
-###############################################################################
-
- def __init__(self, _):
- TestProperty.__init__(
- self,
- "compute_sanitizer_initcheck",
- "debug with compute sanitizer initcheck",
- [("CMAKE_BUILD_TYPE", "Debug"),
- ("EKAT_ENABLE_COMPUTE_SANITIZER", "True"),
- ("EKAT_COMPUTE_SANITIZER_OPTIONS", "--tool=initcheck")],
- uses_baselines=False,
- on_by_default=False,
- default_test_len="short"
- )
-
-###############################################################################
-class CSS(TestProperty):
-###############################################################################
-
- def __init__(self, _):
- TestProperty.__init__(
- self,
- "compute_sanitizer_synccheck",
- "debug with compute sanitizer synccheck",
- [("CMAKE_BUILD_TYPE", "Debug"),
- ("EKAT_ENABLE_COMPUTE_SANITIZER", "True"),
- ("EKAT_COMPUTE_SANITIZER_OPTIONS", "--tool=synccheck")],
- uses_baselines=False,
- on_by_default=False,
- default_test_len="short"
- )
-
-###############################################################################
-def test_factory(user_req_tests, tas):
-###############################################################################
- testclasses = TestProperty.__subclasses__()
- if not user_req_tests:
- result = [testclass(tas) for testclass in testclasses
- if testclass(tas).on_by_default]
- else:
- valid_names = [testclass(tas).shortname for testclass in testclasses]
- for user_req_test in user_req_tests:
- expect(user_req_test in valid_names, f"'{user_req_test}' is not a known test")
-
- result = [testclass(tas) for testclass in testclasses if testclass(tas).shortname in user_req_tests]
-
- return result
-
###############################################################################
class TestAllScream(object):
###############################################################################
- ###########################################################################
- @classmethod
- def get_test_name_desc(cls):
- ###########################################################################
- """
- Returns a dict mapping short test names to full names
- """
- testclasses = TestProperty.__subclasses__()
- return OrderedDict([(testc(None).shortname, testc(None).description) for testc in testclasses])
-
###########################################################################
def __init__(self, cxx_compiler=None, f90_compiler=None, c_compiler=None,
- submit=False, parallel=False, fast_fail=False,
- baseline_ref=None, baseline_dir=None, machine=None, no_tests=False, config_only=False, keep_tree=False,
+ submit=False, parallel=False, generate=False, no_tests=False,
+ baseline_dir=None, machine=None, config_only=False,
custom_cmake_opts=(), custom_env_vars=(), preserve_env=False, tests=(),
integration_test=False, local=False, root_dir=None, work_dir=None,
- quick_rerun=False,quick_rerun_failed=False,dry_run=False,
+ quick_rerun=False,quick_rerun_failed=False,
make_parallel_level=0, ctest_parallel_level=0, update_expired_baselines=False,
extra_verbose=False, limit_test_regex=None, test_level="at", test_size=None,
force_baseline_regen=False):
@@ -299,13 +52,10 @@ def __init__(self, cxx_compiler=None, f90_compiler=None, c_compiler=None,
self._c_compiler = c_compiler
self._submit = submit
self._parallel = parallel
- self._fast_fail = fast_fail
- self._baseline_ref = baseline_ref
self._machine = machine
self._local = local
- self._perform_tests = not no_tests
+ self._run_tests = not no_tests
self._config_only = config_only
- self._keep_tree = keep_tree
self._baseline_dir = baseline_dir
self._custom_cmake_opts = custom_cmake_opts
self._custom_env_vars = custom_env_vars
@@ -315,15 +65,16 @@ def __init__(self, cxx_compiler=None, f90_compiler=None, c_compiler=None,
self._integration_test = integration_test
self._quick_rerun = quick_rerun
self._quick_rerun_failed = quick_rerun_failed
- self._dry_run = dry_run
- self._update_expired_baselines= update_expired_baselines
self._extra_verbose = extra_verbose
self._limit_test_regex = limit_test_regex
self._test_level = test_level
self._test_size = test_size
self._force_baseline_regen = force_baseline_regen
-
- # Not all builds are ment to perform comparisons against pre-built baselines
+ # Integration test always updates expired baselines
+ self._update_expired_baselines= update_expired_baselines or self._integration_test or self._force_baseline_regen
+ # If we are to update expired baselines, then we must run the generate phase
+ # NOTE: the gen phase will do nothing if baselines are present and not expired
+ self._generate = generate or self._update_expired_baselines
if self._quick_rerun_failed:
self._quick_rerun = True
@@ -355,30 +106,22 @@ def __init__(self, cxx_compiler=None, f90_compiler=None, c_compiler=None,
self._root_dir = Path(__file__).resolve().parent.parent
else:
self._root_dir = Path(self._root_dir).resolve()
- expect(self._root_dir.is_dir() and self._root_dir.parts()[-2:] == ("scream", "components"),
- f"Bad root-dir '{self._root_dir}', should be: $scream_repo/components/eamxx")
+ expect(self._root_dir.is_dir() and list(self._root_dir.parts)[-2:] == ["components","eamxx"],
+ f"Bad root-dir '{self._root_dir}', should end with: /components/eamxx")
# Make our test objects! Change mem to default mem-check test for current platform
if "mem" in tests:
tests[tests.index("mem")] = "csm" if self.on_cuda() else "valg"
- self._tests = test_factory(tests, self)
+ self._tests = create_tests(tests, self)
if self._work_dir is not None:
self._work_dir = Path(self._work_dir).absolute()
- expect(self._work_dir.is_dir(),
- f"Error! Work directory '{self._work_dir}' does not exist.")
else:
self._work_dir = self._root_dir.absolute().joinpath("ctest-build")
- self._work_dir.mkdir(exist_ok=True)
- os.chdir(str(self._root_dir)) # needed, or else every git command will need repo=root_dir
- expect(get_current_commit(), f"Root dir: {self._root_dir}, does not appear to be a git repo")
-
- # Print some info on the branch
- self._original_branch = get_current_branch()
- self._original_commit = get_current_commit()
+ self._work_dir.mkdir(parents=True, exist_ok=True)
- print_last_commit(git_ref=self._original_branch, dry_run=self._dry_run)
+ os.chdir(str(self._root_dir)) # needed, or else every git command will need repo=root_dir
###################################
# Compilation/testing resources #
@@ -445,80 +188,84 @@ def __init__(self, cxx_compiler=None, f90_compiler=None, c_compiler=None,
# Setup the env on this machine
setup_mach_env(self._machine, ctest_j=ctest_max_jobs)
+ ############################################
+ # Check repo status #
+ ############################################
+
+ expect(get_current_commit(), f"Root dir: {self._root_dir}, does not appear to be a git repo")
+
+ # Get git status info. Besides printing this info, we will need it to restore the repo initial
+ # configuration if we are running an integration test (where baselines need to be created
+ # from the origin/master commit)
+ self._original_branch = get_current_branch()
+ self._original_commit = get_current_commit()
+
+ print_last_commit(git_ref=self._original_branch)
+
+ # If we have an integration test, we need to merge master. Hence, do two things:
+ # 1) create bkp commit for all uncommitted/unstaged changes
+ # 2) save commit, so we can undo the merge after testing
+ self._has_backup_commit = False
+ if self._integration_test:
+ if not is_repo_clean():
+ # Back up work in a temporary commit
+ create_backup_commit()
+ self._has_backup_commit = True
+
+ self._original_commit = get_current_commit()
+
###################################
# Compute baseline info #
###################################
expect (not self._baseline_dir or self._work_dir != self._baseline_dir,
- f"Error! For your safety, do NOT use '{self._work_dir}' to store baselines. Move them to a different directory (even a subdirectory if that works).")
-
- # If no baseline ref/dir was provided, use default master baseline dir for this machine
- # NOTE: if user specifies baseline ref, baseline dir will be set later to a path within work dir
- if self._baseline_dir is None and self._baseline_ref is None:
- self._baseline_dir = "AUTO"
- print ("No '--baseline-dir XYZ' nor '-b XYZ' provided. Testing against default baselines dir for this machine.")
-
- # If -k was used, make sure it's allowed
- if self._keep_tree:
- expect(not self._integration_test, "Should not be doing keep-tree with integration testing")
- print("WARNING! You have uncommitted changes in your repo.",
- " The PASS/FAIL status may depend on these changes",
- " so if you want to keep them, don't forget to create a commit.",sep="\n")
- if self._baseline_dir is None:
- # Make sure the baseline ref is HEAD
- expect(self._baseline_ref == "HEAD",
- "The option --keep-tree is only available when testing against pre-built baselines "
- "(--baseline-dir) or HEAD (-b HEAD)")
+ f"Error! For your safety, do NOT use '{self._work_dir}' (the work_dir) to store baselines. Move them to a different directory (even a subdirectory if that works).")
+
+ # These two dir are special dir for "on-the-fly baselines" and "machine's official baselines"
+ local_baseline_dir = self._work_dir/"baselines"
+ auto_dir = Path(get_mach_baseline_root_dir(self._machine)).absolute()
+ # Handle the "fake" auto case, used in scripts tests
+ if "SCREAM_FAKE_AUTO" in os.environ:
+ auto_dir = auto_dir / "fake"
+
+ if self._baseline_dir == "LOCAL":
+ self._baseline_dir = local_baseline_dir
+ elif self._baseline_dir == "AUTO":
+ self._baseline_dir = auto_dir
+ elif self._baseline_dir is None:
+ if self._generate and not self._integration_test:
+ print ("No '--baseline-dir XYZ' provided. Baselines will be generated in {local_baseline_dir}.")
+ print ("NOTE: test-all-scream will proceed as if --force-baseline-regen was passed")
+ self._baseline_dir = local_baseline_dir
+ self._force_baseline_regen = True
+ self._update_expired_baselines = True
else:
- # Make sure the baseline ref is unset (or HEAD)
- expect(self._baseline_ref is None or self._baseline_ref == "HEAD",
- "The option --keep-tree is only available when testing against pre-built baselines "
- "(--baseline-dir) or HEAD (-b HEAD)")
- else:
- expect(self._dry_run or is_repo_clean(),
- "Repo must be clean before running. If testing against HEAD or pre-built baselines, "
- "you can pass `--keep-tree` to allow non-clean repo.")
+ print ("No '--baseline-dir XYZ' provided. Testing against default baselines dir for this machine.")
+ self._baseline_dir = auto_dir
- # For integration test, enforce baseline_ref==origin/master, and proceed to merge origin/master
- if self._integration_test:
- expect (self._baseline_ref is None or self._baseline_ref=="origin/master",
- "Error! Integration tests cannot be done against an arbitrary baseline ref.")
+ self._baseline_dir = Path(self._baseline_dir).absolute()
- # Set baseline ref and merge it
- self._baseline_ref = "origin/master"
- merge_git_ref(git_ref=self._baseline_ref, verbose=True, dry_run=self._dry_run)
+ # Only integration tests can overwrite the mach-specific baselines
+ if self._baseline_dir==auto_dir:
+ expect (not self._generate or self._integration_test or self._force_baseline_regen,
+ "You are not allowed to overwrite baselines in AUTO dir folder. Only -i and --force-baseline-regen can do that\n"
+ f" AUTO dir: {auto_dir}")
- # Always update expired baselines if this is an integration test
- self._update_expired_baselines = True
+ # Make the baseline dir, if not already existing.
+ if self._generate:
+ self.create_tests_dirs(self._baseline_dir, clean=False)
- # By now, we should have at least one between baseline_dir and baseline_ref set (possibly both)
- default_baselines_root_dir = self._work_dir/"baselines"
- if self._baseline_dir is None:
- # Use default baseline dir, and create it if necessary
- self._baseline_dir = Path(default_baselines_root_dir).absolute()
- self.create_tests_dirs(self._baseline_dir, True) # Wipe out previous baselines
+ # For now, assume baselines are generated from HEAD. If -i was used, we'll change this
+ self._baseline_ref = "origin/master" if self._integration_test else self._original_commit
- else:
- if self._baseline_dir == "AUTO":
- expect (self._baseline_ref is None or self._baseline_ref == "origin/master",
- "Do not specify `-b XYZ` when using `--baseline-dir AUTO`. The AUTO baseline dir should be used for the master baselines only.\n"
- " `-b XYZ` needs to probably build baselines for ref XYZ. However, no baselines will be built if the dir already contains baselines.\n")
- # We treat the "AUTO" string as a request for automatic baseline dir.
- auto_dir = get_mach_baseline_root_dir(self._machine)
- self._baseline_dir = Path(auto_dir) if auto_dir else default_baselines_root_dir
- if "SCREAM_FAKE_AUTO" in os.environ:
- self._baseline_dir = self._baseline_dir/"fake"
- else:
- self._baseline_dir = Path(self._baseline_dir).absolute()
-
- # Make sure the baseline folders exist (but do not purge content if they exist)
- self.create_tests_dirs(self._baseline_dir, False)
-
- # Do not do baseline operations if mem checking is on
+ # Check baselines status
print (f"Checking baselines directory: {self._baseline_dir}")
- self.baselines_are_present()
+ missing_baselines = self.check_baselines_are_present()
+ expect (len(missing_baselines)==0 or self._generate,
+ f"Missing baselines for builds {missing_baselines}. Re-run with -g to generate them")
+
if self._update_expired_baselines:
- self.baselines_are_expired()
+ self.check_baselines_are_expired()
############################################
# Deduce compilers if needed/possible #
@@ -531,16 +278,11 @@ def __init__(self, cxx_compiler=None, f90_compiler=None, c_compiler=None,
if self._c_compiler is None:
self._c_compiler = get_mach_c_compiler(self._machine)
- if not self._dry_run:
- self._f90_compiler = run_cmd_no_fail(f"which {self._f90_compiler}")
- self._cxx_compiler = run_cmd_no_fail(f"which {self._cxx_compiler}")
- self._c_compiler = run_cmd_no_fail(f"which {self._c_compiler}")
-
###############################################################################
def create_tests_dirs(self, root, clean):
###############################################################################
- # Make sure the baseline root directory exists
+ # Make sure the tests root directory exists
root.mkdir(parents=True,exist_ok=True)
# Create build directories (one per test)
@@ -553,9 +295,11 @@ def create_tests_dirs(self, root, clean):
# TypeError: lstat: illegal type for path parameter
shutil.rmtree(str(test_dir))
- # Create this baseline's build dir
- if not test_dir.exists():
- test_dir.mkdir(parents=True)
+ # Create this built type's build dir (if not already existing)
+ test_dir.mkdir(parents=True,exist_ok=True)
+
+ # Create the 'data' subdir (if not already existing)
+ (test_dir / "data").mkdir(parents=False,exist_ok=True)
###############################################################################
def get_baseline_file_sha(self, test):
@@ -568,8 +312,9 @@ def get_baseline_file_sha(self, test):
return None
###############################################################################
- def set_baseline_file_sha(self, test, sha):
+ def set_baseline_file_sha(self, test):
###############################################################################
+ sha = get_current_commit()
baseline_file = (self.get_preexisting_baseline(test).parent)/"baseline_git_sha"
with baseline_file.open("w", encoding="utf-8") as fd:
return fd.write(sha)
@@ -601,7 +346,7 @@ def get_preexisting_baseline(self, test):
return self._baseline_dir/str(test)/"data"
###############################################################################
- def baselines_are_present(self):
+ def check_baselines_are_present(self):
###############################################################################
"""
Check that all baselines are present (one subdir for all values of self._tests)
@@ -611,19 +356,23 @@ def baselines_are_present(self):
expect(self._baseline_dir is not None,
"Error! Baseline directory not correctly set.")
+ missing = []
for test in self._tests:
if test.uses_baselines:
data_dir = self.get_preexisting_baseline(test)
if not data_dir.is_dir():
- test.missing_baselines = True
+ test.baselines_missing = True
+ missing += [test.longname]
print(f" -> Test {test} is missing baselines")
else:
print(f" -> Test {test} appears to have baselines")
else:
print(f" -> Test {test} does not use baselines")
+ return missing
+
###############################################################################
- def baselines_are_expired(self):
+ def check_baselines_are_expired(self):
###############################################################################
"""
Baselines are expired if either:
@@ -632,40 +381,50 @@ def baselines_are_expired(self):
"""
baseline_ref_sha = get_current_commit(commit=self._baseline_ref)
- # Sanity check
- expect(self._baseline_dir is not None, "Error! This routine should only be called when testing against pre-existing baselines.")
-
for test in self._tests:
- if test.uses_baselines and not test.missing_baselines:
- # this test is not missing a baseline, but it may be expired.
-
- baseline_file_sha = self.get_baseline_file_sha(test)
- if baseline_file_sha is None:
- test.missing_baselines = True
- print(f" -> Test {test} has no stored sha so must be considered expired")
- else:
- num_ref_is_behind_file, num_ref_is_ahead_file = git_refs_difference(baseline_file_sha, baseline_ref_sha)
-
- # If the copy in our repo is behind, then we need to update the repo
- expect (num_ref_is_behind_file==0 or not self._integration_test,
+ if not test.uses_baselines or test.baselines_missing:
+ continue
+
+ if self._force_baseline_regen:
+ test.baselines_expired = True
+ print(f" -> Test {test} baselines are expired because self._force_baseline_regen=True")
+ continue
+
+ # this test is not missing a baseline, but it may be expired.
+ baseline_file_sha = self.get_baseline_file_sha(test)
+ if baseline_file_sha is None:
+ test.baselines_missing = True
+ print(f" -> Test {test} has no stored sha so must be considered expired")
+ continue
+
+ # There is a sha file, so check how it compares with self._baseline_ref
+ try:
+ num_ref_is_behind_file, num_ref_is_ahead_file = git_refs_difference(baseline_file_sha, baseline_ref_sha)
+ except SystemExit as e:
+ test.baselines_expired = True
+ reason = f"Failed to get refs difference between {baseline_file_sha} and {baseline_ref_sha} because: {e}"
+ print(f" -> Test {test} baselines are expired because {reason}")
+ continue
+
+ # If the copy in our repo is behind, then we need to update the repo
+ expect (num_ref_is_behind_file==0 or not self._integration_test,
f"""Error! Your repo seems stale, since the baseline sha in your repo is behind
the one last used to generated them. We do *not* allow an integration
test to replace baselines with older ones, for security reasons.
If this is a legitimate case where baselines need to be 'rewound',
e.g. b/c of a (hopefully VERY RARE) force push to master, then
remove existing baselines first. Otherwise, please run 'git fetch $remote'.
- - baseline_ref: {self._baseline_ref}
- - repo baseline sha: {baseline_ref_sha}
- - last used baseline sha: {baseline_file_sha}""")
-
- # If the copy in our repo is not ahead, then baselines are not expired
- if num_ref_is_ahead_file > 0 or self._force_baseline_regen:
- test.missing_baselines = True
- reason = "forcing baseline regen" if self._force_baseline_regen \
- else f"{self._baseline_ref} is ahead of the baseline commit by {num_ref_is_ahead_file}"
- print(f" -> Test {test} baselines are expired because {reason}")
- else:
- print(f" -> Test {test} baselines are valid and do not need to be regenerated")
+- baseline_ref: {self._baseline_ref}
+- repo baseline sha: {baseline_ref_sha}
+- last used baseline sha: {baseline_file_sha}""")
+
+ # If the copy in our repo is ahead, then baselines are expired
+ if num_ref_is_ahead_file > 0:
+ test.baselines_expired = True
+ reason = f"{self._baseline_ref} is ahead of the existing baseline commit {baseline_file_sha} by {num_ref_is_ahead_file}"
+ print(f" -> Test {test} baselines are expired because {reason}")
+ else:
+ print(f" -> Test {test} baselines are valid and do not need to be regenerated")
###############################################################################
def get_machine_file(self):
@@ -691,6 +450,9 @@ def generate_cmake_config(self, test, for_ctest=False):
stat, c_path, _ = run_cmd("nc-config --prefix")
if stat == 0:
result += f" -DNetCDF_C_PATH={c_path}"
+ stat, pc_path, _ = run_cmd("pnetcdf-config --prefix")
+ if stat == 0:
+ result += f" -DPnetCDF_C_PATH={pc_path}"
# Test-specific cmake options
for key, value in test.cmake_args:
@@ -815,7 +577,7 @@ def generate_ctest_config(self, cmake_config, extra_configs, test):
result += f"--resource-spec-file {test_dir}/ctest_resource_file.json "
if self._baseline_dir is not None and test.uses_baselines:
- cmake_config += f" -DSCREAM_TEST_DATA_DIR={self.get_preexisting_baseline(test)}"
+ cmake_config += f" -DSCREAM_BASELINES_DIR={self.get_preexisting_baseline(test).parent}"
if not self._submit:
result += "-DNO_SUBMIT=True "
@@ -847,91 +609,111 @@ def generate_ctest_config(self, cmake_config, extra_configs, test):
return result
###############################################################################
- def generate_baselines(self, test, commit):
+ def generate_baselines(self, test):
###############################################################################
expect(test.uses_baselines,
f"Something is off. generate_baseline should have not be called for test {test}")
- test_dir = self.get_test_dir(self._baseline_dir, test)
+ baseline_dir = self.get_test_dir(self._baseline_dir, test)
+ test_dir = self.get_test_dir(self._work_dir / "tas_baseline_build", test)
+ if test_dir.exists():
+ shutil.rmtree(test_dir)
+ test_dir.mkdir()
+ num_test_res = self.create_ctest_resource_file(test,test_dir)
cmake_config = self.generate_cmake_config(test)
- cmake_config += " -DSCREAM_BASELINES_ONLY=ON"
- cmake_config += f" -DSCREAM_TEST_DATA_DIR={test_dir}/data"
+ cmake_config += " -DSCREAM_ONLY_GENERATE_BASELINES=ON"
+ cmake_config += f" -DSCREAM_BASELINES_DIR={baseline_dir}"
+ cmake_config += f" -DSCREAM_TEST_MAX_TOTAL_THREADS={num_test_res}"
print("===============================================================================")
print(f"Generating baseline for test {test} with config '{cmake_config}'")
print("===============================================================================")
- success = True
+ # We cannot just crash if we fail to generate baselines, since we would
+ # not get a dashboard report if we did that. Instead, just ensure there is
+ # no baseline file to compare against if there's a problem.
+ stat, _, err = run_cmd(f"{cmake_config} {self._root_dir}",
+ from_dir=test_dir, verbose=True)
+ if stat != 0:
+ print (f"WARNING: Failed to create baselines (config phase):\n{err}")
+ return False
- try:
- # We cannot just crash if we fail to generate baselines, since we would
- # not get a dashboard report if we did that. Instead, just ensure there is
- # no baseline file to compare against if there's a problem.
- stat, _, err = run_cmd(f"{cmake_config} {self._root_dir}",
- from_dir=test_dir, verbose=True, dry_run=self._dry_run)
- if stat != 0:
- print (f"WARNING: Failed to configure baselines:\n{err}")
- success = False
+ cmd = f"make -j{test.compile_res_count}"
+ if self._parallel:
+ start, end = self.get_taskset_range(test)
+ cmd = f"taskset -c {start}-{end} sh -c '{cmd}'"
- else:
- cmd = f"make -j{test.compile_res_count} && make -j{test.testing_res_count} baseline"
- if self._parallel:
- start, end = self.get_taskset_range(test)
- cmd = f"taskset -c {start}-{end} sh -c '{cmd}'"
+ stat, _, err = run_cmd(cmd, from_dir=test_dir, verbose=True)
- stat, _, err = run_cmd(cmd, from_dir=test_dir, verbose=True, dry_run=self._dry_run)
+ if stat != 0:
+ print (f"WARNING: Failed to create baselines (build phase):\n{err}")
+ return False
- if stat != 0:
- print(f"WARNING: Failed to create baselines:\n{err}")
- success = False
+ cmd = f"ctest -j{test.testing_res_count}"
+ cmd += " -L baseline_gen"
+ cmd += f" --resource-spec-file {test_dir}/ctest_resource_file.json"
+ stat, _, err = run_cmd(cmd, from_dir=test_dir, verbose=True)
- finally:
- # Clean up the directory, by removing everything but the 'data' subfolder. This must
- # happen unconditionally or else subsequent runs could be corrupted
- run_cmd_no_fail(r"find -maxdepth 1 -not -name data ! -path . -exec rm -rf {} \;",
- from_dir=test_dir, verbose=True, dry_run=self._dry_run)
+ if stat != 0:
+ print (f"WARNING: Failed to create baselines (run phase):\n{err}")
+ return False
- if success:
- # Store the sha used for baselines generation
- self.set_baseline_file_sha(test, commit)
- test.missing_baselines = False
+ # Read list of nc files to copy to baseline dir
+ with open(test_dir/"data/baseline_list","r",encoding="utf-8") as fd:
+ files = fd.read().splitlines()
- return success
+ with SharedArea():
+ for fn in files:
+ # In case appending to the file leaves an empty line at the end
+ if fn != "":
+ src = Path(fn)
+ dst = baseline_dir / "data" / src.name
+ safe_copy(src, dst)
+
+ # Store the sha used for baselines generation
+ self.set_baseline_file_sha(test)
+ test.baselines_missing = False
+
+ # Clean up the directory by removing everything
+ shutil.rmtree(test_dir)
+
+ return True
###############################################################################
def generate_all_baselines(self):
###############################################################################
- git_head_ref = get_current_head()
+
+ tests_needing_baselines = self.baselines_to_be_generated()
+ if len(tests_needing_baselines)==0:
+ return True
+
+ # Switch to baseline ref
+ checkout_git_ref (self._baseline_ref)
print("###############################################################################")
- print(f"Generating baselines for ref {self._baseline_ref}")
+ print(f"Generating baselines from git ref {self._baseline_ref}")
print("###############################################################################")
- commit = get_current_commit(commit=self._baseline_ref)
-
- # Switch to the baseline commit
- checkout_git_ref(self._baseline_ref, verbose=True, dry_run=self._dry_run)
+ tas_baseline_bld = self._work_dir / "tas_baseline_build"
+ if tas_baseline_bld.exists():
+ shutil.rmtree(tas_baseline_bld)
+ tas_baseline_bld.mkdir()
success = True
- tests_needing_baselines = [test for test in self._tests if test.missing_baselines]
num_workers = len(tests_needing_baselines) if self._parallel else 1
with threading3.ProcessPoolExecutor(max_workers=num_workers) as executor:
future_to_test = {
- executor.submit(self.generate_baselines, test, commit) : test
+ executor.submit(self.generate_baselines, test) : test
for test in tests_needing_baselines}
for future in threading3.as_completed(future_to_test):
test = future_to_test[future]
success &= future.result()
- if not success and self._fast_fail:
- print(f"Generation of baselines for test {test} failed")
- return False
-
- # Switch back to the branch commit
- checkout_git_ref(git_head_ref, verbose=True, dry_run=self._dry_run)
+ # Restore original commit
+ checkout_git_ref (self._original_commit)
return success
@@ -957,12 +739,13 @@ def run_test(self, test):
if self._quick_rerun_failed:
ctest_config += "--rerun-failed "
else:
- # This directory might have been used also to build the model to generate baselines.
+ # This directory might have been used before during another test-all-scream run.
# Although it's ok to build in the same dir, we MUST make sure to erase cmake's cache
- # and internal files from the previous build (CMakeCache.txt and CMakeFiles folder)
- run_cmd_no_fail("rm -rf CMake*", from_dir=test_dir, dry_run=self._dry_run)
+ # and internal files from the previous build (CMakeCache.txt and CMakeFiles folder),
+ # Otherwise, we may not pick up changes in certain cmake vars that are already cached.
+ run_cmd_no_fail("rm -rf CMake*", from_dir=test_dir)
- success = run_cmd(ctest_config, from_dir=test_dir, arg_stdout=None, arg_stderr=None, verbose=True, dry_run=self._dry_run)[0] == 0
+ success = run_cmd(ctest_config, from_dir=test_dir, arg_stdout=None, arg_stderr=None, verbose=True)[0] == 0
return success
@@ -973,9 +756,6 @@ def run_all_tests(self):
print("Running tests!")
print("###############################################################################")
- # First, create build directories (one per test). If existing, nuke the content
- self.create_tests_dirs(self._work_dir, not self._quick_rerun)
-
success = True
tests_success = {
test : False
@@ -991,10 +771,6 @@ def run_all_tests(self):
test = future_to_test[future]
tests_success[test] = future.result()
success &= tests_success[test]
- # If failed, and fast fail is requested, return immediately
- # Note: this is effective only if num_worksers=1
- if not success and self._fast_fail:
- break
for t,s in tests_success.items():
if not s:
@@ -1049,6 +825,23 @@ def get_last_ctest_file(self,test,phase):
else:
return None
+ ###############################################################################
+ def baselines_to_be_generated(self):
+ ###############################################################################
+ """
+ Return list of baselines to generate. Baselines need to be generated if
+ - they are missing
+ - they are expired and we asked to update expired baselines
+ """
+ ret = []
+ for test in self._tests:
+ if test.baselines_missing:
+ ret.append(test)
+ elif self._update_expired_baselines and test.baselines_expired:
+ ret.append(test)
+
+ return ret
+
###############################################################################
def test_all_scream(self):
###############################################################################
@@ -1060,25 +853,30 @@ def test_all_scream(self):
success = True
try:
- # If needed, generate baselines first
- tests_needing_baselines = [test for test in self._tests if test.missing_baselines]
- if tests_needing_baselines:
- expect(self._baseline_ref is not None, "Missing baseline ref")
+ if self._integration_test:
+ # Merge origin/master
+ merge_git_ref(git_ref=self._baseline_ref, verbose=True)
+
+ if self._generate:
success = self.generate_all_baselines()
if not success:
print ("Error(s) occurred during baselines generation phase")
+
+ # Do not continue testing, as you may be testing against old/invalid baselines
return False
- # If requested, run tests
- if self._perform_tests:
+ if self._run_tests:
+ # First, create build directories (one per test). If existing, nuke the content
+ self.create_tests_dirs(self._work_dir, not self._quick_rerun)
+
success &= self.run_all_tests()
if not success:
print ("Error(s) occurred during test phase")
finally:
- if not self._keep_tree:
- # Cleanup the repo if needed
- cleanup_repo(self._original_branch, self._original_commit, dry_run=self._dry_run)
+ # Cleanup the repo if needed
+ if self._original_commit!=get_current_commit():
+ cleanup_repo(self._original_branch, self._original_commit, self._has_backup_commit)
return success
diff --git a/components/eamxx/scripts/test_factory.py b/components/eamxx/scripts/test_factory.py
new file mode 100644
index 000000000000..3c480e3c6d8b
--- /dev/null
+++ b/components/eamxx/scripts/test_factory.py
@@ -0,0 +1,258 @@
+# This module contains classes that describe a test type for test-all-scream
+# Each test type (here represented by a TestProperty object) can have different
+# flags, build type, profiling, cmake options, etc.
+# The function "test_factory" can be used to get a list of test types from
+# their string representation.
+
+from collections import OrderedDict
+from utils import expect
+
+###############################################################################
+class TestProperty(object):
+###############################################################################
+
+ """
+ Parent class of predefined test types for SCREAM standalone. test-all-scream
+ offers a number of customization points, but you may need to just use
+ cmake if you need maximal customization. You can run test-all-scream --dry-run
+ to get the corresponding cmake command which can then be used as a starting
+ point for making your own cmake command.
+ """
+
+ def __init__(self, longname, description, cmake_args,
+ uses_baselines=True, on_by_default=True, default_test_len=None):
+ # What the user uses to select tests via test-all-scream CLI.
+ # Should also match the class name when converted to caps
+ self.shortname = type(self).__name__.lower()
+
+ # A longer name used to name baseline and test directories for a test.
+ # Also used in output/error messages to refer to the test
+ self.longname = longname
+
+ # A longer decription of the test
+ self.description = description
+
+ # Cmake config args for this test. Check that quoting is done with
+ # single quotes.
+ self.cmake_args = cmake_args
+ for name, arg in self.cmake_args:
+ expect('"' not in arg,
+ f"In test definition for {longname}, found cmake args with double quotes {name}='{arg}'"
+ "Please use single quotes if quotes are needed.")
+
+ # Does the test do baseline testing
+ self.uses_baselines = uses_baselines
+
+ # Should this test be run if the user did not specify tests at all?
+ self.on_by_default = on_by_default
+
+ # Should this test have a default test size
+ self.default_test_len = default_test_len
+
+ #
+ # Properties not set by constructor (Set by the main TestAllScream object)
+ #
+
+ # Resources used by this test.
+ self.compile_res_count = None
+ self.testing_res_count = None
+
+ # Does this test need baselines
+ self.baselines_missing = False
+ self.baselines_expired = False
+
+ #
+ # Common
+ #
+
+ if not self.uses_baselines:
+ self.cmake_args += [("SCREAM_ENABLE_BASELINE_TESTS", "False")]
+
+ def disable_baselines(self):
+ if self.uses_baselines:
+ self.uses_baselines = False
+ self.cmake_args += [("SCREAM_ENABLE_BASELINE_TESTS", "False")]
+
+ # Tests will generally be referred to via their longname
+ def __str__(self):
+ return self.longname
+
+###############################################################################
+class DBG(TestProperty):
+###############################################################################
+
+ CMAKE_ARGS = [("CMAKE_BUILD_TYPE", "Debug"), ("EKAT_DEFAULT_BFB", "True")]
+
+ def __init__(self, _):
+ TestProperty.__init__(
+ self,
+ "full_debug",
+ "debug",
+ self.CMAKE_ARGS,
+ )
+
+###############################################################################
+class SP(TestProperty):
+###############################################################################
+
+ def __init__(self, _):
+ TestProperty.__init__(
+ self,
+ "full_sp_debug",
+ "debug single precision",
+ DBG.CMAKE_ARGS + [("SCREAM_DOUBLE_PRECISION", "False")],
+ )
+
+###############################################################################
+class FPE(TestProperty):
+###############################################################################
+
+ def __init__(self, tas):
+ TestProperty.__init__(
+ self,
+ "debug_nopack_fpe",
+ "debug pksize=1 floating point exceptions on",
+ DBG.CMAKE_ARGS + [("SCREAM_PACK_SIZE", "1"), ("SCREAM_FPE","True")],
+ uses_baselines=False,
+ on_by_default=(tas is not None and not tas.on_cuda())
+ )
+
+###############################################################################
+class OPT(TestProperty):
+###############################################################################
+
+ def __init__(self, _):
+ TestProperty.__init__(
+ self,
+ "release",
+ "release",
+ [("CMAKE_BUILD_TYPE", "Release")],
+ )
+
+###############################################################################
+class COV(TestProperty):
+###############################################################################
+
+ def __init__(self, _):
+ TestProperty.__init__(
+ self,
+ "coverage",
+ "debug coverage",
+ [("CMAKE_BUILD_TYPE", "Debug"), ("EKAT_ENABLE_COVERAGE", "True")],
+ uses_baselines=False,
+ on_by_default=False,
+ default_test_len="short"
+ )
+
+###############################################################################
+class VALG(TestProperty):
+###############################################################################
+
+ def __init__(self, tas):
+ TestProperty.__init__(
+ self,
+ "valgrind",
+ "debug with valgrind",
+ [("CMAKE_BUILD_TYPE", "Debug"), ("EKAT_ENABLE_VALGRIND", "True")],
+ uses_baselines=False,
+ on_by_default=False,
+ default_test_len="short"
+ )
+ if tas is not None:
+ # If a stored suppression file exists for this machine, use it
+ persistent_supp_file = tas.get_root_dir() / "scripts" / "jenkins" / "valgrind" / f"{tas.get_machine()}.supp"
+ if persistent_supp_file.exists():
+ self.cmake_args.append( ("EKAT_VALGRIND_SUPPRESSION_FILE", str(persistent_supp_file)) )
+
+###############################################################################
+class CSM(TestProperty):
+###############################################################################
+
+ def __init__(self, _):
+ TestProperty.__init__(
+ self,
+ "compute_sanitizer_memcheck",
+ "debug with compute sanitizer memcheck",
+ [("CMAKE_BUILD_TYPE", "Debug"),
+ ("EKAT_ENABLE_COMPUTE_SANITIZER", "True"),
+ ("EKAT_COMPUTE_SANITIZER_OPTIONS", "--tool=memcheck")],
+ uses_baselines=False,
+ on_by_default=False,
+ default_test_len="short"
+ )
+
+###############################################################################
+class CSR(TestProperty):
+###############################################################################
+
+ def __init__(self, _):
+ TestProperty.__init__(
+ self,
+ "compute_sanitizer_racecheck",
+ "debug with compute sanitizer racecheck",
+ [("CMAKE_BUILD_TYPE", "Debug"),
+ ("EKAT_ENABLE_COMPUTE_SANITIZER", "True"),
+ ("EKAT_COMPUTE_SANITIZER_OPTIONS", "'--tool=racecheck --racecheck-detect-level=error'")],
+ uses_baselines=False,
+ on_by_default=False,
+ default_test_len="short"
+ )
+
+###############################################################################
+class CSI(TestProperty):
+###############################################################################
+
+ def __init__(self, _):
+ TestProperty.__init__(
+ self,
+ "compute_sanitizer_initcheck",
+ "debug with compute sanitizer initcheck",
+ [("CMAKE_BUILD_TYPE", "Debug"),
+ ("EKAT_ENABLE_COMPUTE_SANITIZER", "True"),
+ ("EKAT_COMPUTE_SANITIZER_OPTIONS", "--tool=initcheck")],
+ uses_baselines=False,
+ on_by_default=False,
+ default_test_len="short"
+ )
+
+###############################################################################
+class CSS(TestProperty):
+###############################################################################
+
+ def __init__(self, _):
+ TestProperty.__init__(
+ self,
+ "compute_sanitizer_synccheck",
+ "debug with compute sanitizer synccheck",
+ [("CMAKE_BUILD_TYPE", "Debug"),
+ ("EKAT_ENABLE_COMPUTE_SANITIZER", "True"),
+ ("EKAT_COMPUTE_SANITIZER_OPTIONS", "--tool=synccheck")],
+ uses_baselines=False,
+ on_by_default=False,
+ default_test_len="short"
+ )
+
+###############################################################################
+def create_tests(user_req_tests, tas):
+###############################################################################
+ testclasses = TestProperty.__subclasses__()
+ if not user_req_tests:
+ result = [testclass(tas) for testclass in testclasses
+ if testclass(tas).on_by_default]
+ else:
+ valid_names = [testclass(tas).shortname for testclass in testclasses]
+ for user_req_test in user_req_tests:
+ expect(user_req_test in valid_names, f"'{user_req_test}' is not a known test")
+
+ result = [testclass(tas) for testclass in testclasses if testclass(tas).shortname in user_req_tests]
+
+ return result
+
+###########################################################################
+def get_test_name_dict():
+###########################################################################
+ """
+ Returns a dict mapping short test names to full names
+ """
+ testclasses = TestProperty.__subclasses__()
+ return OrderedDict([(testc(None).shortname, testc(None).description) for testc in testclasses])
diff --git a/components/eamxx/scripts/utils.py b/components/eamxx/scripts/utils.py
index d08075a5e34b..9aafd09ae8ae 100644
--- a/components/eamxx/scripts/utils.py
+++ b/components/eamxx/scripts/utils.py
@@ -2,9 +2,11 @@
Utilities
"""
-import os, sys, re, signal, subprocess, site, time
+import os, sys, re, signal, subprocess, site, time, shutil
from importlib import import_module
+import stat as statlib
from pathlib import Path
+from distutils import file_util # pylint: disable=deprecated-module
###############################################################################
def expect(condition, error_msg, exc_type=SystemExit, error_prefix="ERROR:"):
@@ -415,3 +417,81 @@ def ensure_yaml(): _ensure_pylib_impl("yaml", pip_libname="pyyaml",min_version
def ensure_pylint(): _ensure_pylib_impl("pylint")
def ensure_psutil(): _ensure_pylib_impl("psutil")
def ensure_netcdf4(): _ensure_pylib_impl("netCDF4")
+
+###############################################################################
+def safe_copy(src_path, tgt_path, preserve_meta=True):
+###############################################################################
+ """
+ A flexbile and safe copy routine. Will try to copy file and metadata, but this
+ can fail if the current user doesn't own the tgt file. A fallback data-only copy is
+ attempted in this case. Works even if overwriting a read-only file.
+
+ tgt_path can be a directory, src_path must be a file
+
+ most of the complexity here is handling the case where the tgt_path file already
+ exists. This problem does not exist for the tree operations so we don't need to wrap those.
+
+ preserve_meta toggles if file meta-data, like permissions, should be preserved. If you are
+ copying baseline files, you should be within a SharedArea context manager and preserve_meta
+ should be false so that the umask set up by SharedArea can take affect regardless of the
+ permissions of the src files.
+ """
+
+ # Only works for str paths for now
+ src_path = str(src_path)
+ tgt_path = str(tgt_path)
+
+ tgt_path = (
+ os.path.join(tgt_path, os.path.basename(src_path))
+ if os.path.isdir(tgt_path)
+ else tgt_path
+ )
+
+ # Handle pre-existing file
+ if os.path.isfile(tgt_path):
+ st = os.stat(tgt_path)
+ owner_uid = st.st_uid
+
+ # Handle read-only files if possible
+ if not os.access(tgt_path, os.W_OK):
+ if owner_uid == os.getuid():
+ # I am the owner, make writeable
+ os.chmod(tgt_path, st.st_mode | statlib.S_IWRITE)
+ else:
+ # I won't be able to copy this file
+ raise OSError(
+ "Cannot copy over file {}, it is readonly and you are not the owner".format(
+ tgt_path
+ )
+ )
+
+ if owner_uid == os.getuid():
+ # I am the owner, copy file contents, permissions, and metadata
+ file_util.copy_file(
+ src_path,
+ tgt_path,
+ preserve_mode=preserve_meta,
+ preserve_times=preserve_meta,
+ verbose=0,
+ )
+ else:
+ # I am not the owner, just copy file contents
+ shutil.copyfile(src_path, tgt_path)
+
+ else:
+ # We are making a new file, copy file contents, permissions, and metadata.
+ # This can fail if the underlying directory is not writable by current user.
+ file_util.copy_file(
+ src_path,
+ tgt_path,
+ preserve_mode=preserve_meta,
+ preserve_times=preserve_meta,
+ verbose=0,
+ )
+
+ # If src file was executable, then the tgt file should be too
+ st = os.stat(tgt_path)
+ if os.access(src_path, os.X_OK) and st.st_uid == os.getuid():
+ os.chmod(
+ tgt_path, st.st_mode | statlib.S_IXUSR | statlib.S_IXGRP | statlib.S_IXOTH
+ )
diff --git a/components/eamxx/src/CMakeLists.txt b/components/eamxx/src/CMakeLists.txt
index 9568d3cf85ce..59a5d6646443 100644
--- a/components/eamxx/src/CMakeLists.txt
+++ b/components/eamxx/src/CMakeLists.txt
@@ -4,9 +4,6 @@ add_subdirectory(dynamics)
add_subdirectory(physics)
add_subdirectory(diagnostics)
add_subdirectory(control)
-if ("${SCREAM_DYNAMICS_DYCORE}" STREQUAL "HOMME")
- add_subdirectory(doubly-periodic)
-endif()
if (PROJECT_NAME STREQUAL "E3SM")
add_subdirectory(mct_coupling)
endif()
diff --git a/components/eamxx/src/control/atmosphere_driver.cpp b/components/eamxx/src/control/atmosphere_driver.cpp
index 96adc56127d4..a5dacd856d75 100644
--- a/components/eamxx/src/control/atmosphere_driver.cpp
+++ b/components/eamxx/src/control/atmosphere_driver.cpp
@@ -167,44 +167,44 @@ init_time_stamps (const util::TimeStamp& run_t0, const util::TimeStamp& case_t0)
void AtmosphereDriver::
-setup_intensive_observation_period ()
+setup_iop ()
{
- // At this point, must have comm, params, initialized timestamps, and grids created.
- check_ad_status(s_comm_set | s_params_set | s_ts_inited | s_grids_created);
+ // At this point, must have comm, params, initialized timestamps created.
+ check_ad_status(s_comm_set | s_params_set | s_ts_inited);
// Check to make sure iop is not already initialized
- EKAT_REQUIRE_MSG(not m_intensive_observation_period, "Error! setup_intensive_observation_period() is "
- "called, but IOP already set up.\n");
+ EKAT_REQUIRE_MSG(not m_iop, "Error! setup_iop() is called, but IOP already set up.\n");
// This function should only be called if we are enabling IOP
const bool enable_iop =
- m_atm_params.sublist("driver_options").get("enable_intensive_observation_period", false);
- EKAT_REQUIRE_MSG(enable_iop, "Error! setup_intensive_observation_period() is called, but "
- "enable_intensive_observation_period=false "
+ m_atm_params.sublist("driver_options").get("enable_iop", false);
+ EKAT_REQUIRE_MSG(enable_iop, "Error! setup_iop() is called, but enable_iop=false "
"in driver_options parameters.\n");
- // Params must include intensive_observation_period_options sublist.
- const auto iop_sublist_exists = m_atm_params.isSublist("intensive_observation_period_options");
+ // Params must include iop_options sublist.
+ const auto iop_sublist_exists = m_atm_params.isSublist("iop_options");
EKAT_REQUIRE_MSG(iop_sublist_exists,
- "Error! setup_intensive_observation_period() is called, but no intensive_observation_period_options "
+ "Error! setup_iop() is called, but no iop_options "
"defined in parameters.\n");
- const auto iop_params = m_atm_params.sublist("intensive_observation_period_options");
+ const auto iop_params = m_atm_params.sublist("iop_options");
const auto phys_grid = m_grids_manager->get_grid("Physics");
const auto nlevs = phys_grid->get_num_vertical_levels();
const auto hyam = phys_grid->get_geometry_data("hyam");
const auto hybm = phys_grid->get_geometry_data("hybm");
- m_intensive_observation_period =
- std::make_shared(m_atm_comm,
- iop_params,
- m_run_t0,
- nlevs,
- hyam,
- hybm);
+ m_iop = std::make_shared(m_atm_comm,
+ iop_params,
+ m_run_t0,
+ nlevs,
+ hyam,
+ hybm);
auto dx_short_f = phys_grid->get_geometry_data("dx_short");
- m_intensive_observation_period->set_grid_spacing(dx_short_f.get_view()());
+ m_iop->set_grid_spacing(dx_short_f.get_view()());
+
+ // Set IOP object in atm processes
+ m_atm_process_group->set_iop(m_iop);
}
void AtmosphereDriver::create_atm_processes()
@@ -279,6 +279,14 @@ void AtmosphereDriver::create_grids()
setup_shoc_tms_links();
}
+ // IOP object needs the grids_manager to have been created, but is then needed in set_grids()
+ // implementation of some processes, so setup here.
+ const bool enable_iop =
+ m_atm_params.sublist("driver_options").get("enable_iop", false);
+ if (enable_iop) {
+ setup_iop ();
+ }
+
// Set the grids in the processes. Do this by passing the grids manager.
// Each process will grab what they need
m_atm_process_group->set_grids(m_grids_manager);
@@ -338,10 +346,6 @@ void AtmosphereDriver::setup_surface_coupling_processes () const
std::shared_ptr importer = std::dynamic_pointer_cast(atm_proc);
importer->setup_surface_coupling_data(*m_surface_coupling_import_data_manager);
-
- if (m_intensive_observation_period) {
- importer->set_intensive_observation_period(m_intensive_observation_period);
- }
}
if (atm_proc->type() == AtmosphereProcessType::SurfaceCouplingExporter) {
exporter_found = true;
@@ -691,9 +695,9 @@ void AtmosphereDriver::initialize_output_managers () {
checkpoint_params.set("Frequency",-1);
if (io_params.isSublist("model_restart")) {
auto restart_pl = io_params.sublist("model_restart");
- m_output_managers.emplace_back();
+ restart_pl.set("Averaging Type","Instant");
restart_pl.sublist("provenance") = m_atm_params.sublist("provenance");
- auto& om = m_output_managers.back();
+ auto& om = m_output_managers.emplace_back();
if (fvphyshack) {
// Don't save CGLL fields from ICs to the restart file.
std::map fms;
@@ -839,7 +843,7 @@ initialize_fields ()
auto hw = fm->get_field("horiz_winds");
const auto& fid = hw.get_header().get_identifier();
const auto& layout = fid.get_layout();
- const int vec_dim = layout.get_vector_dim();
+ const int vec_dim = layout.get_vector_component_idx();
const auto& units = fid.get_units();
auto U = hw.subfield("U",units,vec_dim,0);
auto V = hw.subfield("V",units,vec_dim,1);
@@ -855,7 +859,7 @@ initialize_fields ()
auto hw = fm->get_field("surf_mom_flux");
const auto& fid = hw.get_header().get_identifier();
const auto& layout = fid.get_layout();
- const int vec_dim = layout.get_vector_dim();
+ const int vec_dim = layout.get_vector_component_idx();
const auto& units = fid.get_units();
auto surf_mom_flux_U = hw.subfield("surf_mom_flux_U",units,vec_dim,0);
auto surf_mom_flux_V = hw.subfield("surf_mom_flux_V",units,vec_dim,1);
@@ -937,29 +941,34 @@ void AtmosphereDriver::create_logger () {
auto& driver_options_pl = m_atm_params.sublist("driver_options");
ci_string log_fname = driver_options_pl.get("Atm Log File","atm.log");
- ci_string log_level_str = driver_options_pl.get("atm_log_level","info");
+ ci_string log_level = driver_options_pl.get("atm_log_level","info");
+ ci_string flush_level = driver_options_pl.get("atm_flush_level","warn");
EKAT_REQUIRE_MSG (log_fname!="",
"Invalid string for 'Atm Log File': '" + log_fname + "'.\n");
- LogLevel log_level;
- if (log_level_str=="trace") {
- log_level = LogLevel::trace;
- } else if (log_level_str=="debug") {
- log_level = LogLevel::debug;
- } else if (log_level_str=="info") {
- log_level = LogLevel::info;
- } else if (log_level_str=="warn") {
- log_level = LogLevel::warn;
- } else if (log_level_str=="err") {
- log_level = LogLevel::err;
- } else if (log_level_str=="off") {
- log_level = LogLevel::off;
- } else {
- EKAT_ERROR_MSG ("Invalid choice for 'atm_log_level': " + log_level_str + "\n");
- }
+ auto str2lev = [](const std::string& s, const std::string& name) {
+ LogLevel lev;
+ if (s=="trace") {
+ lev = LogLevel::trace;
+ } else if (s=="debug") {
+ lev = LogLevel::debug;
+ } else if (s=="info") {
+ lev = LogLevel::info;
+ } else if (s=="warn") {
+ lev = LogLevel::warn;
+ } else if (s=="err") {
+ lev = LogLevel::err;
+ } else if (s=="off") {
+ lev = LogLevel::off;
+ } else {
+ EKAT_ERROR_MSG ("Invalid choice for '" + name + "': " + s + "\n");
+ }
+ return lev;
+ };
using logger_t = Logger;
- m_atm_logger = std::make_shared(log_fname,log_level,m_atm_comm,"");
+ m_atm_logger = std::make_shared(log_fname,str2lev(log_level,"atm_log_level"),m_atm_comm,"");
+ m_atm_logger->flush_on(str2lev(flush_level,"atm_flush_level"));
m_atm_logger->set_no_format();
// In CIME runs, this is already set to false, so atm log does not pollute e3sm.loc.
@@ -1129,7 +1138,7 @@ void AtmosphereDriver::set_initial_conditions ()
}
}
- if (m_intensive_observation_period) {
+ if (m_iop) {
// For runs with IOP, call to setup io grids and lat
// lon information needed for reading from file
for (const auto& it : m_field_mgrs) {
@@ -1140,7 +1149,7 @@ void AtmosphereDriver::set_initial_conditions ()
ic_pl.get("Filename")
:
ic_pl.get("topography_filename");
- m_intensive_observation_period->setup_io_info(file_name, it.second->get_grid());
+ m_iop->setup_io_info(file_name, it.second->get_grid());
}
}
}
@@ -1152,15 +1161,15 @@ void AtmosphereDriver::set_initial_conditions ()
m_atm_logger->info(" [EAMxx] IC filename: " + file_name);
for (const auto& it : m_field_mgrs) {
const auto& grid_name = it.first;
- if (not m_intensive_observation_period) {
+ if (not m_iop) {
read_fields_from_file (ic_fields_names[grid_name],it.second->get_grid(),file_name,m_current_ts);
} else {
// For IOP enabled, we load from file and copy data from the closest
// lat/lon column to every other column
- m_intensive_observation_period->read_fields_from_file_for_iop(file_name,
- ic_fields_names[grid_name],
- m_current_ts,
- it.second);
+ m_iop->read_fields_from_file_for_iop(file_name,
+ ic_fields_names[grid_name],
+ m_current_ts,
+ it.second);
}
}
}
@@ -1227,7 +1236,7 @@ void AtmosphereDriver::set_initial_conditions ()
m_atm_logger->info(" filename: " + file_name);
for (const auto& it : m_field_mgrs) {
const auto& grid_name = it.first;
- if (not m_intensive_observation_period) {
+ if (not m_iop) {
// Topography files always use "ncol_d" for the GLL grid value of ncol.
// To ensure we read in the correct value, we must change the name for that dimension
auto io_grid = it.second->get_grid();
@@ -1243,11 +1252,11 @@ void AtmosphereDriver::set_initial_conditions ()
} else {
// For IOP enabled, we load from file and copy data from the closest
// lat/lon column to every other column
- m_intensive_observation_period->read_fields_from_file_for_iop(file_name,
- topography_file_fields_names[grid_name],
- topography_eamxx_fields_names[grid_name],
- m_current_ts,
- it.second);
+ m_iop->read_fields_from_file_for_iop(file_name,
+ topography_file_fields_names[grid_name],
+ topography_eamxx_fields_names[grid_name],
+ m_current_ts,
+ it.second);
}
}
// Store in provenance list, for later usage in output file metadata
@@ -1268,16 +1277,16 @@ void AtmosphereDriver::set_initial_conditions ()
m_atm_params.sublist("provenance").set("topography_file","NONE");
}
- if (m_intensive_observation_period) {
+ if (m_iop) {
// Load IOP data file data for initial time stamp
- m_intensive_observation_period->read_iop_file_data(m_current_ts);
+ m_iop->read_iop_file_data(m_current_ts);
// Now that ICs are processed, set appropriate fields using IOP file data.
// Since ICs are loaded on GLL grid, we set those fields only and dynamics
// will take care of the rest (for PG2 case).
if (m_field_mgrs.count("Physics GLL") > 0) {
const auto& fm = m_field_mgrs.at("Physics GLL");
- m_intensive_observation_period->set_fields_from_iop_data(fm);
+ m_iop->set_fields_from_iop_data(fm);
}
}
@@ -1441,12 +1450,15 @@ initialize_constant_field(const FieldIdentifier& fid,
// The user provided a constant value for this field. Simply use that.
const auto& layout = f.get_header().get_identifier().get_layout();
- // For vector fields, we expect something like "fname: [val0,...,valN],
- // where the field dim is N+1. For scalars, "fname: val". So check the
- // field layout first, so we know what to get from the parameter list.
- if (layout.is_vector_layout()) {
- const auto idim = layout.get_vector_dim();
- const auto vec_dim = layout.dim(idim);
+ // For vector fields, we allow either single value init or vector value init.
+ // That is, both these are ok
+ // fname: val
+ // fname: [val1,...,valN]
+ // In the first case, all entries of the field are inited to val, while in the latter,
+ // each component is inited to the corresponding entry of the array.
+ if (layout.is_vector_layout() and ic_pl.isType>(name)) {
+ const auto idim = layout.get_vector_component_idx();
+ const auto vec_dim = layout.get_vector_dim();
const auto& values = ic_pl.get>(name);
EKAT_REQUIRE_MSG (values.size()==static_cast(vec_dim),
"Error! Initial condition values array for '" + name + "' has the wrong dimension.\n"
@@ -1554,12 +1566,6 @@ initialize (const ekat::Comm& atm_comm,
create_grids ();
- const bool enable_iop =
- m_atm_params.sublist("driver_options").get("enable_intensive_observation_period", false);
- if (enable_iop) {
- setup_intensive_observation_period ();
- }
-
create_fields ();
initialize_fields ();
diff --git a/components/eamxx/src/control/atmosphere_driver.hpp b/components/eamxx/src/control/atmosphere_driver.hpp
index bf694da3fb3e..1cd8d4db08e7 100644
--- a/components/eamxx/src/control/atmosphere_driver.hpp
+++ b/components/eamxx/src/control/atmosphere_driver.hpp
@@ -72,7 +72,7 @@ class AtmosphereDriver
void init_scorpio (const int atm_id = 0);
// Setup IntensiveObservationPeriod
- void setup_intensive_observation_period ();
+ void setup_iop ();
// Create atm processes, without initializing them
void create_atm_processes ();
@@ -207,7 +207,7 @@ class AtmosphereDriver
std::shared_ptr m_surface_coupling_import_data_manager;
std::shared_ptr m_surface_coupling_export_data_manager;
- std::shared_ptr m_intensive_observation_period;
+ std::shared_ptr m_iop;
// This is the time stamp at the beginning of the time step.
util::TimeStamp m_current_ts;
diff --git a/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp b/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp
index 1bf32b924215..e816801fa618 100644
--- a/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp
+++ b/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp
@@ -170,9 +170,11 @@ void SurfaceCouplingImporter::do_import(const bool called_during_initialization)
}
});
- // If IOP is defined, potentially overwrite imports with data from IOP file
- if (m_intensive_observation_period) {
- overwrite_iop_imports(called_during_initialization);
+ if (m_iop) {
+ if (m_iop->get_params().get("iop_srf_prop")) {
+ // Overwrite imports with data from IOP file
+ overwrite_iop_imports(called_during_initialization);
+ }
}
}
// =========================================================================================
@@ -181,11 +183,9 @@ void SurfaceCouplingImporter::overwrite_iop_imports (const bool called_during_in
using policy_type = KokkosTypes::RangePolicy;
using C = physics::Constants;
- const auto& iop = m_intensive_observation_period;
-
- const auto has_lhflx = iop->has_iop_field("lhflx");
- const auto has_shflx = iop->has_iop_field("shflx");
- const auto has_Tg = iop->has_iop_field("Tg");
+ const auto has_lhflx = m_iop->has_iop_field("lhflx");
+ const auto has_shflx = m_iop->has_iop_field("shflx");
+ const auto has_Tg = m_iop->has_iop_field("Tg");
static constexpr Real latvap = C::LatVap;
static constexpr Real stebol = C::stebol;
@@ -205,19 +205,19 @@ void SurfaceCouplingImporter::overwrite_iop_imports (const bool called_during_in
// Store IOP surf data into col_val
Real col_val(std::nan(""));
if (fname == "surf_evap" && has_lhflx) {
- const auto f = iop->get_iop_field("lhflx");
+ const auto f = m_iop->get_iop_field("lhflx");
f.sync_to_host();
col_val = f.get_view()()/latvap;
} else if (fname == "surf_sens_flux" && has_shflx) {
- const auto f = iop->get_iop_field("shflx");
+ const auto f = m_iop->get_iop_field("shflx");
f.sync_to_host();
col_val = f.get_view()();
} else if (fname == "surf_radiative_T" && has_Tg) {
- const auto f = iop->get_iop_field("Tg");
+ const auto f = m_iop->get_iop_field("Tg");
f.sync_to_host();
col_val = f.get_view()();
} else if (fname == "surf_lw_flux_up" && has_Tg) {
- const auto f = iop->get_iop_field("Tg");
+ const auto f = m_iop->get_iop_field("Tg");
f.sync_to_host();
col_val = stebol*std::pow(f.get_view()(), 4);
} else {
diff --git a/components/eamxx/src/control/atmosphere_surface_coupling_importer.hpp b/components/eamxx/src/control/atmosphere_surface_coupling_importer.hpp
index 5884c9d40af2..3a34a8b2951e 100644
--- a/components/eamxx/src/control/atmosphere_surface_coupling_importer.hpp
+++ b/components/eamxx/src/control/atmosphere_surface_coupling_importer.hpp
@@ -5,8 +5,6 @@
#include "ekat/ekat_parameter_list.hpp"
#include "share/atm_process/SCDataManager.hpp"
-#include "control/intensive_observation_period.hpp"
-
#include "surface_coupling_utils.hpp"
#include
@@ -36,7 +34,6 @@ class SurfaceCouplingImporter : public AtmosphereProcess
using uview_2d = Unmanaged>;
using name_t = char[32];
- using iop_ptr = std::shared_ptr;
// Constructors
SurfaceCouplingImporter (const ekat::Comm& comm, const ekat::ParameterList& params);
@@ -64,9 +61,6 @@ class SurfaceCouplingImporter : public AtmosphereProcess
// Overwrite imports for IOP cases with IOP file surface data
void overwrite_iop_imports (const bool called_during_initialization);
- void set_intensive_observation_period (const iop_ptr& iop) {
- m_intensive_observation_period = iop;
- }
protected:
// The three main overrides for the subcomponent
@@ -102,9 +96,6 @@ class SurfaceCouplingImporter : public AtmosphereProcess
view_1d m_column_info_d;
decltype(m_column_info_d)::HostMirror m_column_info_h;
- // Intensive observation period object.
- iop_ptr m_intensive_observation_period;
-
// The grid is needed for property checks
std::shared_ptr m_grid;
}; // class SurfaceCouplingImporter
diff --git a/components/eamxx/src/control/intensive_observation_period.cpp b/components/eamxx/src/control/intensive_observation_period.cpp
index f4ab466c17ba..d925b21bfaa3 100644
--- a/components/eamxx/src/control/intensive_observation_period.cpp
+++ b/components/eamxx/src/control/intensive_observation_period.cpp
@@ -116,7 +116,7 @@ IntensiveObservationPeriod(const ekat::Comm& comm,
EKAT_REQUIRE_MSG(m_params.isParameter("target_latitude") && m_params.isParameter("target_longitude"),
"Error! Using intensive observation period files requires "
"target_latitude and target_longitude be gives as parameters in "
- "\"intensive_observation_period_options\" in the input yaml file.\n");
+ "\"iop_options\" in the input yaml file.\n");
const auto target_lat = m_params.get("target_latitude");
const auto target_lon = m_params.get("target_longitude");
EKAT_REQUIRE_MSG(-90 <= target_lat and target_lat <= 90,
@@ -135,16 +135,18 @@ IntensiveObservationPeriod(const ekat::Comm& comm,
if (not m_params.isParameter("iop_nudge_tscale")) m_params.set("iop_nudge_tscale", 10800);
if (not m_params.isParameter("zero_non_iop_tracers")) m_params.set("zero_non_iop_tracers", false);
+ // Store hybrid coords in helper fields
+ m_helper_fields.insert({"hyam", hyam});
+ m_helper_fields.insert({"hybm", hybm});
+
// Use IOP file to initialize parameters
// and timestepping information
- initialize_iop_file(run_t0, model_nlevs, hyam, hybm);
+ initialize_iop_file(run_t0, model_nlevs);
}
void IntensiveObservationPeriod::
initialize_iop_file(const util::TimeStamp& run_t0,
- int model_nlevs,
- const Field& hyam,
- const Field& hybm)
+ int model_nlevs)
{
EKAT_REQUIRE_MSG(m_params.isParameter("iop_file"),
"Error! Using IOP requires defining an iop_file parameter.\n");
@@ -184,6 +186,8 @@ initialize_iop_file(const util::TimeStamp& run_t0,
if (scorpio::has_variable(iop_file, srf_varname)) {
m_iop_field_surface_varnames.insert({iop_varname, srf_varname});
}
+ // Store that the IOP variable is found in the IOP file
+ m_iop_field_type.insert({iop_varname, IOPFieldType::FromFile});
// Allocate field for variable
FieldIdentifier fid(iop_varname, fl, ekat::units::Units::nondimensional(), "");
@@ -191,6 +195,10 @@ initialize_iop_file(const util::TimeStamp& run_t0,
EKAT_REQUIRE_MSG(field_rank <= 1,
"Error! Unexpected field rank "+std::to_string(field_rank)+" for iop file fields.\n");
Field field(fid);
+ if (fl.has_tag(FieldTag::LevelMidPoint) or fl.has_tag(FieldTag::LevelInterface)) {
+ // Request packsize allocation for level layout
+ field.get_header().get_alloc_properties().request_allocation(Pack::n);
+ }
field.allocate_view();
m_iop_fields.insert({iop_varname, field});
}
@@ -230,13 +238,42 @@ initialize_iop_file(const util::TimeStamp& run_t0,
setup_iop_field({"Q2"}, fl_vector);
setup_iop_field({"omega"}, fl_vector, "Ptend");
- // Make sure Ps, T, and q are defined in the iop file
+ // Require Ps, T, q, divT, divq are all defined in the iop file
EKAT_REQUIRE_MSG(has_iop_field("Ps"),
- "Error! Using IOP file requires variable \"Ps\".\n");
+ "Error! IOP file required to contain variable \"Ps\".\n");
EKAT_REQUIRE_MSG(has_iop_field("T"),
- "Error! Using IOP file requires variable \"T\".\n");
+ "Error! IOP file required to contain variable \"T\".\n");
EKAT_REQUIRE_MSG(has_iop_field("q"),
- "Error! Using IOP file requires variable \"q\".\n");
+ "Error! IOP file required to contain variable \"q\".\n");
+ EKAT_REQUIRE_MSG(has_iop_field("divT"),
+ "Error! IOP file required to contain variable \"divT\".\n");
+ EKAT_REQUIRE_MSG(has_iop_field("divq"),
+ "Error! IOP file required to contain variable \"divq\".\n");
+
+ // If we have the vertical component of T/Q forcing, define 3d forcing as a computed field.
+ if (has_iop_field("vertdivT")) {
+ FieldIdentifier fid("divT3d", fl_vector, ekat::units::Units::nondimensional(), "");
+ Field field(fid);
+ field.get_header().get_alloc_properties().request_allocation(Pack::n);
+ field.allocate_view();
+ m_iop_fields.insert({"divT3d", field});
+ m_iop_field_type.insert({"divT3d", IOPFieldType::Computed});
+ }
+ if (has_iop_field("vertdivq")) {
+ FieldIdentifier fid("divq3d", fl_vector, ekat::units::Units::nondimensional(), "");
+ Field field(fid);
+ field.get_header().get_alloc_properties().request_allocation(Pack::n);
+ field.allocate_view();
+ m_iop_fields.insert({"divq3d", field});
+ m_iop_field_type.insert({"divq3d", IOPFieldType::Computed});
+ }
+
+ // Enforce that 3D forcing is all-or-nothing.
+ const bool both = (has_iop_field("divT3d") and has_iop_field("divq3d"));
+ const bool neither = (not (has_iop_field("divT3d") or has_iop_field("divq3d")));
+ EKAT_REQUIRE_MSG(both or neither,
+ "Error! Either T and q both have 3d forcing, or neither have 3d forcing.\n");
+ m_params.set("use_3d_forcing", both);
// Initialize time information
int bdate;
@@ -286,6 +323,7 @@ initialize_iop_file(const util::TimeStamp& run_t0,
ekat::units::Units::nondimensional(),
"");
Field iop_file_pressure(fid);
+ iop_file_pressure.get_header().get_alloc_properties().request_allocation(Pack::n);
iop_file_pressure.allocate_view();
auto data = iop_file_pressure.get_view().data();
read_variable_from_file(iop_file, "lev", "real", {"lev"}, -1, data);
@@ -300,12 +338,9 @@ initialize_iop_file(const util::TimeStamp& run_t0,
fl_vector,
ekat::units::Units::nondimensional(), "");
Field model_pressure(model_pres_fid);
+ model_pressure.get_header().get_alloc_properties().request_allocation(Pack::n);
model_pressure.allocate_view();
m_helper_fields.insert({"model_pressure", model_pressure});
-
- // Store hyam and hybm in helper fields
- m_helper_fields.insert({"hyam", hyam});
- m_helper_fields.insert({"hybm", hybm});
}
void IntensiveObservationPeriod::
@@ -400,7 +435,8 @@ read_fields_from_file_for_iop (const std::string& file_name,
const vos& field_names_nc,
const vos& field_names_eamxx,
const util::TimeStamp& initial_ts,
- const field_mgr_ptr field_mgr)
+ const field_mgr_ptr field_mgr,
+ const int time_index)
{
const auto dummy_units = ekat::units::Units::nondimensional();
@@ -456,7 +492,7 @@ read_fields_from_file_for_iop (const std::string& file_name,
// Read data from file
AtmosphereInput file_reader(file_name,io_grid,io_fields);
- file_reader.read_variables();
+ file_reader.read_variables(time_index);
file_reader.finalize();
// For each field, broadcast data from closest lat/lon column to all processors
@@ -502,27 +538,27 @@ read_fields_from_file_for_iop (const std::string& file_name,
void IntensiveObservationPeriod::
read_iop_file_data (const util::TimeStamp& current_ts)
{
- const auto iop_file = m_params.get("iop_file");
+ // Query to see if we need to load data from IOP file.
+ // If we are still in the time interval as the previous
+ // read from iop file, there is no need to reload data.
const auto iop_file_time_idx = m_time_info.get_iop_file_time_idx(current_ts);
-
- // Sanity check
EKAT_REQUIRE_MSG(iop_file_time_idx >= m_time_info.time_idx_of_current_data,
"Error! Attempting to read previous iop file data time index.\n");
-
- // If we are still in the time interval as the previous read from iop file,
- // there is no need to reload data. Return early
if (iop_file_time_idx == m_time_info.time_idx_of_current_data) return;
+ const auto iop_file = m_params.get("iop_file");
const auto file_levs = scorpio::get_dimlen(iop_file, "lev");
const auto iop_file_pressure = m_helper_fields["iop_file_pressure"];
const auto model_pressure = m_helper_fields["model_pressure"];
const auto surface_pressure = m_iop_fields["Ps"];
- // Loop through iop fields, if rank 1 fields exist we need to
- // gather information for vertically interpolating views
+ // Loop through iop fields, if any rank 1 fields are loaded from file,
+ // we need to gather information for vertical interpolation
bool has_level_data = false;
for (auto& it : m_iop_fields) {
- if (it.second.rank() == 1) {
+ if (it.second.rank() == 1
+ and
+ m_iop_field_type.at(it.first)==IOPFieldType::FromFile) {
has_level_data = true;
break;
}
@@ -589,6 +625,10 @@ read_iop_file_data (const util::TimeStamp& current_ts)
Kokkos::Max(iop_file_start),
Kokkos::Min(iop_file_end));
+ // If no file pressures are found outide the reference pressure range, set to file level endpoints
+ if (iop_file_start == Kokkos::reduction_identity::max()) iop_file_start = 0;
+ if (iop_file_end == Kokkos::reduction_identity::min()) iop_file_end = adjusted_file_levs;
+
// Find model pressure levels just inside range of file pressure levels
Kokkos::parallel_reduce(model_nlevs, KOKKOS_LAMBDA (const int& ilev, int& lmin, int& lmax) {
if (model_pres_v(ilev) >= iop_file_pres_v(iop_file_start) && ilev < lmin) {
@@ -600,6 +640,10 @@ read_iop_file_data (const util::TimeStamp& current_ts)
},
Kokkos::Min(model_start),
Kokkos::Max(model_end));
+
+ // If not reference pressures are found inside file pressures, set to model level endpoints
+ if (model_start == Kokkos::reduction_identity::min()) model_start = model_nlevs-1;
+ if (model_end == Kokkos::reduction_identity::max()) model_end = 1;
}
// Loop through fields and store data from file
@@ -607,6 +651,9 @@ read_iop_file_data (const util::TimeStamp& current_ts)
auto fname = it.first;
auto field = it.second;
+ // If this is a computed field, do not attempt to load from file
+ if (m_iop_field_type.at(fname)==IOPFieldType::Computed) continue;
+
// File may use different varname than IOP class
auto file_varname = (m_iop_file_varnames.count(fname) > 0) ? m_iop_file_varnames[fname] : fname;
@@ -625,6 +672,7 @@ read_iop_file_data (const util::TimeStamp& current_ts)
ekat::units::Units::nondimensional(),
"");
Field iop_file_field(fid);
+ iop_file_field.get_header().get_alloc_properties().request_allocation(Pack::n);
iop_file_field.allocate_view();
// Read data from iop file.
@@ -657,8 +705,8 @@ read_iop_file_data (const util::TimeStamp& current_ts)
iop_file_field.sync_to_dev();
// Vertically interpolate iop file data to iop fields.
- // Note: ekat lininterp requires packs. Use 1d packs here.
- // TODO: allow for nontrivial packsize.
+ // Note: ekat lininterp requires packs. Use 1d packs here
+ // to easily mask out levels which we do not want to interpolate.
const auto iop_file_pres_v = iop_file_pressure.get_view();
const auto model_pres_v = model_pressure.get_view();
const auto iop_file_v = iop_file_field.get_view();
@@ -685,22 +733,42 @@ read_iop_file_data (const util::TimeStamp& current_ts)
// the interpolated region with the value at model_start/model_end
if (fname == "T" || fname == "q" || fname == "u" ||
fname == "u_ls" || fname == "v" || fname == "v_ls") {
- if (model_start > 0) {
- Kokkos::parallel_for(Kokkos::RangePolicy<>(0, model_start),
- KOKKOS_LAMBDA (const int ilev) {
- iop_field_v(ilev) = iop_field_v(model_start);
- });
- }
- if (model_end < total_nlevs) {
- Kokkos::parallel_for(Kokkos::RangePolicy<>(model_end, total_nlevs),
- KOKKOS_LAMBDA (const int ilev) {
- iop_field_v(ilev) = iop_field_v(model_end-1);
- });
- }
+ Kokkos::parallel_for(Kokkos::RangePolicy<>(0, model_start+1),
+ KOKKOS_LAMBDA (const int ilev) {
+ iop_field_v(ilev) = iop_file_v(0);
+ });
+ Kokkos::parallel_for(Kokkos::RangePolicy<>(model_end-1, total_nlevs),
+ KOKKOS_LAMBDA (const int ilev) {
+ iop_field_v(ilev) = iop_file_v(adjusted_file_levs-1);
+ });
}
}
}
+ // Calculate 3d forcing (if applicable).
+ if (has_iop_field("divT3d")) {
+ if (m_iop_field_type.at("divT3d")==IOPFieldType::Computed) {
+ const auto divT = get_iop_field("divT").get_view();
+ const auto vertdivT = get_iop_field("vertdivT").get_view();
+ const auto divT3d = get_iop_field("divT3d").get_view();
+ const auto nlevs = get_iop_field("divT3d").get_header().get_identifier().get_layout().dim(0);
+ Kokkos::parallel_for(nlevs, KOKKOS_LAMBDA (const int ilev) {
+ divT3d(ilev) = divT(ilev) + vertdivT(ilev);
+ });
+ }
+ }
+ if (has_iop_field("divq3d")) {
+ if (m_iop_field_type.at("divq3d")==IOPFieldType::Computed) {
+ const auto divq = get_iop_field("divq").get_view();
+ const auto vertdivq = get_iop_field("vertdivq").get_view();
+ const auto divq3d = get_iop_field("divq3d").get_view();
+ const auto nlevs = get_iop_field("divq3d").get_header().get_identifier().get_layout().dim(0);
+ Kokkos::parallel_for(nlevs, KOKKOS_LAMBDA (const int ilev) {
+ divq3d(ilev) = divq(ilev) + vertdivq(ilev);
+ });
+ }
+ }
+
// Now that data is loaded, reset the index of the currently loaded data.
m_time_info.time_idx_of_current_data = iop_file_time_idx;
}
diff --git a/components/eamxx/src/control/intensive_observation_period.hpp b/components/eamxx/src/control/intensive_observation_period.hpp
index 6e70f44a0f56..6c0b3640ffb2 100644
--- a/components/eamxx/src/control/intensive_observation_period.hpp
+++ b/components/eamxx/src/control/intensive_observation_period.hpp
@@ -26,6 +26,8 @@ class IntensiveObservationPeriod
using KT = ekat::KokkosTypes;
using ESU = ekat::ExeSpaceUtils;
+ using Pack = ekat::Pack;
+ using Pack1d = ekat::Pack;
template
using view_1d = KT::template view_1d;
@@ -35,14 +37,13 @@ class IntensiveObservationPeriod
using view_3d = KT::template view_3d;
template
using view_1d_host = typename view_1d::HostMirror;
- using Pack1d = ekat::Pack;
public:
// Constructor
// Input:
// - comm: MPI communicator
- // - params: Input yaml file needs intensive_observation_period_options sublist
+ // - params: Input yaml file needs iop_options sublist
// - run_t0: Initial timestamp for the simulation
// - model_nlevs: Number of vertical levels in the simulation. Needed since
// the iop file contains a (potentially) different number of levels
@@ -69,31 +70,35 @@ class IntensiveObservationPeriod
void setup_io_info (const std::string& file_name,
const grid_ptr& grid);
- // Read ICs from file for IOP cases. We set all columns in the
- // given fields to the values of the column in the file with the
- // closest lat,lon pair to the target lat,lon in the parameters.
- // The setup_io_info must be called for the correct grids before
- // this function can be called.
- // Input:
+ // Read ICs and SPA data from file and remap to fields in field_mgr.
+ // The remap is defined by setting all columns in the given fields to the
+ // values of the column in the file with the closest lat,lon pair to
+ // the target lat,lon in the parameters.
+ // The function setup_io_info() must be called for the grids corresponding
+ // to the file data before this function can be called.
+ // Fields in the field_mgr must have the same number of levels as the file.
+ // Inputs and outputs:
// - file_name: Name of the file used to load field data (IC or topo file)
// - field_names_nc: Field names used by the input file
// - field_names_eamxx: Field names used by eamxx
- // - initial_ts: Inital timestamp
- // Input/output
+ // - initial_ts: Inital timestamp.
// - field_mgr: Field manager containing fields that need data read from files
+ // - time_index: Time index of read. time_index=-1 will read the latest time in file.
void read_fields_from_file_for_iop(const std::string& file_name,
const vos& field_names_nc,
const vos& field_names_eamxx,
const util::TimeStamp& initial_ts,
- const field_mgr_ptr field_mgr);
+ const field_mgr_ptr field_mgr,
+ const int time_index = -1);
// Version of above, but where nc and eamxx field names are identical
void read_fields_from_file_for_iop(const std::string& file_name,
const vos& field_names,
const util::TimeStamp& initial_ts,
- const field_mgr_ptr field_mgr)
+ const field_mgr_ptr field_mgr,
+ const int time_index = -1)
{
- read_fields_from_file_for_iop(file_name, field_names, field_names, initial_ts, field_mgr);
+ read_fields_from_file_for_iop(file_name, field_names, field_names, initial_ts, field_mgr, time_index);
}
// Set fields using data loaded from the iop file
@@ -175,10 +180,13 @@ class IntensiveObservationPeriod
}
};
+ enum IOPFieldType {
+ FromFile,
+ Computed
+ };
+
void initialize_iop_file(const util::TimeStamp& run_t0,
- int model_nlevs,
- const Field& hyam,
- const Field& hybm);
+ int model_nlevs);
ekat::Comm m_comm;
ekat::ParameterList m_params;
@@ -195,6 +203,7 @@ class IntensiveObservationPeriod
std::map m_iop_file_varnames;
std::map m_iop_field_surface_varnames;
+ std::map m_iop_field_type;
}; // class IntensiveObservationPeriod
} // namespace control
diff --git a/components/eamxx/src/control/tests/CMakeLists.txt b/components/eamxx/src/control/tests/CMakeLists.txt
index 43aa5cebab1b..401c0f576268 100644
--- a/components/eamxx/src/control/tests/CMakeLists.txt
+++ b/components/eamxx/src/control/tests/CMakeLists.txt
@@ -1,5 +1,5 @@
# NOTE: if you have baseline-type tests, add the subdirectory OUTSIDE the following if statement
-if (NOT ${SCREAM_BASELINES_ONLY})
+if (NOT ${SCREAM_ONLY_GENERATE_BASELINES})
include (ScreamUtils)
# Unit test the ad
diff --git a/components/eamxx/src/diagnostics/CMakeLists.txt b/components/eamxx/src/diagnostics/CMakeLists.txt
index 5818c4d836a8..f34d5b99638f 100644
--- a/components/eamxx/src/diagnostics/CMakeLists.txt
+++ b/components/eamxx/src/diagnostics/CMakeLists.txt
@@ -16,6 +16,7 @@ set(DIAGNOSTIC_SRCS
vertical_layer.cpp
virtual_temperature.cpp
water_path.cpp
+ wind_speed.cpp
)
add_library(diagnostics ${DIAGNOSTIC_SRCS})
diff --git a/components/eamxx/src/diagnostics/exner.hpp b/components/eamxx/src/diagnostics/exner.hpp
index 5e029b716bf0..dead0a5cbf64 100644
--- a/components/eamxx/src/diagnostics/exner.hpp
+++ b/components/eamxx/src/diagnostics/exner.hpp
@@ -16,9 +16,6 @@ class ExnerDiagnostic : public AtmosphereDiagnostic
// Constructors
ExnerDiagnostic (const ekat::Comm& comm, const ekat::ParameterList& params);
- // Set type to diagnostic
- AtmosphereProcessType type () const { return AtmosphereProcessType::Diagnostic; }
-
// The name of the diagnostic
std::string name () const { return "Exner"; }
diff --git a/components/eamxx/src/diagnostics/field_at_height.cpp b/components/eamxx/src/diagnostics/field_at_height.cpp
index 7759dfe5811d..38ae5e3e5503 100644
--- a/components/eamxx/src/diagnostics/field_at_height.cpp
+++ b/components/eamxx/src/diagnostics/field_at_height.cpp
@@ -38,6 +38,13 @@ FieldAtHeight (const ekat::Comm& comm, const ekat::ParameterList& params)
: AtmosphereDiagnostic(comm,params)
{
m_field_name = m_params.get("field_name");
+ auto surf_ref = m_params.get("surface_reference");
+ EKAT_REQUIRE_MSG(surf_ref == "sealevel" or surf_ref == "surface",
+ "Error! Invalid surface reference for FieldAtHeight.\n"
+ " - field name: " + m_field_name + "\n"
+ " - surface reference: " + surf_ref + "\n"
+ " - valid options: sealevel, surface\n");
+ m_z_name = (surf_ref == "sealevel") ? "z" : "geopotential";
const auto& location = m_params.get("vertical_location");
auto chars_start = location.find_first_not_of("0123456789.");
EKAT_REQUIRE_MSG (chars_start!=0 && chars_start!=std::string::npos,
@@ -52,7 +59,7 @@ FieldAtHeight (const ekat::Comm& comm, const ekat::ParameterList& params)
"Error! Invalid string for height value for FieldAtHeight.\n"
" - input string : " + location + "\n"
" - expected format: Nm, with N integer\n");
- m_diag_name = m_field_name + "_at_" + m_params.get("vertical_location");
+ m_diag_name = m_field_name + "_at_" + m_params.get("vertical_location") + "_above_" + surf_ref;
}
void FieldAtHeight::
@@ -62,8 +69,8 @@ set_grids (const std::shared_ptr grids_manager)
add_field(m_field_name,gname);
// We don't know yet which one we need
- add_field("z_mid",gname);
- add_field("z_int",gname);
+ add_field(m_z_name+"_mid",gname);
+ add_field(m_z_name+"_int",gname);
}
void FieldAtHeight::
@@ -90,7 +97,7 @@ initialize_impl (const RunType /*run_type*/)
" - field layout: " + to_string(layout) + "\n");
// Figure out the z value
- m_z_name = tag==LEV ? "z_mid" : "z_int";
+ m_z_suffix = tag==LEV ? "_mid" : "_int";
// All good, create the diag output
FieldIdentifier d_fid (m_diag_name,layout.strip_dim(tag),fid.get_units(),fid.get_grid_name());
@@ -111,7 +118,7 @@ initialize_impl (const RunType /*run_type*/)
// =========================================================================================
void FieldAtHeight::compute_diagnostic_impl()
{
- const auto z_view = get_field_in(m_z_name).get_view();
+ const auto z_view = get_field_in(m_z_name + m_z_suffix).get_view();
const Field& f = get_field_in(m_field_name);
const auto& fl = f.get_header().get_identifier().get_layout();
diff --git a/components/eamxx/src/diagnostics/field_at_height.hpp b/components/eamxx/src/diagnostics/field_at_height.hpp
index 54843b4f1a0e..e6198153f940 100644
--- a/components/eamxx/src/diagnostics/field_at_height.hpp
+++ b/components/eamxx/src/diagnostics/field_at_height.hpp
@@ -33,6 +33,7 @@ class FieldAtHeight : public AtmosphereDiagnostic
std::string m_diag_name;
std::string m_z_name;
+ std::string m_z_suffix;
std::string m_field_name;
Real m_z;
diff --git a/components/eamxx/src/diagnostics/longwave_cloud_forcing.cpp b/components/eamxx/src/diagnostics/longwave_cloud_forcing.cpp
index 23ef59891e9f..4e44dff9dc76 100644
--- a/components/eamxx/src/diagnostics/longwave_cloud_forcing.cpp
+++ b/components/eamxx/src/diagnostics/longwave_cloud_forcing.cpp
@@ -19,6 +19,8 @@ void LongwaveCloudForcingDiagnostic::set_grids(const std::shared_ptrget_grid("Physics");
const auto& grid_name = grid->name();
@@ -33,7 +35,7 @@ void LongwaveCloudForcingDiagnostic::set_grids(const std::shared_ptr("LW_clrsky_flux_up", scalar3d_layout_mid, W/m2, grid_name);
// Construct and allocate the diagnostic field
- FieldIdentifier fid (name(), scalar2d_layout_col, W/m2, grid_name);
+ FieldIdentifier fid (name(), scalar2d_layout_col, radflux_units, grid_name);
m_diagnostic_output = Field(fid);
auto& C_ap = m_diagnostic_output.get_header().get_alloc_properties();
C_ap.request_allocation();
diff --git a/components/eamxx/src/diagnostics/longwave_cloud_forcing.hpp b/components/eamxx/src/diagnostics/longwave_cloud_forcing.hpp
index 9703330ce0cb..efe0e7c04760 100644
--- a/components/eamxx/src/diagnostics/longwave_cloud_forcing.hpp
+++ b/components/eamxx/src/diagnostics/longwave_cloud_forcing.hpp
@@ -16,9 +16,6 @@ class LongwaveCloudForcingDiagnostic : public AtmosphereDiagnostic
// Constructors
LongwaveCloudForcingDiagnostic (const ekat::Comm& comm, const ekat::ParameterList& params);
- // Set type to diagnostic
- AtmosphereProcessType type () const { return AtmosphereProcessType::Diagnostic; }
-
// The name of the diagnostic
std::string name () const { return "LongwaveCloudForcing"; }
diff --git a/components/eamxx/src/diagnostics/potential_temperature.hpp b/components/eamxx/src/diagnostics/potential_temperature.hpp
index 1e0af49fb597..933a6935005d 100644
--- a/components/eamxx/src/diagnostics/potential_temperature.hpp
+++ b/components/eamxx/src/diagnostics/potential_temperature.hpp
@@ -20,9 +20,6 @@ class PotentialTemperatureDiagnostic : public AtmosphereDiagnostic
// Constructors
PotentialTemperatureDiagnostic (const ekat::Comm& comm, const ekat::ParameterList& params);
- // Set type to diagnostic
- AtmosphereProcessType type () const { return AtmosphereProcessType::Diagnostic; }
-
// The name of the diagnostic
std::string name () const { return "PotentialTemperature"; }
diff --git a/components/eamxx/src/diagnostics/register_diagnostics.hpp b/components/eamxx/src/diagnostics/register_diagnostics.hpp
index 181a531a7c87..1f0c3bd63e3f 100644
--- a/components/eamxx/src/diagnostics/register_diagnostics.hpp
+++ b/components/eamxx/src/diagnostics/register_diagnostics.hpp
@@ -19,6 +19,7 @@
#include "diagnostics/field_at_pressure_level.hpp"
#include "diagnostics/precip_surf_mass_flux.hpp"
#include "diagnostics/surf_upward_latent_heat_flux.hpp"
+#include "diagnostics/wind_speed.hpp"
namespace scream {
@@ -45,6 +46,7 @@ inline void register_diagnostics () {
diag_factory.register_product("VaporFlux",&create_atmosphere_diagnostic);
diag_factory.register_product("precip_surf_mass_flux",&create_atmosphere_diagnostic);
diag_factory.register_product("surface_upward_latent_heat_flux",&create_atmosphere_diagnostic);
+ diag_factory.register_product("wind_speed",&create_atmosphere_diagnostic);
}
} // namespace scream
diff --git a/components/eamxx/src/diagnostics/sea_level_pressure.hpp b/components/eamxx/src/diagnostics/sea_level_pressure.hpp
index 8c522a2e75fe..0ae793658cd1 100644
--- a/components/eamxx/src/diagnostics/sea_level_pressure.hpp
+++ b/components/eamxx/src/diagnostics/sea_level_pressure.hpp
@@ -25,9 +25,6 @@ class SeaLevelPressureDiagnostic : public AtmosphereDiagnostic
// Constructors
SeaLevelPressureDiagnostic (const ekat::Comm& comm, const ekat::ParameterList& params);
- // Set type to diagnostic
- AtmosphereProcessType type () const { return AtmosphereProcessType::Diagnostic; }
-
// The name of the diagnostic
std::string name () const { return "SeaLevelPressure"; }
diff --git a/components/eamxx/src/diagnostics/shortwave_cloud_forcing.cpp b/components/eamxx/src/diagnostics/shortwave_cloud_forcing.cpp
index e0e815549c8a..9ca5ea4a8a14 100644
--- a/components/eamxx/src/diagnostics/shortwave_cloud_forcing.cpp
+++ b/components/eamxx/src/diagnostics/shortwave_cloud_forcing.cpp
@@ -17,7 +17,8 @@ void ShortwaveCloudForcingDiagnostic::set_grids(const std::shared_ptrget_grid("Physics");
const auto& grid_name = grid->name();
@@ -28,13 +29,13 @@ void ShortwaveCloudForcingDiagnostic::set_grids(const std::shared_ptr("SW_flux_dn", scalar3d_layout_mid, W/m2, grid_name);
- add_field("SW_flux_up", scalar3d_layout_mid, W/m2, grid_name);
- add_field("SW_clrsky_flux_dn", scalar3d_layout_mid, W/m2, grid_name);
- add_field("SW_clrsky_flux_up", scalar3d_layout_mid, W/m2, grid_name);
+ add_field("SW_flux_dn", scalar3d_layout_mid, radflux_units, grid_name);
+ add_field("SW_flux_up", scalar3d_layout_mid, radflux_units, grid_name);
+ add_field("SW_clrsky_flux_dn", scalar3d_layout_mid, radflux_units, grid_name);
+ add_field("SW_clrsky_flux_up", scalar3d_layout_mid, radflux_units, grid_name);
// Construct and allocate the diagnostic field
- FieldIdentifier fid (name(), scalar2d_layout_col, W/m2, grid_name);
+ FieldIdentifier fid (name(), scalar2d_layout_col, radflux_units, grid_name);
m_diagnostic_output = Field(fid);
auto& C_ap = m_diagnostic_output.get_header().get_alloc_properties();
C_ap.request_allocation();
diff --git a/components/eamxx/src/diagnostics/shortwave_cloud_forcing.hpp b/components/eamxx/src/diagnostics/shortwave_cloud_forcing.hpp
index 9d676338a765..421d06d3fe07 100644
--- a/components/eamxx/src/diagnostics/shortwave_cloud_forcing.hpp
+++ b/components/eamxx/src/diagnostics/shortwave_cloud_forcing.hpp
@@ -16,9 +16,6 @@ class ShortwaveCloudForcingDiagnostic : public AtmosphereDiagnostic
// Constructors
ShortwaveCloudForcingDiagnostic (const ekat::Comm& comm, const ekat::ParameterList& params);
- // Set type to diagnostic
- AtmosphereProcessType type () const { return AtmosphereProcessType::Diagnostic; }
-
// The name of the diagnostic
std::string name () const { return "ShortwaveCloudForcing"; }
diff --git a/components/eamxx/src/diagnostics/surf_upward_latent_heat_flux.cpp b/components/eamxx/src/diagnostics/surf_upward_latent_heat_flux.cpp
index 19a49ad595c5..009f8e6dd77f 100644
--- a/components/eamxx/src/diagnostics/surf_upward_latent_heat_flux.cpp
+++ b/components/eamxx/src/diagnostics/surf_upward_latent_heat_flux.cpp
@@ -22,6 +22,9 @@ set_grids (const std::shared_ptr grids_manager)
{
const auto m2 = ekat::units::m * ekat::units::m;
const auto W = ekat::units::W;
+ auto radflux_units = W/(m2);
+ radflux_units.set_string("W/m2");
+
const auto surf_evap_units = ekat::units::kg / m2 / ekat::units::s;
auto grid = grids_manager->get_grid("Physics");
@@ -35,7 +38,7 @@ set_grids (const std::shared_ptr grids_manager)
add_field("surf_evap", scalar2d_layout_mid, surf_evap_units, grid_name);
// Construct and allocate the diagnostic field
- FieldIdentifier fid(name(), scalar2d_layout_mid, W/m2, grid_name);
+ FieldIdentifier fid(name(), scalar2d_layout_mid, radflux_units, grid_name);
// handle parent class member variables
m_diagnostic_output = Field(fid);
m_diagnostic_output.get_header().get_alloc_properties().request_allocation();
diff --git a/components/eamxx/src/diagnostics/tests/CMakeLists.txt b/components/eamxx/src/diagnostics/tests/CMakeLists.txt
index 0882d3f6119d..d413b013f444 100644
--- a/components/eamxx/src/diagnostics/tests/CMakeLists.txt
+++ b/components/eamxx/src/diagnostics/tests/CMakeLists.txt
@@ -6,7 +6,7 @@ function (createDiagTest test_name test_srcs)
LABELS diagnostics)
endfunction ()
-if (NOT SCREAM_BASELINES_ONLY)
+if (NOT SCREAM_ONLY_GENERATE_BASELINES)
include(ScreamUtils)
# Test extracting a single level of a field
@@ -59,4 +59,6 @@ if (NOT SCREAM_BASELINES_ONLY)
# Test surface latent heat flux
CreateDiagTest(surface_upward_latent_heat_flux "surf_upward_latent_heat_flux_tests.cpp")
+ # Test wind speed diagnostic
+ CreateDiagTest(wind_speed "wind_speed_tests.cpp")
endif()
diff --git a/components/eamxx/src/diagnostics/tests/field_at_height_tests.cpp b/components/eamxx/src/diagnostics/tests/field_at_height_tests.cpp
index 0d45eb62e879..57a057116102 100644
--- a/components/eamxx/src/diagnostics/tests/field_at_height_tests.cpp
+++ b/components/eamxx/src/diagnostics/tests/field_at_height_tests.cpp
@@ -9,6 +9,10 @@
namespace scream {
+void f_z_src(const Real y0, const Real m, const Field& z_data, Field& out_data);
+void f_z_tgt(const Real y0, const Real m, const Real z_target, const Field& z_data, Field& out_data);
+bool views_are_approx_equal(const Field& f0, const Field& f1, const Real tol, const bool msg = true);
+
TEST_CASE("field_at_height")
{
using namespace ShortFieldTagsNames;
@@ -18,11 +22,12 @@ TEST_CASE("field_at_height")
// Get an MPI comm group for test
ekat::Comm comm(MPI_COMM_WORLD);
- constexpr int nruns = 10;
+ constexpr int nruns = 100;
util::TimeStamp t0 ({2022,1,1},{0,0,0});
// Create a grids manager w/ a point grid
+ constexpr Real tol = std::numeric_limits::epsilon()*1e5;
int ncols = 3;
int ndims = 4;
int nlevs = 10;
@@ -31,35 +36,57 @@ TEST_CASE("field_at_height")
gm->build_grids();
auto grid = gm->get_grid("Point Grid");
- // Create input test fields, as well as z_mid/int fields
const auto m = ekat::units::m;
+ // Create input data test fields
FieldIdentifier s_mid_fid ("s_mid",FieldLayout({COL, LEV},{ncols, nlevs }),m,grid->name());
FieldIdentifier s_int_fid ("s_int",FieldLayout({COL, ILEV},{ncols, nlevs+1}),m,grid->name());
FieldIdentifier v_mid_fid ("v_mid",FieldLayout({COL,CMP, LEV},{ncols,ndims,nlevs }),m,grid->name());
FieldIdentifier v_int_fid ("v_int",FieldLayout({COL,CMP,ILEV},{ncols,ndims,nlevs+1}),m,grid->name());
- FieldIdentifier z_mid_fid ("z_mid",FieldLayout({COL, LEV},{ncols, nlevs }),m,grid->name());
- FieldIdentifier z_int_fid ("z_int",FieldLayout({COL, ILEV},{ncols, nlevs+1}),m,grid->name());
+ // Create vertical fields z and geo on both midpoints and interfaces
+ FieldIdentifier z_surf_fid ("z_surf", FieldLayout({COL },{ncols }),m,grid->name());
+ FieldIdentifier z_mid_fid ("z_mid", FieldLayout({COL, LEV},{ncols, nlevs }),m,grid->name());
+ FieldIdentifier z_int_fid ("z_int", FieldLayout({COL, ILEV},{ncols, nlevs+1}),m,grid->name());
+ FieldIdentifier geo_mid_fid ("geopotential_mid",FieldLayout({COL, LEV},{ncols, nlevs }),m,grid->name());
+ FieldIdentifier geo_int_fid ("geopotential_int",FieldLayout({COL, ILEV},{ncols, nlevs+1}),m,grid->name());
+ // Keep track of reference fields for comparison
+ FieldIdentifier s_tgt_fid ("scalar_target",FieldLayout({COL },{ncols }),m,grid->name());
+ FieldIdentifier v_tgt_fid ("vector_target",FieldLayout({COL,CMP},{ncols,ndims}),m,grid->name());
- Field s_mid (s_mid_fid);
- Field s_int (s_int_fid);
- Field v_mid (v_mid_fid);
- Field v_int (v_int_fid);
- Field z_mid (z_mid_fid);
- Field z_int (z_int_fid);
+ Field s_mid (s_mid_fid);
+ Field s_int (s_int_fid);
+ Field v_mid (v_mid_fid);
+ Field v_int (v_int_fid);
+ Field z_surf (z_surf_fid);
+ Field z_mid (z_mid_fid);
+ Field z_int (z_int_fid);
+ Field geo_mid (geo_mid_fid);
+ Field geo_int (geo_int_fid);
+ Field s_tgt (s_tgt_fid);
+ Field v_tgt (v_tgt_fid);
s_mid.allocate_view();
s_int.allocate_view();
v_mid.allocate_view();
v_int.allocate_view();
+ z_surf.allocate_view();
z_mid.allocate_view();
z_int.allocate_view();
+ geo_mid.allocate_view();
+ geo_int.allocate_view();
+ s_tgt.allocate_view();
+ v_tgt.allocate_view();
s_mid.get_header().get_tracking().update_time_stamp(t0);
s_int.get_header().get_tracking().update_time_stamp(t0);
v_mid.get_header().get_tracking().update_time_stamp(t0);
v_int.get_header().get_tracking().update_time_stamp(t0);
+ z_surf.get_header().get_tracking().update_time_stamp(t0);
z_mid.get_header().get_tracking().update_time_stamp(t0);
z_int.get_header().get_tracking().update_time_stamp(t0);
+ geo_mid.get_header().get_tracking().update_time_stamp(t0);
+ geo_int.get_header().get_tracking().update_time_stamp(t0);
+ s_tgt.get_header().get_tracking().update_time_stamp(t0);
+ v_tgt.get_header().get_tracking().update_time_stamp(t0);
auto print = [&](const std::string& msg) {
if (comm.am_i_root()) {
@@ -69,16 +96,19 @@ TEST_CASE("field_at_height")
auto engine = scream::setup_random_test(&comm);
using IPDF = std::uniform_int_distribution;
+ using RPDF = std::uniform_real_distribution;
IPDF pdf_fields (0,1000);
- IPDF pdf_levs (1,nlevs-1);
+ RPDF pdf_m (1,10);
+ RPDF pdf_y0 (0,5);
// Lambda to create and run a diag, and return output
auto run_diag = [&](const Field& f, const Field& z,
- const std::string& loc) {
+ const std::string& loc, const std::string& surf_ref) {
util::TimeStamp t0 ({2022,1,1},{0,0,0});
auto& factory = AtmosphereDiagnosticFactory::instance();
ekat::ParameterList pl;
+ pl.set("surface_reference",surf_ref);
pl.set("vertical_location",loc);
pl.set("field_name",f.name());
pl.set("grid_name",grid->name());
@@ -92,135 +122,231 @@ TEST_CASE("field_at_height")
return diag->get_diagnostic();
};
- // Create z(i,j)=nlevs-j, which makes testing easier
- for (auto f : {z_mid, z_int}) {
- auto v = f.get_view();
- const auto& dims = f.get_header().get_identifier().get_layout().dims();
- for (int i=0; i();
+ const auto& zmid_v = z_mid.get_view();
+ const auto& zsurf_v = z_surf.get_view();
+ const auto& geoint_v = geo_int.get_view();
+ const auto& geomid_v = geo_mid.get_view();
+ int min_col_thickness = z_top;
+ int max_surf = 0;
+ for (int ii=0; ii max_surf ? zsurf_v(ii) : max_surf;
+ const Real col_thickness = z_top - zsurf_v(ii);
+ min_col_thickness = min_col_thickness < col_thickness ? col_thickness : min_col_thickness;
+ const Real dz = (z_top - zsurf_v(ii))/nlevs;
+ zint_v(ii,0) = z_top;
+ geoint_v(ii,0) = z_top - zsurf_v(ii); // Note, the distance above surface needs to consider the surface height.
+ for (int jj=0; jj Testing throws error with unsupported reference height...\n");
+ {
+ REQUIRE_THROWS(run_diag (s_mid,geo_mid,"1m","foobar"));
}
+ print(" -> Testing throws error with unsupported reference height... OK\n");
// Run many times
- Real z_tgt,lev_tgt;
+ int z_tgt;
std::string loc;
- for (int irun=0; irun();
- const auto& size = f.get_header().get_identifier().get_layout().size();
- for (int i=0; i Testing for a reference height above %s...\n",surf_ref.c_str());
+ const auto mid_src = surf_ref == "sealevel" ? z_mid : geo_mid;
+ const auto int_src = surf_ref == "sealevel" ? z_int : geo_int;
+ const int max_surf_4test = surf_ref == "sealevel" ? max_surf : 0;
+ for (int irun=0; irun Testing with z_tgt coinciding with a z level\n");
- {
- print(" -> scalar midpoint field...............\n");
- auto d = run_diag (s_mid,z_mid,loc);
- auto tgt = s_mid.subfield(1,static_cast(lev_tgt));
- REQUIRE (views_are_equal(d,tgt,&comm));
- print(" -> scalar midpoint field............... OK!\n");
- }
- {
- print(" -> scalar interface field...............\n");
- auto d = run_diag (s_int,z_int,loc);
- // z_mid = nlevs+1-ilev, so the tgt slice is nlevs+1-z_tgt
- auto tgt = s_int.subfield(1,static_cast(lev_tgt));
- REQUIRE (views_are_equal(d,tgt,&comm));
- print(" -> scalar interface field............... OK!\n");
- }
- {
- print(" -> vector midpoint field...............\n");
- auto d = run_diag (v_mid,z_mid,loc);
- // We can't subview over 3rd index and keep layout right,
- // so do all cols separately
- for (int i=0; i(lev_tgt));
- REQUIRE (views_are_equal(di,tgt,&comm));
+ // Set target z-slice for testing to a random value.
+ z_tgt = pdf_levs(engine)+max_surf_4test;
+ loc = std::to_string(z_tgt) + "m";
+ printf(" -> test at height of %s.............\n",loc.c_str());
+ {
+ print(" -> scalar midpoint field...............\n");
+ auto d = run_diag(s_mid,mid_src,loc,surf_ref);
+ f_z_tgt(inter,slope,z_tgt,mid_src,s_tgt);
+ REQUIRE (views_are_approx_equal(d,s_tgt,tol));
+ print(" -> scalar midpoint field............... OK!\n");
+ }
+ {
+ print(" -> scalar interface field...............\n");
+ auto d = run_diag (s_int,int_src,loc,surf_ref);
+ f_z_tgt(inter,slope,z_tgt,int_src,s_tgt);
+ REQUIRE (views_are_approx_equal(d,s_tgt,tol));
+ print(" -> scalar interface field............... OK!\n");
+ }
+ {
+ print(" -> vector midpoint field...............\n");
+ auto d = run_diag (v_mid,mid_src,loc,surf_ref);
+ f_z_tgt(inter,slope,z_tgt,mid_src,v_tgt);
+ REQUIRE (views_are_approx_equal(d,v_tgt,tol));
+ print(" -> vector midpoint field............... OK!\n");
+ }
+ {
+ print(" -> vector interface field...............\n");
+ auto d = run_diag (v_int,int_src,loc,surf_ref);
+ f_z_tgt(inter,slope,z_tgt,int_src,v_tgt);
+ REQUIRE (views_are_approx_equal(d,v_tgt,tol));
+ print(" -> vector interface field............... OK!\n");
+ }
+ {
+ print(" -> Forced fail, give incorrect location...............\n");
+ const int z_tgt_adj = (z_tgt+max_surf_4test)/2;
+ std::string loc_err = std::to_string(z_tgt_adj) + "m";
+ auto d = run_diag(s_int,int_src,loc_err,surf_ref);
+ f_z_tgt(inter,slope,z_tgt,int_src,s_tgt);
+ REQUIRE (!views_are_approx_equal(d,s_tgt,tol,false));
+ print(" -> Forced fail, give incorrect location............... OK!\n");
}
- print(" -> vector midpoint field............... OK!\n");
}
{
- print(" -> vector interface field...............\n");
- auto d = run_diag (v_int,z_int,loc);
- // We can't subview over 3rd index and keep layout right,
- // so do all cols separately
- for (int i=0; i(lev_tgt));
- REQUIRE (views_are_equal(di,tgt,&comm));
- }
- print(" -> vector interface field............... OK!\n");
+ print(" -> Forced extrapolation ...............\n");
+ auto slope = pdf_m(engine);
+ auto inter = pdf_y0(engine);
+ f_z_src(inter, slope, int_src, s_int);
+ print(" -> at top...............\n");
+ z_tgt = 2*z_top;
+ std::string loc = std::to_string(z_tgt) + "m";
+ auto dtop = run_diag(s_int,int_src,loc,surf_ref);
+ f_z_tgt(inter,slope,z_tgt,int_src,s_tgt);
+ REQUIRE (views_are_approx_equal(dtop,s_tgt,tol));
+ print(" -> at bot...............\n");
+ z_tgt = 0;
+ loc = std::to_string(z_tgt) + "m";
+ auto dbot = run_diag(s_int,int_src,loc,surf_ref);
+ f_z_tgt(inter,slope,z_tgt,int_src,s_tgt);
+ REQUIRE (views_are_approx_equal(dbot,s_tgt,tol));
+ print(" -> Forced extrapolation............... OK!\n");
}
+ printf(" -> Testing for a reference height above %s... OK!\n",surf_ref.c_str());
+ }
+}
- z_tgt = pdf_levs(engine) + 0.5;
- lev_tgt = nlevs-z_tgt;
- loc = std::to_string(z_tgt) + "m";
-
- auto zp1 = static_cast(std::round(lev_tgt+0.5));
- auto zm1 = static_cast(std::round(lev_tgt-0.5));
-
- print(" -> Testing with z_tgt between levels\n");
- {
- print(" -> scalar midpoint field...............\n");
- auto d = run_diag (s_mid,z_mid,loc);
- auto tgt = s_mid.subfield(1,zp1).clone();
- tgt.update(s_mid.subfield(1,zm1),0.5,0.5);
- REQUIRE (views_are_equal(d,tgt,&comm));
- print(" -> scalar midpoint field............... OK!\n");
+//-------------------------------
+// Set up the inpute data. To make the test simple we assume a linear distribution of the data
+// with height. That way we can exactly calculate what a linear interpolation to a random
+// height would be.
+void f_z_src(const Real y0, const Real m, const Field& z_data, Field& out_data) {
+ using namespace ShortFieldTagsNames;
+ const auto layout = out_data.get_header().get_identifier().get_layout();
+ if (layout.has_tag(CMP)) { // Is a vector layout, meaning different dims than z_data.
+ const auto& dims = layout.dims();
+ const auto& z_view = z_data.get_view();
+ const auto& out_view = out_data.get_view();
+ for (int ii=0; ii scalar interface field...............\n");
- auto d = run_diag (s_int,z_int,loc);
- auto tgt = s_int.subfield(1,zp1).clone();
- tgt.update(s_int.subfield(1,zm1),0.5,0.5);
- REQUIRE (views_are_equal(d,tgt,&comm));
- print(" -> scalar interface field............... OK!\n");
+ } else { // Not a vector output, easier to deal with
+ const auto z_view = z_data.get_internal_view_data();
+ const auto& size = z_data.get_header().get_identifier().get_layout().size();
+ auto out_view = out_data.get_internal_view_data();
+ for (int ii=0; ii vector midpoint field...............\n");
- auto d = run_diag (v_mid,z_mid,loc);
- // We can't subview over 3rd index and keep layout right,
- // so do all cols separately
- for (int i=0; i();
+ const auto& zdims = z_data.get_header().get_identifier().get_layout().dims();
+ if (layout.has_tag(CMP)) { // Is a vector layout, meaning different dims than z_target.
+ const auto& dims = layout.dims();
+ const auto& out_view = out_data.get_view();
+ for (int ii=0; ii z_view(ii,0)) {
+ out_view(ii,nd) = y0 + m*(nd+1)*z_view(ii,0);
+ } else if ( z_target < z_view(ii,zdims[1]-1)) {
+ out_view(ii,nd) = y0 + m*(nd+1)*z_view(ii,zdims[1]-1);
+ } else {
+ out_view(ii,nd) = y0 + m*(nd+1)*z_target;
+ }
}
- print(" -> vector midpoint field............... OK!\n");
}
- {
- print(" -> vector interface field...............\n");
- auto d = run_diag (v_int,z_int,loc);
- // We can't subview over 3rd index and keep layout right,
- // so do all cols separately
- for (int i=0; i();
+ for (int ii=0; ii z_view(ii,0)) {
+ out_view(ii) = y0 + m*z_view(ii,0);
+ } else if ( z_target < z_view(ii,zdims[1]-1)) {
+ out_view(ii) = y0 + m*z_view(ii,zdims[1]-1);
+ } else {
+ out_view(ii) = y0 + m*z_target;
}
- print(" -> vector interface field............... OK!\n");
}
}
+ out_data.sync_to_dev();
+}
+/*-----------------------------------------------------------------------------------------------*/
+bool views_are_approx_equal(const Field& f0, const Field& f1, const Real tol, const bool msg)
+{
+ const auto& l0 = f0.get_header().get_identifier().get_layout();
+ const auto& l1 = f1.get_header().get_identifier().get_layout();
+ EKAT_REQUIRE_MSG(l0==l1,"Error! views_are_approx_equal - the two fields don't have matching layouts.");
+ // Take advantage of field utils update, min and max to assess the max difference between the two fields
+ // simply.
+ auto ft = f0.clone();
+ ft.update(f1,1.0,-1.0);
+ auto d_min = field_min(ft);
+ auto d_max = field_max(ft);
+ if (std::abs(d_min) > tol or std::abs(d_max) > tol) {
+ if (msg) {
+ printf("The two copies of (%16s) are NOT approx equal within a tolerance of %e.\n The min and max errors are %e and %e respectively.\n",f0.name().c_str(),tol,d_min,d_max);
+ }
+ return false;
+ } else {
+ return true;
+ }
+
}
} // namespace scream
diff --git a/components/eamxx/src/diagnostics/tests/vapor_flux_tests.cpp b/components/eamxx/src/diagnostics/tests/vapor_flux_tests.cpp
index aceb705a61c7..bcd7efc8bb87 100644
--- a/components/eamxx/src/diagnostics/tests/vapor_flux_tests.cpp
+++ b/components/eamxx/src/diagnostics/tests/vapor_flux_tests.cpp
@@ -83,7 +83,7 @@ void run(std::mt19937_64& engine)
REQUIRE_THROWS (diag_factory.create("VaporFlux",comm,params)); // No 'Wind Component'
params.set("Wind Component","foo");
REQUIRE_THROWS (diag_factory.create("VaporFlux",comm,params)); // Invalid 'Wind Component'
- for (const std::string& which_comp : {"Zonal", "Meridional"}) {
+ for (const std::string which_comp : {"Zonal", "Meridional"}) {
// Construct the Diagnostic
params.set("Wind Component",which_comp);
auto diag = diag_factory.create("VaporFlux",comm,params);
diff --git a/components/eamxx/src/diagnostics/tests/wind_speed_tests.cpp b/components/eamxx/src/diagnostics/tests/wind_speed_tests.cpp
new file mode 100644
index 000000000000..7e3affedacb2
--- /dev/null
+++ b/components/eamxx/src/diagnostics/tests/wind_speed_tests.cpp
@@ -0,0 +1,96 @@
+#include "catch2/catch.hpp"
+
+#include "diagnostics/register_diagnostics.hpp"
+#include "share/grid/mesh_free_grids_manager.hpp"
+#include "share/util/scream_setup_random_test.hpp"
+#include "share/field/field_utils.hpp"
+
+namespace scream {
+
+std::shared_ptr
+create_gm (const ekat::Comm& comm, const int ncols, const int nlevs) {
+
+ const int num_global_cols = ncols*comm.size();
+
+ using vos_t = std::vector;
+ ekat::ParameterList gm_params;
+ gm_params.set("grids_names",vos_t{"Point Grid"});
+ auto& pl = gm_params.sublist("Point Grid");
+ pl.set("type","point_grid");
+ pl.set("aliases",vos_t{"Physics"});
+ pl.set("number_of_global_columns", num_global_cols);
+ pl.set("number_of_vertical_levels", nlevs);
+
+ auto gm = create_mesh_free_grids_manager(comm,gm_params);
+ gm->build_grids();
+
+ return gm;
+}
+
+TEST_CASE("wind_speed")
+{
+ using namespace ShortFieldTagsNames;
+ using namespace ekat::units;
+
+ // A world comm
+ ekat::Comm comm(MPI_COMM_WORLD);
+
+ // A time stamp
+ util::TimeStamp t0 ({2022,1,1},{0,0,0});
+
+ // Create a grids manager - single column for these tests
+ constexpr int nlevs = 33;
+ const int ngcols = 2*comm.size();;
+ auto gm = create_gm(comm,ngcols,nlevs);
+ auto grid = gm->get_grid("Physics");
+
+ // Input (randomized) velocity
+ auto vector3d = grid->get_3d_vector_layout(true,CMP,2);
+ FieldIdentifier uv_fid ("horiz_winds",vector3d,m/s,grid->name());
+ Field uv(uv_fid);
+ uv.allocate_view();
+ uv.get_header().get_tracking().update_time_stamp(t0);
+
+ // Construct random number generator stuff
+ using RPDF = std::uniform_real_distribution;
+ RPDF pdf(-1,1);
+ auto engine = scream::setup_random_test();
+
+ // Construct the Diagnostics
+ std::map> diags;
+ auto& diag_factory = AtmosphereDiagnosticFactory::instance();
+ register_diagnostics();
+
+ constexpr int ntests = 5;
+ for (int itest=0; itestset_grids(gm);
+ diag->set_required_field(uv);
+ diag->initialize(t0,RunType::Initial);
+
+ // Run diag
+ diag->compute_diagnostic();
+
+ // Check result
+ uv.sync_to_host();
+ diag->get_diagnostic().sync_to_host();
+
+ auto uv_h = uv.get_view();
+ auto ws_h = diag->get_diagnostic().get_view();
+
+ for (int icol=0; icolget_num_local_dofs(); ++icol) {
+ for (int ilev=0; ilev
+
+namespace scream
+{
+
+WindSpeed::
+WindSpeed (const ekat::Comm& comm, const ekat::ParameterList& params)
+ : AtmosphereDiagnostic(comm,params)
+{
+ // Nothing to do here
+}
+
+void WindSpeed::
+set_grids(const std::shared_ptr grids_manager)
+{
+ using namespace ekat::units;
+ using namespace ShortFieldTagsNames;
+
+ auto grid = grids_manager->get_grid("Physics");
+ const auto& grid_name = grid->name();
+
+ m_ncols = grid->get_num_local_dofs();
+ m_nlevs = grid->get_num_vertical_levels();
+
+ auto scalar3d = grid->get_3d_scalar_layout(true);
+ auto vector3d = grid->get_3d_vector_layout(true,CMP,2);
+
+ // The fields required for this diagnostic to be computed
+ add_field("horiz_winds", vector3d, Pa, grid_name);
+
+ // Construct and allocate the 3d wind_speed field
+ FieldIdentifier fid ("wind_speed", scalar3d, m/s, grid_name);
+ m_diagnostic_output = Field(fid);
+ m_diagnostic_output.allocate_view();
+}
+
+void WindSpeed::compute_diagnostic_impl()
+{
+ using KT = KokkosTypes;
+ using RP = typename KT::RangePolicy;
+
+ const auto uv = get_field_in("horiz_winds").get_view();
+ const auto ws = m_diagnostic_output.get_view();
+
+ const int nlevs = m_nlevs;
+ Kokkos::parallel_for("Compute " + name(), RP(0,m_nlevs*m_ncols),
+ KOKKOS_LAMBDA(const int& idx) {
+ const int icol = idx / nlevs;
+ const int ilev = idx % nlevs;
+ const auto& u = uv(icol,0,ilev);
+ const auto& v = uv(icol,1,ilev);
+ ws (icol,ilev) = sqrt(u*u + v*v);
+ });
+}
+
+} //namespace scream
diff --git a/components/eamxx/src/diagnostics/wind_speed.hpp b/components/eamxx/src/diagnostics/wind_speed.hpp
new file mode 100644
index 000000000000..91ac551a1b76
--- /dev/null
+++ b/components/eamxx/src/diagnostics/wind_speed.hpp
@@ -0,0 +1,37 @@
+#ifndef EAMXX_WIND_SPEED_HPP
+#define EAMXX_WIND_SPEED_HPP
+
+#include "share/atm_process/atmosphere_diagnostic.hpp"
+
+namespace scream
+{
+
+/*
+ * This diagnostic will compute the magnitute of the horiz_winds vector
+ */
+
+class WindSpeed : public AtmosphereDiagnostic
+{
+public:
+ // Constructors
+ WindSpeed (const ekat::Comm& comm, const ekat::ParameterList& params);
+
+ // The name of the diagnostic
+ std::string name () const override { return "wind_speed"; }
+
+ // Set the grid
+ void set_grids (const std::shared_ptr grids_manager) override;
+
+protected:
+#ifdef KOKKOS_ENABLE_CUDA
+public:
+#endif
+ void compute_diagnostic_impl () override;
+
+ int m_ncols;
+ int m_nlevs;
+};
+
+} //namespace scream
+
+#endif // EAMXX_WIND_SPEED_HPP
diff --git a/components/eamxx/src/doubly-periodic/CMakeLists.txt b/components/eamxx/src/doubly-periodic/CMakeLists.txt
deleted file mode 100644
index 09dab68a8e28..000000000000
--- a/components/eamxx/src/doubly-periodic/CMakeLists.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-include (ScreamUtils)
-
-set(DP_SRCS
- dp_f90.cpp
- dp_iso_c.f90
- #${SCREAM_BASE_DIR}/../eam/src/control/apply_iop_forcing.F90
- #${SCREAM_BASE_DIR}/../eam/src/dynamics/se/se_iop_intr_mod.F90",
- #${SCREAM_BASE_DIR}/../eam/src/control/iop_data_mod.F90",
- #${SCREAM_BASE_DIR}/../eam/src/control/history_iop.F90"
-)
-
-# Set cmake config options for Homme
-if (NOT "${SCREAM_DYNAMICS_DYCORE}" STREQUAL "HOMME")
- message(FATAL_ERROR "Requires homme")
-endif()
-
-# Get or create the dynamics lib
-# HOMME_TARGET NP PLEV QSIZE_D
-CreateDynamicsLib("theta-l_kokkos" 4 72 10)
-
-if (NOT SCREAM_LIB_ONLY)
- list(APPEND DP_SRCS
- dp_functions_f90.cpp
- ) # Add f90 bridges needed for testing
-endif()
-
-# Add ETI source files if not on CUDA/HIP
-if (NOT EAMXX_ENABLE_GPU OR Kokkos_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE OR Kokkos_ENABLE_HIP_RELOCATABLE_DEVICE_CODE)
- list(APPEND DP_SRCS
- eti/dp_advance_iop_forcing.cpp
- eti/dp_advance_iop_nudging.cpp
- eti/dp_advance_iop_subsidence.cpp
- eti/dp_iop_setinitial.cpp
- eti/dp_iop_broadcast.cpp
- eti/dp_apply_iop_forcing.cpp
- eti/dp_iop_domain_relaxation.cpp
- eti/dp_crm_resolved_turb.cpp
- eti/dp_iop_default_opts.cpp
- eti/dp_iop_setopts.cpp
- eti/dp_setiopupdate_init.cpp
- eti/dp_setiopupdate.cpp
- eti/dp_readiopdata.cpp
- eti/dp_iop_intht.cpp
- ) # DP ETI SRCS
-endif()
-
-add_library(dp ${DP_SRCS})
-set_target_properties(dp PROPERTIES
- Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/modules
-)
-target_include_directories(dp PUBLIC
- ${CMAKE_CURRENT_BINARY_DIR}/modules
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/impl
-)
-target_link_libraries(dp PUBLIC physics_share scream_share ${dynLibName})
-
-#if (NOT SCREAM_LIB_ONLY)
-# add_subdirectory(tests)
-#endif()
diff --git a/components/eamxx/src/doubly-periodic/dp_constants.hpp b/components/eamxx/src/doubly-periodic/dp_constants.hpp
deleted file mode 100644
index c974106f83ec..000000000000
--- a/components/eamxx/src/doubly-periodic/dp_constants.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef DP_CONSTANTS_HPP
-#define DP_CONSTANTS_HPP
-
-namespace scream {
-namespace dp {
-
-/*
- * Mathematical constants used by dp.
- */
-
-template
-struct Constants
-{
- static constexpr Scalar iop_nudge_tq_low = 1050;
- static constexpr Scalar iop_nudge_tq_high = 0;
- static constexpr Scalar iop_nudge_tscale = 10800;
-};
-
-} // namespace dp
-} // namespace scream
-
-#endif
diff --git a/components/eamxx/src/doubly-periodic/dp_f90.cpp b/components/eamxx/src/doubly-periodic/dp_f90.cpp
deleted file mode 100644
index 2802e5266fd5..000000000000
--- a/components/eamxx/src/doubly-periodic/dp_f90.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "dp_f90.hpp"
-#include "physics_constants.hpp"
-
-#include "ekat/ekat_assert.hpp"
-
-using scream::Int;
-
-extern "C" {
-
-void init_time_level_c (const int& nm1, const int& n0, const int& np1,
- const int& nstep, const int& nstep0);
-
-}
-
-namespace scream {
-namespace dp {
-
-void dp_init(const bool force_reinit) {
- static bool is_init = false;
- if (!is_init || force_reinit) {
- init_time_level_c(10, 3, 11, 5, 4);
- is_init = true;
- }
-}
-
-} // namespace dp
-} // namespace scream
diff --git a/components/eamxx/src/doubly-periodic/dp_f90.hpp b/components/eamxx/src/doubly-periodic/dp_f90.hpp
deleted file mode 100644
index 338a583f777a..000000000000
--- a/components/eamxx/src/doubly-periodic/dp_f90.hpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef SCREAM_DP_F90_HPP
-#define SCREAM_DP_F90_HPP
-
-#include "share/scream_types.hpp"
-
-#include
-#include
-
-namespace scream {
-namespace dp {
-
-// Initialize DP. This is only for standalone DP testing.
-void dp_init(const bool force_reinit=false);
-
-} // namespace dp
-} // namespace scream
-
-#endif
diff --git a/components/eamxx/src/doubly-periodic/dp_functions.hpp b/components/eamxx/src/doubly-periodic/dp_functions.hpp
deleted file mode 100644
index 18e6ec58ba9e..000000000000
--- a/components/eamxx/src/doubly-periodic/dp_functions.hpp
+++ /dev/null
@@ -1,325 +0,0 @@
-#ifndef DP_FUNCTIONS_HPP
-#define DP_FUNCTIONS_HPP
-
-#include "physics/share/physics_constants.hpp"
-#include "dp_constants.hpp"
-
-#include "share/scream_types.hpp"
-
-#include "ekat/ekat_pack_kokkos.hpp"
-#include "ekat/ekat_workspace.hpp"
-
-#include "Elements.hpp"
-#include "Tracers.hpp"
-
-namespace scream {
-namespace dp {
-
-/*
- * Functions is a stateless struct used to encapsulate a
- * number of functions for DP. We use the ETI pattern for
- * these functions.
- *
- * DP assumptions:
- * - Kokkos team policies have a vector length of 1
- */
-
-using element_t = Homme::Elements;
-using tracer_t = Homme::Tracers;
-struct hvcoord_t{};
-struct timelevel_t{};
-struct hybrid_t{};
-
-template
-struct Functions
-{
- //
- // ------- Types --------
- //
-
- using Scalar = ScalarT;
- using Device = DeviceT;
-
- template
- using BigPack = ekat::Pack;
- template
- using SmallPack = ekat::Pack;
-
- using IntSmallPack = SmallPack;
- using Pack = BigPack;
- using Spack = SmallPack;
-
- using Mask = ekat::Mask;
- using Smask = ekat::Mask;
-
- using KT = ekat::KokkosTypes;
- using ExeSpace = typename KT::ExeSpace;
-
- using C = physics::Constants;
- using DPC = dp::Constants;
-
- template
- using view_1d = typename KT::template view_1d;
- template
- using view_2d = typename KT::template view_2d;
- template
- using view_3d = typename KT::template view_3d;
-
- template
- using view_1d_ptr_array = typename KT::template view_1d_ptr_carray;
-
- template
- using uview_1d = typename ekat::template Unmanaged >;
-
- template
- using uview_2d = typename ekat::template Unmanaged >;
-
- using MemberType = typename KT::MemberType;
-
- using WorkspaceMgr = typename ekat::WorkspaceManager;
- using Workspace = typename WorkspaceMgr::Workspace;
-
- //
- // --------- Functions ---------
- //
-
- // ---------------------------------------------------------------------
- // Define the pressures of the interfaces and midpoints from the
- // coordinate definitions and the surface pressure.
- // ---------------------------------------------------------------------
- KOKKOS_FUNCTION
- static void plevs0(
- // Input arguments
- const Int& nver, // vertical dimension
- const Scalar& ps, // Surface pressure (pascals)
- const uview_1d& hyai, // ps0 component of hybrid coordinate - interfaces
- const uview_1d& hyam, // ps0 component of hybrid coordinate - midpoints
- const uview_1d& hybi, // ps component of hybrid coordinate - interfaces
- const uview_1d& hybm, // ps component of hybrid coordinate - midpoints
- // Kokkos stuff
- const MemberType& team,
- // Output arguments
- const uview_1d& pint, // Pressure at model interfaces
- const uview_1d& pmid, // Pressure at model levels
- const uview_1d& pdel); // Layer thickness (pint(k+1) - pint(k))
-
- //-----------------------------------------------------------------------
- // advance_iop_forcing
- // Purpose:
- // Apply large scale forcing for t, q, u, and v as provided by the
- // case IOP forcing file.
- //
- // Author:
- // Original version: Adopted from CAM3.5/CAM5
- // Updated version for E3SM: Peter Bogenschutz (bogenschutz1@llnl.gov)
- // and replaces the forecast.F90 routine in CAM3.5/CAM5/CAM6/E3SMv1/E3SMv2
- // CXX version: James Foucar (jgfouca@sandia.gov)
- //
- //-----------------------------------------------------------------------
- KOKKOS_FUNCTION
- static void advance_iop_forcing(
- // Input arguments
- const Int& plev, // number of vertical levels
- const Int& pcnst, // number of advected constituents including cloud water
- const bool& have_u, // dataset contains u
- const bool& have_v, // dataset contains v
- const bool& dp_crm, // use 3d forcing
- const bool& use_3dfrc, // use 3d forcing
- const Scalar& scm_dt, // model time step [s]
- const Scalar& ps_in, // surface pressure [Pa]
- const uview_1d& u_in, // zonal wind [m/s]
- const uview_1d& v_in, // meridional wind [m/s]
- const uview_1d& t_in, // temperature [K]
- const uview_2d& q_in, // q tracer array [units vary]
- const uview_1d& t_phys_frc, // temperature forcing from physics [K/s]
- const uview_1d& divt3d, // 3D T advection
- const uview_2d& divq3d, // 3D q advection
- const uview_1d& divt, // Divergence of temperature
- const uview_2d& divq, // Divergence of moisture
- const uview_1d& wfld, // Vertical motion (slt)
- const uview_1d& uobs, // actual u wind
- const uview_1d& vobs, // actual v wind
- const uview_1d& hyai, // ps0 component of hybrid coordinate - interfaces
- const uview_1d& hyam, // ps0 component of hybrid coordinate - midpoints
- const uview_1d& hybi, // ps component of hybrid coordinate - interfaces
- const uview_1d& hybm, // ps component of hybrid coordinate - midpoints
- // Kokkos stuff
- const MemberType& team,
- const Workspace& workspace,
- // Output arguments
- const uview_1d& u_update, // updated temperature [K]
- const uview_1d& v_update, // updated q tracer array [units vary]
- const uview_1d& t_update, // updated zonal wind [m/s]
- const uview_2d& q_update); // updated meridional wind [m/s]
-
- //-----------------------------------------------------------------------
- // advance_iop_nudging
- // Purpose:
- // Option to nudge t and q to observations as specified by the IOP file
- //
- // Author:
- // Original version: Adopted from CAM3.5/CAM5
- // Updated version for E3SM: Peter Bogenschutz (bogenschutz1@llnl.gov)
- // CXX version: Conrad Clevenger (tccleve@sandia.gov)
- //
- //-----------------------------------------------------------------------
- KOKKOS_FUNCTION
- static void advance_iop_nudging(
- // Input arguments
- const Int& plev, // number of vertical levels
- const Scalar& scm_dt, // model time step [s]
- const Scalar& ps_in, // surface pressure [Pa]
- const uview_1d& t_in, // temperature [K]
- const uview_1d& q_in, // water vapor mixing ratio [kg/kg]
- const uview_1d& tobs, // observed temperature [K]
- const uview_1d& qobs, // observed vapor mixing ratio [kg/kg]
- const uview_1d& hyai, // ps0 component of hybrid coordinate - interfaces
- const uview_1d& hyam, // ps0 component of hybrid coordinate - midpoints
- const uview_1d& hybi, // ps component of hybrid coordinate - interfaces
- const uview_1d& hybm, // ps component of hybrid coordinate - midpoints
- // Kokkos stuff
- const MemberType& team,
- const Workspace& workspace,
- // Output arguments
- const uview_1d& t_update, // updated temperature [K]
- const uview_1d& q_update, // updated water vapor [kg/kg]
- const uview_1d& relaxt, // relaxation of temperature [K/s]
- const uview_1d& relaxq); // relaxation of vapor [kg/kg/s]
-
- KOKKOS_INLINE_FUNCTION
- static void do_advance_iop_subsidence_update(
- const Int& k,
- const Int& plev,
- const Spack& fac,
- const Spack& swfldint,
- const Spack& swfldint_p1,
- const uview_1d& in,
- const uview_1d& in_s,
- const uview_1d& update);
-
- //-----------------------------------------------------------------------
- //
- // Purpose:
- // Option to compute effects of large scale subsidence on T, q, u, and v.
- // Code originated from CAM3.5/CAM5 Eulerian subsidence computation for SCM
- // in the old forecast.f90 routine.
- //-----------------------------------------------------------------------
- KOKKOS_FUNCTION
- static void advance_iop_subsidence(
- // Input arguments
- const Int& plev, // number of vertical levels
- const Int& pcnst, // number of advected constituents including cloud water
- const Scalar& scm_dt, // model time step [s]
- const Scalar& ps_in, // surface pressure [Pa]
- const uview_1d& u_in, // zonal wind [m/s]
- const uview_1d& v_in, // meridional wind [m/s]
- const uview_1d& t_in, // temperature [K]
- const uview_2d& q_in, // tracer [vary]
- const uview_1d& hyai, // ps0 component of hybrid coordinate - interfaces
- const uview_1d& hyam, // ps0 component of hybrid coordinate - midpoints
- const uview_1d& hybi, // ps component of hybrid coordinate - interfaces
- const uview_1d& hybm, // ps component of hybrid coordinate - midpoints
- const uview_1d& wfld, // Vertical motion (slt)
- // Kokkos stuff
- const MemberType& team,
- const Workspace& workspace,
- // Output arguments
- const uview_1d& u_update, // zonal wind [m/s]
- const uview_1d