diff --git a/.github/workflows/build_and_push_docker_latest.yml b/.github/workflows/build_and_push_docker_latest.yml new file mode 100644 index 000000000..4f04b7ec5 --- /dev/null +++ b/.github/workflows/build_and_push_docker_latest.yml @@ -0,0 +1,34 @@ +name: build_test_and_push_docker + +on: + push: + branches: + # Only build containers when pushing to main + - "main" + +env: + LATEST_TAG: dtcenter/ccpp-scm:latest + +jobs: + docker: + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Push latest tag + uses: docker/build-push-action@v5 + with: + context: . + file: docker/Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ env.LATEST_TAG }} diff --git a/.github/workflows/ci_build_scm_ubuntu_22.04_nvidia.yml b/.github/workflows/ci_build_scm_ubuntu_22.04_nvidia.yml new file mode 100644 index 000000000..8bb7fcedb --- /dev/null +++ b/.github/workflows/ci_build_scm_ubuntu_22.04_nvidia.yml @@ -0,0 +1,264 @@ +name: CI test to build the CCPP-SCM on ubuntu v22.04 + +on: [pull_request,workflow_dispatch] + +jobs: + + build_scm: + # The type of runner that the job will run on + runs-on: ubuntu-22.04 + strategy: + matrix: + fortran-compiler: [nvfortran] + build-type: [Release]#, Debug] + enable-gpu-acc: [False, True] + py-version: [3.7.13, 3.9.12] + + # Environmental variables + env: + NETCDF: /home/runner/netcdf + bacio_ROOT: /home/runner/bacio + sp_ROOT: /home/runner/NCEPLIBS-sp + w3emc_ROOT: /home/runner/myw3emc + SCM_ROOT: /home/runner/work/ccpp-scm/ccpp-scm + zlib_ROOT: /home/runner/zlib + HDF5_ROOT: /home/runner/hdf5 + suites: SCM_GFS_v15p2,SCM_GFS_v16,SCM_GFS_v17_p8,SCM_HRRR,SCM_RRFS_v1beta,SCM_RAP,SCM_WoFS_v0 + suites_ps: SCM_GFS_v15p2_ps,SCM_GFS_v16_ps,SCM_GFS_v17_p8_ps,SCM_HRRR_ps,SCM_RRFS_v1beta_ps,SCM_RAP_ps,SCM_WoFS_v0_ps + + # Workflow steps + steps: + + ####################################################################################### + # Cleanup space + ####################################################################################### + - name: Check space (pre) + run: | + df -h + + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@main + with: + # this might remove tools that are actually needed, + # if set to "true" but frees about 6 GB + tool-cache: false + + # all of these default to true, but feel free to set to + # "false" if necessary for your workflow + android: false + dotnet: false + haskell: true + large-packages: true + docker-images: false + swap-storage: false + + - name: Check space (post) + run: | + df -h + + ####################################################################################### + # Initial + ####################################################################################### + - name: Checkout SCM code (into /home/runner/work/ccpp-scm/) + uses: actions/checkout@v3 + + - name: Initialize submodules + run: git submodule update --init --recursive + + ####################################################################################### + # Python setup + ####################################################################################### + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: ${{matrix.py-version}} + + - name: Add conda to system path + run: | + echo $CONDA/bin >> $GITHUB_PATH + + - name: Install NetCDF Python libraries + run: | + conda install --yes -c conda-forge h5py>=3.4 netCDF4 f90nml + + ####################################################################################### + # Install Nvidia. + ####################################################################################### + + - name: Nvidia setup compilers. + env: + NVCOMPILERS: /home/runner/hpc_sdk + NVARCH: Linux_x86_64 + NVHPC_SILENT: true + NVHPC_INSTALL_DIR: /home/runner/hpc_sdk + NVHPC_INSTALL_TYPE: network + NVHPC_INSTALL_LOCAL_DIR: /home/runner/hpc_sdk + run: | + mkdir /home/runner/hpc_sdk && cd /home/runner/hpc_sdk + wget -q https://developer.download.nvidia.com/hpc-sdk/24.1/nvhpc_2024_241_Linux_x86_64_cuda_12.3.tar.gz + tar xpzf nvhpc_2024_241_Linux_x86_64_cuda_12.3.tar.gz + nvhpc_2024_241_Linux_x86_64_cuda_12.3/install + export PATH=${PATH}:${NVCOMPILERS}/${NVARCH}/24.1/compilers/bin + export MANPATH=${MANPATH}:${NVCOMPILERS}/${NVARCH}/24.1/compilers/man + echo "The nvfortran installed is:" + nvfortran --version + echo "The path to nvfortran is:" + command -v nvfortran + echo "Removing tarball" + rm nvhpc_2024_241_Linux_x86_64_cuda_12.3.tar.gz + + - name: Set environment for Nvidia compiler. + run: | + echo "CC=/home/runner/hpc_sdk/Linux_x86_64/24.1/compilers/bin/nvc" >> $GITHUB_ENV + echo "FC=/home/runner/hpc_sdk/Linux_x86_64/24.1/compilers/bin/nvfortran" >> $GITHUB_ENV + echo "CMAKE_C_COMPILER=/home/runner/hpc_sdk/Linux_x86_64/24.1/compilers/bin/nvc" >> $GITHUB_ENV + echo "CMAKE_Fortran_COMPILER=/home/runner/hpc_sdk/Linux_x86_64/24.1/compilers/bin/nvfortran" >> $GITHUB_ENV + + ####################################################################################### + # Install FORTRAN dependencies + ####################################################################################### + + - name: Install zlib + env: + CFLAGS: -fPIC + run: | + wget https://github.com/madler/zlib/releases/download/v1.2.13/zlib-1.2.13.tar.gz + tar -zxvf zlib-1.2.13.tar.gz + cd zlib-1.2.13 + ./configure --prefix=${zlib_ROOT} + make + make install + echo "LD_LIBRARY_PATH=$zlib_ROOT/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV + + - name: Install HDF5 + env: + CPPFLAGS: -I${zlib_ROOT}/include + LDFLAGS: -L${zlib_ROOT}/lib + run: | + wget https://github.com/HDFGroup/hdf5/archive/refs/tags/hdf5-1_14_1-2.tar.gz + tar -zxvf hdf5-1_14_1-2.tar.gz + cd hdf5-hdf5-1_14_1-2 + ./configure --prefix=${HDF5_ROOT} --with-zlib=${zlib_ROOT} + make -j4 + make install + echo "LD_LIBRARY_PATH=$HDF5_ROOT/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV + echo "PATH=$HDF5_ROOT/lib:$PATH" >> $GITHUB_ENV + + - name: Install Curl + run: | + sudo apt-get install curl + sudo apt-get install libssl-dev libcurl4-openssl-dev + + - name: Cache NetCDF C library + id: cache-netcdf-c + uses: actions/cache@v3 + with: + path: /home/runner/netcdf-c + key: cache-netcdf-c-${{matrix.fortran-compiler}}-key + + - name: Install NetCDF C library + if: steps.cache-netcdf-c.outputs.cache-hit != 'true' + run: | + wget https://github.com/Unidata/netcdf-c/archive/refs/tags/v4.7.4.tar.gz + tar -zvxf v4.7.4.tar.gz + cd netcdf-c-4.7.4 + CPPFLAGS="-I/home/runner/hdf5/include -I/home/runner/zlib/include" LDFLAGS="-L/home/runner/hdf5/lib -L/home/runner/zlib/lib" ./configure --prefix=${NETCDF} + make + make install + echo "LD_LIBRARY_PATH=$NETCDF/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV + echo "PATH=$NETCDF/lib:$PATH" >> $GITHUB_ENV + + - name: Cache NetCDF Fortran library + id: cache-netcdf-fortran + uses: actions/cache@v3 + with: + path: /home/runner/netcdf-fortran + key: cache-netcdf-fortran-${{matrix.fortran-compiler}}-key + + - name: Install NetCDF Fortran library + if: steps.cache-netcdf-fortran.outputs.cache-hit != 'true' + run: | + wget https://github.com/Unidata/netcdf-fortran/archive/refs/tags/v4.6.1.tar.gz + tar -zvxf v4.6.1.tar.gz + cd netcdf-fortran-4.6.1 + FCFLAGS="-fPIC" FFLAGS="-fPIC" CPPFLAGS="-I/home/runner/hdf5/include -I/home/runner/zlib/include -I/home/runner/netcdf/include" LDFLAGS="-L/home/runner/hdf5/lib -L/home/runner/zlib/lib -L/home/runner/netcdf/lib" ./configure --prefix=${NETCDF} + make + make install + + - name: Cache bacio library v2.4.1 + id: cache-bacio-fortran + uses: actions/cache@v3 + with: + path: /home/runner/bacio + key: cache-bacio-fortran-${{matrix.fortran-compiler}}-key + + - name: Install bacio library v2.4.1 + if: steps.cache-bacio-fortran.outputs.cache-hit != 'true' + run: | + git clone --branch v2.4.1 https://github.com/NOAA-EMC/NCEPLIBS-bacio.git bacio + cd bacio && mkdir build && cd build + cmake -DCMAKE_INSTALL_PREFIX=${bacio_ROOT} ../ + make -j2 + make install + echo "bacio_DIR=/home/runner/bacio/lib/cmake/bacio" >> $GITHUB_ENV + + - name: Cache SP-library v2.3.3 + id: cache-sp-fortran + uses: actions/cache@v3 + with: + path: /home/runner/NCEPLIBS-sp + key: cache-sp-fortran-${{matrix.fortran-compiler}}-key + + - name: Install SP-library v2.3.3 + if: steps.cache-sp-fortran.outputs.cache-hit != 'true' + run: | + git clone --branch v2.3.3 https://github.com/NOAA-EMC/NCEPLIBS-sp.git NCEPLIBS-sp + cd NCEPLIBS-sp && mkdir build && cd build + cmake -DCMAKE_INSTALL_PREFIX=${sp_ROOT} ../ + make -j2 + make install + echo "sp_DIR=/home/runner/NCEPLIBS-sp/lib/cmake/sp" >> $GITHUB_ENV + + - name: Cache w3emc library v2.9.2 + id: cache-w3emc-fortran + uses: actions/cache@v3 + with: + path: /home/runner/myw3emc + key: cache-w3emc-fortran-${{matrix.fortran-compiler}}-key + + - name: Install w3emc library v2.9.2 + if: steps.cache-w3emc-fortran.outputs.cache-hit != 'true' + run: | + git clone --branch v2.9.2 https://github.com/NOAA-EMC/NCEPLIBS-w3emc.git NCEPLIBS-w3emc + cd NCEPLIBS-w3emc && mkdir build && cd build + cmake -DCMAKE_INSTALL_PREFIX=${w3emc_ROOT} ../ + make -j2 + make install + echo "w3emc_DIR=/home/runner/myw3emc/lib/cmake/w3emc" >> $GITHUB_ENV + + ####################################################################################### + # Build and run SCM regression tests (ccpp-scm/test/rt_test_cases.py) + ####################################################################################### + + - name: Configure build with CMake + run: | + cd ${SCM_ROOT}/scm + mkdir bin && cd bin + cmake -DCCPP_SUITES=${suites},${suites_ps} -DCMAKE_BUILD_TYPE=${{matrix.build-type}} -DENABLE_NVIDIA_OPENACC=${{matrix.enable-gpu-acc}} ../src + + - name: Build SCM. + run: | + cd ${SCM_ROOT}/scm/bin + make -j4 + + - name: Download data for SCM + run: | + cd ${SCM_ROOT} + ./contrib/get_all_static_data.sh + ./contrib/get_thompson_tables.sh + + - name: Run SCM RTs (w/o GPU) + if: contains(matrix.enable-gpu-acc, 'False') + run: | + cd ${SCM_ROOT}/scm/bin + ./run_scm.py --file /home/runner/work/ccpp-scm/ccpp-scm/test/rt_test_cases.py --runtime_mult 0.1 -v diff --git a/.github/workflows/ci_test_docker.yml b/.github/workflows/ci_test_docker.yml new file mode 100644 index 000000000..3406d8326 --- /dev/null +++ b/.github/workflows/ci_test_docker.yml @@ -0,0 +1,29 @@ +name: build_test_and_push_docker + +on: [pull_request,workflow_dispatch] + +env: + TEST_TAG: dtcenter/ccpp-scm:test + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build and export test tag + uses: docker/build-push-action@v5 + with: + context: . + file: docker/Dockerfile + load: true + tags: ${{ env.TEST_TAG }} + - name: Test + run: | + mkdir $HOME/output + chmod a+rw $HOME/output + docker run --rm -v $HOME/output:/home ${{ env.TEST_TAG }} ./run_scm.py -f ../../test/rt_test_cases.py --runtime_mult 0.1 -d diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 000000000..4c335023f --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,54 @@ +title: "CCPP Single Column Model (SCM)" +version: 6.0.0 +message: "Please cite this software using the metadata from this file." +type: software +identifiers: + - description: "This is the archived snapshot of all versions of CCPP SCM" + type: doi + value: 10.5281/zenodo.6896437 + - description: "This is the archived snapshot of CCPP SCM v6.0.0" + type: doi + value: 10.5281/zenodo.6896438 +repository-code: "https://github.com/NCAR/ccpp-scm" +url: "https://dtcenter.org/community-code/common-community-physics-package-ccpp" +authors: + - given-names: Grant + family-names: Firl + affiliation: >- + Cooperative Institute for Research in the Atmosphere, + Developmental Testbed Center, + National Oceanic and Atmospheric Administration Global Systems Laboratory + orcid: 0009-0001-7076-2735 + - given-names: Dustin + family-names: Swales + affiliation: >- + Developmental Testbed Center and + National Oceanic and Atmospheric Administration Global Systems Laboratory + orcid: 0000-0002-5322-4521 + - given-names: Laurie + family-names: Carson + affiliation: >- + Developmental Testbed Center and National Center for Atmospheric Research + - given-names: Ligia + family-names: Bernardet + affiliation: >- + Developmental Testbed Center and + National Oceanic and Atmospheric Administration Global Systems Laboratory + orcid: 0000-0002-4952-4038 + - given-names: Dominikus + family-names: Heinzeller + affiliation: Joint Center for Satellite Data Assimilation + orcid: 0000-0003-2962-1049 + - given-names: Michelle + family-names: Harrold + affiliation: >- + Developmental Testbed Center and National Center for Atmospheric Research + - given-names: Tracy + family-names: Hertneky + affiliation: >- + Developmental Testbed Center and National Center for Atmospheric Research + - given-names: Michael + family-names: Kavulich + affiliation: >- + Developmental Testbed Center and National Center for Atmospheric Research +cff-version: 1.2.0 diff --git a/ccpp/framework b/ccpp/framework index 219f2e9c8..f0b9a18b0 160000 --- a/ccpp/framework +++ b/ccpp/framework @@ -1 +1 @@ -Subproject commit 219f2e9c88b7b774becac2bd1453696e105af1c4 +Subproject commit f0b9a18b005d950cb9b0038fbc827b6b37500f43 diff --git a/ccpp/physics b/ccpp/physics index 6b0599ef6..6d8fccbea 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit 6b0599ef6c7ea076336b1f073899c5b97e37d584 +Subproject commit 6d8fccbea12c11387c0bc457dcb3855574cd29aa diff --git a/ccpp/physics_namelists/input_GFS_v17_HR3.nml b/ccpp/physics_namelists/input_GFS_v17_HR3.nml new file mode 100644 index 000000000..8d859e580 --- /dev/null +++ b/ccpp/physics_namelists/input_GFS_v17_HR3.nml @@ -0,0 +1,171 @@ +&gfs_physics_nml + fhzero = 6 + h2o_phys = .true. + ldiag3d = .true. + qdiag3d = .true. + print_diff_pgr = .false. + fhcyc = 24 + use_ufo = .true. + pre_rad = .false. + imp_physics = 8 + iovr = 3 + ltaerosol = .false. + lradar = .true. + ttendlim = -999 + dt_inner = 150 + sedi_semi = .true. + decfl = 10 + oz_phys = .false. + oz_phys_2015 = .true. + lsoil_lsm = 4 + do_mynnedmf = .false. + do_mynnsfclay = .false. + icloud_bl = 1 + bl_mynn_edmf = 1 + bl_mynn_tkeadvect = .true. + bl_mynn_edmf_mom = 1 + do_ugwp = .false. + do_tofd = .false. + gwd_opt = 2 + do_ugwp_v0 = .false. + do_ugwp_v1 = .true. + do_ugwp_v0_orog_only = .false. + do_ugwp_v0_nst_only = .false. + do_gsl_drag_ls_bl = .true. + do_gsl_drag_ss = .true. + do_gsl_drag_tofd = .true. + do_ugwp_v1_orog_only = .false. + min_lakeice = 0.15 + min_seaice = 1.0e-6 + use_cice_alb = .true. + pdfcld = .false. + fhswr = 1200. + fhlwr = 1200. + progsigma = .true. + betascu = 8.0 + betamcu = 1.0 + betadcu = 2.0 + ialb = 2 + iems = 2 + iaer = 1011 + icliq_sw = 2 + ico2 = 2 + isubc_sw = 2 + isubc_lw = 2 + isol = 2 + lwhtr = .true. + swhtr = .true. + cnvgwd = .true. + shal_cnv = .true. + cal_pre = .false. + redrag = .true. + dspheat = .true. + hybedmf = .false. + satmedmf = .true. + isatmedmf = 1 + lheatstrg = .true. + lseaspray = .true. + random_clds = .false. + trans_trac = .true. + cnvcld = .true. + imfshalcnv = 2 + imfdeepcnv = 2 + ras = .false. + cdmbgwd = 2.5,7.5,1.0,1.0 + prslrd0 = 0. + ivegsrc = 1 + isot = 1 + lsoil = 4 + lsm = 2 + iopt_dveg = 4 + iopt_crs = 2 + iopt_btr = 1 + iopt_run = 1 + iopt_sfc = 3 + iopt_trs = 2 + iopt_frz = 1 + iopt_inf = 1 + iopt_rad = 3 + iopt_alb = 1 + iopt_snf = 4 + iopt_tbot = 2 + iopt_stc = 3 + debug = .false. + nstf_name = 2,0,0,0,0 + nst_anl = .true. + psautco = 0.0008,0.0005 + prautco = 0.00015,0.00015 + lgfdlmprad = .false. + effr_in = .true. + ldiag_ugwp = .false. + do_sppt = .false. + do_shum = .false. + do_skeb = .false. + do_RRTMGP = .false. + doGP_cldoptics_LUT = .true. + doGP_lwscat = .true. + active_gases = 'h2o_co2_o3_n2o_ch4_o2' + ngases = 6 + rrtmgp_root = '../../ccpp/physics/physics/rte-rrtmgp/' + lw_file_gas = 'rrtmgp/data/rrtmgp-data-lw-g128-210809.nc' + lw_file_clouds = 'extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-lw.nc' + sw_file_gas = 'rrtmgp/data/rrtmgp-data-sw-g112-210809.nc' + sw_file_clouds = 'extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-sw.nc' + rrtmgp_nGptsSW = 112 + rrtmgp_nGptsLW = 128 + rrtmgp_nBandsLW = 16 + rrtmgp_nBandsSW = 14 + frac_grid = .true. + cplchm = .false. + cplflx = .false. + cplice = .false. + cplwav = .false. + cplwav2atm = .false. + do_ca = .false. + ca_global = .false. + ca_sgs = .true. + nca = 1 + ncells = 5 + nlives = 12 + nseed = 1 + nfracseed = 0.5 + nthresh = 18 + ca_trigger = .true. + nspinup = 1 + iseed_ca = 1448371824 +/ + +&cires_ugwp_nml + knob_ugwp_solver = 2 + knob_ugwp_version = 1 + knob_ugwp_source = 1,1,0,0 + knob_ugwp_wvspec = 1,25,25,25 + knob_ugwp_azdir = 2,4,4,4 + knob_ugwp_stoch = 0,0,0,0 + knob_ugwp_effac = 1,1,1,1 + knob_ugwp_doaxyz = 1 + knob_ugwp_doheat = 1 + knob_ugwp_dokdis = 2 + knob_ugwp_ndx4lh = 4 + knob_ugwp_palaunch = 275.0e2 + knob_ugwp_nslope = 1 + knob_ugwp_lzmax = 15.750e3 + knob_ugwp_lzmin = 0.75e3 + knob_ugwp_lzstar = 2.0e3 + knob_ugwp_taumin = 0.25e-3 + knob_ugwp_tauamp = 0.5e-3 + knob_ugwp_lhmet = 200.0e3 + knob_ugwp_orosolv = 'pss-1986' +/ + +&ccpp_suite_sim_nml + suite_sim_file = '' + nprc_sim = 7 + prc_LWRAD_cfg = 0, 0, 1 + prc_SWRAD_cfg = 0, 0, 2 + prc_PBL_cfg = 1, 0, 3 + prc_GWD_cfg = 1, 0, 4 + prc_SCNV_cfg = 1, 1, 5 + prc_DCNV_cfg = 1, 1, 6 + prc_cldMP_cfg = 1, 1, 7 +/ diff --git a/ccpp/physics_namelists/input_GFS_v17_HR3_RRTMGP.nml b/ccpp/physics_namelists/input_GFS_v17_HR3_RRTMGP.nml new file mode 100644 index 000000000..f7cf90973 --- /dev/null +++ b/ccpp/physics_namelists/input_GFS_v17_HR3_RRTMGP.nml @@ -0,0 +1,171 @@ +&gfs_physics_nml + fhzero = 6 + h2o_phys = .true. + ldiag3d = .true. + qdiag3d = .true. + print_diff_pgr = .false. + fhcyc = 24 + use_ufo = .true. + pre_rad = .false. + imp_physics = 8 + iovr = 3 + ltaerosol = .false. + lradar = .true. + ttendlim = -999 + dt_inner = 150 + sedi_semi = .true. + decfl = 10 + oz_phys = .false. + oz_phys_2015 = .true. + lsoil_lsm = 4 + do_mynnedmf = .false. + do_mynnsfclay = .false. + icloud_bl = 1 + bl_mynn_edmf = 1 + bl_mynn_tkeadvect = .true. + bl_mynn_edmf_mom = 1 + do_ugwp = .false. + do_tofd = .false. + gwd_opt = 2 + do_ugwp_v0 = .false. + do_ugwp_v1 = .true. + do_ugwp_v0_orog_only = .false. + do_ugwp_v0_nst_only = .false. + do_gsl_drag_ls_bl = .true. + do_gsl_drag_ss = .true. + do_gsl_drag_tofd = .true. + do_ugwp_v1_orog_only = .false. + min_lakeice = 0.15 + min_seaice = 1.0e-6 + use_cice_alb = .true. + pdfcld = .false. + fhswr = 1200. + fhlwr = 1200. + progsigma = .true. + betascu = 8.0 + betamcu = 1.0 + betadcu = 2.0 + ialb = 2 + iems = 2 + iaer = 1011 + icliq_sw = 2 + ico2 = 2 + isubc_sw = 2 + isubc_lw = 2 + isol = 2 + lwhtr = .true. + swhtr = .true. + cnvgwd = .true. + shal_cnv = .true. + cal_pre = .false. + redrag = .true. + dspheat = .true. + hybedmf = .false. + satmedmf = .true. + isatmedmf = 1 + lheatstrg = .true. + lseaspray = .true. + random_clds = .false. + trans_trac = .true. + cnvcld = .true. + imfshalcnv = 2 + imfdeepcnv = 2 + ras = .false. + cdmbgwd = 2.5,7.5,1.0,1.0 + prslrd0 = 0. + ivegsrc = 1 + isot = 1 + lsoil = 4 + lsm = 2 + iopt_dveg = 4 + iopt_crs = 2 + iopt_btr = 1 + iopt_run = 1 + iopt_sfc = 3 + iopt_trs = 2 + iopt_frz = 1 + iopt_inf = 1 + iopt_rad = 3 + iopt_alb = 1 + iopt_snf = 4 + iopt_tbot = 2 + iopt_stc = 3 + debug = .false. + nstf_name = 2,0,0,0,0 + nst_anl = .true. + psautco = 0.0008,0.0005 + prautco = 0.00015,0.00015 + lgfdlmprad = .false. + effr_in = .true. + ldiag_ugwp = .false. + do_sppt = .false. + do_shum = .false. + do_skeb = .false. + do_RRTMGP = .true. + doGP_cldoptics_LUT = .true. + doGP_lwscat = .true. + active_gases = 'h2o_co2_o3_n2o_ch4_o2' + ngases = 6 + rrtmgp_root = '../../ccpp/physics/physics/Radiation/RRTMGP/rte-rrtmgp/' + lw_file_gas = 'rrtmgp/data/rrtmgp-data-lw-g128-210809.nc' + lw_file_clouds = 'extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-lw.nc' + sw_file_gas = 'rrtmgp/data/rrtmgp-data-sw-g112-210809.nc' + sw_file_clouds = 'extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-reordered-sw.nc' + rrtmgp_nGptsSW = 112 + rrtmgp_nGptsLW = 128 + rrtmgp_nBandsLW = 16 + rrtmgp_nBandsSW = 14 + frac_grid = .true. + cplchm = .false. + cplflx = .false. + cplice = .false. + cplwav = .false. + cplwav2atm = .false. + do_ca = .false. + ca_global = .false. + ca_sgs = .true. + nca = 1 + ncells = 5 + nlives = 12 + nseed = 1 + nfracseed = 0.5 + nthresh = 18 + ca_trigger = .true. + nspinup = 1 + iseed_ca = 1448371824 +/ + +&cires_ugwp_nml + knob_ugwp_solver = 2 + knob_ugwp_version = 1 + knob_ugwp_source = 1,1,0,0 + knob_ugwp_wvspec = 1,25,25,25 + knob_ugwp_azdir = 2,4,4,4 + knob_ugwp_stoch = 0,0,0,0 + knob_ugwp_effac = 1,1,1,1 + knob_ugwp_doaxyz = 1 + knob_ugwp_doheat = 1 + knob_ugwp_dokdis = 2 + knob_ugwp_ndx4lh = 4 + knob_ugwp_palaunch = 275.0e2 + knob_ugwp_nslope = 1 + knob_ugwp_lzmax = 15.750e3 + knob_ugwp_lzmin = 0.75e3 + knob_ugwp_lzstar = 2.0e3 + knob_ugwp_taumin = 0.25e-3 + knob_ugwp_tauamp = 0.5e-3 + knob_ugwp_lhmet = 200.0e3 + knob_ugwp_orosolv = 'pss-1986' +/ + +&ccpp_suite_sim_nml + suite_sim_file = '' + nprc_sim = 7 + prc_LWRAD_cfg = 0, 0, 1 + prc_SWRAD_cfg = 0, 0, 2 + prc_PBL_cfg = 1, 0, 3 + prc_GWD_cfg = 1, 0, 4 + prc_SCNV_cfg = 1, 1, 5 + prc_DCNV_cfg = 1, 1, 6 + prc_cldMP_cfg = 1, 1, 7 +/ diff --git a/ccpp/physics_namelists/input_GFS_v17_HR3_RRTMGP_ps.nml b/ccpp/physics_namelists/input_GFS_v17_HR3_RRTMGP_ps.nml new file mode 100644 index 000000000..c562957f2 --- /dev/null +++ b/ccpp/physics_namelists/input_GFS_v17_HR3_RRTMGP_ps.nml @@ -0,0 +1,171 @@ +&gfs_physics_nml + fhzero = 6 + h2o_phys = .true. + ldiag3d = .true. + qdiag3d = .true. + print_diff_pgr = .false. + fhcyc = 24 + use_ufo = .true. + pre_rad = .false. + imp_physics = 8 + iovr = 3 + ltaerosol = .False. + lradar = .true. + ttendlim = -999 + dt_inner = 150 + sedi_semi = .true. + decfl = 10 + oz_phys = .false. + oz_phys_2015 = .true. + lsoil_lsm = 4 + do_mynnedmf = .false. + do_mynnsfclay = .false. + icloud_bl = 1 + bl_mynn_edmf = 1 + bl_mynn_tkeadvect = .true. + bl_mynn_edmf_mom = 1 + do_ugwp = .false. + do_tofd = .false. + gwd_opt = 2 + do_ugwp_v0 = .false. + do_ugwp_v1 = .true. + do_ugwp_v0_orog_only = .false. + do_ugwp_v0_nst_only = .false. + do_gsl_drag_ls_bl = .true. + do_gsl_drag_ss = .true. + do_gsl_drag_tofd = .true. + do_ugwp_v1_orog_only = .false. + min_lakeice = 0.15 + min_seaice = 1.0e-6 + use_cice_alb = .true. + pdfcld = .false. + fhswr = 1200. + fhlwr = 1200. + progsigma = .true. + betascu = 8.0 + betamcu = 1.0 + betadcu = 2.0 + ialb = 2 + iems = 2 + iaer = 1011 + icliq_sw = 2 + ico2 = 2 + isubc_sw = 2 + isubc_lw = 2 + isol = 2 + lwhtr = .true. + swhtr = .true. + cnvgwd = .true. + shal_cnv = .true. + cal_pre = .false. + redrag = .true. + dspheat = .true. + hybedmf = .false. + satmedmf = .true. + isatmedmf = 1 + lheatstrg = .false. + lseaspray = .true. + random_clds = .false. + trans_trac = .true. + cnvcld = .true. + imfshalcnv = 2 + imfdeepcnv = 2 + ras = .false. + cdmbgwd = 2.5,7.5,1.0,1.0 + prslrd0 = 0. + ivegsrc = 1 + isot = 1 + lsoil = 4 + lsm = 2 + iopt_dveg = 4 + iopt_crs = 2 + iopt_btr = 1 + iopt_run = 1 + iopt_sfc = 3 + iopt_trs = 2 + iopt_frz = 1 + iopt_inf = 1 + iopt_rad = 3 + iopt_alb = 1 + iopt_snf = 4 + iopt_tbot = 2 + iopt_stc = 3 + debug = .false. + nstf_name = 2,0,0,0,0 + nst_anl = .true. + psautco = 0.0008,0.0005 + prautco = 0.00015,0.00015 + lgfdlmprad = .false. + effr_in = .true. + ldiag_ugwp = .false. + do_sppt = .false. + do_shum = .false. + do_skeb = .false. + do_RRTMGP = .true. + doGP_cldoptics_LUT = .true. + doGP_lwscat = .true. + active_gases = 'h2o_co2_o3_n2o_ch4_o2' + ngases = 6 + rrtmgp_root = '../../ccpp/physics/physics/Radiation/RRTMGP/rte-rrtmgp/' + lw_file_gas = 'rrtmgp/data/rrtmgp-data-lw-g128-210809.nc' + lw_file_clouds = 'extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-lw.nc' + sw_file_gas = 'rrtmgp/data/rrtmgp-data-sw-g112-210809.nc' + sw_file_clouds = 'extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-reordered-sw.nc' + rrtmgp_nGptsSW = 112 + rrtmgp_nGptsLW = 128 + rrtmgp_nBandsLW = 16 + rrtmgp_nBandsSW = 14 + frac_grid = .true. + cplchm = .false. + cplflx = .false. + cplice = .false. + cplwav = .false. + cplwav2atm = .false. + do_ca = .false. + ca_global = .false. + ca_sgs = .true. + nca = 1 + ncells = 5 + nlives = 12 + nseed = 1 + nfracseed = 0.5 + nthresh = 18 + ca_trigger = .true. + nspinup = 1 + iseed_ca = 1448371824 +/ + +&cires_ugwp_nml + knob_ugwp_solver = 2 + knob_ugwp_version = 1 + knob_ugwp_source = 1,1,0,0 + knob_ugwp_wvspec = 1,25,25,25 + knob_ugwp_azdir = 2,4,4,4 + knob_ugwp_stoch = 0,0,0,0 + knob_ugwp_effac = 1,1,1,1 + knob_ugwp_doaxyz = 1 + knob_ugwp_doheat = 1 + knob_ugwp_dokdis = 2 + knob_ugwp_ndx4lh = 4 + knob_ugwp_palaunch = 275.0e2 + knob_ugwp_nslope = 1 + knob_ugwp_lzmax = 15.750e3 + knob_ugwp_lzmin = 0.75e3 + knob_ugwp_lzstar = 2.0e3 + knob_ugwp_taumin = 0.25e-3 + knob_ugwp_tauamp = 0.5e-3 + knob_ugwp_lhmet = 200.0e3 + knob_ugwp_orosolv = 'pss-1986' +/ + +&ccpp_suite_sim_nml + suite_sim_file = '' + nprc_sim = 7 + prc_LWRAD_cfg = 0, 0, 1 + prc_SWRAD_cfg = 0, 0, 2 + prc_PBL_cfg = 1, 0, 3 + prc_GWD_cfg = 1, 0, 4 + prc_SCNV_cfg = 1, 1, 5 + prc_DCNV_cfg = 1, 1, 6 + prc_cldMP_cfg = 1, 1, 7 +/ diff --git a/ccpp/physics_namelists/input_GFS_v17_HR3_ps.nml b/ccpp/physics_namelists/input_GFS_v17_HR3_ps.nml new file mode 100644 index 000000000..b2f93c79c --- /dev/null +++ b/ccpp/physics_namelists/input_GFS_v17_HR3_ps.nml @@ -0,0 +1,171 @@ +&gfs_physics_nml + fhzero = 6 + h2o_phys = .true. + ldiag3d = .true. + qdiag3d = .true. + print_diff_pgr = .false. + fhcyc = 24 + use_ufo = .true. + pre_rad = .false. + imp_physics = 8 + iovr = 3 + ltaerosol = .False. + lradar = .true. + ttendlim = -999 + dt_inner = 150 + sedi_semi = .true. + decfl = 10 + oz_phys = .false. + oz_phys_2015 = .true. + lsoil_lsm = 4 + do_mynnedmf = .false. + do_mynnsfclay = .false. + icloud_bl = 1 + bl_mynn_edmf = 1 + bl_mynn_tkeadvect = .true. + bl_mynn_edmf_mom = 1 + do_ugwp = .false. + do_tofd = .false. + gwd_opt = 2 + do_ugwp_v0 = .false. + do_ugwp_v1 = .true. + do_ugwp_v0_orog_only = .false. + do_ugwp_v0_nst_only = .false. + do_gsl_drag_ls_bl = .true. + do_gsl_drag_ss = .true. + do_gsl_drag_tofd = .true. + do_ugwp_v1_orog_only = .false. + min_lakeice = 0.15 + min_seaice = 1.0e-6 + use_cice_alb = .true. + pdfcld = .false. + fhswr = 1200. + fhlwr = 1200. + progsigma = .true. + betascu = 8.0 + betamcu = 1.0 + betadcu = 2.0 + ialb = 2 + iems = 2 + iaer = 1011 + icliq_sw = 2 + ico2 = 2 + isubc_sw = 2 + isubc_lw = 2 + isol = 2 + lwhtr = .true. + swhtr = .true. + cnvgwd = .true. + shal_cnv = .true. + cal_pre = .false. + redrag = .true. + dspheat = .true. + hybedmf = .false. + satmedmf = .true. + isatmedmf = 1 + lheatstrg = .false. + lseaspray = .true. + random_clds = .false. + trans_trac = .true. + cnvcld = .true. + imfshalcnv = 2 + imfdeepcnv = 2 + ras = .false. + cdmbgwd = 2.5,7.5,1.0,1.0 + prslrd0 = 0. + ivegsrc = 1 + isot = 1 + lsoil = 4 + lsm = 2 + iopt_dveg = 4 + iopt_crs = 2 + iopt_btr = 1 + iopt_run = 1 + iopt_sfc = 3 + iopt_trs = 2 + iopt_frz = 1 + iopt_inf = 1 + iopt_rad = 3 + iopt_alb = 1 + iopt_snf = 4 + iopt_tbot = 2 + iopt_stc = 3 + debug = .false. + nstf_name = 2,0,0,0,0 + nst_anl = .true. + psautco = 0.0008,0.0005 + prautco = 0.00015,0.00015 + lgfdlmprad = .false. + effr_in = .true. + ldiag_ugwp = .false. + do_sppt = .false. + do_shum = .false. + do_skeb = .false. + do_RRTMGP = .false. + doGP_cldoptics_LUT = .true. + doGP_lwscat = .true. + active_gases = 'h2o_co2_o3_n2o_ch4_o2' + ngases = 6 + rrtmgp_root = '../../ccpp/physics/physics/rte-rrtmgp/' + lw_file_gas = 'rrtmgp/data/rrtmgp-data-lw-g128-210809.nc' + lw_file_clouds = 'extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-lw.nc' + sw_file_gas = 'rrtmgp/data/rrtmgp-data-sw-g112-210809.nc' + sw_file_clouds = 'extensions/cloud_optics/rrtmgp-cloud-optics-coeffs-sw.nc' + rrtmgp_nGptsSW = 112 + rrtmgp_nGptsLW = 128 + rrtmgp_nBandsLW = 16 + rrtmgp_nBandsSW = 14 + frac_grid = .true. + cplchm = .false. + cplflx = .false. + cplice = .false. + cplwav = .false. + cplwav2atm = .false. + do_ca = .false. + ca_global = .false. + ca_sgs = .true. + nca = 1 + ncells = 5 + nlives = 12 + nseed = 1 + nfracseed = 0.5 + nthresh = 18 + ca_trigger = .true. + nspinup = 1 + iseed_ca = 1448371824 +/ + +&cires_ugwp_nml + knob_ugwp_solver = 2 + knob_ugwp_version = 1 + knob_ugwp_source = 1,1,0,0 + knob_ugwp_wvspec = 1,25,25,25 + knob_ugwp_azdir = 2,4,4,4 + knob_ugwp_stoch = 0,0,0,0 + knob_ugwp_effac = 1,1,1,1 + knob_ugwp_doaxyz = 1 + knob_ugwp_doheat = 1 + knob_ugwp_dokdis = 2 + knob_ugwp_ndx4lh = 4 + knob_ugwp_palaunch = 275.0e2 + knob_ugwp_nslope = 1 + knob_ugwp_lzmax = 15.750e3 + knob_ugwp_lzmin = 0.75e3 + knob_ugwp_lzstar = 2.0e3 + knob_ugwp_taumin = 0.25e-3 + knob_ugwp_tauamp = 0.5e-3 + knob_ugwp_lhmet = 200.0e3 + knob_ugwp_orosolv = 'pss-1986' +/ + +&ccpp_suite_sim_nml + suite_sim_file = '' + nprc_sim = 7 + prc_LWRAD_cfg = 0, 0, 1 + prc_SWRAD_cfg = 0, 0, 2 + prc_PBL_cfg = 1, 0, 3 + prc_GWD_cfg = 1, 0, 4 + prc_SCNV_cfg = 1, 1, 5 + prc_DCNV_cfg = 1, 1, 6 + prc_cldMP_cfg = 1, 1, 7 +/ diff --git a/ccpp/physics_namelists/input_RRFS_v1.nml b/ccpp/physics_namelists/input_RRFS_v1.nml new file mode 100644 index 000000000..60de83a4e --- /dev/null +++ b/ccpp/physics_namelists/input_RRFS_v1.nml @@ -0,0 +1,145 @@ +&gfs_physics_nml + addsmoke_flag = 1 + aero_dir_fdb = .true. + aero_ind_fdb = .false. + bl_mynn_edmf = 1 + bl_mynn_edmf_mom = 1 + bl_mynn_tkeadvect = .true. + cal_pre = .false. + cdmbgwd = 3.5, 1.0 + clm_debug_print = .false. + clm_lake_debug = .false. + cnvcld = .false. + cnvgwd = .false. + coarsepm_settling = 1 + cplflx = .false. + diag_log = .true. + debug = .false. + do_deep = .true. + do_gsl_drag_ls_bl = .true. + do_gsl_drag_ss = .true. + do_gsl_drag_tofd = .true. + do_mynnedmf = .true. + do_mynnsfclay = .true. + do_plumerise = .true. + do_smoke_transport = .true. + do_tofd = .false. + do_ugwp = .false. + do_ugwp_v0 = .false. + do_ugwp_v0_nst_only = .false. + do_ugwp_v0_orog_only = .false. + drydep_opt = 1 + dspheat = .true. + dt_inner = 36 + dust_alpha = 10.0 + dust_drylimit_factor = 0.5 + dust_gamma = 1.3 + dust_moist_correction = 2.0 + dust_opt = 1 + ebb_dcycle = 2 + effr_in = .true. + enh_mix = .false. + fhcyc = 0 + fhlwr = 900.0 + fhswr = 900.0 + fhzero = 1.0 + frac_ice = .true. + gwd_opt = 3 + h2o_phys = .true. + hybedmf = .false. + iaer = 1011 + ialb = 2 + iau_delthrs = 6 + iau_inc_files = '' + iaufhrs = 30 + iccn = 2 + icliq_sw = 2 + icloud_bl = 1 + ico2 = 2 + iems = 2 + imfdeepcnv = 3 + imfshalcnv = -1 + imp_physics = 8 + iopt_alb = 2 + iopt_btr = 1 + iopt_crs = 1 + iopt_dveg = 2 + iopt_frz = 1 + iopt_inf = 1 + iopt_lake = 2 + iopt_rad = 1 + iopt_run = 1 + iopt_sfc = 1 + iopt_snf = 4 + iopt_stc = 1 + iopt_tbot = 2 + iovr = 3 + isncond_opt = 2 + isncovr_opt = 3 + isol = 2 + isot = 1 + isubc_lw = 2 + isubc_sw = 2 + ivegsrc = 1 + kice = 9 + ldiag3d = .true. + ldiag_ugwp = .false. + lgfdlmprad = .false. + lheatstrg = .false. + lightning_threat = .true. + lkm = 1 + lradar = .true. + lrefres = .true. + lsm = 3 + lsoil = 9 + lsoil_lsm = 9 + ltaerosol = .true. + lwhtr = .true. + min_lakeice = 0.15 + min_seaice = 0.15 + mix_chem = .true. + mosaic_lu = 1 + mosaic_soil = 1 + nsfullradar_diag = 3600 + oz_phys = .false. + oz_phys_2015 = .true. + pdfcld = .false. + plume_wind_eff = 1 + plumerisefire_frq = 60 + pre_rad = .false. + print_diff_pgr = .true. + prslrd0 = 0.0 + qdiag3d = .true. + random_clds = .false. + redrag = .true. + rrfs_sd = .true. + rrfs_smoke_debug = .false. + satmedmf = .false. + seas_opt = 0 + sfclay_compute_flux = .true. + shal_cnv = .false. + smoke_conv_wet_coef = 0.5, 0.5, 0.5 + smoke_forecast = 1 + swhtr = .true. + thsfc_loc = .false. + trans_trac = .true. + ttendlim = -999 + use_ufo = .true. + wetdep_ls_alpha = 0.5 + wetdep_ls_opt = 1 +/ + +&cires_ugwp_nml + knob_ugwp_azdir = 2, 4, 4, 4 + knob_ugwp_doaxyz = 1 + knob_ugwp_doheat = 1 + knob_ugwp_dokdis = 1 + knob_ugwp_effac = 1, 1, 1, 1 + knob_ugwp_ndx4lh = 1 + knob_ugwp_solver = 2 + knob_ugwp_source = 1, 1, 0, 0 + knob_ugwp_stoch = 0, 0, 0, 0 + knob_ugwp_version = 0 + knob_ugwp_wvspec = 1, 25, 25, 25 + launch_level = 25 +/ diff --git a/ccpp/suites/suite_SCM_GFS_v17_HR3.xml b/ccpp/suites/suite_SCM_GFS_v17_HR3.xml new file mode 100644 index 000000000..92effe13c --- /dev/null +++ b/ccpp/suites/suite_SCM_GFS_v17_HR3.xml @@ -0,0 +1,88 @@ + + + + + + + GFS_time_vary_pre + GFS_rrtmg_setup + GFS_rad_time_vary + GFS_phys_time_vary + + + + + GFS_suite_interstitial_rad_reset + GFS_rrtmg_pre + GFS_radiation_surface + rad_sw_pre + rrtmg_sw + rrtmg_sw_post + rrtmg_lw + rrtmg_lw_post + GFS_rrtmg_post + + + + + GFS_suite_interstitial_phys_reset + GFS_suite_stateout_reset + get_prs_fv3 + GFS_suite_interstitial_1 + GFS_surface_generic_pre + GFS_surface_composites_pre + dcyc2t3 + GFS_surface_composites_inter + GFS_suite_interstitial_2 + + + + sfc_diff + GFS_surface_loop_control_part1 + sfc_nst_pre + sfc_nst + sfc_nst_post + noahmpdrv + sfc_sice + GFS_surface_loop_control_part2 + + + + GFS_surface_composites_post + sfc_diag + sfc_diag_post + GFS_surface_generic_post + GFS_PBL_generic_pre + satmedmfvdifq + GFS_PBL_generic_post + GFS_GWD_generic_pre + ugwpv1_gsldrag + ugwpv1_gsldrag_post + GFS_GWD_generic_post + GFS_suite_stateout_update + h2ophys + get_phi_fv3 + GFS_suite_interstitial_3 + GFS_DCNV_generic_pre + samfdeepcnv + GFS_DCNV_generic_post + GFS_SCNV_generic_pre + samfshalcnv + GFS_SCNV_generic_post + GFS_suite_interstitial_4 + cnvc90 + GFS_MP_generic_pre + mp_thompson_pre + + + mp_thompson + + + mp_thompson_post + GFS_MP_generic_post + maximum_hourly_diagnostics + GFS_physics_post + + + + diff --git a/ccpp/suites/suite_SCM_GFS_v17_HR3_RRTMGP.xml b/ccpp/suites/suite_SCM_GFS_v17_HR3_RRTMGP.xml new file mode 100644 index 000000000..09bcbfa64 --- /dev/null +++ b/ccpp/suites/suite_SCM_GFS_v17_HR3_RRTMGP.xml @@ -0,0 +1,89 @@ + + + + + + + GFS_time_vary_pre + GFS_rrtmgp_setup + GFS_rad_time_vary + GFS_phys_time_vary + + + + + GFS_suite_interstitial_rad_reset + GFS_rrtmgp_pre + GFS_radiation_surface + GFS_rrtmgp_cloud_mp + GFS_rrtmgp_cloud_overlap + GFS_cloud_diagnostics + rrtmgp_aerosol_optics + rrtmgp_sw_main + rrtmgp_lw_main + GFS_rrtmgp_post + + + + + GFS_suite_interstitial_phys_reset + GFS_suite_stateout_reset + get_prs_fv3 + GFS_suite_interstitial_1 + GFS_surface_generic_pre + GFS_surface_composites_pre + dcyc2t3 + GFS_surface_composites_inter + GFS_suite_interstitial_2 + + + + sfc_diff + GFS_surface_loop_control_part1 + sfc_nst_pre + sfc_nst + sfc_nst_post + noahmpdrv + sfc_sice + GFS_surface_loop_control_part2 + + + + GFS_surface_composites_post + sfc_diag + sfc_diag_post + GFS_surface_generic_post + GFS_PBL_generic_pre + satmedmfvdifq + GFS_PBL_generic_post + GFS_GWD_generic_pre + ugwpv1_gsldrag + ugwpv1_gsldrag_post + GFS_GWD_generic_post + GFS_suite_stateout_update + h2ophys + get_phi_fv3 + GFS_suite_interstitial_3 + GFS_DCNV_generic_pre + samfdeepcnv + GFS_DCNV_generic_post + GFS_SCNV_generic_pre + samfshalcnv + GFS_SCNV_generic_post + GFS_suite_interstitial_4 + cnvc90 + GFS_MP_generic_pre + mp_thompson_pre + + + mp_thompson + + + mp_thompson_post + GFS_MP_generic_post + maximum_hourly_diagnostics + GFS_physics_post + + + + diff --git a/ccpp/suites/suite_SCM_GFS_v17_HR3_RRTMGP_ps.xml b/ccpp/suites/suite_SCM_GFS_v17_HR3_RRTMGP_ps.xml new file mode 100644 index 000000000..0ba77dff3 --- /dev/null +++ b/ccpp/suites/suite_SCM_GFS_v17_HR3_RRTMGP_ps.xml @@ -0,0 +1,70 @@ + + + + + + + GFS_time_vary_pre + GFS_rrtmgp_setup + GFS_rad_time_vary + GFS_phys_time_vary + + + + + GFS_suite_interstitial_rad_reset + GFS_rrtmgp_pre + GFS_radiation_surface + GFS_rrtmgp_cloud_mp + GFS_rrtmgp_cloud_overlap + GFS_cloud_diagnostics + rrtmgp_aerosol_optics + rrtmgp_sw_main + rrtmgp_lw_main + GFS_rrtmgp_post + + + + + GFS_suite_interstitial_phys_reset + GFS_suite_stateout_reset + get_prs_fv3 + GFS_suite_interstitial_1 + GFS_surface_generic_pre + scm_sfc_flux_spec + dcyc2t3 + GFS_suite_interstitial_2 + GFS_PBL_generic_pre + satmedmfvdifq + GFS_PBL_generic_post + GFS_GWD_generic_pre + ugwpv1_gsldrag + ugwpv1_gsldrag_post + GFS_GWD_generic_post + GFS_suite_stateout_update + h2ophys + get_phi_fv3 + GFS_suite_interstitial_3 + GFS_DCNV_generic_pre + samfdeepcnv + GFS_DCNV_generic_post + GFS_SCNV_generic_pre + samfshalcnv + GFS_SCNV_generic_post + GFS_suite_interstitial_4 + cnvc90 + GFS_MP_generic_pre + mp_thompson_pre + + + mp_thompson + + + mp_thompson_post + GFS_MP_generic_post + maximum_hourly_diagnostics + GFS_physics_post + + + + diff --git a/ccpp/suites/suite_SCM_GFS_v17_HR3_ps.xml b/ccpp/suites/suite_SCM_GFS_v17_HR3_ps.xml new file mode 100644 index 000000000..d9e833936 --- /dev/null +++ b/ccpp/suites/suite_SCM_GFS_v17_HR3_ps.xml @@ -0,0 +1,69 @@ + + + + + + + GFS_time_vary_pre + GFS_rrtmg_setup + GFS_rad_time_vary + GFS_phys_time_vary + + + + + GFS_suite_interstitial_rad_reset + GFS_rrtmg_pre + GFS_radiation_surface + rad_sw_pre + rrtmg_sw + rrtmg_sw_post + rrtmg_lw + rrtmg_lw_post + GFS_rrtmg_post + + + + + GFS_suite_interstitial_phys_reset + GFS_suite_stateout_reset + get_prs_fv3 + GFS_suite_interstitial_1 + GFS_surface_generic_pre + scm_sfc_flux_spec + dcyc2t3 + GFS_suite_interstitial_2 + GFS_PBL_generic_pre + satmedmfvdifq + GFS_PBL_generic_post + GFS_GWD_generic_pre + ugwpv1_gsldrag + ugwpv1_gsldrag_post + GFS_GWD_generic_post + GFS_suite_stateout_update + h2ophys + get_phi_fv3 + GFS_suite_interstitial_3 + GFS_DCNV_generic_pre + samfdeepcnv + GFS_DCNV_generic_post + GFS_SCNV_generic_pre + samfshalcnv + GFS_SCNV_generic_post + GFS_suite_interstitial_4 + cnvc90 + GFS_MP_generic_pre + mp_thompson_pre + + + mp_thompson + + + mp_thompson_post + GFS_MP_generic_post + maximum_hourly_diagnostics + GFS_physics_post + + + + diff --git a/ccpp/suites/suite_SCM_RRFS_v1.xml b/ccpp/suites/suite_SCM_RRFS_v1.xml new file mode 100644 index 000000000..ef1c73157 --- /dev/null +++ b/ccpp/suites/suite_SCM_RRFS_v1.xml @@ -0,0 +1,79 @@ + + + + + + GFS_time_vary_pre + GFS_rrtmg_setup + GFS_rad_time_vary + GFS_phys_time_vary + + + + + GFS_suite_interstitial_rad_reset + sgscloud_radpre + GFS_rrtmg_pre + GFS_radiation_surface + rad_sw_pre + rrtmg_sw + rrtmg_sw_post + rrtmg_lw + sgscloud_radpost + rrtmg_lw_post + GFS_rrtmg_post + + + + + GFS_suite_interstitial_phys_reset + GFS_suite_stateout_reset + get_prs_fv3 + GFS_suite_interstitial_1 + GFS_surface_generic_pre + GFS_surface_composites_pre + dcyc2t3 + GFS_surface_composites_inter + GFS_suite_interstitial_2 + + + + mynnsfc_wrapper + GFS_surface_loop_control_part1 + lsm_ruc + clm_lake + GFS_surface_loop_control_part2 + + + + GFS_surface_composites_post + sfc_diag + sfc_diag_post + GFS_surface_generic_post + rrfs_smoke_wrapper + mynnedmf_wrapper + rrfs_smoke_postpbl + GFS_GWD_generic_pre + drag_suite + GFS_GWD_generic_post + GFS_suite_stateout_update + h2ophys + get_phi_fv3 + GFS_suite_interstitial_3 + GFS_DCNV_generic_pre + cu_gf_driver_pre + cu_gf_driver + GFS_DCNV_generic_post + GFS_suite_interstitial_4 + cnvc90 + GFS_MP_generic_pre + mp_thompson_pre + mp_thompson + mp_thompson_post + GFS_MP_generic_post + cu_gf_driver_post + maximum_hourly_diagnostics + GFS_physics_post + + + \ No newline at end of file diff --git a/ccpp/suites/suite_SCM_RRFS_v1_ps.xml b/ccpp/suites/suite_SCM_RRFS_v1_ps.xml new file mode 100644 index 000000000..91918a6b8 --- /dev/null +++ b/ccpp/suites/suite_SCM_RRFS_v1_ps.xml @@ -0,0 +1,63 @@ + + + + + + GFS_time_vary_pre + GFS_rrtmg_setup + GFS_rad_time_vary + GFS_phys_time_vary + + + + + GFS_suite_interstitial_rad_reset + sgscloud_radpre + GFS_rrtmg_pre + GFS_radiation_surface + rad_sw_pre + rrtmg_sw + rrtmg_sw_post + rrtmg_lw + sgscloud_radpost + rrtmg_lw_post + GFS_rrtmg_post + + + + + GFS_suite_interstitial_phys_reset + GFS_suite_stateout_reset + get_prs_fv3 + GFS_suite_interstitial_1 + GFS_surface_generic_pre + scm_sfc_flux_spec + dcyc2t3 + GFS_suite_interstitial_2 + rrfs_smoke_wrapper + mynnedmf_wrapper + rrfs_smoke_postpbl + GFS_GWD_generic_pre + drag_suite + GFS_GWD_generic_post + GFS_suite_stateout_update + h2ophys + get_phi_fv3 + GFS_suite_interstitial_3 + GFS_DCNV_generic_pre + cu_gf_driver_pre + cu_gf_driver + GFS_DCNV_generic_post + GFS_suite_interstitial_4 + cnvc90 + GFS_MP_generic_pre + mp_thompson_pre + mp_thompson + mp_thompson_post + GFS_MP_generic_post + cu_gf_driver_post + maximum_hourly_diagnostics + GFS_physics_post + + + \ No newline at end of file diff --git a/contrib/get_aerosol_climo.sh b/contrib/get_aerosol_climo.sh new file mode 100755 index 000000000..2039dc732 --- /dev/null +++ b/contrib/get_aerosol_climo.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +#set -ex + +# Directory where this script is located +if [[ $(uname -s) == Darwin ]]; then + if [[ $(sw_vers -productVersion) < 12.3 ]]; then + MYDIR=$(cd "$(dirname "$(greadlink -f -n "${BASH_SOURCE[0]}" )" )" && pwd -P) + else + MYDIR=$(cd "$(dirname "$(readlink -f -n "${BASH_SOURCE[0]}" )" )" && pwd -P) + fi +else + MYDIR=$(cd "$(dirname "$(readlink -f -n "${BASH_SOURCE[0]}" )" )" && pwd -P) +fi +BASEDIR=$MYDIR/.. + +# Change to directory containing the physics input data, download and extract archive +data_files=("FV3_aeroclim1" "FV3_aeroclim2" "FV3_aeroclim3" "FV3_aeroclim_optics") + +cd $BASEDIR/scm/data/physics_input_data/ +for file in "${data_files[@]}"; do + echo "Retrieving $file.tar.gz" + wget https://github.com/NCAR/ccpp-scm/releases/download/v6.0.0/${file}.tar.gz + tar -xvf ${file}.tar.gz + rm -f ${file}.tar.gz +done + +cd $BASEDIR/ + diff --git a/docker/Dockerfile b/docker/Dockerfile index 99fc2a25b..7d0586090 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,55 +1,81 @@ -FROM dtcenter/common-community-container:gnu9 +FROM debian:12 +MAINTAINER Michael Kavulich -MAINTAINER Michelle Harrold or Grant Firl or Michael Kavulich +# Set up base OS environment -# -# Dockerfile for building CCPP SCM container -# +RUN apt-get -y update -# Note: The common community container image contains the following packages, which are used to build the SCM: -# gfortran, gcc, cmake, netCDF, HDF5, ZLIB, SZIP, Python, and libxml2 -# To access the common community container repository: https://github.com/NCAR/Common-Community-Container +# Get "essential" tools and libraries +RUN apt-get -y install build-essential \ + && apt-get -y install cmake curl git file gfortran-12 ksh m4 python3 tcsh time wget vim \ + && apt-get -y install libnetcdf-pnetcdf-19 libnetcdff7 libnetcdf-dev libnetcdff-dev libxml2 \ + && apt-get -y install python3-pip python3.11-venv -# Obtain CCPP SCM source code -RUN cd /comsoftware \ - && git clone --recursive -b release/public-v6 https://github.com/NCAR/ccpp-scm - -# Obtain static data that was previously stored in repository -RUN cd /comsoftware/ccpp-scm/ \ - && . contrib/get_all_static_data.sh - -# Obtain the pre-computed look-up tables for running with Thompson microphysics -RUN cd /comsoftware/ccpp-scm/ \ - && . contrib/get_thompson_tables.sh - -# Run the machine setup script to set environment variables -ENV CC=/opt/rh/devtoolset-9/root/usr/bin/gcc -ENV CXX=/opt/rh/devtoolset-9/root/usr/bin/g++ -ENV F77=/opt/rh/devtoolset-9/root/usr/bin/gfortran -ENV F90=/opt/rh/devtoolset-9/root/usr/bin/gfortran -ENV FC=/opt/rh/devtoolset-9/root/usr/bin/gfortran - -ENV NETCDF=/comsoftware/libs/netcdf - -RUN cd /comsoftware/ccpp-scm/contrib \ - && wget https://raw.githubusercontent.com/NCAR/ccpp-scm/3f501aa8af0fb00ff124d8301c932292d1d0abf3/contrib/build_nceplibs.sh \ - && chmod +x build_nceplibs.sh \ - && cd .. \ - && ./contrib/build_nceplibs.sh $PWD/nceplibs - -ENV bacio_ROOT /comsoftware/ccpp-scm/nceplibs -ENV sp_ROOT /comsoftware/ccpp-scm/nceplibs -ENV w3nco_ROOT /comsoftware/ccpp-scm/nceplibs - -# Create your own link from python -> python3 -# This works without setting the system PATH env var -# since /usr/local/bin is before /usr/bin in the search path. -USER root -RUN ln -s /usr/bin/python3 /usr/local/bin/python +MAINTAINER Grant Firl or Michael Kavulich + +#Compiler environment variables +ENV CC /usr/bin/gcc +ENV FC /usr/bin/gfortran +ENV CXX /usr/bin/g++ +ENV F77 /usr/bin/gfortran +ENV F90 /usr/bin/gfortran + +# Other necessary environment variables +ENV LD_LIBRARY_PATH /usr/lib/ + +# Set up unpriviledged user account, set up user home space and make sure user has permissions on all stuff in /comsoftware +RUN groupadd comusers -g 9999 \ + && useradd -u 9999 -g comusers -M -s /bin/bash -c "Unpriviledged user account" -d /home comuser \ + && mkdir /comsoftware \ + && chown -R comuser:comusers /home \ + && chmod 6755 /home \ + && chown -R comuser:comusers /comsoftware \ + && chmod -R 6755 /comsoftware + +# Link version-specific aliases (python3 will be created later with virtual environment) +RUN ln -s ~comuser/.venv/bin/python3 /usr/local/bin/python +RUN ln -s /usr/bin/gfortran-12 /usr/bin/gfortran + +# all root steps completed above, now continue below as regular userID comuser USER comuser +WORKDIR /home + +# Build NCEP libraries we need for SCM + +ENV NCEPLIBS_DIR /comsoftware/nceplibs -# Invoke cmake on the source code to build -RUN cd /comsoftware/ccpp-scm/scm \ +RUN mkdir -p $NCEPLIBS_DIR/src && cd $NCEPLIBS_DIR/src \ + && git clone -b v2.4.1 --recursive https://github.com/NOAA-EMC/NCEPLIBS-bacio \ + && mkdir NCEPLIBS-bacio/build && cd NCEPLIBS-bacio/build \ + && cmake -DCMAKE_INSTALL_PREFIX=$NCEPLIBS_DIR .. \ + && make VERBOSE=1 \ + && make install + +RUN cd $NCEPLIBS_DIR/src \ + && git clone -b v2.3.3 --recursive https://github.com/NOAA-EMC/NCEPLIBS-sp \ + && mkdir NCEPLIBS-sp/build && cd NCEPLIBS-sp/build \ + && cmake -DCMAKE_INSTALL_PREFIX=$NCEPLIBS_DIR .. \ + && make VERBOSE=1 \ + && make install + +RUN cd $NCEPLIBS_DIR/src \ + && git clone -b v2.11.0 --recursive https://github.com/NOAA-EMC/NCEPLIBS-w3emc \ + && mkdir NCEPLIBS-w3emc/build && cd NCEPLIBS-w3emc/build \ + && cmake -DCMAKE_INSTALL_PREFIX=$NCEPLIBS_DIR .. \ + && make VERBOSE=1 \ + && make install + +ENV bacio_ROOT /comsoftware/nceplibs +ENV sp_ROOT /comsoftware/nceplibs +ENV w3emc_ROOT /comsoftware/nceplibs + +# Obtain CCPP SCM source code and static data, build code +RUN cd /comsoftware \ + && git clone --recursive -b main https://github.com/NCAR/ccpp-scm \ + && cd /comsoftware/ccpp-scm/ \ + && ./contrib/get_all_static_data.sh \ + && ./contrib/get_thompson_tables.sh \ + && cd /comsoftware/ccpp-scm/scm \ && mkdir bin \ && cd bin \ && cmake ../src \ @@ -67,3 +93,12 @@ RUN cd /comsoftware/ccpp-scm/scm \ WORKDIR /comsoftware/ccpp-scm/scm/bin ENV SCM_WORK=/comsoftware ENV SCM_ROOT=/comsoftware/ccpp-scm/ + +# For interactive use, vim mouse settings are infuriating +RUN echo "set mouse=" > ~/.vimrc + +# Set up python virtual environment and install needed packages +ENV VIRTUAL_ENV=~/.venv +RUN python3 -m venv $VIRTUAL_ENV +ENV PATH="$VIRTUAL_ENV/bin:$PATH" +RUN pip3 install f90nml==1.4.4 netcdf4==1.6.5 diff --git a/scm/doc/TechGuide/chap_intro.rst b/scm/doc/TechGuide/chap_intro.rst index 68e4ddf1d..94d134d85 100644 --- a/scm/doc/TechGuide/chap_intro.rst +++ b/scm/doc/TechGuide/chap_intro.rst @@ -103,7 +103,7 @@ This release bundle has some known limitations: - As of this release, using the SCM over a land point with an LSM is possible through the use of UFS initial conditions (see - :numref:`Section %s `). However, advective forcing terms + :numref:`Section %s `). However, advective forcing terms are unavailable as of this release, so only short integrations using this configuration should be employed. Using dynamical tendencies (advective forcing terms) from the UFS will be part of a future diff --git a/scm/doc/TechGuide/chap_quick.rst b/scm/doc/TechGuide/chap_quick.rst index 69f165b94..9f407dbba 100644 --- a/scm/doc/TechGuide/chap_quick.rst +++ b/scm/doc/TechGuide/chap_quick.rst @@ -4,18 +4,8 @@ Quick Start Guide ================= This chapter provides instructions for obtaining and compiling the CCPP -SCM. The SCM code calls CCPP-compliant physics schemes through the CCPP -framework code. As such, it requires the CCPP framework code and physics -code, both of which are included as submodules within the SCM git repository. This -package can be considered a simple example for an atmospheric model to -interact with physics through the CCPP. - -Alternatively, if one doesn’t have access to or care to set up a machine -with the appropriate system requirements but has a working Docker -installation, it is possible to create and use a Docker container with a -pre-configured computing environment with a pre-compiled model. This is -also an avenue for running this software with a Windows PC. See section -:numref:`Section %s ` for more information. +SCM. We provide instructions on building the code from scratch (:numref:`Section %s `), as well as +using Docker containers for machines that have Docker software installed (:numref:`Section %s `). .. _obtaining_code: @@ -29,7 +19,7 @@ developer code, but may not be as stable or consistent with existing documentati Instructions for using either option are discussed here. Release Code -~~~~~~~~~~~~ +^^^^^^^^^^^^ Clone the source using @@ -37,11 +27,10 @@ Clone the source using git clone --recursive -b v6.0.0 https://github.com/NCAR/ccpp-scm -By using the ``--recursive`` option, it guarantees that you are checking out the commits -of ccpp-physics and ccpp-framework that were tested with the latest -commit of the SCM main branch. If not included initially, you can always retrieve the commits of -the submodules that were intended to be used with a given commit of the -SCM by executing the following command from the SCM directory: +The ``--recursive`` option is required to retrieve the ccpp-physics and ccpp-framework code, +which are stored in separate repositories and linked to the SCM repository as submodules. +If not included initially, you can always retrieve the submodules +by executing the following command from the SCM directory: .. code:: bash @@ -54,19 +43,10 @@ this level. The CCPP physics parameterizations can be found in the .. _`development_code`: Development Code -~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^ -If you would like to contribute as a developer to this project, please -see (in addition to the rest of this guide) the scientific and technical -documentation included with this release for both the SCM and the CCPP: - -https://dtcenter.org/community-code/common-community-physics-package-ccpp/documentation - -There you will find links to all of the documentation pertinent to -developers. - -For working with the development branches (stability not guaranteed), -check out the ``main`` branch of the repository: +Developers seeking to contribute code to the SCM or CCPP will need to use the most up-to-date +version of the code, which can be found on the ``main`` branch of the repository: .. code:: bash @@ -82,7 +62,21 @@ SCM by executing the following command from the SCM directory: git submodule update --init --recursive -You can try to use the latest commits of the ccpp-physics and +While the ``main`` branch is tested regularly for compilation and basic functionality (as described in :numref:`Section %s `), +it may not be as stable or scientifically vetted as the latest release code, and may be lacking in up-to-date documentation. + +If you would like to contribute as a developer to this project, please +see (in addition to the rest of this guide) the scientific and technical +documentation included with this release for both the SCM and the CCPP: + +https://dtcenter.org/community-code/common-community-physics-package-ccpp/documentation + +There you will find links to all of the documentation pertinent to +developers. + + +While the SCM is updated with the latest commits to the CCPP submodules (ccpp-physics and ccpp-framework) +on a fairly regular basis, it may be behind by a few commits at times. You can try to use the latest commits of the ccpp-physics and ccpp-framework submodules if you wish, but this may not have been tested (i.e. SCM development may lag ccpp-physics and/or ccpp-framework development). To do so: @@ -129,66 +123,49 @@ System Requirements, Libraries, and Tools The source code for the SCM and CCPP components is in the form of programs written in FORTRAN 90 (with some required features from the FORTRAN 2008 standard), and C. In addition, the model I/O -relies on the NetCDF libraries. Beyond the standard scripts, the build +relies on the NetCDF libraries, as well as the NCEP libraries ``bacio``, ``sp`` and ``w3emc``. + +Beyond the standard shell scripts, the build system relies on use of the Python scripting language, along with cmake, GNU make and date. -The following software stacks have been tested with this code. Other -versions of various components will likely still work, however. - -- gfortran 12.1.0, gcc 12.1.0, cmake 3.23.2, NetCDF 4.7.4, Python - 3.9.12 - -- GNU compilers 10.1.0, cmake 3.16.4, NetCDF 4.8.1, Python 3.7.12 - -- GNU compilers 11.1.0, cmake 3.18.2, NetCDF 4.8.1, Python 3.8.5 +For the latest release, the minimum required Python version is 3.8, and CMake requires a minimum version of 3.14. +While exact minimum required versions of other prerequisites have not been established, users can reference the +list of Continuous Integration tests run on the CCPP SCM repository (see :numref:`Section %s `) +for examples of known working configurations. -- Intel compilers 2022.0.2, cmake 3.20.1, NetCDF 4.7.4, Python 3.7.11 +Spack-stack +^^^^^^^^^^^^ -- Intel compilers 2022.1.0, cmake 3.22.0, NetCDF 4.8.1, Python 3.7.12 +A joint effort between NOAA's Unified Forecast System (UFS) and Joint Effort for Data assimilation Integration (JEDI). +It is designed to be a comprehensive, all-in-one package containing prerequisite libraries and tools needed for all +software in the UFS ecosystem, including the CCPP SCM. As of the version 7, installing spack-stack is the main +supported method of installing the prerequisites needed for building the SCM. The latest version of the SCM is meant +to be built with spack-stack v1.6.0. Older versions may work, but are not guaranteed. Version 1.6.0 of spack-stack +contains the following set of libraries needed for building the SCM: -Because these tools are typically the purview of system administrators -to install and maintain, they are considered part of the basic system -requirements. The Unified Forecast System (UFS) Short-Range Weather -Application release v1.0.0 of March 2021 provides software packages and -detailed instructions to install these prerequisites and the hpc-stack -on supported platforms (see :numref:`Section %s `) + - Netcdf-c (v4.9.2) -Further, there are several utility libraries as part of the hpc-stack -package that must be installed with environment variables pointing to -their locations prior to building the SCM. + - Netcdf-FORTRAN (v4.6.0) -- bacio - Binary I/O Library + - BACIO (v2.4.1) - Binary I/O Library -- sp - Spectral Transformation Library + - SP (v2.3.3) - Spectral Transformation Library -- w3emc - GRIB decoder and encoder library + - W3EMC (2.10.0) - GRIB decoder and encoder library -The following environment variables are used by the build system to -properly link these libraries: ``bacio_ROOT``, ``sp_ROOT``, and ``w3emc_ROOT`` Computational platforms on -which these libraries are prebuilt and installed in a central location -are referred to as *preconfigured* platforms. Examples of preconfigured -platforms are most NOAA high-performance computing machines (using the -Intel compiler) and the NCAR Cheyenne system (using the Intel and GNU -compilers). The machine setup scripts mentioned in -:numref:`Section %s ` load these libraries (which are identical -to those used by the UFS Short and Medium Range Weather Applications on -those machines) and set these environment variables for the user -automatically. For installing the libraries and its prerequisites on -supported platforms, existing UFS packages can be used (see -:numref:`Section %s `). +Instructions for installing spack-stack can be found in the `spack-stack documentation `__. +Spack-stack is already installed and maintained on many HPC platforms, including NSF NCAR's Derecho, NOAA's Hera and +Jet, and MSU's Orion. Compilers -~~~~~~~~~ - +^^^^^^^^^ The CCPP and SCM have been tested on a variety of computing platforms. Currently the CCPP system is actively supported on Linux and MacOS computing platforms using the Intel or GNU Fortran compilers. Windows users have a path to use this software through a Docker container that -uses Linux internally (see section `1.5 <#docker>`__). Please use -compiler versions listed in the previous section as unforeseen build -issues may occur when using older versions. Typically the best results -come from using the most recent version of a compiler. If you have +uses Linux internally (see :numref:`Section %s `). Typically the best chance of successfully building and +running the SCM on a new machine comes from using the most recent version of a compiler. If you have problems with compilers, please check the “Known Issues” section of the release website (https://dtcenter.org/community-code/common-community-physics-package-ccpp/download). @@ -196,7 +173,7 @@ release website .. _`use_preconfigured_platforms`: Using Existing Libraries on Preconfigured Platforms -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Because the SCM can be built using the so-called `"spack-stack" libraries `__ @@ -223,61 +200,80 @@ both building and running the SCM. .. _`setup_supported_platforms`: Installing Libraries on Non-preconfigured Platforms -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ For users on supported platforms such as generic Linux or macOS systems -that have not been preconfigured, the project is suggested for -installing prerequisite libraries. Visit -https://github.com/NOAA-EMC/hpc-stack for instructions for installing -prerequisite libraries via *hpc-stack* in their docs directory. UFS users who -already installed libraries via the *hpc-stack* package only need to set the -compiler (``CC``, ``CXX``, ``FC``), NetCDF (``NetCDF_ROOT``), and ``bacio``, -``sp`` and ``w3emc`` (``bacio_ROOT``, ``sp_ROOT``, ``w3emc_ROOT``) environment variables to point -to their installation paths in order to compile the SCM. - -The SCM uses only a small part of the UFS *hpc-stack* package and has fewer -prerequisites (i.e. no ESMF or wgrib2 needed). Users who are not planning to use the -UFS can install only NetCDF/NetCDF-Fortran manually or using the -software package manager (apt, yum, brew). - -The Python environment must provide the module for the SCM scripts to -function. Users can test if f90nml is installed using this command in +that have not been preconfigured, installing ``spack-stack`` (see :ref:`Section %s `) +is highly recommended, as it provides all the necessary prerequisite libraries needed for installing the SCM. + +The CCPP/SCM team does not support spack-stack, so users with questions or requiring help with spack-stack installation +should reference the `spack-stack documentation `__. +However, we have provided an example procedure in +`this GitHub discussion `__. + +The main downside to spack-stack is that it contains a large number of libraries and utilities used by the whole +Unified Forecast System and related applications, only a minority of which are required for the SCM. Users may +install libraries manually if they wish, but they will need to make sure the appropriate environment variables +are set to the correct values so that the build system can find them, as described in the following chapter. + + +Setting up compilation environment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For users on a pre-configured platform, you can load the spack-stack environment via one of the provided modules in ``scm/etc/modules/``. +For example, users on the NSF NCAR machine Derecho who wish to use Intel compilers can do the following: + +:: + + cd [path/to/ccpp-scm/] + module use scm/etc/modules/ + module load derecho_intel + +Additionally, for users who have installed spack-stack on their own MacOS or Linux machine can use the provided ``macos_clang`` +or ``linux_gnu`` modules. + +.. note:: + + The provided modules assume ``clang``/``gfortran`` compilers on MacOS and GNU compilers for Linux. + If you are using a different set of compilers, you may need to modify the module file. + +If libraries were installed manually, users will need to set some environment variables +needed for specifying the location of the various prerequisites. Users will need to set variables for the +compilers (``CC``, ``CXX``, ``FC``), as well as the root directories for the library installs of NetCDF (``NetCDF_ROOT``), +``bacio`` (``bacio_ROOT``), ``sp`` (``sp_ROOT``), and ``w3emc`` (``w3emc_ROOT``). This is the procedure used in the +provided Dockerfile in ``ccpp-scm/docker/``, so users can reference that file for guidance on how to install this software +and set these variables. + + +Python requirements +""""""""""""""""""""" + +The SCM build system invokes the ``ccpp_prebuild.py`` script, and so the Python environment must be set up prior to building. +As mentioned earlier, a minimum Python version of 3.8 is required. Additionally, there are a few non-default modules required for the SCM to +function: ``f90nml`` (`documentation `__) and +``netcdf4`` (`documentation `__). Users can test if these are installed using this command in the shell: :: - python -c "import f90nml" + python -c "import f90nml; import netcdf4" If is installed, this command will succeed silently, otherwise an ``ImportError: No module named f90nml`` -will be printed to screen. To install the ``f90nml`` (v0.19) Python module, use the -install method preferred for your Python environment (one of the -following): +will be printed to screen. To install the ``f90nml`` (v1.4.4; ) and ``netcdf4`` (v1.6.5) Python modules, use the +install method preferred for your Python environment (one of the following): - :: - easy_install f90nml==0.19 + easy_install f90nml==1.4.4 netcdf4==1.6.5 - :: - pip install f90nml==0.19 + pip install f90nml==1.4.4 netcdf4==1.6.5 - :: - conda install f90nml=0.19 - -or perform the following steps to install it manually from source: - -:: - - cd /directory/with/write/priveleges - git clone -b v0.19 https://github.com/marshallward/f90nml - cd f90nml - python setup.py install [--prefix=/my/install/directory or --user] + conda install -c conda-forge f90nml==1.4.4 netcdf4==1.6.5 -The directory ``/my/install/directory`` must exist and its subdirectory -``/my/install/directory/lib/python[version]/site-packages`` (or ``lib64`` -instead of ``lib``, depending on the system) must be in the ``PYTHONPATH`` -environment variable. .. _`compiling`: @@ -286,24 +282,7 @@ Compiling SCM with CCPP The first step in compiling the CCPP and SCM is to properly setup your user environment as described in -sections :numref:`%s ` and :numref:`Section %s `. The second step is -to download the lookup tables and other large datasets (large binaries, -:math:`<`\ 1 GB) needed by the physics schemes and place them in the -correct directory: From the top-level code directory (``ccpp-scm`` by default), -execute the following scripts: - -.. code:: bash - - ./contrib/get_all_static_data.sh - ./contrib/get_thompson_tables.sh - -If the download step fails, make sure that your system’s firewall does -not block access to GitHub. If it does, download the files ``comparison_data.tar.gz``, -``physics_input_data.tar.gz``, ``processed_case_input.tar.gz``, and ``raw_case_input.tar.gz`` -from the GitHub release website using your browser and manually extract its -contents in the directory ``scm/data``. Similarly, do the same for -``thompson_tables.tar.gz`` and ``MG_INCCN_data.tar.gz`` and extract -to ``scm/data/physics_input_data/``. +sections :numref:`%s ` and :numref:`Section %s `. Following this step, the top level build system will use ``cmake`` to query system parameters, execute the CCPP prebuild script to match the physics @@ -367,7 +346,8 @@ components. -DOPENMP=ON - - Debug mode + - Debug mode, which compiles with lower optimization and additional compile-time checks. Only + recommended for development and debugging, because code compiled in this mode will run slower. .. code:: bash @@ -421,12 +401,13 @@ directory) pwd #confirm that you are in the ccpp-scm/scm/bin directory before deleting files rm -rfd * -Note: This command can be dangerous (deletes files without confirming), -so make sure that you’re in the right directory before executing! +.. warning:: + This command can be dangerous (deletes files without confirming), + so make sure that you’re in the right directory before executing! If you encounter errors, please capture a log file from all of the -steps, and start a thread on the support forum at: -https://dtcenter.org/forum/ccpp-user-support/ccpp-single-column-model +steps, and start a thread on the Github Discussions support forum at: +https://github.com/NCAR/ccpp-scm/discussions Run the SCM with a supplied case -------------------------------- @@ -439,10 +420,37 @@ executed through a Python run script that is pre-staged into the ``bin`` directory: ``run_scm.py``. It can be used to run one integration or several integrations serially, depending on the command line arguments supplied. +Downloading input data +^^^^^^^^^^^^^^^^^^^^^^ +The various SCM cases require staged input data in order to run. This includes +input data for cases and lookup tables for runtime use. This is a large dataset +(:math:`<`\ 1 GB) so it is not stored in the SCM repository, and must be downloaded +separately. To download this data place it in the correct directories, +execute the following scripts: + +.. code:: bash + + ./contrib/get_all_static_data.sh + ./contrib/get_thompson_tables.sh + +If the download step fails, make sure that your system’s firewall does +not block access to GitHub. If it does, download the files ``comparison_data.tar.gz``, +``physics_input_data.tar.gz``, ``processed_case_input.tar.gz``, and ``raw_case_input.tar.gz`` +from the `SCM release page `__ using your browser and manually extract its +contents in the directory ``scm/data``. Similarly, do the same for +``thompson_tables.tar.gz`` and ``MG_INCCN_data.tar.gz`` and extract +to ``scm/data/physics_input_data/``. + +New with the SCM v7 release, static data is available for running cases with GOCART climatological aerosols (where the value of ``iaer`` in the ``&gfs_physics_nml`` namelist starts with 1; see the `CCPP Scientific Documentation `__ for more information); one example of this is with the default namelist settings for the GFS_v17_HR3 scheme. This dataset is very large (~12 GB), so it is recommended only to download it if you will be using it. + +.. code:: bash + + ./contrib/get_aerosol_climo.sh + .. _`singlerunscript`: Run Script Usage -~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^ Running a case requires four pieces of information: the case to run (consisting of initial conditions, geolocation, forcing data, etc.), the @@ -453,16 +461,34 @@ namelists in ``../etc/case_config``. A default physics suite is provided as a us variable in the script and default namelists and tracer configurations are associated with each physics suite (through ``../src/suite_info.py``), so, technically, one must only specify a case to run with the SCM when running just one -integration. For running multiple integrations at once, one need only -specify one argument (``-m``) which runs through all permutations of supported -suites from ``../src/suite_info.py`` and cases from ``../src/supported_cases.py``. The run script’s options are described -below where option abbreviations are included in brackets. +integration. For example, to run the "BOMEX" case: + +.. code:: bash + + ./run_scm.py -c bomex + +For running multiple integrations at once, the run script can accept a file that contains a list of tests to run. +The file ``ccpp-scm/test/rt_test_cases.py`` contains the full list of regression test cases, so you could run that list +of tests with the following command: + +.. code:: bash + + ./run_scm.py -f ../../test/rt_test_cases.py + +To see the full list of available options, use the ``--help`` flag: + +.. code:: bash + + ./run_scm.py --help + + +The run script’s full set of options are described below, where optional abbreviations are included in brackets. +If using the main branch, you should run the above command to ensure you have the most up-to-date list of options. - ``--case [-c]`` - - **This or the ``--multirun`` option are the minimum required arguments.** The - case should correspond to the name of a case in ``../etc/case_config`` (without the - ``.nml`` extension). + - **This is the only required argument.** The provided argument should correspond to the name of a case in + ``../etc/case_config`` (without the ``.nml`` extension). - ``--suite [-s]`` @@ -481,18 +507,9 @@ below where option abbreviations are included in brackets. the ``.txt`` extension). If this argument is omitted, the default tracer configuration for the given suite in ``../src/suite_info.py`` will be used. -- ``--multirun [-m]`` - - - **This or the ``--case`` option are the minimum required arguments.** When - used alone, this option runs through all permutations of supported - suites from ``../src/suite_info.py`` and cases from ``../src/supported_cases.py``. When used in conjunction with the - ``--file`` option, only the runs configured in the file will be run. - - ``--file [-f]`` - - This option may be used in conjunction with the ``--multirun`` argument. It - specifies a path and filename to a python file where multiple runs - are configured. + - This option may be used to specify a list of tests to run; see ../../test/rt_test_cases.py for an example. - ``--gdb [-g]`` @@ -503,7 +520,7 @@ below where option abbreviations are included in brackets. - Use this argument when running in a docker container in order to successfully mount a volume between the host machine and the - Docker container instance and to share the output and plots with + Docker container instance, allowing the container to share the output and plots with the host machine. - ``--runtime`` @@ -516,9 +533,9 @@ below where option abbreviations are included in brackets. - Use this to override the runtime provided in the case configuration namelist by multiplying the runtime by the given value. This is used, for example, in regression testing to reduce - total runtimes. + total runtimes (e.g., ``--runtime_mult 0.1``). -- ``--levels [-l] +- ``--levels [-l]`` - Use this to change the number of vertical levels. @@ -572,7 +589,7 @@ configuration files located in ``../etc/case_config`` (*without the .nml extensi specifying a suite other than the default, the suite name used must match the value of the suite name in one of the suite definition files located in ``../../ccpp/suites`` (Note: not the filename of the suite definition file). As -part of the sixth CCPP release, the following suite names are valid: +part of the sixth CCPP release, the following suite names are supported: #. SCM_GFS_v16 @@ -667,7 +684,7 @@ volume-mounting purposes. Any standard NetCDF file viewing or analysis tools may be used to examine the output file (ncdump, ncview, NCL, etc). Batch Run Script -~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^ If using the model on HPC resources and significant amounts of processor time is anticipated for the experiments, it will likely be necessary to @@ -697,10 +714,12 @@ In order to run a precompiled version of the CCPP SCM in a container, Docker will need to be available on your machine. Please visit https://www.docker.com to download and install the version compatible with your system. Docker frequently releases updates to the software; it -is recommended to apply all available updates. NOTE: In order to install -Docker on your machine, you will be required to have root access -privileges. More information about getting started can be found at -https://docs.docker.com/get-started +is recommended to apply all available updates. + +.. note:: + In order to install Docker on your machine, you will be required to have root access + privileges. More information about getting started can be found at + https://docs.docker.com/get-started The following tips were acquired during a recent installation of Docker on a machine with Windows 10 Home Edition. Further help should be @@ -728,43 +747,40 @@ internet search. docker-machine create default --virtualbox-no-vtx-check Building the Docker image -~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^ The Dockerfile builds CCPP SCM v6.0.0 from source using the GNU -compiler. A number of required codes are built and installed via the -DTC-supported common community container. For reference, the common -community container repository can be accessed here: -https://github.com/NCAR/Common-Community-Container. +compiler. The CCPP SCM has a number of system requirements and necessary libraries and tools. Below is a list, including versions, used to create the the -GNU-based Docker image: - -- gfortran - 9.3 +GNU-based Docker image. These are included for reference, but recall that +the Docker container contains all of this software built-in, you do not need to install them separately! -- gcc - 9.3 +- gfortran - 12.2.0 -- cmake - 3.16.5 +- gcc - 12.2.0 -- NetCDF - 4.6.2 +- cmake - 3.25.1 -- HDF5 - 1.10.4 +- NetCDF - 4.9.0 -- ZLIB - 1.2.7 +- Python - 3.11.2 -- SZIP - 2.1.1 +- NCEPLIBS BACIO - v2.4.1 -- Python - 3 +- NCEPLIBS SP - v2.3.3 -- NCEPLIBS subset: bacio v2.4.1_4, sp v2.3.3_d, w3emc v2.9.2_d +- NCEPLIBS W3EMC - v2.11.0 A Docker image containing the SCM, CCPP, and its software prerequisites can be generated from the code in the software repository obtained by following the instructions in :numref:`Section %s `, and then executing the following steps: -NOTE: Windows users can execute these steps in the terminal application -that was installed as part of Docker Toolbox. +.. note:: + Windows users can execute these steps in the terminal application + that was installed as part of Docker Toolbox. #. Navigate to the ``ccpp-scm/docker`` directory. @@ -778,16 +794,18 @@ that was installed as part of Docker Toolbox. Inspect the Dockerfile if you would like to see details for how the image is built. The image will contain SCM prerequisite software from DTC, the SCM and CCPP code, and a pre-compiled executable for the SCM - with the 6 supported suites for the SCM. A successful build will show - two images: dtcenter/common-community-container, and ccpp-scm. To - list images, type: + with the 6 supported suites for the SCM. To view .. code:: bash - docker images + > docker images + + REPOSITORY TAG IMAGE ID CREATED SIZE + ccpp-scm latest 1b2e0a0afdf9 2 days ago 3.21GB + Using a prebuilt Docker image from Dockerhub -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A prebuilt Docker image for this release is available on Dockerhub if it is not desired to build from source. In order to use this, execute the @@ -804,10 +822,11 @@ To verify that it exists afterward, run docker images Running the Docker image -~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^ -NOTE: Windows users can execute these steps through the Docker -Quickstart application installed with Docker Toolbox. +.. note:: + Windows users can execute these steps through the Docker + Quickstart application installed with Docker Toolbox. #. Set up a directory that will be shared between the host machine and the Docker container. When set up correctly, it will contain output @@ -832,14 +851,7 @@ Quickstart application installed with Docker Toolbox. does not) and make sure that the “auto-mount" and “permanent" options are checked. -#. Set an environment variable to use for your SCM output directory. For - *t/csh* shells, - - .. code:: bash - - setenv OUT_DIR /path/to/output - - For bourne/bash shells, +#. Set an environment variable to use for your SCM output directory. .. code:: bash @@ -858,13 +870,17 @@ Quickstart application installed with Docker Toolbox. docker run --rm -it -v ${OUT_DIR}:/home --name run-ccpp-scm ccpp-scm ./run_scm.py -c twpice -d will run through the TWPICE case using the default suite and namelist - and put the output in the shared directory. NOTE: Windows users may - need to omit the curly braces around environment variables: use ``$OUT_DIR`` - instead of ``${OUT_DIR}``. For running through all supported cases and suites, use + and put the output in the shared directory. + + .. note:: + Windows users may need to omit the curly braces around environment variables: use ``$OUT_DIR`` + instead of ``${OUT_DIR}``. + + For running through all supported cases and suites, use .. code:: bash - docker run --rm -it -v ${OUT_DIR}:/home --name run-ccpp-scm ccpp-scm ./run_scm.py -m -d + docker run --rm -it -v ${OUT_DIR}:/home --name run-ccpp-scm ccpp-scm ./run_scm.py -f ../../test/rt_test_cases.py --runtime_mult 0.1 -d The options included in the above ``run`` commands are the following: @@ -882,9 +898,10 @@ Quickstart application installed with Docker Toolbox. - ``−−name`` names the container. If no name is provided, the daemon will autogenerate a random string name. - NOTE: If you are using a prebuilt image from Dockerhub, substitute - the name of the image that was pulled from Dockerhub in the commands - above; i.e. instead of ``ccpp-scm`` above, one would have ``dtcenter/ccpp-scm:v6.0.0``. + .. note:: + If you are using a prebuilt image from Dockerhub, substitute + the name of the image that was pulled from Dockerhub in the commands + above; i.e. instead of ``ccpp-scm`` above, one would have ``dtcenter/ccpp-scm:v6.0.0``. #. To use the SCM interactively, run non-default configurations, create plots, or even develop code, issue the following command: @@ -897,6 +914,9 @@ Quickstart application installed with Docker Toolbox. directory of the SCM with a pre-compiled executable. At this point, one could use the run scripts as described in previous sections (remembering to include the option on run scripts if output is to be - shared with the host machine). NOTE: If developing, since the - container is ephemeral, one should push their changes to a remote git - repository to save them (i.e. a fork on GitHub.com). + shared with the host machine). + + .. warning:: + + If developing or modifying code, since the container is ephemeral, one should push their changes to a remote git + repository to save them (i.e. a fork on GitHub.com). diff --git a/scm/doc/TechGuide/chap_repo.rst b/scm/doc/TechGuide/chap_repo.rst index d49b9605a..36f0a10ce 100644 --- a/scm/doc/TechGuide/chap_repo.rst +++ b/scm/doc/TechGuide/chap_repo.rst @@ -60,3 +60,24 @@ Cubed-Sphere (FV3) dynamical core. | ``│   └── src`` - source code for SCM infrastructure, Python run script, CMakeLists.txt for the SCM, example multirun setup files, suite_info.py | ``└── test`` - Contains scripts for regression testing, Continuous Integration tests +Testing +----------------- + +Regression Testing +^^^^^^^^^^^^^^^^^^ + +Regression tests are a comprehensive set of build and run tests meant to ensure that new changes to the SCM do not break any existing capabilities. These tests are run on code changes before they are merged, and so ensure that the ``main`` branch is always free of major bugs in all facets of the system covered by the tests. + +The latest set of Regression tests are run automatically for every new code change when a Pull Request is opened via GitHub's `Continuous Integration`_. Regression tests are also run manually on a wide variety of platforms in preparation for code release to ensure that all capabilities work as expected for a reasonable spectrum of possible machines a user might want to use. + +Continuous Integration +^^^^^^^^^^^^^^^^^^^^^^ + +The CCPP SCM GitHub repository is set up with Continuous Integration (CI) testing for building the SCM and running some simple test cases. These tests are run automatically on code changes before they are merged, and so ensures that new changes to the SCM do not break basic capabilities. The latest set of tests use the following combinations of SCM prerequisites: + +**Regression tests** + - GNU compilers 11.4.0, Python 3.9.12, netCDF-c 4.7.3, netCDF-FORTRAN 4.5.3, bacio 2.4.1, sp 2.3.3, and w3emc 2.9.2 + +**Build tests** + +All tests use the same versions of NCEP-supported libraries: bacio 2.4.1, sp 2.3.3, and w3emc 2.9.2. Detailed information on these tests can be found in the definition files for these tests, stored in the SCM repository under ``ccpp-scm/.github/workflows``. diff --git a/scm/etc/modules/linux_gnu.lua b/scm/etc/modules/linux_gnu.lua new file mode 100644 index 000000000..1c0c65efa --- /dev/null +++ b/scm/etc/modules/linux_gnu.lua @@ -0,0 +1,33 @@ +help([[ +This module loads libraries for building the CCPP Single-Column Model on +a generic Linux machine with GNU compilers. Note that you may have to make +modifications to this file based on your own compilers and specifics of +how spack-stack was installed; see the Users Guide for details +]]) + +whatis([===[Loads libraries needed for building the CCPP SCM on a Linux machine with GNU compilers]===]) + +local ssd=os.getenv("SPACK_STACK_DIR") or LmodError ("Environment variable SPACK_STACK_DIR is not set") +prepend_path("MODULEPATH", ssd .. "/envs/scm-test/install/modulefiles/Core") + +load("stack-gnu") +load("stack-python/3.10.13") +load("stack-openmpi/4.1.6") + + +load("cmake/3.28.3") + +load("netcdf-c/4.9.2") +load("netcdf-fortran/4.6.1") + +load("py-f90nml/1.4.3") +load("py-netcdf4/1.5.8") + + +load("bacio/2.4.1") +load("sp/2.5.0") +load("w3emc/2.10.0") + +setenv("CMAKE_C_COMPILER","mpicc") +setenv("CMAKE_CXX_COMPILER","mpicxx") +setenv("CMAKE_Fortran_COMPILER","mpif90") diff --git a/scm/etc/modules/macos_clang.lua b/scm/etc/modules/macos_clang.lua new file mode 100644 index 000000000..41aef7680 --- /dev/null +++ b/scm/etc/modules/macos_clang.lua @@ -0,0 +1,32 @@ +help([[ +This module loads libraries for building the CCPP Single-Column Model on +a MacOS machine with clang compilers +]]) + +whatis([===[Loads libraries needed for building the CCPP SCM on a MacOS machine with clang compilers]===]) + +local ssd=os.getenv("SPACK_STACK_DIR") or LmodError ("Environment variable SPACK_STACK_DIR is not set") +prepend_path("MODULEPATH", ssd .. "/envs/scm-test/install/modulefiles/Core") + +load("stack-apple-clang") +load("stack-python/3.10.13") +load("stack-openmpi/4.1.6") + + +load("cmake/3.28.3") + +load("netcdf-c/4.9.2") +load("netcdf-fortran/4.6.1") + +load("py-f90nml/1.4.3") +load("py-netcdf4/1.5.8") + + +load("bacio/2.4.1") +load("sp/2.5.0") +load("w3emc/2.10.0") + +setenv("CMAKE_C_COMPILER","clang") +setenv("CMAKE_CXX_COMPILER","clang++") +setenv("CMAKE_Fortran_COMPILER","gfortran-12") +setenv("CMAKE_Platform","macos.clang") diff --git a/scm/etc/scripts/UFS_IC_generator.py b/scm/etc/scripts/UFS_IC_generator.py index 6fdbd13fd..5e290d3df 100755 --- a/scm/etc/scripts/UFS_IC_generator.py +++ b/scm/etc/scripts/UFS_IC_generator.py @@ -464,18 +464,20 @@ def get_UFS_IC_data(dir, grid_dir, tile, i, j, old_chgres, lam): #returns dictionaries with the data vgrid_data = get_UFS_vgrid_data(grid_dir) #only needed for ak, bk to calculate pressure - state_data = get_UFS_state_data(vgrid_data, dir, tile, i, j, old_chgres, lam) + (state_data, error_msg) = get_UFS_state_data(vgrid_data, dir, tile, i, j, old_chgres, lam) surface_data = get_UFS_surface_data(dir, tile, i, j, old_chgres, lam) oro_data = get_UFS_oro_data(dir, tile, i, j, lam) - return (state_data, surface_data, oro_data) + return (state_data, surface_data, oro_data, error_msg) ######################################################################################## # ######################################################################################## def get_UFS_state_data(vgrid, dir, tile, i, j, old_chgres, lam): """Get the state data for the given tile and indices""" - + + state = {} + error_msg=None if lam: nc_file_data = Dataset('{0}/{1}'.format(dir,'gfs_data.nc')) else: @@ -600,7 +602,10 @@ def get_UFS_state_data(vgrid, dir, tile, i, j, old_chgres, lam): icewat_model_rev[k] = cloud_water - liqwat_model_rev[0,k] (liqwat_model_rev[0,k], dummy_rain, icewat_model_rev[k], dummy_snow) = fv3_remap.mp_auto_conversion(liqwat_model_rev[0,k], icewat_model_rev[k]) - [u_s, u_n, v_w, v_e] = get_zonal_and_meridional_winds_on_cd_grid(tile, dir, i, j, nc_file_data, lam) + [u_s, u_n, v_w, v_e, unknown_grid] = get_zonal_and_meridional_winds_on_cd_grid(tile, dir, i, j, nc_file_data, lam) + if unknown_grid: + error_msg='unknown grid orientation' + return(state,error_msg) #put C/D grid zonal/meridional winds on model pressure levels u_s_model_rev = fv3_remap.mappm(levp_data, pressure_from_data_rev[np.newaxis, :], u_s[np.newaxis, :], nlevs_model, pressure_model_interfaces_rev[np.newaxis, :], 1, 1, -1, 8, ptop_data) @@ -638,7 +643,7 @@ def get_UFS_state_data(vgrid, dir, tile, i, j, old_chgres, lam): "pa_i": pressure_model_interfaces } - return state + return (state,error_msg) ######################################################################################## # @@ -665,6 +670,10 @@ def get_zonal_and_meridional_winds_on_cd_grid(tile, dir, i, j, nc_file_data, lam raise Exception(message) nc_file_grid = Dataset('{0}/{1}'.format(dir,filename)) + + # Get grid dimension + nz,nx,ny = np.shape(nc_file_data['u_w']) + if (lam): #strip ghost/halo points and return supergrid @@ -696,7 +705,7 @@ def get_zonal_and_meridional_winds_on_cd_grid(tile, dir, i, j, nc_file_data, lam east_test_point = np.argmax(test_lon_diff) north_test_point = np.argmax(test_lat_diff) - + unknown=False if east_test_point == 0: #longitude increases most along the positive i axis if north_test_point == 2: @@ -775,7 +784,11 @@ def get_zonal_and_meridional_winds_on_cd_grid(tile, dir, i, j, nc_file_data, lam (ex, ey) = fv3_remap.get_latlon_vector(p3) v_e = nc_file_data['u_w'][:,j,i+1]*fv3_remap.inner_prod(e1, ex) + nc_file_data['v_w'][:,j,i+1]*fv3_remap.inner_prod(e1, ey) else: - print('unknown grid orientation') + u_s = np.zeros(nz) + u_n = np.zeros(nz) + v_w = np.zeros(nz) + v_e = np.zeros(nz) + unknown=True elif east_test_point == 1: #longitude increases most along the negative i axis if north_test_point == 2: @@ -853,7 +866,11 @@ def get_zonal_and_meridional_winds_on_cd_grid(tile, dir, i, j, nc_file_data, lam (ex, ey) = fv3_remap.get_latlon_vector(p3) v_e = nc_file_data['u_w'][:,j,i-1]*fv3_remap.inner_prod(e1, ex) + nc_file_data['v_w'][:,j,i-1]*fv3_remap.inner_prod(e1, ey) else: - print('unknown grid orientation') + u_s = np.zeros(nz) + u_n = np.zeros(nz) + v_w = np.zeros(nz) + v_e = np.zeros(nz) + unknown=True elif east_test_point == 2: #longitude increases most along the positive j axis if north_test_point == 0: @@ -929,9 +946,16 @@ def get_zonal_and_meridional_winds_on_cd_grid(tile, dir, i, j, nc_file_data, lam p3 = fv3_remap.mid_pt_sphere(p1*deg_to_rad, p2*deg_to_rad) e1 = fv3_remap.get_unit_vect2(p1*deg_to_rad, p2*deg_to_rad) (ex, ey) = fv3_remap.get_latlon_vector(p3) - v_e = nc_file_data['u_w'][:,j+1,i]*fv3_remap.inner_prod(e1, ex) + nc_file_data['v_w'][:,j+1,i]*fv3_remap.inner_prod(e1, ey) + if (j < nx -1): + v_e = nc_file_data['u_w'][:,j+1,i]*fv3_remap.inner_prod(e1, ex) + nc_file_data['v_w'][:,j+1,i]*fv3_remap.inner_prod(e1, ey) + else: + v_e = nc_file_data['v_w'][:,j,i] else: - print('unknown grid orientation') + u_s = np.zeros(nz) + u_n = np.zeros(nz) + v_w = np.zeros(nz) + v_e = np.zeros(nz) + unknown=True elif east_test_point == 3: #longitude increases most along the negative j axis if north_test_point == 0: @@ -1009,12 +1033,15 @@ def get_zonal_and_meridional_winds_on_cd_grid(tile, dir, i, j, nc_file_data, lam (ex, ey) = fv3_remap.get_latlon_vector(p3) v_e = nc_file_data['u_w'][:,j-1,i]*fv3_remap.inner_prod(e1, ex) + nc_file_data['v_w'][:,j-1,i]*fv3_remap.inner_prod(e1, ey) else: - print('unknown grid orientation') - + u_s = np.zeros(nz) + u_n = np.zeros(nz) + v_w = np.zeros(nz) + v_e = np.zeros(nz) + unknown=True nc_file_grid.close() - return [u_s, u_n, v_w, v_e] + return [u_s, u_n, v_w, v_e, unknown] ######################################################################################## # @@ -1066,10 +1093,14 @@ def get_UFS_surface_data(dir, tile, i, j, old_chgres, lam): tprcp_in = read_NetCDF_surface_var(nc_file, 'tprcp', i, j, old_chgres, 0) srflag_in = read_NetCDF_surface_var(nc_file, 'srflag', i, j, old_chgres, 0) sncovr_in = read_NetCDF_surface_var(nc_file, 'sncovr', i, j, old_chgres, 0) - tsfcl_in = read_NetCDF_surface_var(nc_file, 'tsfcl', i, j, old_chgres, 0) - zorll_in = read_NetCDF_surface_var(nc_file, 'zorll', i, j, old_chgres, 0) - zorli_in = read_NetCDF_surface_var(nc_file, 'zorli', i, j, old_chgres, 0) - + tsfcl_in = read_NetCDF_surface_var(nc_file, 'tsea', i, j, old_chgres, 0) + zorll_in = read_NetCDF_surface_var(nc_file, 'zorl', i, j, old_chgres, 0) + zorli_in = read_NetCDF_surface_var(nc_file, 'zorl', i, j, old_chgres, 0) + if (snwdph_in > 0): + sncovr_in = 1.0 + else: + sncovr_in = 0.0 + # present when cplwav = T zorlw_in = read_NetCDF_surface_var(nc_file, 'zorlw', i, j, old_chgres, 0) @@ -1171,6 +1202,12 @@ def get_UFS_surface_data(dir, tile, i, j, old_chgres, lam): # fractional grid tiice_in = read_NetCDF_surface_var(nc_file, 'tiice', i, j, old_chgres, missing_variable_ice_layers) + # soil color (From the UFS FV3: io/fv3atm_sfc_io.F90) + if (slmsk_in == 1): + scolor_in = 4 + else: + scolor_in = 1 + # nc_file.close() @@ -1187,6 +1224,7 @@ def get_UFS_surface_data(dir, tile, i, j, old_chgres, lam): "facsf": facsf_in, "facwf": facwf_in, "soiltyp": styp_in, + "scolor": scolor_in, "slopetyp": slope_in, "vegtyp": vtyp_in, "vegfrac": vfrac_in, @@ -1313,7 +1351,7 @@ def get_UFS_oro_data(dir, tile, i, j, lam): if lam: nc_file = Dataset('{0}/{1}'.format(dir,'oro_data.nc')) else: - filename_pattern = 'oro_data.tile{0}.nc'.format(tile) + filename_pattern = 'oro*.tile{0}.nc'.format(tile) for f_name in os.listdir(dir): if fnmatch.fnmatch(f_name, filename_pattern): filename = f_name @@ -1462,8 +1500,8 @@ def get_UFS_forcing_data(nlevs, state_IC, location, use_nearest, forcing_dir, gr atm_ftag = 'atmf*.tile{0}.nc'.format(tile) sfc_ftag = 'sfcf*.tile{0}.nc'.format(tile) else: - atm_ftag = 'atmf*.nc' - sfc_ftag = 'sfcf*.nc' + atm_ftag = '*atmf*.nc' + sfc_ftag = '*sfcf*.nc' # Get list of UFS history files with 3D ATMospheric state variables. atm_filenames = [] @@ -1906,37 +1944,6 @@ def get_UFS_forcing_data(nlevs, state_IC, location, use_nearest, forcing_dir, gr pres_adv[t+1,:] = pres_adv[t,:] pres_i_adv[t+1,:] = pres_i_adv[t,:] - if save_comp_data: - # - t_layr = np.zeros([n_files+1,nlevs]) - qv_layr = np.zeros([n_files+1,nlevs]) - u_layr = np.zeros([n_files+1,nlevs]) - v_layr = np.zeros([n_files+1,nlevs]) - p_layr = np.zeros([n_files+1,nlevs]) - - # - for t in range(0,n_files): - from_p[0,:] = stateNATIVE["p_lev"][t,::-1] - to_p[0,:] = stateNATIVE["p_lev"][1,::-1] - log_from_p[0,:] = np.log(from_p[0,:]) - log_to_p[0,:] = np.log(to_p[0,:]) - p_layr[t,:] = stateNATIVE["p_lay"][1,::-1] - for k in range(0,nlevs): dp2[0,k] = to_p[0,k+1] - to_p[0,k] - t_layr[t,:] = fv3_remap.map_scalar(nlevs, log_from_p, stateNATIVE["t_lay"][t:t+1,::-1], \ - dummy, nlevs, log_to_p, 0, 0, 1, np.abs(kord_tm), t_min) - qv_layr[t,:] = fv3_remap.map1_q2(nlevs, from_p, stateNATIVE["qv_lay"][t:t+1,::-1], \ - nlevs, to_p, dp2, 0, 0, 0, kord_tr, q_min) - u_layr[t,:] = fv3_remap.map1_ppm(nlevs, from_p, stateNATIVE["u_lay"][t:t+1,::-1], \ - 0.0, nlevs, to_p, 0, 0, -1, kord_tm) - v_layr[t,:] = fv3_remap.map1_ppm(nlevs, from_p, stateNATIVE["v_lay"][t:t+1,::-1], \ - 0.0, nlevs, to_p, 0, 0, -1, kord_tm) - - t_layr[t+1,:] = t_layr[t,:] - qv_layr[t+1,:] = qv_layr[t,:] - u_layr[t+1,:] = u_layr[t,:] - v_layr[t+1,:] = v_layr[t,:] - p_layr[t+1,:] = p_layr[t,:] - #################################################################################### # # if we had atmf,sfcf files at every timestep (and the SCM timestep is made to match @@ -2105,11 +2112,11 @@ def get_UFS_forcing_data(nlevs, state_IC, location, use_nearest, forcing_dir, gr if (save_comp_data): comp_data = { "time": stateNATIVE["time"]*sec_in_hr, - "pa" : p_layr[:,::-1], - "ta" : t_layr[:,::-1], - "qv" : qv_layr[:,::-1], - "ua" : u_layr[:,::-1], - "va" : v_layr[:,::-1], + "pa" : stateNATIVE["p_lay"][:,:], + "ta" : stateNATIVE["t_lay"][:,:], + "qv" : stateNATIVE["qv_lay"][:,:], + "ua" : stateNATIVE["u_lay"][:,:], + "va" : stateNATIVE["v_lay"][:,:], "vars2d":vars2d} else: comp_data = {} @@ -2392,7 +2399,7 @@ def write_SCM_case_file(state, surface, oro, forcing, case, date, stateREGRID): {"name": "mrsos_forc", "type":wp, "dimd": ('time' ), "units": "kg m-2", "desc": "forcing_mass_content_of_water_in_soil_layer"}] # - var_oro = [{"name": "area", "type":wp, "dimd": ('t0'), "units": "m 2-1", "desc": "grid_cell_area"},\ + var_oro = [{"name": "area", "type":wp, "dimd": ('t0'), "units": "m2", "desc": "grid_cell_area"},\ {"name": "stddev", "type":wp, "dimd": ('t0'), "units": "m", "desc": "standard deviation of subgrid orography"}, \ {"name": "convexity", "type":wp, "dimd": ('t0'), "units": "none", "desc": "convexity of subgrid orography"}, \ {"name": "oa1", "type":wp, "dimd": ('t0'), "units": "none", "desc": "assymetry of subgrid orography 1"}, \ @@ -2450,6 +2457,7 @@ def write_SCM_case_file(state, surface, oro, forcing, case, date, stateREGRID): {"name": "q2m", "type":wp, "dimd": ('t0'), "units": "kg kg-1", "desc": "2-meter specific humidity"}, \ {"name": "vegtyp", "type":wi, "dimd": ('t0'), "units": "none", "desc": "vegetation type (1-12)"}, \ {"name": "soiltyp", "type":wi, "dimd": ('t0'), "units": "none", "desc": "soil type (1-12)"}, \ + {"name": "scolor", "type":wp, "dimd": ('t0'), "units": "none", "desc": "soil color"}, \ {"name": "ffmm", "type":wp, "dimd": ('t0'), "units": "none", "desc": "Monin-Obukhov similarity function for momentum"}, \ {"name": "ffhh", "type":wp, "dimd": ('t0'), "units": "none", "desc": "Monin-Obukhov similarity function for heat"}, \ {"name": "hice", "type":wp, "dimd": ('t0'), "units": "m", "desc": "sea ice thickness"}, \ @@ -2638,7 +2646,7 @@ def write_comparison_file(comp_data, case_name, date, surface): ######################################################################################## def find_date(forcing_dir): - atm_ftag = 'atmf*.nc' + atm_ftag = '*atmf*.nc' atm_filenames = [] for f_name in os.listdir(forcing_dir): @@ -2704,8 +2712,12 @@ def main(): # get UFS IC data (TODO: flag to read in RESTART data rather than IC data and implement # different file reads) - (state_data, surface_data, oro_data) = get_UFS_IC_data(in_dir, grid_dir, tile, tile_i,\ - tile_j, old_chgres, lam) + (state_data, surface_data, oro_data, error_msg) = get_UFS_IC_data(in_dir, grid_dir, tile, tile_i,\ + tile_j, old_chgres, lam) + if (error_msg): + print(error_msg) + print("STOPPING") + exit() if not date: # date was not included on command line; look in atmf* file for initial date diff --git a/scm/etc/scripts/UFS_forcing_ensemble_generator.py b/scm/etc/scripts/UFS_forcing_ensemble_generator.py index d057dc6cf..c4a533127 100755 --- a/scm/etc/scripts/UFS_forcing_ensemble_generator.py +++ b/scm/etc/scripts/UFS_forcing_ensemble_generator.py @@ -20,6 +20,7 @@ parser.add_argument('-latl', '--lat_limits', help='latitude range, separated by a space', nargs=2, type=float, required=False) parser.add_argument('-lons', '--lon_list', help='longitudes, separated by a space', nargs='*', type=float, required=False) parser.add_argument('-lats', '--lat_list', help='latitudes, separated by a space', nargs='*', type=float, required=False) +parser.add_argument('-fxy', '--lonlat_file', help='file containing longitudes and latitude',nargs=1, required=False) parser.add_argument('-nens', '--nensmembers', help='number of SCM UFS ensemble memebers to create', type=int, required=False) parser.add_argument('-dt', '--timestep', help='SCM timestep, in seconds', type=int, default = 3600) parser.add_argument('-cres', '--C_RES', help='UFS spatial resolution', type=int, default = 96) @@ -43,25 +44,29 @@ def main(): if (args.lon_limits and args.lon_list): print("ERROR: Can't provide explicit longitude(s) AND a longitude range") exit() + # end if if (args.lat_limits and args.lat_list): print("ERROR: Can't provide explicit latitude(s) AND a latitude range") exit() + # end if if (args.lon_limits or args.lat_limits) and not args.nensmembers: print("ERROR: Longitude/Latitude range provided, but NOT ensemble count.") exit() - + # end if if (args.nensmembers): npts = args.nensmembers if (args.lat_list or args.lon_list): print("ERROR: Can't provide explicit lon/lat range AND number of points for ensemble generation.") exit() - else: - if (args.lon_list and args.lat_list): - if (len(args.lon_list) == len(args.lat_list)): - npts = len(args.lon_list) - else: - print("ERROR: Number of longitude/latitudes are inconsistent") - exit() + # end if + elif (args.lon_list and args.lat_list): + if (len(args.lon_list) == len(args.lat_list)): + npts = len(args.lon_list) + else: + print("ERROR: Number of longitude/latitudes are inconsistent") + exit() + # end if + # end if ########################################################################### # @@ -83,19 +88,42 @@ def main(): lats[ipt] = args.lat_limits[0] + (args.lat_limits[1]-args.lat_limits[0])*rng1[ipt] else: lats[ipt] = rng1[ipt]*180-90 + # end if if args.lon_limits: lons[ipt] = args.lon_limits[0] + (args.lon_limits[1]-args.lon_limits[0])*rng2[ipt] else: lons[ipt] = rng2[ipt]*360 + # end if + # end for ########################################################################### # - # Use longitude and latitude provided + # Use longitude and latitude provided to command line # ########################################################################### - else: + elif (args.lon_list and args.lat_list): lons = np.asarray(args.lon_list) lats = np.asarray(args.lat_list) - + ########################################################################### + # + # Use longitude and latitude from input file + # + ########################################################################### + elif (args.lonlat_file): + fid = open(args.lonlat_file[0], 'r') + lines = fid.read().split('\n') + lon_list = lines[0] + lons = eval(lon_list) + lat_list = lines[1] + lats = eval(lat_list) + npts = len(lons) + else: + print("ERROR: Must provide input points in one of the following formats:") + print(" Using -nens [] -lonl [] -latl [] (e.g. -nens 20 -lonl 30 40 -latl 30 35)") + print(" Using -lons [] -lats [] (e.g. -lons 203 204 205 -lats 30 30 30)") + print(" Using -fxy (e.g. -fxy lonlat.txt w/ -lons [] -lats [])") + exit() + # end if + ########################################################################### # # Create SCM case configuration (etc/case_config) file. @@ -125,35 +153,38 @@ def main(): print(com) os.system(com) - # Add case to ensemble list. - case_list = case_list + '"'+case_name+'"' - if (count != npts-1): case_list = case_list + ', ' + if (os.path.isfile(file_scminput)): + # Add case to ensemble list. + case_list = case_list + '"'+case_name+'"' + if (count != npts-1): case_list = case_list + ', ' - # What is the surface type? (get from SCM input file) - dataset = xr.open_dataset(file_scminput) - sfc_type = int(np.round_(dataset.slmsk.values[0])) + # What is the surface type? (get from SCM input file) + dataset = xr.open_dataset(file_scminput) + sfc_type = int(np.round_(dataset.slmsk.values[0])) - # Create case_config file(s) - fileOUT = "../../etc/case_config/"+case_name+".nml" - fileID = open(fileOUT, 'w') - fileID.write('$case_config') - fileID.write('\n') - fileID.write('case_name = ' + "'" + case_name + "',") - fileID.write('\n') - fileID.write('sfc_type = ' + str(sfc_type) + ",") - fileID.write('\n') - for opts in case_config: - fileID.write(opts["name"] + ' = ' + opts["values"] + ",") + # Create case_config file(s) + fileOUT = "../../etc/case_config/"+case_name+".nml" + fileID = open(fileOUT, 'w') + fileID.write('$case_config') fileID.write('\n') - fileID.write('$end') - fileID.write('\n') - fileID.close() + fileID.write('case_name = ' + "'" + case_name + "',") + fileID.write('\n') + fileID.write('sfc_type = ' + str(sfc_type) + ",") + fileID.write('\n') + for opts in case_config: + fileID.write(opts["name"] + ' = ' + opts["values"] + ",") + fileID.write('\n') + fileID.write('$end') + fileID.write('\n') + fileID.close() - # Add case to dictionary to be used by run_scm.py - run_list.append({"case": case_name, "suite": args.suite}) + # Add case to dictionary to be used by run_scm.py + run_list.append({"case": case_name, "suite": args.suite}) - # - count = count + 1 + # + count = count + 1 + # end if + # end for ########################################################################### # @@ -171,6 +202,7 @@ def main(): #print(' {"case": "' , run["case"] , '", "suite": "' , run["suite"] , '"},') fileID.write(' {"case": "' + run["case"] + '", "suite": "' + run["suite"] + '"},') fileID.write('\n') + # end for fileID.write(' ]') fileID.close() diff --git a/scm/etc/scripts/create_lonlat4replay.py b/scm/etc/scripts/create_lonlat4replay.py new file mode 100755 index 000000000..844095fcc --- /dev/null +++ b/scm/etc/scripts/create_lonlat4replay.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +################################################################################################# +# Dependencies +################################################################################################# +import os +import numpy as np +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument('-d', '--dir', help='path to UFS Regression Test output', required=True) +parser.add_argument('-n', '--case_name', help='name of case', required=True) +parser.add_argument('-lonl', '--lon_range', help='longitude range, separated by a space', nargs=2, type=int, required=True) +parser.add_argument('-latl', '--lat_range', help='latitude range, separated by a space', nargs=2, type=int, required=True) +parser.add_argument('-dlat', '--dlat', help='latitude spacing', type=int, required=True) +parser.add_argument('-dlon', '--dlon', help='longitude spacing', type=int, required=True) +parser.add_argument('-dt', '--timestep', help='SCM timestep, in seconds', type=int, required=True) +parser.add_argument('-cres', '--C_RES', help='UFS spatial resolution', type=int, required=True) +parser.add_argument('-sdf', '--suite', help='CCPP suite definition file to use for ensemble', required=True) +parser.add_argument('-fout', '--fileOUT', help='Text file containing lon/lat points', required=False, default='lonlats.txt') + +def main(): + + # Get command line arguments + args = parser.parse_args() + dir = args.dir+'/'+args.case_name + + com_pre = './UFS_forcing_ensemble_generator.py -d '+dir+' -sc --C_RES '+str(args.C_RES)+' -dt '+str(args.timestep)+' -n '+args.case_name+' -sdf '+args.suite + + lons = [] + lats = [] + count = 0 + for lon in range(args.lon_range[0],args.lon_range[1],args.dlon): + for lat in range(args.lat_range[0],args.lat_range[1],args.dlat): + count = count + 1 + lons.append(lon) + lats.append(lat) + # end for + # end for + + comA = '-lons ' + for ij in lons: + comA = comA + str(ij)+' ' + # end for + comB = '-lats ' + for ij in lats: + comB = comB + str(ij)+' ' + # end for + com = com_pre+comA+comB + print(com) + print("#######################################################################################") + + # For python list input file + comA = '' + countA = 0 + for ij in lons: + countA = countA + 1 + if (countA < count): + comA = comA + str(ij)+', ' + else: + comA = comA + str(ij) + #end if + # end for + + comB = '' + countB = 0 + for ij in lats: + countB = countB + 1 + if (countB < count): + comB = comB + str(ij)+', ' + else: + comB = comB + str(ij) + # end if + # end for + + fileID = open(args.fileOUT,'w') + fileID.write(comA+"\n") + fileID.write(comB+"\n") + fileID.close() + com = com_pre+' -fxy '+args.fileOUT + print(com) + +if __name__ == '__main__': + main() diff --git a/scm/etc/scripts/extract_FV3GFS_column_ic.py b/scm/etc/scripts/extract_FV3GFS_column_ic.py deleted file mode 100755 index 6684125c1..000000000 --- a/scm/etc/scripts/extract_FV3GFS_column_ic.py +++ /dev/null @@ -1,415 +0,0 @@ -#!/usr/bin/env python -from netCDF4 import Dataset -import numpy as np - -# define date -YYYY=2014 -MM=8 -DD=1 -HH=0 -MI=0 -SC=0 - -# define path to FV3 GFS initial and boundary conditions -icpath='../../data/raw_case_input/UFS_test_ics' -fixpath='../../data/raw_case_input/UFS_test_ics' -print (icpath) -# defint i,j and tile to extract colmn -ipt=16 -jpt=41 -tilenum=2 - -ipt2=ipt*2+1 -jpt2=jpt*2+1 - -# I have surface cycle on the sfc_data initial conditions to get the proper surface fields -infile1='%s/gfs_data.tile%i.nc' % (icpath,tilenum) -infile2='%s/sfc_data.tile%i.nc' %(icpath,tilenum) -infile3='%s/C96_oro_data.tile%i.nc' %(fixpath,tilenum) -infile4='%s/C96_grid.tile%i.nc' %(fixpath,tilenum) -infile5='%s/gfs_ctrl.nc' %icpath -ncin1=Dataset(infile1) -ncin2=Dataset(infile2) -ncin3=Dataset(infile3) -ncin4=Dataset(infile4) -ncin5=Dataset(infile5) -# assume model contains one less level than the cold start spectral GFS initial conditions -nlevs=len(ncin1.dimensions['lev'])-1 -# pick off lat and lon from i and j point defined above -lon0=ncin4['x'][jpt2,ipt2] -lat0=ncin4['y'][jpt2,ipt2] - -# extract out area of grid cell -area_in=ncin4['area'][jpt2-1:jpt2+1,ipt2-1:ipt2+1] -print (lat0,lon0) - -# upper air fields from initial conditions -zh=ncin1['zh'][::-1,jpt,ipt] -uw1=ncin1['u_w'][::-1,jpt,ipt] -uw2=ncin1['u_w'][::-1,jpt,ipt+1] -us1=ncin1['u_s'][::-1,jpt,ipt] -us2=ncin1['u_s'][::-1,jpt+1,ipt] -vw1=ncin1['v_w'][::-1,jpt,ipt] -vw2=ncin1['v_w'][::-1,jpt,ipt+1] -vs1=ncin1['v_s'][::-1,jpt,ipt] -vs2=ncin1['v_s'][::-1,jpt+1,ipt] -ucomp=0.25*(uw1+uw2+us1+us2) # estimate u winds on the a grid -vcomp=0.25*(vw1+vw2+vs1+vs2) # estimate v winds on the a grid -sphum=ncin1['sphum'][::-1,jpt,ipt] -# o3 and qv are taken from ics. -o3=ncin1['o3mr'][::-1,jpt,ipt] -liqwat=ncin1['liq_wat'][:-1,jpt,ipt] - -# surface pressure and skin temperature -ps=ncin1['ps'][jpt,ipt] -ts=ncin2['tsea'][jpt,ipt] - -# land state -stc_in=ncin2['stc'][:,jpt,ipt] -smc_in=ncin2['smc'][:,jpt,ipt] -slc_in=ncin2['slc'][:,jpt,ipt] -tg3_in=ncin2['tg3'][jpt,ipt] - -# surface properties -uustar_in=ncin2['uustar'][jpt,ipt] -alvsf=ncin2['alvsf'][jpt,ipt] -alvwf=ncin2['alvwf'][jpt,ipt] -alnsf=ncin2['alnsf'][jpt,ipt] -alnwf=ncin2['alnwf'][jpt,ipt] -facsf_in=ncin2['facsf'][jpt,ipt] -facwf_in=ncin2['facwf'][jpt,ipt] -styp_in=ncin2['stype'][jpt,ipt] -slope_in=ncin2['slope'][jpt,ipt] -vtyp_in=ncin2['vtype'][jpt,ipt] -vfrac_in=ncin2['vfrac'][jpt,ipt] -shdmin_in=ncin2['shdmin'][jpt,ipt] -shdmax_in=ncin2['shdmax'][jpt,ipt] -zorl_in=ncin2['zorl'][jpt,ipt] -slmsk_in=ncin2['slmsk'][jpt,ipt] -canopy_in=ncin2['canopy'][jpt,ipt] -hice_in=ncin2['hice'][jpt,ipt] -fice_in=ncin2['fice'][jpt,ipt] -tisfc_in=ncin2['tisfc'][jpt,ipt] -snwdph_in=ncin2['snwdph'][jpt,ipt] -snoalb_in=ncin2['snoalb'][jpt,ipt] - -# orographyic properties -stddev_in=ncin3['stddev'][jpt,ipt] -convexity_in=ncin3['convexity'][jpt,ipt] -oa1_in=ncin3['oa1'][jpt,ipt] -oa2_in=ncin3['oa2'][jpt,ipt] -oa3_in=ncin3['oa3'][jpt,ipt] -oa4_in=ncin3['oa4'][jpt,ipt] -ol1_in=ncin3['ol1'][jpt,ipt] -ol2_in=ncin3['ol2'][jpt,ipt] -ol3_in=ncin3['ol3'][jpt,ipt] -ol4_in=ncin3['ol4'][jpt,ipt] -theta_in=ncin3['theta'][jpt,ipt] -gamma_in=ncin3['gamma'][jpt,ipt] -sigma_in=ncin3['sigma'][jpt,ipt] -elvmax_in=ncin3['elvmax'][jpt,ipt] - -# vertical coordinate definition -ak=ncin5['vcoord'][0,::-1] -bk=ncin5['vcoord'][1,::-1] - -#calculate temperature -rdgas = 287.05 -rvgas = 461.50 -zvir = rvgas/rdgas - 1. -grav=9.80665 -gz=zh*grav -pn1=np.zeros([nlevs+1]) -temp=np.zeros([nlevs]) -for k in range(nlevs+1): - pn1[k]=np.log(ak[k]+ps*bk[k]) -for k in range(nlevs): - temp[k] = (gz[k]-gz[k+1])/( rdgas*(pn1[k+1]-pn1[k])*(1.+zvir*sphum[k]) ) - -# open output file -nc = Dataset('../../data/processed_case_input/fv3_model_point.nc', mode='w') -nc.description = "FV3GFS model profile input (no forcing)" - -time = nc.createDimension('time',None) -levels = nc.createDimension('levels',None) -nsoil = nc.createDimension('nsoil',None) -t = nc.createVariable('time',np.float64,('time',)) -t.units = "s" -t.description = "elapsed time since the beginning of the simulation" -z = nc.createVariable('levels',np.float64,('levels',)) -z.units = "Pa" -z.description = "pressure levels" -#scalars -iyr = nc.createVariable('scalars/init_year',np.int32) -imo = nc.createVariable('scalars/init_month',np.int32) -idy = nc.createVariable('scalars/init_day',np.int32) -ihr = nc.createVariable('scalars/init_hour',np.int32) -imi = nc.createVariable('scalars/init_minute',np.int32) -isc = nc.createVariable('scalars/init_second',np.int32) -ivegsrc = nc.createVariable('scalars/vegsrc',np.int32) -ivegtyp = nc.createVariable('scalars/vegtyp',np.int32) -isoiltyp = nc.createVariable('scalars/soiltyp',np.int32) -islopetyp = nc.createVariable('scalars/slopetyp',np.int32) -ivegfrac = nc.createVariable('scalars/vegfrac',np.float) -ishdmin = nc.createVariable('scalars/shdmin',np.float) -ishdmax = nc.createVariable('scalars/shdmax',np.float) -izorl = nc.createVariable('scalars/zorl',np.float) -islmsk = nc.createVariable('scalars/slmsk',np.float) -icanopy = nc.createVariable('scalars/canopy',np.float) -ihice = nc.createVariable('scalars/hice',np.float) -ifice = nc.createVariable('scalars/fice',np.float) -itisfc = nc.createVariable('scalars/tisfc',np.float) -isnwdph = nc.createVariable('scalars/snwdph',np.float) -isnoalb = nc.createVariable('scalars/snoalb',np.float) -isncovr = nc.createVariable('scalars/sncovr',np.float) -itg3 = nc.createVariable('scalars/tg3',np.float) -iuustar = nc.createVariable('scalars/uustar',np.float) - -iyr.units = "years" -iyr.description = "year at time of initial values" -imo.units = "months" -imo.description = "month at time of initial values" -idy.units = "days" -idy.description = "day at time of initial values" -ihr.units = "hours" -ihr.description = "hour at time of initial values" -imi.units = "minutes" -imi.description = "minute at time of initial values" -isc.units = "seconds" -isc.description = "second at time of initial values" -ivegsrc.description = "vegetation soure (1-2)" -ivegtyp.description = "vegetation type (1-12)" -isoiltyp.description = "soil type (1-12)" -islopetyp.description = "slope type (1-9)" -ivegfrac.description = "vegetation fraction" -ishdmin.description = "minimum vegetation fraction" -ishdmax.description = "maximum vegetation fraction" -izorl.description = "surface roughness length" -islmsk.description = "land-sea-ice mask" -icanopy.description = "canopy moisture" -ihice.description = "ice thickness" -ifice.description = "ice fraction" -itisfc.description = "ice temperature" -isnwdph.description = "snow depth" -isnoalb.description = "snow albedo" -isncovr.description = "snow cover" -itg3.description = "deep soil temperature" -itg3.units = "K" -iuustar.description = "frication velocity" -iuustar.units = "m2s-2?" - - -#initial -ic_t = nc.createVariable('initial/temp',np.float64,('levels',)) -ic_qt = nc.createVariable('initial/qt',np.float64,('levels',)) -ic_ql = nc.createVariable('initial/ql',np.float64,('levels',)) -ic_qi = nc.createVariable('initial/qi',np.float64,('levels',)) -ic_u = nc.createVariable('initial/u',np.float64,('levels',)) -ic_v = nc.createVariable('initial/v',np.float64,('levels',)) -ic_tke = nc.createVariable('initial/tke',np.float64,('levels',)) -ic_o3 = nc.createVariable('initial/ozone',np.float64,('levels',)) -ic_stc = nc.createVariable('initial/stc',np.float64,('nsoil',)) -ic_smc = nc.createVariable('initial/smc',np.float64,('nsoil',)) -ic_slc = nc.createVariable('initial/slc',np.float64,('nsoil',)) -ic_t.units = "K" -#ic_t.description = "initial profile of ice-liquid water potential temperature" -ic_t.description = "initial profile of temperature" -ic_qt.units = "kg kg^-1" -ic_qt.description = "initial profile of total water specific humidity" -ic_ql.units = "kg kg^-1" -ic_ql.description = "initial profile of liquid water specific humidity" -ic_qi.units = "kg kg^-1" -ic_qi.description = "initial profile of ice water specific humidity" -ic_u.units = "m s^-1" -ic_u.description = "initial profile of E-W horizontal wind" -ic_v.units = "m s^-1" -ic_v.description = "initial profile of N-S horizontal wind" -ic_tke.units = "m^2 s^-2" -ic_tke.description = "initial profile of turbulence kinetic energy" -ic_o3.units = "kg kg^-1" -ic_o3.description = "initial profile of ozone mass mixing ratio" -ic_stc.units = "K" -ic_stc.description = "initial profile of soil temperature" -ic_smc.units = "kg" -ic_smc.description = "initial profile of soil moisture" -ic_slc.units = "kg" -ic_slc.description = "initial profile of soil liquid moisture" - -lat=nc.createVariable('forcing/lat',np.float64,('time',)) -lat.units = "degrees N" -lat.description = "latitude of column" -lon=nc.createVariable('forcing/lon',np.float64,('time',)) -lon.units = "degrees E" -lon.description = "longitude of column" -p_surf=nc.createVariable('forcing/p_surf',np.float64,('time',)) -p_surf.units = "Pa" -p_surf.description = "surface pressure" -T_surf=nc.createVariable('forcing/T_surf',np.float64,('time',)) -T_surf.units = "K" -T_surf.description = "surface absolute temperature" -area1=nc.createVariable('scalars/area',np.float64,('time',)) -alb1=nc.createVariable('scalars/alvsf',np.float64,('time',)) -alb2=nc.createVariable('scalars/alnsf',np.float64,('time',)) -alb3=nc.createVariable('scalars/alvwf',np.float64,('time',)) -alb4=nc.createVariable('scalars/alnwf',np.float64,('time',)) -stddev=nc.createVariable('scalars/stddev',np.float64,('time',)) -convexity=nc.createVariable('scalars/convexity',np.float64,('time',)) -oa1=nc.createVariable('scalars/oa1',np.float64,('time',)) -oa2=nc.createVariable('scalars/oa2',np.float64,('time',)) -oa3=nc.createVariable('scalars/oa3',np.float64,('time',)) -oa4=nc.createVariable('scalars/oa4',np.float64,('time',)) -ol1=nc.createVariable('scalars/ol1',np.float64,('time',)) -ol2=nc.createVariable('scalars/ol2',np.float64,('time',)) -ol3=nc.createVariable('scalars/ol3',np.float64,('time',)) -ol4=nc.createVariable('scalars/ol4',np.float64,('time',)) -theta=nc.createVariable('scalars/theta',np.float64,('time',)) -gamma=nc.createVariable('scalars/gamma',np.float64,('time',)) -sigma=nc.createVariable('scalars/sigma',np.float64,('time',)) -elvmax=nc.createVariable('scalars/elvmax',np.float64,('time',)) -facsf=nc.createVariable('scalars/facsf',np.float64,('time',)) -facwf=nc.createVariable('scalars/facwf',np.float64,('time',)) -area1.units = "m^2" -alb1.units = "None" -alb2.units = "None" -alb3.units = "None" -alb4.units = "None" -facsf.units = "None" -facwf.units = "None" -area1.description = "grid cell area" -alb1.description = "uv+visible black sky albedo (z=60 degree)" -alb2.description = "near IR black sky albedo (z=60 degree)" -alb3.description = "uv+visible white sky albedo" -alb4.description = "near IR white sky albedo" -stddev.description = "surface orography standard deviation" -facsf.description = "fraction of grid cell with strong sun angle albedo dependence" -facwf.description = "fraction of grid cell with weak sun angle albedo dependence" -w_ls=nc.createVariable('forcing/w_ls',np.float64,('levels','time',)) -w_ls.units = "m s^-1" -w_ls.description = "large scale vertical velocity" -omega=nc.createVariable('forcing/omega',np.float64,('levels','time',)) -omega.units = "Pa s^-1" -omega.description = "large scale pressure vertical velocity" -u_g=nc.createVariable('forcing/u_g',np.float64,('levels','time',)) -u_g.units = "m s^-1" -u_g.description = "large scale geostrophic E-W wind" -v_g=nc.createVariable('forcing/v_g',np.float64,('levels','time',)) -v_g.units = "m s^-1" -v_g.description = "large scale geostrophic N-S wind" -u_nudge=nc.createVariable('forcing/u_nudge',np.float64,('levels','time',)) -u_nudge.units = "m s^-1" -u_nudge.description = "E-W wind to nudge toward" -v_nudge=nc.createVariable('forcing/v_nudge',np.float64,('levels','time',)) -v_nudge.units = "m s^-1" -v_nudge.description = "N-S wind to nudge toward" -T_nudge=nc.createVariable('forcing/T_nudge',np.float64,('levels','time',)) -T_nudge.units = "K" -T_nudge.description = "absolute temperature to nudge toward" -thil_nudge=nc.createVariable('forcing/thil_nudge',np.float64,('levels','time',)) -thil_nudge.units = "K" -thil_nudge.description = "potential temperature to nudge toward" -qt_nudge=nc.createVariable('forcing/qt_nudge',np.float64,('levels','time',)) -qt_nudge.units = "kg kg^-1" -qt_nudge.description = "q_t to nudge toward" -dT_dt_rad=nc.createVariable('forcing/dT_dt_rad',np.float64,('levels','time',)) -dT_dt_rad.units = "K s^-1" -dT_dt_rad.description = "prescribed radiative heating rate" -h_advec_thetail=nc.createVariable('forcing/h_advec_thetail',np.float64,('levels','time',)) -h_advec_thetail.units = "K s^-1" -h_advec_thetail.description = "prescribed theta_il tendency due to horizontal advection" -v_advec_thetail=nc.createVariable('forcing/v_advec_thetail',np.float64,('levels','time',)) -v_advec_thetail.units = "K s^-1" -v_advec_thetail.description = "prescribed theta_il tendency due to vertical advection" -h_advec_qt=nc.createVariable('forcing/h_advec_qt',np.float64,('levels','time',)) -h_advec_qt.units = "kg kg^-1 s^-1" -h_advec_qt.description = "prescribed q_t tendency due to horizontal advection" -v_advec_qt=nc.createVariable('forcing/v_advec_qt',np.float64,('levels','time',)) -v_advec_qt.units = "kg kg^-1 s^-1" -v_advec_qt.description = "prescribed q_t tendency due to vertical advection" - - -# date -iyr[:]=YYYY -imo[:]=MM -idy[:]=DD -ihr[:]=HH -imi[:]=MI -isc[:]=SC -# axes -t[0]=0 - -#ics -ic_t[:] = temp[0:nlevs] -ic_qt[:] = sphum[0:nlevs] -ic_ql[:] = liqwat[0:nlevs] -ic_qi[:] = 0.0 -ic_u[:] = ucomp[0:nlevs] -ic_v[:] = vcomp[0:nlevs] -ic_tke[:] = 0.0 -ic_o3[:] = o3[0:nlevs] -ic_stc[:] = stc_in -ic_smc[:] = smc_in -ic_slc[:] = slc_in - -lat[:]=lat0 -lon[:]=lon0 - -p_surf[:]=ps -T_surf[:]=ts -area1[:]=area_in.sum() -alb1[:]=alvsf -alb2[:]=alnsf -alb3[:]=alvwf -alb4[:]=alnwf -stddev[:]=stddev_in -convexity[:]=convexity_in -oa1[:]=oa1_in -oa2[:]=oa2_in -oa3[:]=oa3_in -oa4[:]=oa4_in -ol1[:]=ol1_in -ol2[:]=ol2_in -ol3[:]=ol3_in -ol4[:]=ol4_in -theta[:]=theta_in -gamma[:]=gamma_in -sigma[:]=sigma_in -elvmax[:]=elvmax_in -facsf[:]=facsf_in -facwf[:]=facwf_in -z[:]=np.exp(pn1[0:nlevs]) -w_ls[:]=0.0 -omega[:]=0.0 -u_g[:]=0.0 -v_g[:]=0.0 -u_nudge[:]=0.0 -v_nudge[:]=0.0 -T_nudge[:]=0.0 -thil_nudge[:]=0.0 -qt_nudge[:]=0.0 -dT_dt_rad[:]=0.0 -h_advec_thetail[:]=0.0 -v_advec_thetail[:]=0.0 -h_advec_qt[:]=0.0 -v_advec_qt[:]=0.0 - -ivegsrc[:] = 1 -ivegtyp[:] = vtyp_in -isoiltyp[:] = styp_in -islopetyp[:] = slope_in -ishdmin[:] = shdmin_in -ishdmax[:] = shdmax_in -izorl[:] = zorl_in -islmsk[:] = slmsk_in -icanopy[:] = canopy_in -ihice[:] = hice_in -ifice[:] = fice_in -itisfc[:] = tisfc_in -isnwdph[:] = snwdph_in -isnoalb[:] = snoalb_in -isncovr[:] = 0.0 -itg3[:] = tg3_in -iuustar[:] = uustar_in -ivegfrac[:]=vfrac_in - -nc.close() - diff --git a/scm/etc/tracer_config/tracers_GFS_v17_HR3.txt b/scm/etc/tracer_config/tracers_GFS_v17_HR3.txt new file mode 100644 index 000000000..eeba3d9e3 --- /dev/null +++ b/scm/etc/tracer_config/tracers_GFS_v17_HR3.txt @@ -0,0 +1,11 @@ +"sphum","water_vapor_specific_humidity","kg kg-1" +"liq_wat","cloud_condensed_water_mixing_ratio","kg kg-1" +"ice_wat","ice_water_mixing_ratio","kg kg-1" +"rainwat","rain_water_mixing_ratio","kg kg-1" +"snowwat","snow_water_mixing_ratio","kg kg-1" +"graupel","graupel_mixing_ratio","kg kg-1" +"ice_nc","ice_number_concentration","kg-1" +"rain_nc","rain_number_concentration","kg-1" +"o3mr","ozone_mixing_ratio","kg kg-1" +"sgs_tke","turbulent_kinetic_energy","m2 s-2" +"sigmab"," prognostic_updraft_area_fraction_in_convection","frac" diff --git a/scm/etc/tracer_config/tracers_RRFS_v1.txt b/scm/etc/tracer_config/tracers_RRFS_v1.txt new file mode 100644 index 000000000..3835c38a2 --- /dev/null +++ b/scm/etc/tracer_config/tracers_RRFS_v1.txt @@ -0,0 +1,16 @@ +"sphum","water_vapor_specific_humidity","kg kg-1" +"liq_wat","cloud_condensed_water_mixing_ratio","kg kg-1" +"ice_wat","ice_water_mixing_ratio","kg kg-1" +"rainwat","rain_water_mixing_ratio","kg kg-1" +"snowwat","snow_water_mixing_ratio","kg kg-1" +"graupel","graupel_mixing_ratio","kg kg-1" +"water_nc","cloud_droplet_number_concentration","kg-1" +"ice_nc","ice_number_concentration","kg-1" +"rain_nc","rain_number_concentration","kg-1" +"o3mr","ozone_mixing_ratio","kg kg-1" +"liq_aero","water_friendly_aerosol_number_concentration","kg-1" +"ice_aero","ice_friendly_aerosol_number_concentration","kg-1" +"sgs_tke","turbulent_kinetic_energy","m2 s-2" +"smoke","smoke_tracer_concentration","ug kg-1" +"dust","dust_tracer_concentration","ug kg-1" +"coarsepm","coarse_particulate_matter","ug kg-1" \ No newline at end of file diff --git a/scm/src/CCPP_typedefs.F90 b/scm/src/CCPP_typedefs.F90 index 878422d39..0b49ed010 100644 --- a/scm/src/CCPP_typedefs.F90 +++ b/scm/src/CCPP_typedefs.F90 @@ -622,7 +622,7 @@ subroutine gfs_interstitial_create (Interstitial, IM, Model) allocate (Interstitial%sigma (IM)) allocate (Interstitial%sigmaf (IM)) allocate (Interstitial%sigmafrac (IM,Model%levs)) - allocate (Interstitial%sigmatot (IM,Model%levs)) + allocate (Interstitial%sigmatot (IM,Model%levs+1)) allocate (Interstitial%snowc (IM)) allocate (Interstitial%snohf (IM)) allocate (Interstitial%snowmt (IM)) diff --git a/scm/src/CCPP_typedefs.meta b/scm/src/CCPP_typedefs.meta index 8ab9f4ba2..8208bd1d5 100644 --- a/scm/src/CCPP_typedefs.meta +++ b/scm/src/CCPP_typedefs.meta @@ -1952,7 +1952,7 @@ standard_name = convective_updraft_area_fraction_at_model_interfaces long_name = convective updraft area fraction at model interfaces units = frac - dimensions = (horizontal_loop_extent,vertical_layer_dimension) + dimensions = (horizontal_loop_extent,vertical_interface_dimension) type = real kind = kind_phys [skip_macro] diff --git a/scm/src/CMakeLists.txt b/scm/src/CMakeLists.txt index b952680b6..2ef20bb84 100644 --- a/scm/src/CMakeLists.txt +++ b/scm/src/CMakeLists.txt @@ -186,6 +186,37 @@ elseif (${CMAKE_Fortran_COMPILER_ID} MATCHES "Intel") set(CMAKE_Fortran_FLAGS_RELEASE "-O2 -fPIC" CACHE STRING "" FORCE) set(CMAKE_C_FLAGS_BITFORBIT "-O2 -fPIC" CACHE STRING "" FORCE) set(CMAKE_Fortran_FLAGS_BITFORBIT "-O2 -fPIC" CACHE STRING "" FORCE) + +elseif (${CMAKE_Fortran_COMPILER_ID} MATCHES "NVHPC") + if(ENABLE_NVIDIA_OPENACC MATCHES "true") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -acc -Minfo=accel") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -acc -Minfo=accel") + else() + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + endif() + + if(NOT 32BIT) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -r8") + endif() + + if (${CMAKE_BUILD_TYPE} MATCHES "Debug") + set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -O0 -g") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g") + else() + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -O2") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") + endif() + + set(MPI_C_COMPILER mpicc) + set(MPI_CXX_COMPILER mpicxx) + set(MPI_Fortran_COMPILER mpif90) + + set(CMAKE_C_FLAGS_RELEASE "-O2 -fPIC" CACHE STRING "" FORCE) + set(CMAKE_Fortran_FLAGS_RELEASE "-O2 -fPIC" CACHE STRING "" FORCE) + set(CMAKE_C_FLAGS_BITFORBIT "-O2 -fPIC" CACHE STRING "" FORCE) + set(CMAKE_Fortran_FLAGS_BITFORBIT "-O2 -fPIC" CACHE STRING "" FORCE) + else (${CMAKE_Fortran_COMPILER_ID} MATCHES "GNU") message (FATAL_ERROR "This program has only been compiled with gfortran and ifort. If another compiler is needed, the appropriate flags must be added in ${CMAKE_SOURCE_DIR}/CMakeLists.txt") endif (${CMAKE_Fortran_COMPILER_ID} MATCHES "GNU") diff --git a/scm/src/GFS_typedefs.F90 b/scm/src/GFS_typedefs.F90 index 2e822487a..cf4a6db0c 100644 --- a/scm/src/GFS_typedefs.F90 +++ b/scm/src/GFS_typedefs.F90 @@ -5393,6 +5393,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & call label_dtend_tracer(Model,100+Model%ntgz,'graupel_ref','graupel reflectivity','m3 kg-1 s-1') call label_dtend_tracer(Model,100+Model%nthz,'hail_ref','hail reflectivity','m3 kg-1 s-1') call label_dtend_tracer(Model,100+Model%ntke,'sgs_tke','turbulent kinetic energy','J s-1') + call label_dtend_tracer(Model,100+Model%ntsigma,'sigmab','prognostic updraft area fraction in convection','frac') call label_dtend_tracer(Model,100+Model%nqrimef,'q_rimef','mass weighted rime factor','kg-1 s-1') call label_dtend_tracer(Model,100+Model%ntwa,'liq_aero','number concentration of water-friendly aerosols','kg-1 s-1') call label_dtend_tracer(Model,100+Model%ntia,'ice_aero','number concentration of ice-friendly aerosols','kg-1 s-1') diff --git a/scm/src/run_scm.py b/scm/src/run_scm.py index 20cfbce6a..926fb68ba 100755 --- a/scm/src/run_scm.py +++ b/scm/src/run_scm.py @@ -488,12 +488,12 @@ def setup_rundir(self): try: input_type = case_nml['case_config']['input_type'] if input_type == 1: + surface_flux_spec = False #open the case data file and read the surfaceForcing global attribute - case_data_dir = case_nml['case_config']['case_data_dir'] - nc_fid = Dataset(os.path.join(SCM_ROOT, case_data_dir) + '/' + self._case + '_SCM_driver.nc' , 'r') - surfaceForcing = nc_fid.getncattr('surfaceForcing') + nc_fid = Dataset(os.path.join(SCM_ROOT, self._case_data_dir) + '/' + self._case + '_SCM_driver.nc' , 'r') + surfaceForcing = nc_fid.getncattr('surface_forcing_temp') nc_fid.close() - if (surfaceForcing.lower() == 'flux' or surfaceForcing.lower() == 'surfaceflux'): + if (surfaceForcing.lower() == 'flux' or surfaceForcing.lower() == 'surface_flux'): surface_flux_spec = True except KeyError: # if not using DEPHY format, check to see if surface fluxes are specified in the case configuration file (default is False) diff --git a/scm/src/scm_input.F90 b/scm/src/scm_input.F90 index a39404366..cc3effcd5 100644 --- a/scm/src/scm_input.F90 +++ b/scm/src/scm_input.F90 @@ -950,7 +950,7 @@ subroutine get_case_init_DEPHY(scm_state, scm_input) real(kind=sp) :: z_nudging_temp, z_nudging_theta, z_nudging_thetal, z_nudging_qv, z_nudging_qt, z_nudging_rv, z_nudging_rt, z_nudging_u, z_nudging_v real(kind=sp) :: p_nudging_temp, p_nudging_theta, p_nudging_thetal, p_nudging_qv, p_nudging_qt, p_nudging_rv, p_nudging_rt, p_nudging_u, p_nudging_v character(len=5) :: input_surfaceType - character(len=11) :: input_surfaceForcingWind='',input_surfaceForcingMoist='',input_surfaceForcingLSM='',input_surfaceForcingTemp='' + character(len=12) :: input_surfaceForcingWind='',input_surfaceForcingMoist='',input_surfaceForcingLSM='',input_surfaceForcingTemp='' ! initial variables (IC = Initial Condition) real(kind=dp), allocatable :: input_lat(:) !< column latitude (deg) @@ -1630,7 +1630,7 @@ subroutine get_case_init_DEPHY(scm_state, scm_input) call NetCDF_read_var(ncid, "wprvp_s", .False., input_force_wprvp) call NetCDF_read_var(ncid, "wprtp_s", .False., input_force_wprtp) else if (trim(input_surfaceForcingMoist) == 'surface_flux') then - call NetCDF_read_var(ncid, "hfls", .False., input_force_sfc_sens_flx) + call NetCDF_read_var(ncid, "hfls", .False., input_force_sfc_lat_flx) endif ! diff --git a/scm/src/scm_output.F90 b/scm/src/scm_output.F90 index 3e452882b..3458da3c9 100644 --- a/scm/src/scm_output.F90 +++ b/scm/src/scm_output.F90 @@ -187,6 +187,7 @@ subroutine output_init_state(ncid, time_inst_id, hor_dim_id, vert_dim_id, vert_d call NetCDF_def_var(ncid, 'ql', NF90_FLOAT, "suspended resolved liquid cloud water on model layer centers", "kg kg-1", dummy_id, (/ hor_dim_id, vert_dim_id, time_inst_id /)) call NetCDF_def_var(ncid, 'qi', NF90_FLOAT, "suspended resolved ice cloud water on model layer centers", "kg kg-1", dummy_id, (/ hor_dim_id, vert_dim_id, time_inst_id /)) call NetCDF_def_var(ncid, 'qc', NF90_FLOAT, "suspended (resolved + SGS) total cloud water on model layer centers", "kg kg-1", dummy_id, (/ hor_dim_id, vert_dim_id, time_inst_id /)) + call NetCDF_def_var(ncid, 'sigmab', NF90_FLOAT, "updraft area fraction on model layer centers", "frac", dummy_id, (/ hor_dim_id, time_inst_id /)) end subroutine output_init_state @@ -497,6 +498,7 @@ subroutine output_append_state(ncid, scm_state, physics) call NetCDF_put_var(ncid, "v", scm_state%state_v(:,:,1), scm_state%itt_out) call NetCDF_put_var(ncid, "ql", scm_state%state_tracer(:,:,scm_state%cloud_water_index,1), scm_state%itt_out) call NetCDF_put_var(ncid, "qi", scm_state%state_tracer(:,:,scm_state%cloud_ice_index,1), scm_state%itt_out) + call NetCDF_put_var(ncid, "sigmab", scm_state%state_tracer(:,1,scm_state%sigmab_index,1), scm_state%itt_out) if (physics%model%do_mynnedmf) then call NetCDF_put_var(ncid, "qc", scm_state%state_tracer(:,:,scm_state%cloud_water_index,1) + & scm_state%state_tracer(:,:,scm_state%cloud_ice_index,1) + & diff --git a/scm/src/scm_type_defs.F90 b/scm/src/scm_type_defs.F90 index df026e067..01629bacf 100644 --- a/scm/src/scm_type_defs.F90 +++ b/scm/src/scm_type_defs.F90 @@ -81,10 +81,14 @@ module scm_type_defs integer :: graupel_volume_index !< index for graupel volume in the tracer array integer :: hail_volume_index !< index for hail volume in the tracer array integer :: tke_index !< index for TKE in the tracer array + integer :: sigmab_index !< index for prognostic updraft area fraction in convection integer :: ccn_index !< index for CCN in the tracer array integer :: water_friendly_aerosol_index !< index for water-friendly aerosols in the tracer array integer :: ice_friendly_aerosol_index !< index for ice-friendly aerosols in the tracer array integer :: mass_weighted_rime_factor_index !< index for mass-weighted rime factor + integer :: smoke_index !< index for smoke in the tracer array + integer :: dust_index !< index for dust in the tracer array + integer :: coarsepm_index !< index for coarsepm in the tracer array integer :: init_year, init_month, init_day, init_hour, init_min character(len=32), allocatable :: tracer_names(:) !< integer, allocatable :: tracer_types(:) !< @@ -485,10 +489,14 @@ subroutine scm_state_create(scm_state, n_columns, n_levels, n_soil, n_snow, n_ti scm_state%graupel_volume_index = get_tracer_index(scm_state%tracer_names,"graupel_vol") scm_state%hail_volume_index = get_tracer_index(scm_state%tracer_names,"hail_vol") scm_state%tke_index = get_tracer_index(scm_state%tracer_names,"sgs_tke") + scm_state%sigmab_index = get_tracer_index(scm_state%tracer_names,"sigmab") scm_state%ccn_index = get_tracer_index(scm_state%tracer_names,"ccn_nc") scm_state%water_friendly_aerosol_index = get_tracer_index(scm_state%tracer_names,"liq_aero") scm_state%ice_friendly_aerosol_index = get_tracer_index(scm_state%tracer_names,"ice_aero") scm_state%mass_weighted_rime_factor_index = get_tracer_index(scm_state%tracer_names,"q_rimef") + scm_state%smoke_index = get_tracer_index(scm_state%tracer_names,"smoke") + scm_state%dust_index = get_tracer_index(scm_state%tracer_names,"dust") + scm_state%coarsepm_index = get_tracer_index(scm_state%tracer_names,"coarsepm") scm_state%nwat = 0 if(scm_state%water_vapor_index /= -99) then @@ -1044,27 +1052,6 @@ subroutine physics_set(physics, scm_input, scm_state) logical :: missing_var(100) real, parameter:: min_lake_orog = 200.0_dp - !check whether input has NoahMP or RUC LSM input data - if (scm_state%model_ics .or. scm_state%lsm_ics) then - if (physics%Model%lsm == physics%Model%lsm_noahmp) then - !FV3GFS_io.F90 uses the presence of the snowxy variable in the ICs to indicate presence of NoahMP warm start - call check_missing(scm_input%input_snowxy, missing_var(1)) - if (missing_var(1)) then - physics%Model%lsm_cold_start = .true. - else - physics%Model%lsm_cold_start = .false. - end if - elseif (physics%Model%lsm == physics%Model%lsm_ruc) then - !RUC LSM uses the tslb variable as soil temperature; if it is missing, assume a cold start using Noah LSM ICs - call check_missing(scm_input%input_tslb(:), missing_var(1)) - if (missing_var(1)) then - physics%Model%lsm_cold_start = .true. - else - physics%Model%lsm_cold_start = .false. - end if - end if - end if - !double check under what circumstances these should actually be set from input!!! (these overwrite the initialzation in GFS_typedefs) missing_var = .false. do i = 1, physics%Model%ncols @@ -1074,6 +1061,9 @@ subroutine physics_set(physics, scm_input, scm_state) physics%Sfcprop%landfrac(i) = missing_value physics%Sfcprop%lakefrac(i) = missing_value end if + ! + ! Orographical data (2D) + ! if (scm_state%model_ics) then write(0,'(a)') "Setting internal physics variables from the orographic section of the case input file (scalars)..." call conditionally_set_var(scm_input%input_stddev, physics%Sfcprop%hprime(i,1), "stddev", .true., missing_var(1)) @@ -1096,7 +1086,6 @@ subroutine physics_set(physics, scm_input, scm_state) call conditionally_set_var(scm_input%input_lakefrac, physics%Sfcprop%lakefrac(i), "lakefrac", (physics%Model%lkm == 1), missing_var(18)) call conditionally_set_var(scm_input%input_lakedepth, physics%Sfcprop%lakedepth(i), "lakedepth", (physics%Model%lkm == 1), missing_var(19)) - !write out warning if missing data for non-required variables n = 19 if ( i==1 .and. ANY( missing_var(1:n) ) ) then write(0,'(a)') "INPUT CHECK: Some missing input data was found related to (potentially non-required) orography and gravity wave drag parameters. This may lead to crashes or other strange behavior." @@ -1108,55 +1097,58 @@ subroutine physics_set(physics, scm_input, scm_state) missing_var = .false. end if - if (scm_state%model_ics .or. scm_state%lsm_ics) then + ! + ! Surface data (2D) + ! + if (scm_state%model_ics .or. scm_state%lsm_ics) then write(0,'(a)') "Setting internal physics variables from the surface section of the case input file (scalars)..." - call conditionally_set_var(scm_input%input_slmsk, physics%Sfcprop%slmsk(i), "slmsk", (.not. physics%Model%frac_grid), missing_var(1)) - call conditionally_set_var(scm_input%input_tsfco, physics%Sfcprop%tsfco(i), "tsfco", .true., missing_var(2)) - call conditionally_set_var(scm_input%input_weasd, physics%Sfcprop%weasd(i), "weasd", .true., missing_var(3)) - call conditionally_set_var(scm_input%input_tg3, physics%Sfcprop%tg3(i), "tg3", .true., missing_var(4)) - call conditionally_set_var(scm_input%input_zorl, physics%Sfcprop%zorl(i), "zorl", .true., missing_var(5)) - call conditionally_set_var(scm_input%input_alvsf, physics%Sfcprop%alvsf(i), "alvsf", .true., missing_var(6)) - call conditionally_set_var(scm_input%input_alnsf, physics%Sfcprop%alnsf(i), "alnsf", .true., missing_var(7)) - call conditionally_set_var(scm_input%input_alvwf, physics%Sfcprop%alvwf(i), "alvwf", .true., missing_var(8)) - call conditionally_set_var(scm_input%input_alnwf, physics%Sfcprop%alnwf(i), "alnwf", .true., missing_var(9)) - call conditionally_set_var(scm_input%input_facsf, physics%Sfcprop%facsf(i), "facsf", .true., missing_var(10)) - call conditionally_set_var(scm_input%input_facwf, physics%Sfcprop%facwf(i), "facwf", .true., missing_var(11)) - call conditionally_set_var(scm_input%input_vegfrac, physics%Sfcprop%vfrac(i), "vegfrac", .true., missing_var(12)) + call conditionally_set_var(scm_input%input_slmsk, physics%Sfcprop%slmsk(i), "slmsk", (.not. physics%Model%frac_grid), missing_var(1)) + call conditionally_set_var(scm_input%input_tsfco, physics%Sfcprop%tsfco(i), "tsfco", .true., missing_var(2)) + call conditionally_set_var(scm_input%input_weasd, physics%Sfcprop%weasd(i), "weasd", .true., missing_var(3)) + call conditionally_set_var(scm_input%input_tg3, physics%Sfcprop%tg3(i), "tg3", .true., missing_var(4)) + call conditionally_set_var(scm_input%input_zorl, physics%Sfcprop%zorl(i), "zorl", .true., missing_var(5)) + call conditionally_set_var(scm_input%input_alvsf, physics%Sfcprop%alvsf(i), "alvsf", .true., missing_var(6)) + call conditionally_set_var(scm_input%input_alnsf, physics%Sfcprop%alnsf(i), "alnsf", .true., missing_var(7)) + call conditionally_set_var(scm_input%input_alvwf, physics%Sfcprop%alvwf(i), "alvwf", .true., missing_var(8)) + call conditionally_set_var(scm_input%input_alnwf, physics%Sfcprop%alnwf(i), "alnwf", .true., missing_var(9)) + call conditionally_set_var(scm_input%input_facsf, physics%Sfcprop%facsf(i), "facsf", .true., missing_var(10)) + call conditionally_set_var(scm_input%input_facwf, physics%Sfcprop%facwf(i), "facwf", .true., missing_var(11)) + call conditionally_set_var(scm_input%input_vegfrac, physics%Sfcprop%vfrac(i), "vegfrac", .true., missing_var(12)) !GJF: is this needed anymore (not in FV3GFS_io)? physics%Interstitial%sigmaf(i) = min(physics%Sfcprop%vfrac(i),0.01) - call conditionally_set_var(scm_input%input_canopy, physics%Sfcprop%canopy(i), "canopy", .true., missing_var(13)) - call conditionally_set_var(scm_input%input_f10m, physics%Sfcprop%f10m(i), "f10m", .false., missing_var(14)) - call conditionally_set_var(scm_input%input_t2m, physics%Sfcprop%t2m(i), "t2m", physics%Model%cplflx, missing_var(15)) - call conditionally_set_var(scm_input%input_q2m, physics%Sfcprop%q2m(i), "q2m", physics%Model%cplflx, missing_var(16)) - call conditionally_set_var(scm_input%input_vegtyp, physics%Sfcprop%vtype(i), "vegtyp", .true., missing_var(17)) - call conditionally_set_var(scm_input%input_soiltyp, physics%Sfcprop%stype(i), "soiltyp", .true., missing_var(18)) - call conditionally_set_var(scm_input%input_uustar, physics%Sfcprop%uustar(i), "uustar", .true., missing_var(19)) - call conditionally_set_var(scm_input%input_ffmm, physics%Sfcprop%ffmm(i), "ffmm", .false., missing_var(20)) - call conditionally_set_var(scm_input%input_ffhh, physics%Sfcprop%ffhh(i), "ffhh", .false., missing_var(21)) - call conditionally_set_var(scm_input%input_hice, physics%Sfcprop%hice(i), "hice", .true., missing_var(22)) - call conditionally_set_var(scm_input%input_fice, physics%Sfcprop%fice(i), "fice", .true., missing_var(23)) - call conditionally_set_var(scm_input%input_tisfc, physics%Sfcprop%tisfc(i), "tisfc", .true., missing_var(24)) - call conditionally_set_var(scm_input%input_tprcp, physics%Sfcprop%tprcp(i), "tprcp", .false., missing_var(25)) - call conditionally_set_var(scm_input%input_srflag, physics%Sfcprop%srflag(i), "srflag", .false., missing_var(26)) - call conditionally_set_var(scm_input%input_snwdph, physics%Sfcprop%snowd(i), "snwdph", .true., missing_var(27)) - call conditionally_set_var(scm_input%input_shdmin, physics%Sfcprop%shdmin(i), "shdmin", .true., missing_var(28)) - call conditionally_set_var(scm_input%input_shdmax, physics%Sfcprop%shdmax(i), "shdmax", .true., missing_var(29)) - call conditionally_set_var(scm_input%input_slopetype, physics%Sfcprop%slope(i), "slopetyp", .true., missing_var(30)) - call conditionally_set_var(scm_input%input_snoalb, physics%Sfcprop%snoalb(i), "snoalb", .true., missing_var(31)) - call conditionally_set_var(scm_input%input_sncovr, physics%Sfcprop%sncovr(i), "sncovr", .false., missing_var(32)) - call conditionally_set_var(scm_input%input_snodl, physics%Sfcprop%snodl(i), "snodl", .false., missing_var(33)) - call conditionally_set_var(scm_input%input_weasdl, physics%Sfcprop%weasdl(i), "weasdl", .false., missing_var(34)) - call conditionally_set_var(scm_input%input_tsfc, physics%Sfcprop%tsfc(i), "tsfc", .false., missing_var(35)) - call conditionally_set_var(scm_input%input_tsfcl, physics%Sfcprop%tsfcl(i), "tsfcl", .false., missing_var(36)) - call conditionally_set_var(scm_input%input_zorlw, physics%Sfcprop%zorlw(i), "zorlw", .false., missing_var(37)) - call conditionally_set_var(scm_input%input_zorll, physics%Sfcprop%zorll(i), "zorll", .false., missing_var(38)) - call conditionally_set_var(scm_input%input_zorli, physics%Sfcprop%zorli(i), "zorli", .false., missing_var(39)) + call conditionally_set_var(scm_input%input_canopy, physics%Sfcprop%canopy(i), "canopy", .true., missing_var(13)) + call conditionally_set_var(scm_input%input_f10m, physics%Sfcprop%f10m(i), "f10m", .false., missing_var(14)) + call conditionally_set_var(scm_input%input_t2m, physics%Sfcprop%t2m(i), "t2m", physics%Model%cplflx, missing_var(15)) + call conditionally_set_var(scm_input%input_q2m, physics%Sfcprop%q2m(i), "q2m", physics%Model%cplflx, missing_var(16)) + call conditionally_set_var(scm_input%input_vegtyp, physics%Sfcprop%vtype(i), "vegtyp", .true., missing_var(17)) + call conditionally_set_var(scm_input%input_soiltyp, physics%Sfcprop%stype(i), "soiltyp", .true., missing_var(18)) + call conditionally_set_var(scm_input%input_uustar, physics%Sfcprop%uustar(i), "uustar", .true., missing_var(19)) + call conditionally_set_var(scm_input%input_ffmm, physics%Sfcprop%ffmm(i), "ffmm", .false., missing_var(20)) + call conditionally_set_var(scm_input%input_ffhh, physics%Sfcprop%ffhh(i), "ffhh", .false., missing_var(21)) + call conditionally_set_var(scm_input%input_hice, physics%Sfcprop%hice(i), "hice", .true., missing_var(22)) + call conditionally_set_var(scm_input%input_fice, physics%Sfcprop%fice(i), "fice", .true., missing_var(23)) + call conditionally_set_var(scm_input%input_tisfc, physics%Sfcprop%tisfc(i), "tisfc", .true., missing_var(24)) + call conditionally_set_var(scm_input%input_tprcp, physics%Sfcprop%tprcp(i), "tprcp", .false., missing_var(25)) + call conditionally_set_var(scm_input%input_srflag, physics%Sfcprop%srflag(i), "srflag", .false., missing_var(26)) + call conditionally_set_var(scm_input%input_snwdph, physics%Sfcprop%snowd(i), "snwdph", .true., missing_var(27)) + call conditionally_set_var(scm_input%input_shdmin, physics%Sfcprop%shdmin(i), "shdmin", .true., missing_var(28)) + call conditionally_set_var(scm_input%input_shdmax, physics%Sfcprop%shdmax(i), "shdmax", .true., missing_var(29)) + call conditionally_set_var(scm_input%input_slopetype, physics%Sfcprop%slope(i), "slopetyp", .true., missing_var(30)) + call conditionally_set_var(scm_input%input_snoalb, physics%Sfcprop%snoalb(i), "snoalb", .true., missing_var(31)) + call conditionally_set_var(scm_input%input_sncovr, physics%Sfcprop%sncovr(i), "sncovr", .false., missing_var(32)) + call conditionally_set_var(scm_input%input_snodl, physics%Sfcprop%snodl(i), "snodl", .false., missing_var(33)) + call conditionally_set_var(scm_input%input_weasdl, physics%Sfcprop%weasdl(i), "weasdl", .false., missing_var(34)) + call conditionally_set_var(scm_input%input_tsfc, physics%Sfcprop%tsfc(i), "tsfc", .false., missing_var(35)) + call conditionally_set_var(scm_input%input_tsfcl, physics%Sfcprop%tsfcl(i), "tsfcl", .false., missing_var(36)) + call conditionally_set_var(scm_input%input_zorlw, physics%Sfcprop%zorlw(i), "zorlw", .false., missing_var(37)) + call conditionally_set_var(scm_input%input_zorll, physics%Sfcprop%zorll(i), "zorll", .false., missing_var(38)) + call conditionally_set_var(scm_input%input_zorli, physics%Sfcprop%zorli(i), "zorli", .false., missing_var(39)) call conditionally_set_var(scm_input%input_albdirvis_lnd, physics%Sfcprop%albdirvis_lnd(i), "albdirvis_lnd", .false., missing_var(40)) call conditionally_set_var(scm_input%input_albdirnir_lnd, physics%Sfcprop%albdirnir_lnd(i), "albdirnir_lnd", .false., missing_var(41)) call conditionally_set_var(scm_input%input_albdifvis_lnd, physics%Sfcprop%albdifvis_lnd(i), "albdifvis_lnd", .false., missing_var(42)) call conditionally_set_var(scm_input%input_albdifnir_lnd, physics%Sfcprop%albdifnir_lnd(i), "albdifnir_lnd", .false., missing_var(43)) - call conditionally_set_var(scm_input%input_emis_lnd, physics%Sfcprop%emis_lnd(i), "emis_lnd", .false., missing_var(44)) - if (physics%Model%use_cice_alb .or. physics%Model%lsm == physics%Model%lsm_ruc) then + call conditionally_set_var(scm_input%input_emis_lnd, physics%Sfcprop%emis_lnd(i), "emis_lnd", .false., missing_var(44)) + if (physics%Model%use_cice_alb) then call conditionally_set_var(scm_input%input_albdirvis_ice, physics%Sfcprop%albdirvis_ice(i), "albdirvis_ice", .false., missing_var(45)) call conditionally_set_var(scm_input%input_albdirnir_ice, physics%Sfcprop%albdirnir_ice(i), "albdirnir_ice", .false., missing_var(46)) call conditionally_set_var(scm_input%input_albdifvis_ice, physics%Sfcprop%albdifvis_ice(i), "albdifvis_ice", .false., missing_var(47)) @@ -1206,12 +1198,10 @@ subroutine physics_set(physics, scm_input, scm_state) if (physics%Sfcprop%slmsk(i) > 1.9_dp) physics%Sfcprop%fice(i) = 1.0 !needed to calculate tsfc and zorl below when model_ics == .false. if (physics%Sfcprop%slmsk(i) < 0.1_dp) physics%Sfcprop%oceanfrac(i) = 1.0 end if - - !this overwrites what is in the suite namelist file -- is that desirable? - !if (scm_state%model_ics) then - ! physics%Model%ivegsrc = scm_input%input_vegsrc - !end if - + + ! + ! Derive physics quantities using surface model ICs. + ! if(scm_state%model_ics .or. scm_state%lsm_ics) then if (physics%Sfcprop%stype(i) == 14 .or. physics%Sfcprop%stype(i)+0.5 <= 0) then physics%Sfcprop%landfrac(i) = real_zero @@ -1311,10 +1301,11 @@ subroutine physics_set(physics, scm_input, scm_state) endif end if - !--- NSSTM variables + ! + ! NSSTM variables + ! if (physics%Model%nstf_name(1) > 0) then - if (physics%Model%nstf_name(2) == 1 .or. .not. (scm_state%model_ics .or. scm_state%lsm_ics)) then ! nsst spinup - !--- nsstm tref + if (physics%Model%nstf_name(2) == 1 .or. .not. (scm_state%model_ics .or. scm_state%lsm_ics)) then physics%Sfcprop%tref(i) = physics%Sfcprop%tsfco(i) physics%Sfcprop%z_c(i) = real_zero physics%Sfcprop%c_0(i) = real_zero @@ -1335,183 +1326,50 @@ subroutine physics_set(physics, scm_input, scm_state) physics%Sfcprop%qrain(i) = real_zero elseif (physics%Model%nstf_name(2) == 0) then ! nsst restart write(0,'(a)') "Setting internal physics variables from the NSST section of the case input file (scalars)..." - call conditionally_set_var(scm_input%input_tref, physics%Sfcprop%tref(i), "tref", .true., missing_var(1)) - call conditionally_set_var(scm_input%input_z_c, physics%Sfcprop%z_c(i), "z_c", .true., missing_var(2)) - call conditionally_set_var(scm_input%input_c_0, physics%Sfcprop%c_0(i), "c_0", .true., missing_var(3)) - call conditionally_set_var(scm_input%input_c_d, physics%Sfcprop%c_d(i), "c_d", .true., missing_var(4)) - call conditionally_set_var(scm_input%input_w_0, physics%Sfcprop%w_0(i), "w_0", .true., missing_var(5)) - call conditionally_set_var(scm_input%input_w_d, physics%Sfcprop%w_d(i), "w_d", .true., missing_var(6)) - call conditionally_set_var(scm_input%input_xt, physics%Sfcprop%xt(i), "xt", .true., missing_var(7)) - call conditionally_set_var(scm_input%input_xs, physics%Sfcprop%xs(i), "xs", .true., missing_var(8)) - call conditionally_set_var(scm_input%input_xu, physics%Sfcprop%xu(i), "xu", .true., missing_var(9)) - call conditionally_set_var(scm_input%input_xv, physics%Sfcprop%xv(i), "xv", .true., missing_var(10)) - call conditionally_set_var(scm_input%input_xz, physics%Sfcprop%xz(i), "xz", .true., missing_var(11)) - call conditionally_set_var(scm_input%input_zm, physics%Sfcprop%zm(i), "zm", .true., missing_var(12)) - call conditionally_set_var(scm_input%input_xtts, physics%Sfcprop%xtts(i), "xtts", .true., missing_var(13)) - call conditionally_set_var(scm_input%input_xzts, physics%Sfcprop%xzts(i), "xzts", .true., missing_var(14)) - call conditionally_set_var(scm_input%input_d_conv, physics%Sfcprop%d_conv(i), "d_conv", .true., missing_var(15)) - call conditionally_set_var(scm_input%input_ifd, physics%Sfcprop%ifd(i), "ifd", .true., missing_var(16)) + call conditionally_set_var(scm_input%input_tref, physics%Sfcprop%tref(i), "tref", .true., missing_var(1)) + call conditionally_set_var(scm_input%input_z_c, physics%Sfcprop%z_c(i), "z_c", .true., missing_var(2)) + call conditionally_set_var(scm_input%input_c_0, physics%Sfcprop%c_0(i), "c_0", .true., missing_var(3)) + call conditionally_set_var(scm_input%input_c_d, physics%Sfcprop%c_d(i), "c_d", .true., missing_var(4)) + call conditionally_set_var(scm_input%input_w_0, physics%Sfcprop%w_0(i), "w_0", .true., missing_var(5)) + call conditionally_set_var(scm_input%input_w_d, physics%Sfcprop%w_d(i), "w_d", .true., missing_var(6)) + call conditionally_set_var(scm_input%input_xt, physics%Sfcprop%xt(i), "xt", .true., missing_var(7)) + call conditionally_set_var(scm_input%input_xs, physics%Sfcprop%xs(i), "xs", .true., missing_var(8)) + call conditionally_set_var(scm_input%input_xu, physics%Sfcprop%xu(i), "xu", .true., missing_var(9)) + call conditionally_set_var(scm_input%input_xv, physics%Sfcprop%xv(i), "xv", .true., missing_var(10)) + call conditionally_set_var(scm_input%input_xz, physics%Sfcprop%xz(i), "xz", .true., missing_var(11)) + call conditionally_set_var(scm_input%input_zm, physics%Sfcprop%zm(i), "zm", .true., missing_var(12)) + call conditionally_set_var(scm_input%input_xtts, physics%Sfcprop%xtts(i), "xtts", .true., missing_var(13)) + call conditionally_set_var(scm_input%input_xzts, physics%Sfcprop%xzts(i), "xzts", .true., missing_var(14)) + call conditionally_set_var(scm_input%input_d_conv, physics%Sfcprop%d_conv(i), "d_conv", .true., missing_var(15)) + call conditionally_set_var(scm_input%input_ifd, physics%Sfcprop%ifd(i), "ifd", .true., missing_var(16)) call conditionally_set_var(scm_input%input_dt_cool, physics%Sfcprop%dt_cool(i), "dt_cool", .true., missing_var(17)) - call conditionally_set_var(scm_input%input_qrain, physics%Sfcprop%qrain(i), "qrain", .true., missing_var(18)) + call conditionally_set_var(scm_input%input_qrain, physics%Sfcprop%qrain(i), "qrain", .true., missing_var(18)) ! all NNST variables are required when NNST spin-up is off, so no need to write out warning for missing data (the model would have already stopped) missing_var = .false. endif endif - - if ((scm_state%model_ics .or. scm_state%lsm_ics) .and. physics%Model%lsm == physics%Model%lsm_ruc .and. .not. physics%Model%lsm_cold_start) then - !--- Extra RUC LSM variables - write(0,'(a)') "Setting internal physics variables from the RUC LSM section of the case input file (scalars)..." - call conditionally_set_var(scm_input%input_wetness, physics%Sfcprop%wetness(i), "wetness", .true., missing_var(1)) - call conditionally_set_var(scm_input%input_clw_surf_land, physics%Sfcprop%clw_surf_land(i), "clw_surf_land", .true., missing_var(2)) - call conditionally_set_var(scm_input%input_clw_surf_ice, physics%Sfcprop%clw_surf_ice(i), "clw_surf_ice", .true., missing_var(3)) - call conditionally_set_var(scm_input%input_qwv_surf_land, physics%Sfcprop%qwv_surf_land(i), "qwv_surf_land", .true., missing_var(4)) - call conditionally_set_var(scm_input%input_qwv_surf_ice, physics%Sfcprop%qwv_surf_ice(i), "qwv_surf_ice", .true., missing_var(5)) - call conditionally_set_var(scm_input%input_tsnow_land, physics%Sfcprop%tsnow_land(i), "tsnow_land", .true., missing_var(6)) - call conditionally_set_var(scm_input%input_tsnow_ice, physics%Sfcprop%tsnow_ice(i), "tsnow_ice", .true., missing_var(7)) - call conditionally_set_var(scm_input%input_snowfallac_land, physics%Sfcprop%snowfallac_land(i), "snowfallac_land", .true., missing_var(8)) - call conditionally_set_var(scm_input%input_snowfallac_ice, physics%Sfcprop%snowfallac_ice(i), "snowfallac_ice", .true., missing_var(9)) - call conditionally_set_var(scm_input%input_sncovr_ice, physics%Sfcprop%sncovr_ice(i), "sncovr_ice", .false., missing_var(10)) - call conditionally_set_var(scm_input%input_sfalb_lnd, physics%Sfcprop%sfalb_lnd(i), "sfalb_lnd", .true., missing_var(11)) - call conditionally_set_var(scm_input%input_sfalb_lnd_bck, physics%Sfcprop%sfalb_lnd_bck(i), "sfalb_lnd_bck", .true., missing_var(12)) - call conditionally_set_var(scm_input%input_sfalb_ice, physics%Sfcprop%sfalb_ice(i), "sfalb_ice", .true., missing_var(13)) - call conditionally_set_var(scm_input%input_emis_ice, physics%Sfcprop%emis_ice(i), "emis_ice", .true., missing_var(14)) - if (physics%Model%lsm == physics%Model%lsm_ruc .and. physics%Model%rdlai) then - !when rdlai = T, RUC LSM expects the LAI to be read in, hence the required variable attribute below - call conditionally_set_var(scm_input%input_lai, physics%Sfcprop%xlaixy(i), "lai", .true., missing_var(15)) - end if - - !if sncovr_ice is missing, set to the land value - if(missing_var(10)) then - call conditionally_set_var(scm_input%input_sncovr, physics%Sfcprop%sncovr_ice(i), "sncovr_ice", .true., missing_var(10)) - end if - - !write out warning if missing data for non-required variables - n = 15 - if ( i==1 .and. ANY( missing_var(1:n) ) ) then - write(0,'(a)') "INPUT CHECK: Some missing input data was found related to (potentially non-required) surface variables for RUC LSM. This may lead to crashes or other strange behavior." - write(0,'(a)') "Check gmtb_scm_type_defs.F90/physics_set to see the names of variables that are missing, corresponding to the following indices:" - do j=1, n - if (missing_var(j)) write(0,'(a,i0)') "variable index ",j - end do - end if - missing_var = .false. - elseif ((scm_state%model_ics .or. scm_state%lsm_ics) .and. physics%Model%lsm == physics%Model%lsm_ruc .and. physics%Model%lsm_cold_start) then - call conditionally_set_var(scm_input%input_sncovr, physics%Sfcprop%sncovr_ice(i), "sncovr_ice", .true., missing_var(1)) - if (physics%Model%rdlai) then - !when rdlai = T, RUC LSM expects the LAI to be read in, hence the required variable attribute below - call conditionally_set_var(scm_input%input_lai, physics%Sfcprop%xlaixy(i), "lai", .true., missing_var(2)) - end if - - !write out warning if missing data for non-required variables - n = 2 - if ( i==1 .and. ANY( missing_var(1:n) ) ) then - write(0,'(a)') "INPUT CHECK: Some missing input data was found related to (potentially non-required) surface variables for RUC LSM. This may lead to crashes or other strange behavior." - write(0,'(a)') "Check gmtb_scm_type_defs.F90/physics_set to see the names of variables that are missing, corresponding to the following indices:" - do j=1, n - if (missing_var(j)) write(0,'(a,i0)') "variable index ",j - end do - end if - missing_var = .false. - elseif ((scm_state%model_ics .or. scm_state%lsm_ics) .and. physics%Model%lsm == physics%Model%lsm_noahmp) then - write(0,'(a)') "Setting internal physics variables from the NoahMP section of the case input file (scalars)..." - !all of these can be missing, since a method exists to "cold start" these variables - call conditionally_set_var(scm_input%input_snowxy, physics%Sfcprop%snowxy(i), "snowxy", .false., missing_var(1)) - call conditionally_set_var(scm_input%input_tvxy, physics%Sfcprop%tvxy(i), "tvxy", .false., missing_var(2)) - call conditionally_set_var(scm_input%input_tgxy, physics%Sfcprop%tgxy(i), "tgxy", .false., missing_var(3)) - call conditionally_set_var(scm_input%input_canicexy, physics%Sfcprop%canicexy(i), "canicexy", .false., missing_var(4)) - call conditionally_set_var(scm_input%input_canliqxy, physics%Sfcprop%canliqxy(i), "canliqxy", .false., missing_var(5)) - call conditionally_set_var(scm_input%input_eahxy, physics%Sfcprop%eahxy(i), "eahxy", .false., missing_var(6)) - call conditionally_set_var(scm_input%input_tahxy, physics%Sfcprop%tahxy(i), "tahxy", .false., missing_var(7)) - call conditionally_set_var(scm_input%input_cmxy, physics%Sfcprop%cmxy(i), "cmxy", .false., missing_var(8)) - call conditionally_set_var(scm_input%input_chxy, physics%Sfcprop%chxy(i), "chxy", .false., missing_var(9)) - call conditionally_set_var(scm_input%input_fwetxy, physics%Sfcprop%fwetxy(i), "fwetxy", .false., missing_var(10)) - call conditionally_set_var(scm_input%input_sneqvoxy, physics%Sfcprop%sneqvoxy(i), "sneqvoxy", .false., missing_var(11)) - call conditionally_set_var(scm_input%input_alboldxy, physics%Sfcprop%alboldxy(i), "alboldxy", .false., missing_var(12)) - call conditionally_set_var(scm_input%input_qsnowxy, physics%Sfcprop%qsnowxy(i), "qsnowxy", .false., missing_var(13)) - call conditionally_set_var(scm_input%input_wslakexy, physics%Sfcprop%wslakexy(i), "wslakexy", .false., missing_var(14)) - call conditionally_set_var(scm_input%input_zwtxy, physics%Sfcprop%zwtxy(i), "zwtxy", .false., missing_var(15)) - call conditionally_set_var(scm_input%input_waxy, physics%Sfcprop%waxy(i), "waxy", .false., missing_var(16)) - call conditionally_set_var(scm_input%input_wtxy, physics%Sfcprop%wtxy(i), "wtxy", .false., missing_var(17)) - call conditionally_set_var(scm_input%input_lfmassxy, physics%Sfcprop%lfmassxy(i), "lfmassxy", .false., missing_var(18)) - call conditionally_set_var(scm_input%input_rtmassxy, physics%Sfcprop%rtmassxy(i), "rtmassxy", .false., missing_var(19)) - call conditionally_set_var(scm_input%input_stmassxy, physics%Sfcprop%stmassxy(i), "stmassxy", .false., missing_var(20)) - call conditionally_set_var(scm_input%input_woodxy, physics%Sfcprop%woodxy(i), "woodxy", .false., missing_var(21)) - call conditionally_set_var(scm_input%input_stblcpxy, physics%Sfcprop%stblcpxy(i), "stblcpxy", .false., missing_var(22)) - call conditionally_set_var(scm_input%input_fastcpxy, physics%Sfcprop%fastcpxy(i), "fastcpxy", .false., missing_var(23)) - call conditionally_set_var(scm_input%input_xsaixy, physics%Sfcprop%xsaixy(i), "xsaixy", .false., missing_var(24)) - call conditionally_set_var(scm_input%input_xlaixy, physics%Sfcprop%xlaixy(i), "xlaixy", .false., missing_var(25)) - call conditionally_set_var(scm_input%input_taussxy, physics%Sfcprop%taussxy(i), "taussxy", .false., missing_var(26)) - call conditionally_set_var(scm_input%input_smcwtdxy, physics%Sfcprop%smcwtdxy(i), "smcwtdxy", .false., missing_var(27)) - call conditionally_set_var(scm_input%input_deeprechxy, physics%Sfcprop%deeprechxy(i), "deeprechxy", .false., missing_var(28)) - call conditionally_set_var(scm_input%input_rechxy, physics%Sfcprop%rechxy(i), "rechxy", .false., missing_var(29)) - - !write out warning if missing data for non-required variables - n = 29 - if ( i==1 .and. ANY( missing_var(1:n) ) ) then - write(0,'(a)') "INPUT CHECK: Some missing input data was found related to surface variables for NoahMP LSM. Due to this, a cold-start algorithm to initialize variables will be used." - write(0,'(a)') "Check scm_type_defs.F90/physics_set to see the names of variables that are missing, corresponding to the following indices:" - do j=1, n - if (missing_var(j)) write(0,'(a,i0)') "variable index ",j - end do - end if - missing_var = .false. - end if - - if ((scm_state%model_ics .or. scm_state%lsm_ics) .and. (physics%Model%lsm == physics%Model%lsm_noah .or. & - physics%Model%lsm == physics%Model%lsm_noahmp .or. physics%Model%lsm_cold_start)) then - + + ! + ! LSM model ICs (3D) + ! + if (scm_state%model_ics .or. scm_state%lsm_ics) then call conditionally_set_var(scm_input%input_stc(:), physics%Sfcprop%stc(i,:), "stc", .true., missing_var(1)) call conditionally_set_var(scm_input%input_smc(:), physics%Sfcprop%smc(i,:), "smc", .true., missing_var(2)) call conditionally_set_var(scm_input%input_slc(:), physics%Sfcprop%slc(i,:), "slc", .true., missing_var(3)) - if (physics%Model%lsm == physics%Model%lsm_noahmp) then - call conditionally_set_var(scm_input%input_snicexy(:), physics%Sfcprop%snicexy(i,:), "snicexy", .false., missing_var(4)) - call conditionally_set_var(scm_input%input_snliqxy(:), physics%Sfcprop%snliqxy(i,:), "sliqexy", .false., missing_var(5)) - call conditionally_set_var(scm_input%input_tsnoxy(:), physics%Sfcprop%tsnoxy(i,:), "tsnoxy", .false., missing_var(6)) - - call conditionally_set_var(scm_input%input_smoiseq(:), physics%Sfcprop%smoiseq(i,:), "smoiseq", .false., missing_var(7)) - - call conditionally_set_var(scm_input%input_zsnsoxy(:), physics%Sfcprop%zsnsoxy(i,:), "zsnzoxy", .false., missing_var(8)) - - !write out warning if missing data for non-required variables - n = 8 - if ( i==1 .and. ANY( missing_var(1:n) ) ) then - write(0,'(a)') "INPUT CHECK: Some missing input data was found related to surface variables for NoahMP LSM. Due to this, a cold-start algorithm to initialize variables will be used." - write(0,'(a)') "Check scm_type_defs.F90/physics_set to see the names of variables that are missing, corresponding to the following indices:" - do j=1, n + n = 3 + if ( i==1 .and. ANY( missing_var(1:n) ) ) then + write(0,'(a)') "INPUT CHECK: Some missing input data was found related to surface variables needed by the LSM. Due to this, a cold-start algorithm to initialize variables will be used." + write(0,'(a)') "Check scm_type_defs.F90/physics_set to see the names of variables that are missing, corresponding to the following indices:" + do j=1, n if (missing_var(j)) write(0,'(a,i0)') "variable index ",j - end do - end if - missing_var = .false. - endif - - else if ((scm_state%model_ics .or. scm_state%lsm_ics) .and. physics%Model%lsm == physics%Model%lsm_ruc) then - call conditionally_set_var(scm_input%input_tslb(:), physics%Sfcprop%tslb(i,:), "tslb", .false., missing_var(1)) - call conditionally_set_var(scm_input%input_smois(:), physics%Sfcprop%smois(i,:), "smois", .false., missing_var(2)) - call conditionally_set_var(scm_input%input_sh2o(:), physics%Sfcprop%sh2o(i,:), "sh2o", .false., missing_var(3)) - call conditionally_set_var(scm_input%input_smfr(:), physics%Sfcprop%keepsmfr(i,:), "smfr", .false., missing_var(4)) - call conditionally_set_var(scm_input%input_flfr(:), physics%Sfcprop%flag_frsoil(i,:), "flfr", .false., missing_var(5)) - - !write out warning if missing data for non-required variables - n = 5 - if ( i==1 .and. ANY( missing_var(1:n) ) ) then - write(0,'(a)') "INPUT CHECK: Some missing input data was found related to (potentially non-required) surface variables for RUC LSM. This may lead to crashes or other strange behavior." - write(0,'(a)') "Check scm_type_defs.F90/physics_set to see the names of variables that are missing, corresponding to the following indices:" - do j=1, n - if (missing_var(j)) write(0,'(a,i0)') "variable index ",j - end do - end if - missing_var = .false. - end if - - if (scm_state%model_ics .or. scm_state%lsm_ics) then - !check for nonmissing values - call conditionally_set_var(scm_input%input_tiice(:), physics%Sfcprop%tiice(i,:), "tiice", .false., missing_var(1)) - if (missing_var(1)) then - write(0,'(a)') "INPUT CHECK: Some missing input data was found related to the internal sea ice temperature. These will be set from the internal soil temperature variable (stc)." + end do end if - end if + end if + ! + ! Compute surface fields that may/maynot present in model IC files. + ! if (scm_state%model_ics .or. scm_state%lsm_ics) then if (scm_input%input_snodl <= real_zero) then if (physics%Sfcprop%landfrac(i) > real_zero) then @@ -1563,41 +1421,33 @@ subroutine physics_set(physics, scm_input, scm_state) if (scm_input%input_zorlwav <= real_zero) then physics%Sfcprop%zorlwav(i) = physics%Sfcprop%zorlw(i) !--- compute zorlwav from existing variables end if - - if (physics%Model%lsm_cold_start) then - if(physics%Model%frac_grid .and. (scm_state%model_ics .or. scm_state%lsm_ics)) then ! 3-way composite - if( physics%Model%phour < 1.e-7) physics%Sfcprop%tsfco(i) = max(con_tice, physics%Sfcprop%tsfco(i)) - tem1 = real_one - physics%Sfcprop%landfrac(i) - tem = tem1 * physics%Sfcprop%fice(i) ! tem = ice fraction wrt whole cell - physics%Sfcprop%zorl(i) = physics%Sfcprop%zorll(i) * physics%Sfcprop%landfrac(i) & - + physics%Sfcprop%zorli(i) * tem & - + physics%Sfcprop%zorlw(i) * (tem1-tem) - - physics%Sfcprop%tsfc(i) = physics%Sfcprop%tsfcl(i) * physics%Sfcprop%landfrac(i) & - + physics%Sfcprop%tisfc(i) * tem & - + physics%Sfcprop%tsfco(i) * (tem1-tem) - else - !--- specify tsfcl/zorll/zorli from existing variable tsfco/zorlw - ! physics%Sfcprop%tsfcl(i) = physics%Sfcprop%tsfco(i) - ! physics%Sfcprop%zorll(i) = physics%Sfcprop%zorlw(i) - ! physics%Sfcprop%zorli(i) = physics%Sfcprop%zorlw(i) - ! physics%Sfcprop%zorl(i) = physics%Sfcprop%zorlw(i) - ! physics%Sfcprop%tsfc(i) = physics%Sfcprop%tsfco(i) - if (physics%Sfcprop%slmsk(i) == 1) then - physics%Sfcprop%zorl(i) = physics%Sfcprop%zorll(i) - physics%Sfcprop%tsfc(i) = physics%Sfcprop%tsfcl(i) - else - tem = real_one - physics%Sfcprop%fice(i) - physics%Sfcprop%zorl(i) = physics%Sfcprop%zorli(i) * physics%Sfcprop%fice(i) & - + physics%Sfcprop%zorlw(i) * tem - physics%Sfcprop%tsfc(i) = physics%Sfcprop%tisfc(i) * physics%Sfcprop%fice(i) & - + physics%Sfcprop%tsfco(i) * tem - endif - endif ! if (Model%frac_grid) - endif !if (physics%Model%lsm_cold_start) - - if ((scm_state%model_ics .or. scm_state%lsm_ics) .and. MAXVAL(scm_input%input_tiice) < real_zero) then + if(physics%Model%frac_grid .and. (scm_state%model_ics .or. scm_state%lsm_ics) ) then ! 3-way composite + if( physics%Model%phour < 1.e-7) physics%Sfcprop%tsfco(i) = max(con_tice, physics%Sfcprop%tsfco(i)) + tem1 = real_one - physics%Sfcprop%landfrac(i) + tem = tem1 * physics%Sfcprop%fice(i) ! tem = ice fraction wrt whole cell + physics%Sfcprop%zorl(i) = physics%Sfcprop%zorll(i) * physics%Sfcprop%landfrac(i) & + + physics%Sfcprop%zorli(i) * tem & + + physics%Sfcprop%zorlw(i) * (tem1-tem) + + physics%Sfcprop%tsfc(i) = physics%Sfcprop%tsfcl(i) * physics%Sfcprop%landfrac(i) & + + physics%Sfcprop%tisfc(i) * tem & + + physics%Sfcprop%tsfco(i) * (tem1-tem) + else + if (physics%Sfcprop%slmsk(i) == 1) then + physics%Sfcprop%zorl(i) = physics%Sfcprop%zorll(i) + physics%Sfcprop%tsfc(i) = physics%Sfcprop%tsfcl(i) + else + tem = real_one - physics%Sfcprop%fice(i) + physics%Sfcprop%zorl(i) = physics%Sfcprop%zorli(i) * physics%Sfcprop%fice(i) & + + physics%Sfcprop%zorlw(i) * tem + + physics%Sfcprop%tsfc(i) = physics%Sfcprop%tisfc(i) * physics%Sfcprop%fice(i) & + + physics%Sfcprop%tsfco(i) * tem + endif + endif ! if (Model%frac_grid) + + if (scm_state%model_ics .and. MAXVAL(scm_input%input_tiice) < real_zero) then physics%Sfcprop%tiice(i,1) = physics%Sfcprop%stc(i,1) !--- initialize internal ice temp from soil temp at layer 1 physics%Sfcprop%tiice(i,2) = physics%Sfcprop%stc(i,2) !--- initialize internal ice temp from soil temp at layer 2 end if diff --git a/scm/src/suite_info.py b/scm/src/suite_info.py index 63d35c97c..69b0b0a73 100755 --- a/scm/src/suite_info.py +++ b/scm/src/suite_info.py @@ -44,7 +44,10 @@ def timestep(self, value): suite_list = [] suite_list.append(suite('SCM_GFS_v16', 'tracers_GFS_v16.txt', 'input_GFS_v16.nml', 600.0, 1800.0, True )) suite_list.append(suite('SCM_GFS_v17_p8', 'tracers_GFS_v17_p8.txt', 'input_GFS_v17_p8.nml', 600.0, 600.0, True )) +suite_list.append(suite('SCM_GFS_v17_HR3', 'tracers_GFS_v17_HR3.txt', 'input_GFS_v17_HR3.nml', 600.0, 600.0, True )) +suite_list.append(suite('SCM_GFS_v17_HR3_RRTMGP','tracers_GFS_v17_p8.txt', 'input_GFS_v17_HR3_RRTMGP.nml', 600.0, 600.0, True )) suite_list.append(suite('SCM_RAP', 'tracers_RAP.txt', 'input_RAP.nml', 600.0, 600.0 , True )) +suite_list.append(suite('SCM_RRFS_v1', 'tracers_RRFS_v1.txt', 'input_RRFS_v1.nml', 600.0, 600.0 , True )) suite_list.append(suite('SCM_RRFS_v1beta', 'tracers_RRFS_v1beta.txt', 'input_RRFS_v1beta.nml', 600.0, 600.0 , True )) suite_list.append(suite('SCM_WoFS_v0', 'tracers_WoFS_v0.txt', 'input_WoFS_v0.nml', 600.0, 600.0 , True )) suite_list.append(suite('SCM_HRRR', 'tracers_HRRR.txt', 'input_HRRR.nml', 600.0, 600.0 , True )) diff --git a/scm/src/supported_suites.py b/scm/src/supported_suites.py index 8cbac028c..aee06a705 100644 --- a/scm/src/supported_suites.py +++ b/scm/src/supported_suites.py @@ -1 +1 @@ -suites = ["SCM_GFS_v16","SCM_GFS_v17_p8","SCM_HRRR","SCM_RAP","SCM_RRFS_v1beta","SCM_WoFS_v0"] +suites = ["SCM_GFS_v16","SCM_GFS_v17_p8","SCM_GFS_v17_HR3","SCM_HRRR","SCM_RAP","SCM_RRFS_v1beta","SCM_WoFS_v0"] diff --git a/test/rt_test_cases_nvidia.py b/test/rt_test_cases_nvidia.py new file mode 100644 index 000000000..a19c81ba9 --- /dev/null +++ b/test/rt_test_cases_nvidia.py @@ -0,0 +1,9 @@ +run_list = [\ + #---------------------------------------------------------------------------------------------------------------------------------------------- + # CCPP-SCM v6 supported suites + #---------------------------------------------------------------------------------------------------------------------------------------------- + {"case": "arm_sgp_summer_1997_A", "suite": "SCM_RAP"}, \ + {"case": "twpice", "suite": "SCM_RAP"}, \ + {"case": "bomex", "suite": "SCM_RAP"}, \ + {"case": "astex", "suite": "SCM_RAP"}, \ + {"case": "LASSO_2016051812", "suite": "SCM_RAP"}]