diff --git a/.github/workflows/ci_fv3_ccpp_prebuild.yml b/.github/workflows/ci_fv3_ccpp_prebuild.yml new file mode 100644 index 000000000..a32b66b7b --- /dev/null +++ b/.github/workflows/ci_fv3_ccpp_prebuild.yml @@ -0,0 +1,58 @@ +name: CI test to run FV3 ccpp_prebuild step + +on: [push, pull_request] + +jobs: + build-linux: + + # The type of runner that the job will run on + runs-on: ubuntu-latest + strategy: + max-parallel: 5 + + steps: + - name: Checkout current ccpp-physics code + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Store remote-URL for current ccpp-physics code + run: echo "GIT_REMOTE_URL=`git remote get-url origin`" >> $GITHUB_ENV + + - name: Store branch name for current ccpp-physics code + run: echo "GIT_REMOTE_BRANCH=`git rev-parse --abbrev-ref HEAD`" >> $GITHUB_ENV + + - name: Store hash for HEAD of current ccpp-physics code + run: echo "GIT_REMOTE_HASH=`git rev-parse HEAD`" >> $GITHUB_ENV + + - name: Checkout latest fv3atm + run: git clone https://github.com/NOAA-EMC/fv3atm.git + + - name: Initialize submodules + run: | + cd /home/runner/work/ccpp-physics/ccpp-physics/fv3atm + git submodule update --init --recursive + + - name: Update ccpp-physics hash in fv3atm + if: github.event.pull_request == false + run: | + cd /home/runner/work/ccpp-physics/ccpp-physics/fv3atm/ccpp/physics + git remote add remote_local $GIT_REMOTE_URL + git fetch remote_local $GIT_REMOTE_BRANCH + git checkout remote_local/$GIT_REMOTE_BRANCH + + - name: Set up Python 3.8.5 + uses: actions/setup-python@v3 + with: + python-version: 3.8.5 + + - name: Add conda to system path + run: | + # $CONDA is an environment variable pointing to the root of the miniconda directory + echo $CONDA/bin >> $GITHUB_PATH + + - name: Run ccpp_prebuild.py + run: | + cd /home/runner/work/ccpp-physics/ccpp-physics/fv3atm/ccpp/ + mkdir -p /home/runner/work/ccpp-physics/ccpp-physics/fv3atm/bin/ccpp/physics/physics/ + ./framework/scripts/ccpp_prebuild.py --config config/ccpp_prebuild_config.py \ No newline at end of file diff --git a/.github/workflows/ci_scm_ccpp_prebuild.yml b/.github/workflows/ci_scm_ccpp_prebuild.yml new file mode 100644 index 000000000..64fac3cd1 --- /dev/null +++ b/.github/workflows/ci_scm_ccpp_prebuild.yml @@ -0,0 +1,63 @@ +name: CI test to run SCM ccpp_prebuild step + +on: [push, pull_request] + +jobs: + build-linux: + + # The type of runner that the job will run on + runs-on: ubuntu-latest + strategy: + max-parallel: 5 + + steps: + + - name: Checkout current ccpp-physics code + uses: actions/checkout@v3 + + - name: Store remote-URL for current ccpp-physics code + run: echo "GIT_REMOTE_URL=`git remote get-url origin`" >> $GITHUB_ENV + + - name: Store branch name for current ccpp-physics code + run: echo "GIT_REMOTE_BRANCH=`git rev-parse --abbrev-ref HEAD`" >> $GITHUB_ENV + + - name: Store hash for HEAD of current ccpp-physics code + run: echo "GIT_REMOTE_HASH=`git rev-parse HEAD`" >> $GITHUB_ENV + + - name: Checkout latest ccpp-scm code + run: git clone https://github.com/NCAR/ccpp-scm.git + + - name: Initialize submodules + run: | + cd /home/runner/work/ccpp-physics/ccpp-physics/ccpp-scm + git submodule update --init --recursive + + - name: Update ccpp-physics hash in ccpp-scm + if: github.event.pull_request == false + run: | + cd /home/runner/work/ccpp-physics/ccpp-physics/ccpp-scm/ccpp/physics + echo $GIT_REMOTE_URL + echo $GIT_REMOTE_BRANCH + echo ${{github.repository}} + echo ${{ github.event.pull_request.head.sha }} + echo $GITHUB_SHA + git remote add remote_local $GIT_REMOTE_URL + git fetch remote_local $GIT_REMOTE_BRANCH + git checkout remote_local/$GIT_REMOTE_BRANCH + + - name: Set up Python 3.8.5 + uses: actions/setup-python@v3 + with: + python-version: 3.8.5 + + - name: Add conda to system path + run: | + # $CONDA is an environment variable pointing to the root of the miniconda directory + echo $CONDA/bin >> $GITHUB_PATH + + - name: Run ccpp_prebuild.py + run: | + cd /home/runner/work/ccpp-physics/ccpp-physics/ccpp-scm/ + git status + mkdir -p /home/runner/work/ccpp-physics/ccpp-physics/ccpp-scm/scm/bin/ccpp/physics/physics/ + ./ccpp/framework/scripts/ccpp_prebuild.py --config ccpp/config/ccpp_prebuild_config.py \ No newline at end of file diff --git a/physics/GFS_rrtmgp_cloud_mp.F90 b/physics/GFS_rrtmgp_cloud_mp.F90 index 546379a98..9ca340763 100644 --- a/physics/GFS_rrtmgp_cloud_mp.F90 +++ b/physics/GFS_rrtmgp_cloud_mp.F90 @@ -50,11 +50,12 @@ subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldic relhum, lsmask, xlon, xlat, dx, tv_lay, effrin_cldliq, effrin_cldice, & effrin_cldrain, effrin_cldsnow, tracer, cnv_mixratio, cld_cnv_frac, qci_conv, & deltaZ, deltaZc, deltaP, qc_mynn, qi_mynn, cld_pbl_frac, con_g, con_rd, con_eps, & - con_ttp, doGP_cldoptics_PADE, doGP_cldoptics_LUT, cld_frac, cld_lwp, cld_reliq, & + con_ttp, doGP_cldoptics_PADE, doGP_cldoptics_LUT, doGP_smearclds, & + cld_frac, cld_lwp, cld_reliq, & cld_iwp, cld_reice, cld_swp, cld_resnow, cld_rwp, cld_rerain, precip_frac, & cld_cnv_lwp, cld_cnv_reliq, cld_cnv_iwp, cld_cnv_reice, cld_pbl_lwp, & cld_pbl_reliq, cld_pbl_iwp, cld_pbl_reice, lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - errmsg, errflg) + cldfra2d, errmsg, errflg) implicit none ! Inputs @@ -92,7 +93,8 @@ subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldic uni_cld, & ! Flag for unified cloud scheme lmfdeep2, & ! Flag for mass flux deep convection doGP_cldoptics_LUT, & ! Flag to do GP cloud-optics (LUTs) - doGP_cldoptics_PADE ! (PADE approximation) + doGP_cldoptics_PADE, & ! (PADE approximation) + doGP_smearclds ! If true, add sgs clouds to gridmean clouds real(kind_phys), intent(in) :: & con_g, & ! Physical constant: gravitational constant con_rd, & ! Physical constant: gas-constant for dry air @@ -135,6 +137,8 @@ subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldic iwp_ex, & ! Total ice water path from explicit microphysics lwp_fc, & ! Total liquid water path from cloud fraction scheme iwp_fc ! Total ice water path from cloud fraction scheme + real(kind_phys), dimension(:), intent(out) :: & + cldfra2d ! Instantaneous 2D (max-in-column) cloud fraction real(kind_phys), dimension(:,:),intent(inout) :: & cld_frac, & ! Cloud-fraction for stratiform clouds cld_lwp, & ! Water path for stratiform liquid cloud-particles @@ -267,8 +271,9 @@ subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldic endif call cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_cldrain,& i_cldsnow, i_cldgrpl, p_lev, p_lay, tv_lay, t_lay, tracer, qs_lay, q_lay, & - relhum, con_g, con_rd, con_eps, alpha0, lwp_ex, iwp_ex, lwp_fc, iwp_fc, & - cld_frac, cld_lwp, cld_iwp, cld_swp, cld_rwp, cond_cfrac_onRH = .true.) + relhum, con_ttp, con_g, con_rd, con_eps, alpha0, cnv_mixratio, lwp_ex, & + iwp_ex, lwp_fc, iwp_fc, cld_frac, cld_lwp, cld_iwp, cld_swp, cld_rwp, & + cond_cfrac_onRH = .true., doGP_smearclds = doGP_smearclds) endif ! Bound effective radii for RRTMGP, LUT's for cloud-optics go from @@ -293,6 +298,14 @@ subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldic endif endif + ! Instantaneous 2D (max-in-column) cloud fraction + do iCol = 1, nCol + cldfra2d(iCol) = 0._kind_phys + do iLay = 1, nLev-1 + cldfra2d(iCol) = max(cldfra2d(iCol), cld_frac(iCol,iLay)) + enddo + enddo + precip_frac(1:nCol,1:nLev) = cld_frac(1:nCol,1:nLev) end subroutine GFS_rrtmgp_cloud_mp_run @@ -659,13 +672,14 @@ end subroutine cloud_mp_uni !! \section cloud_mp_thompson_gen General Algorithm subroutine cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_cldrain,& i_cldsnow, i_cldgrpl, p_lev, p_lay, tv_lay, t_lay, tracer, qs_lay, q_lay, relhum, & - con_g, con_rd, con_eps, alpha0, lwp_ex, iwp_ex, lwp_fc, iwp_fc, cld_frac, cld_lwp,& - cld_iwp, cld_swp, cld_rwp, cond_cfrac_onRH) + con_ttp, con_g, con_rd, con_eps, alpha0, cnv_mixratio, lwp_ex, iwp_ex, lwp_fc, & + iwp_fc, cld_frac, cld_lwp, cld_iwp, cld_swp, cld_rwp, cond_cfrac_onRH, doGP_smearclds) implicit none ! Inputs logical, intent(in), optional :: & - cond_cfrac_onRH + cond_cfrac_onRH, & ! If true, cloud-fracion set to unity when rh>99% + doGP_smearclds ! If true, add sgs clouds to gridmean clouds integer, intent(in) :: & nCol, & ! Number of horizontal grid points nLev, & ! Number of vertical layers @@ -677,6 +691,7 @@ subroutine cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_c i_cldsnow, & ! cloud snow amount. i_cldgrpl ! cloud groupel amount. real(kind_phys), intent(in) :: & + con_ttp, & ! Triple point temperature of water (K) con_g, & ! Physical constant: gravitational constant con_rd, & ! Physical constant: gas-constant for dry air con_eps, & ! Physical constant: gas constant air / gas constant H2O @@ -687,7 +702,8 @@ subroutine cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_c qs_lay, & ! Saturation vapor pressure (Pa) q_lay, & ! water-vapor mixing ratio (kg/kg) relhum, & ! Relative humidity - p_lay ! Pressure at model-layers (Pa) + p_lay, & ! Pressure at model-layers (Pa) + cnv_mixratio ! Convective cloud mixing-ratio (kg/kg) real(kind_phys), dimension(:,:), intent(in) :: & p_lev ! Pressure at model-level interfaces (Pa) real(kind_phys), dimension(:,:,:),intent(in) :: & @@ -707,16 +723,15 @@ subroutine cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_c cld_rwp ! Cloud rain water path ! Local variables - real(kind_phys) :: tem1, pfac, cld_mr, deltaP + real(kind_phys) :: tem1, pfac, cld_mr, deltaP, tem2 real(kind_phys), dimension(nCol, nLev, min(4,ncnd)) :: cld_condensate integer :: iCol,iLay,l ! Cloud condensate cld_condensate(1:nCol,1:nLev,1) = tracer(1:nCol,1:nLev,i_cldliq) ! -liquid water cld_condensate(1:nCol,1:nLev,2) = tracer(1:nCol,1:nLev,i_cldice) ! -ice water - cld_condensate(1:nCol,1:nLev,3) = tracer(1:nCol,1:nLev,i_cldrain) ! -rain water - cld_condensate(1:nCol,1:nLev,4) = tracer(1:nCol,1:nLev,i_cldsnow) + &! -snow + grapuel - tracer(1:nCol,1:nLev,i_cldgrpl) + cld_condensate(1:nCol,1:nLev,3) = tracer(1:nCol,1:nLev,i_cldrain) ! -rain hydrometeors + cld_condensate(1:nCol,1:nLev,4) = tracer(1:nCol,1:nLev,i_cldsnow) ! -snow hydrometeors cld_lwp(:,:) = 0.0 cld_iwp(:,:) = 0.0 @@ -726,6 +741,12 @@ subroutine cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_c tem1 = 1.0e5/con_g do iLay = 1, nLev-1 do iCol = 1, nCol + ! Add convective cloud to gridmean cloud? + if (doGP_smearclds) then + tem2 = min(1.0, max(0.0, (con_ttp-t_lay(iCol,iLay))*0.05)) + cld_condensate(iCol,iLay,1) = cld_condensate(iCol,iLay,1) + cnv_mixratio(iCol,iLay)*(1._kind_phys - tem2) + cld_condensate(iCol,iLay,2) = cld_condensate(iCol,iLay,2) + cnv_mixratio(iCol,iLay)*tem2 + endif ! Compute liquid/ice condensate path from mixing ratios (kg/kg)->(g/m2) deltaP = abs(p_lev(iCol,iLay+1)-p_lev(iCol,iLay))*0.01 cld_lwp(iCol,iLay) = max(0., cld_condensate(iCol,iLay,1) * tem1 * deltaP) @@ -738,7 +759,7 @@ subroutine cloud_mp_thompson(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, i_c cld_frac(iCol,iLay) = 1._kind_phys else cld_mr = cld_condensate(iCol,iLay,1) + cld_condensate(iCol,iLay,2) + & - cld_condensate(iCol,iLay,4) + cld_condensate(iCol,iLay,3) + cld_condensate(iCol,iLay,4) cld_frac(iCol,iLay) = cld_frac_XuRandall(p_lay(iCol,iLay), & qs_lay(iCol,iLay), relhum(iCol,iLay), cld_mr, alpha0) endif diff --git a/physics/GFS_rrtmgp_cloud_mp.meta b/physics/GFS_rrtmgp_cloud_mp.meta index 4f48d53ef..1eb870da8 100644 --- a/physics/GFS_rrtmgp_cloud_mp.meta +++ b/physics/GFS_rrtmgp_cloud_mp.meta @@ -462,6 +462,13 @@ dimensions = () type = logical intent = in +[doGP_smearclds] + standard_name = flag_for_implicit_sgs_cloud_in_RRTMGP + long_name = logical flag to impicit SGS cloud in RRTMGP + units = flag + dimensions = () + type = logical + intent = in [cld_frac] standard_name = total_cloud_fraction long_name = layer total cloud fraction @@ -646,6 +653,14 @@ type = real kind = kind_phys intent = inout +[cldfra2d] + standard_name = max_in_column_cloud_fraction + long_name = instantaneous 2D (max-in-column) cloud fraction + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = out [errmsg] standard_name = ccpp_error_message long_name = error message for error handling in CCPP diff --git a/physics/radiation_clouds.f b/physics/radiation_clouds.f index 47b9b79fa..bf255ce00 100644 --- a/physics/radiation_clouds.f +++ b/physics/radiation_clouds.f @@ -2160,7 +2160,7 @@ subroutine progcld_thompson_wsm6 & integer :: i, k, id, nf ! --- constant values - real (kind=kind_phys), parameter :: xrc3 = 200. + real (kind=kind_phys), parameter :: xrc3 = 100. ! !===> ... begin here @@ -2177,7 +2177,7 @@ subroutine progcld_thompson_wsm6 & rei (i,k) = re_ice(i,k) rer (i,k) = rrain_def ! default rain radius to 1000 micron res (i,k) = re_snow(i,K) -! tem2d (i,k) = min( 1.0, max( 0.0, (con_ttp-tlyr(i,k))*0.05 ) ) + tem2d (i,k) = min( 1.0, max( 0.0, (con_ttp-tlyr(i,k))*0.05 ) ) clwf(i,k) = 0.0 enddo enddo @@ -2208,12 +2208,14 @@ subroutine progcld_thompson_wsm6 & enddo enddo -!> - Compute cloud liquid/ice condensate path in \f$ g/m^2 \f$ . - +!> - Compute total-cloud liquid/ice condensate path in \f$ g/m^2 \f$. +!> The total condensate includes convective condensate. do k = 1, NLAY-1 do i = 1, IX - cwp(i,k) = max(0.0, clw(i,k,ntcw) * gfac * delp(i,k)) - cip(i,k) = max(0.0, clw(i,k,ntiw) * gfac * delp(i,k)) + cwp(i,k) = max(0.0, (clw(i,k,ntcw)+cnvw(i,k)* + & (1.-tem2d(i,k))) * gfac * delp(i,k)) + cip(i,k) = max(0.0, (clw(i,k,ntiw) + cnvw(i,k)* + & tem2d(i,k)) *gfac * delp(i,k)) crp(i,k) = max(0.0, clw(i,k,ntrw) * gfac * delp(i,k)) csp(i,k) = max(0.0, clw(i,k,ntsw) * gfac * delp(i,k)) enddo @@ -3902,7 +3904,7 @@ subroutine cloud_fraction_mass_flx_2 & clwmin = 0.0 do k = 1, NLAY-1 do i = 1, IX - clwt = 1.0e-10 * (plyr(i,k)*0.001) + clwt = 1.0e-6 * (plyr(i,k)*0.001) if (clwf(i,k) > clwt) then if(rhly(i,k) > 0.99) then