Skip to content

Commit

Permalink
CCPPize Hack shallow convection (#195)
Browse files Browse the repository at this point in the history
Originator(s): @jimmielin

Summary (include the keyword ['closes', 'fixes', 'resolves'] and issue
number):
- Closes #136: CCPPize Hack shallow convection scheme (`cmfmca`) and
related interstitials
- Move ZM namelist read to a separate `zm_conv_options` scheme so not
all of ZM has to run while ZM namelist options are read for zm_conv_evap
(needed for complete shallow convection)
- Closes #197: Changes ZM convective mass flux units to `kg m-2 s-1`
- Closes #201: Adds `errmsg`, `errflg` to `cloud_fraction_fice` sxheme
- Fixes ESCOMP/CAM-SIMA#284: Updates `top_lev`
in `cloud_fraction_fice` to a registry quantity that can be defined by
macrophysics initialization
- Fixes ZM reserved liquid unit metadata to be `m s-1`
- Freeze ChangeLog

Describe any changes made to the namelist:
- new hack shallow convection namelist options `cmfmca_namelist.xml`
- move ZM namelist options to `zm_conv_options_namelist.xml` 

List all files eliminated and why: N/A

List all files added and what they do:
```
CCPPize Hack shallow convection
A       schemes/hack_shallow/hack_convect_shallow.F90
A       schemes/hack_shallow/hack_convect_shallow.meta
A       schemes/hack_shallow/hack_convect_shallow_namelist.xml
A       test/test_suites/suite_convect_shallow_hack.xml
A       schemes/sima_diagnostics/convect_shallow_diagnostics.F90
A       schemes/sima_diagnostics/convect_shallow_diagnostics.meta

Interstitial schemes for zm_conv_evap
A       schemes/hack_shallow/set_general_conv_fluxes_to_shallow.F90
A       schemes/hack_shallow/set_general_conv_fluxes_to_shallow.meta
A       schemes/hack_shallow/set_shallow_conv_fluxes_to_general.F90
A       schemes/hack_shallow/set_shallow_conv_fluxes_to_general.meta

Interstitial schemes to combine shallow and deep convective fluxes
A       schemes/hack_shallow/convect_shallow_sum_to_deep.F90
A       schemes/hack_shallow/convect_shallow_sum_to_deep.meta

Move ZM namelist options to zm_conv_options scheme
A       schemes/zhang_mcfarlane/zm_conv_options.F90
A       schemes/zhang_mcfarlane/zm_conv_options.meta

Update cloud_fraction_fice to accept top_lev registry quantity (vertical_layer_index_of_cloud_fraction_top)
Add new init-phase only scheme to assign top_lev to trop_cloud_top_lev for CAM5+ macrophysics
M       schemes/cloud_fraction/cloud_fraction_fice.F90
M       schemes/cloud_fraction/cloud_fraction_fice.meta
A       schemes/cloud_fraction/set_cloud_fraction_top.F90
A       schemes/cloud_fraction/set_cloud_fraction_top.meta
```

List all existing files that have been modified, and describe the
changes:
(Helpful git command: `git diff --name-status
development...<your_branch_name>`)
```
Freeze ChangeLog
M       doc/ChangeLog

Move ZM namelist options to zm_conv_options scheme
R100    schemes/zhang_mcfarlane/zm_convr_namelist.xml   schemes/zhang_mcfarlane/zm_conv_options_namelist.xml
M       suites/suite_cam7.xml
M       test/test_suites/suite_zhang_mcfarlane.xml

Update cloud_fraction_fice to accept top_lev registry quantity (vertical_layer_index_of_cloud_fraction_top)
M       schemes/cloud_fraction/cloud_fraction_fice.F90
M       schemes/cloud_fraction/cloud_fraction_fice.meta
M       suites/suite_cam7.xml
M       test/test_suites/suite_zhang_mcfarlane.xml

Change CMFMC_DP units for consistency with snapshot; update rliq metadata unit
M       schemes/zhang_mcfarlane/zm_convr.F90
M       schemes/zhang_mcfarlane/zm_convr.meta
M       schemes/sima_diagnostics/zm_diagnostics.F90
M       schemes/sima_diagnostics/zm_diagnostics.meta

Update dlf, dif standard names
M       schemes/zhang_mcfarlane/zm_convr.meta

Change constituent properties pointer unit from None to none
M       schemes/sima_diagnostics/sima_state_diagnostics.meta
M       schemes/utilities/geopotential_temp.meta
M       schemes/utilities/qneg.meta
M       schemes/zhang_mcfarlane/zm_conv_convtran.meta
```

List any test failures: 

Is this a science-changing update? New physics package, algorithm
change, tuning changes, etc?
New Hack shallow convection scheme
  • Loading branch information
jimmielin authored Feb 27, 2025
1 parent 3722442 commit 299c279
Show file tree
Hide file tree
Showing 31 changed files with 2,933 additions and 93 deletions.
56 changes: 0 additions & 56 deletions doc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,59 +1,3 @@

===============================================================

Tag name:
Originator(s): cacraig
Date: Dec 24, 2024
One-line Summary: Complete Zhang McFarlane conversion to CCPP
Github PR URL:

This PR fixes the following NCAR/atmospheric_physics Github issues:
Add ccpp'ized ZM : https://github.com/ESCOMP/atmospheric_physics/issues/66

Code reviewed by:

List all existing files that have been added (A), modified (M), or deleted (D),
and describe the changes:
A schemes/cloud_fraction/cloud_fraction_fice.F90
A schemes/cloud_fraction/cloud_fraction_fice.meta
A schemes/sima_diagnostics/zm_convr_tendency_diagnostics.F90
A schemes/sima_diagnostics/zm_convr_tendency_diagnostics.meta
A schemes/sima_diagnostics/zm_diagnostics.F90
A schemes/sima_diagnostics/zm_diagnostics.meta
A schemes/sima_diagnostics/zm_evap_tendency_diagnostics.F90
A schemes/sima_diagnostics/zm_evap_tendency_diagnostics.meta
A schemes/sima_diagnostics/zm_momtran_tendency_diagnostics.F90
A schemes/sima_diagnostics/zm_momtran_tendency_diagnostics.meta
A schemes/sima_diagnostics/zm_tendency_diagnostics.F90
A schemes/sima_diagnostics/zm_tendency_diagnostics.meta
A schemes/utilities/to_be_ccppized_temporary.F90
A schemes/utilities/to_be_ccppized_temporary.meta
A schemes/zhang_mcfarlane/set_deep_conv_fluxes_to_general.F90
A schemes/zhang_mcfarlane/set_deep_conv_fluxes_to_general.meta
A schemes/zhang_mcfarlane/set_general_conv_fluxes_to_deep.F90
A schemes/zhang_mcfarlane/set_general_conv_fluxes_to_deep.meta
M schemes/zhang_mcfarlane/zm_conv_convtran.F90
M schemes/zhang_mcfarlane/zm_conv_convtran.meta
M schemes/zhang_mcfarlane/zm_conv_evap.F90
M schemes/zhang_mcfarlane/zm_conv_evap.meta
M schemes/zhang_mcfarlane/zm_conv_momtran.F90
M schemes/zhang_mcfarlane/zm_conv_momtran.meta
M schemes/zhang_mcfarlane/zm_convr.F90
M schemes/zhang_mcfarlane/zm_convr.meta
A schemes/zhang_mcfarlane/zm_convr_namelist.xml
A suites/suite_zhang_mcfarlane.xml
M test/test_schemes/initialize_constituents.F90
A to_be_ccppized/error_messages.F90
A to_be_ccppized/namelist_utils.F90
A to_be_ccppized/units.F90
A to_be_ccppized/wv_sat_methods.F90
A to_be_ccppized/wv_saturation.F90

List and Describe any test failures:

Summarize any changes to answers:

===============================================================
===============================================================

Tag name: atmos_phys0_07_000
Expand Down
22 changes: 14 additions & 8 deletions schemes/cloud_fraction/cloud_fraction_fice.F90
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module cloud_fraction_fice
!> \section arg_table_cloud_fraction_fice_run Argument Table
!! \htmlinclude cloud_fraction_fice_run.html
!!
subroutine cloud_fraction_fice_run(ncol, t, tmelt, top_lev, pver, fice, fsnow)
subroutine cloud_fraction_fice_run(ncol, t, tmelt, top_lev, pver, fice, fsnow, errmsg, errflg)
!
! Compute the fraction of the total cloud water which is in ice phase.
! The fraction depends on temperature only.
Expand All @@ -22,14 +22,17 @@ subroutine cloud_fraction_fice_run(ncol, t, tmelt, top_lev, pver, fice, fsnow)
!-----------------------------------------------------------------------

! Arguments
integer, intent(in) :: ncol ! number of active columns (count)
real(kind_phys), intent(in) :: t(:,:) ! temperature (K)
real(kind_phys), intent(in) :: tmelt ! freezing point of water (K)
integer, intent(in) :: top_lev ! Vertical layer index for highest layer with tropopheric clouds (index)
integer, intent(in) :: pver ! Number of vertical layers (count)
integer, intent(in) :: ncol ! number of active columns (count)
real(kind_phys), intent(in) :: t(:,:) ! temperature (K)
real(kind_phys), intent(in) :: tmelt ! freezing point of water (K)
integer, intent(in) :: top_lev ! Vertical layer index for highest layer with tropopheric clouds (index)
integer, intent(in) :: pver ! Number of vertical layers (count)

real(kind_phys), intent(out) :: fice(:,:) ! Fractional ice content within cloud
real(kind_phys), intent(out) :: fsnow(:,:) ! Fractional snow content for convection
real(kind_phys), intent(out) :: fice(:,:) ! Fractional ice content within cloud
real(kind_phys), intent(out) :: fsnow(:,:) ! Fractional snow content for convection

character(len=512), intent(out) :: errmsg
integer, intent(out) :: errflg

! Local variables
real(kind_phys) :: tmax_fice ! max temperature for cloud ice formation
Expand All @@ -41,6 +44,9 @@ subroutine cloud_fraction_fice_run(ncol, t, tmelt, top_lev, pver, fice, fsnow)

!-----------------------------------------------------------------------

errmsg = ''
errflg = 0

tmax_fice = tmelt - 10._kind_phys ! max temperature for cloud ice formation
tmin_fice = tmax_fice - 30._kind_phys ! min temperature for cloud ice formation
tmax_fsnow = tmelt ! max temperature for transition to convective snow
Expand Down
14 changes: 13 additions & 1 deletion schemes/cloud_fraction/cloud_fraction_fice.meta
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
dimensions = ()
intent = in
[ top_lev ]
standard_name = vertical_layer_index_of_troposphere_cloud_top
standard_name = vertical_layer_index_of_cloud_fraction_top
units = index
type = integer
dimensions = ()
Expand All @@ -47,3 +47,15 @@
type = real | kind = kind_phys
dimensions = (horizontal_loop_extent,vertical_layer_dimension)
intent = out
[ errmsg ]
standard_name = ccpp_error_message
units = none
type = character | kind = len=512
dimensions = ()
intent = out
[ errflg ]
standard_name = ccpp_error_code
units = 1
type = integer
dimensions = ()
intent = out
31 changes: 31 additions & 0 deletions schemes/cloud_fraction/set_cloud_fraction_top.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
! Copyright (C) 2024 National Science Foundation-National Center for Atmospheric Research
! SPDX-License-Identifier: Apache-2.0
!
! Stub scheme to set top of cloud physics to below top cloud level.
! Used for all macrophysical schemes except RK.
module set_cloud_fraction_top
implicit none
private

public :: set_cloud_fraction_top_init

contains

!> \section arg_table_set_cloud_fraction_top_init Argument Table
!! \htmlinclude set_cloud_fraction_top_init.html
subroutine set_cloud_fraction_top_init(trop_cloud_top_lev, top_lev, errmsg, errflg)
integer, intent(in) :: trop_cloud_top_lev ! Troposphere cloud physics top level [index]
integer, intent(out) :: top_lev ! Cloud fraction top level [index]
character(len=512), intent(out) :: errmsg ! Error message
integer, intent(out) :: errflg ! Error flag

! Initialize error handling
errmsg = ''
errflg = 0

! Limit CAM5+ cloud physics to below top cloud level.
top_lev = trop_cloud_top_lev

end subroutine set_cloud_fraction_top_init

end module set_cloud_fraction_top
31 changes: 31 additions & 0 deletions schemes/cloud_fraction/set_cloud_fraction_top.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[ccpp-table-properties]
name = set_cloud_fraction_top
type = scheme

[ccpp-arg-table]
name = set_cloud_fraction_top_init
type = scheme
[ trop_cloud_top_lev ]
standard_name = vertical_layer_index_of_troposphere_cloud_physics_top
units = index
type = integer
dimensions = ()
intent = in
[ top_lev ]
standard_name = vertical_layer_index_of_cloud_fraction_top
units = index
type = integer
dimensions = ()
intent = out
[ errmsg ]
standard_name = ccpp_error_message
units = none
type = character | kind = len=512
dimensions = ()
intent = out
[ errflg ]
standard_name = ccpp_error_code
units = 1
type = integer
dimensions = ()
intent = out
134 changes: 134 additions & 0 deletions schemes/hack_shallow/convect_shallow_sum_to_deep.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
! Copyright (C) 2024-2025 National Science Foundation-National Center for Atmospheric Research
! SPDX-License-Identifier: Apache-2.0
!
! Note: There is an implicit dependency in the shallow convective code
! that deep convection runs *before* shallow convection.
! Efforts have been made to make this dependency clear in the form that
! deep convective quantities are merged with the shallow convective
! quantities (incl. determining the final cloud top/bottom, cloud mass flux, ...)
! in this module, and shallow convection modules only using the quantities
! with a _from_shallow_convection suffix.
module convect_shallow_sum_to_deep
use ccpp_kinds, only: kind_phys
implicit none
private

public :: convect_shallow_sum_to_deep_run

contains
! Combines shallow and deep convection quantities into total convective quantities.
!> \section arg_table_convect_shallow_sum_to_deep_run Argument Table
!! \htmlinclude arg_table_convect_shallow_sum_to_deep_run.html
subroutine convect_shallow_sum_to_deep_run( &
ncol, &
pver, pverp, &
pmid, &
! All convection input+outputs (input is from deep)
rliq_total, &
! Deep convection inputs
cmfmc_deep, & ! see notes.
rprddp, &
qc_deep, &
cnt_deep, &
cnb_deep, &
! Shallow convection inputs
cmfmc_sh, &
qc_sh, &
rliq_sh, &
rprdsh, & ! cmfdqr
cnt_sh, &
cnb_sh, &
! Total convection outputs
cmfmc_total, &
rprdtot, &
qc_total, &
cnt, cnb, p_cnt, p_cnb, &
errmsg, errflg)

! Input arguments
integer, intent(in) :: ncol ! # of columns
integer, intent(in) :: pver ! # of model layers
integer, intent(in) :: pverp ! # of layer interfaces (pver + 1)
real(kind_phys), intent(in) :: pmid(:,:) ! air_pressure [Pa]

! Deep convective inputs
real(kind_phys), intent(in) :: cmfmc_deep(:,:) ! Deep convection cloud mass flux [kg m-2 s-1]
real(kind_phys), intent(in) :: rprddp(:,:) ! Deep convection convective rainout Q tendency [kg kg-1 s-1]
real(kind_phys), intent(in) :: qc_deep(:,:) ! Deep convection cloud water tendency [kg kg-1 s-1]
integer, intent(in) :: cnt_deep(:) ! Deep convection cloud top index [index] (jctop / jt)
integer, intent(in) :: cnb_deep(:) ! Deep convection cloud base index [index] (jcbot / maxg)

! Shallow convective inputs
real(kind_phys), intent(in) :: cmfmc_sh(:,:) ! Shallow convection cloud mass flux [kg m-2 s-1]
real(kind_phys), intent(in) :: qc_sh(:,:) ! Shallow convection cloud water tendency [kg kg-1 s-1]
real(kind_phys), intent(in) :: rliq_sh(:) ! Shallow convection reserved liquid [m s-1]
real(kind_phys), intent(in) :: rprdsh(:,:) ! Shallow convection convective rainout Q tendency [kg kg-1 s-1]
integer, intent(in) :: cnt_sh(:) ! Shallow convection cloud top index [index]
integer, intent(in) :: cnb_sh(:) ! Shallow convection cloud base index [index]

! Input/output (total) arguments
! At this point, "total" is only deep because deep convection has written
! to these quantities but shallow convection has not.
! In: deep only, Out: deep+shallow
real(kind_phys), intent(inout) :: rliq_total(:) ! Total convective reserved liquid [m s-1]

! Output arguments
real(kind_phys), intent(out) :: cmfmc_total(:,:) ! Total convective mass flux [kg m-2 s-1]
real(kind_phys), intent(out) :: rprdtot(:,:) ! Total convective rainout Q tendency [kg kg-1 s-1]
real(kind_phys), intent(out) :: qc_total(:,:) ! Total convection cloud water tendency [kg kg-1 s-1]
integer, intent(out) :: cnt(:) ! Convective cloud top index [index]
integer, intent(out) :: cnb(:) ! Convective cloud base index [index]
real(kind_phys), intent(out) :: p_cnt(:) ! Convective cloud top pressure [Pa]
real(kind_phys), intent(out) :: p_cnb(:) ! Convective cloud base pressure [Pa]
character(len=512),intent(out) :: errmsg
integer, intent(out) :: errflg

! Local variables
integer :: i

errmsg = ''
errflg = 0

! Sum convective mass flux at interfaces
cmfmc_total(:ncol,:pverp) = cmfmc_deep(:ncol,:pverp) + cmfmc_sh(:ncol,:pverp)

! Sum detrainment of water at midpoints
qc_total(:ncol,:pver) = qc_deep(:ncol,:pver) + qc_sh(:ncol,:pver)

! Sum vertically-integrated reserved liquid
rliq_total(:ncol) = rliq_total(:ncol) + rliq_sh(:ncol)

! Sum RPRDTOT = RPRDSH + RPRDDP
! CMFDQR is the shallow convective rainout only. The total is stored in RPRDTOT.
rprdtot(:ncol,:pver) = rprdsh(:ncol,:pver) + rprddp(:ncol,:pver)

! Merge the shallow and deep convective "cloud top/base" and compute pressures
! Note: Indices decrease with height
cnt(:ncol) = cnt_deep(:ncol)
cnb(:ncol) = cnb_deep(:ncol)
do i = 1, ncol
! if shallow cloud top is higher then use shallow cloud top
if(cnt_sh(i) < cnt(i)) cnt(i) = cnt_sh(i)

! if shallow cloud base is lower then use shallow cloud base
if(cnb_sh(i) > cnb(i)) cnb(i) = cnb_sh(i)

! if cloud base is at model top then set it to cloud top
if(cnb(i) == 1) cnb(i) = cnt(i)

! ensure cloud top and cloud base indices are within range
if(cnt(i) < 1 .or. cnb(i) < 1 .or. cnt(i) > pver .or. cnb(i) > pver) then
! set to a set of "safe" values
! (cnt-cnb should not be zero to avoid division errors with this quantity)
cnt(i) = pver-1
cnb(i) = pver
endif

! set pressures
p_cnt(i) = pmid(i, cnt(i))
p_cnb(i) = pmid(i, cnb(i))
enddo


end subroutine convect_shallow_sum_to_deep_run
end module convect_shallow_sum_to_deep
Loading

0 comments on commit 299c279

Please sign in to comment.