因为有同门做过对流相关工作,所以稍微看看深对流过程的代码
有之前的经验,现在可以很快的锁定相关代码的位置
深对流过程的位于tphybc子例程,该过程会在CAM与其他模块交互之前调用
排除熟悉的输入输出定义,以及局部变量初始化,还有从pbuf中取值赋值等操作
在湿对流过程中,首先调用的就是一个深对流过程,并在过程结束调用physics_update过程更新物理变量
整个convect_deep_tend子例程比较简单,关键部分是调用了zm_conv_tend子例程
该子例程在调用之前取出了两个变量planetary boundary layer depth (pblt) 以及Perturbation temperature by planetary boundary layer processes (tpert),均是边界层相关的变量
subroutine zm_conv_tend(pblh ,mcon ,cme , &
tpert ,dlf ,pflx ,zdu , &
rliq , &
ztodt , &
jctop ,jcbot , &
state ,ptend_all ,landfrac, pbuf)
use cam_history, only: outfld
use physics_types, only: physics_state, physics_ptend
use physics_types, only: physics_ptend_init, physics_update
use physics_types, only: physics_state_copy, physics_state_dealloc
use physics_types, only: physics_ptend_sum, physics_ptend_dealloc
use phys_grid, only: get_lat_p, get_lon_p
use time_manager, only: get_nstep, is_first_step
use physics_buffer, only : pbuf_get_field, physics_buffer_desc, pbuf_old_tim_idx
use constituents, only: pcnst, cnst_get_ind, cnst_is_convtran1
use check_energy, only: check_energy_chng
use physconst, only: gravit
use phys_control, only: cam_physpkg_is
! Arguments
type(physics_state), intent(in ) :: state ! Physics state variables
type(physics_ptend), intent(out) :: ptend_all ! individual parameterization tendencies
type(physics_buffer_desc), pointer :: pbuf(:)
real(r8), intent(in) :: ztodt ! 2 delta t (model time increment)
real(r8), intent(in) :: pblh(pcols) ! Planetary boundary layer height
real(r8), intent(in) :: tpert(pcols) ! Thermal temperature excess
real(r8), intent(in) :: landfrac(pcols) ! RBN - Landfrac
real(r8), intent(out) :: mcon(pcols,pverp) ! Convective mass flux--m sub c
real(r8), intent(out) :: dlf(pcols,pver) ! scattrd version of the detraining cld h2o tend
real(r8), intent(out) :: pflx(pcols,pverp) ! scattered precip flux at each level
real(r8), intent(out) :: cme(pcols,pver) ! cmf condensation - evaporation
real(r8), intent(out) :: zdu(pcols,pver) ! detraining mass flux
real(r8), intent(out) :: rliq(pcols) ! reserved liquid (not yet in cldliq) for energy integrals
! Local variables
integer :: i,k,m
integer :: ilon ! global longitude index of a column
integer :: ilat ! global latitude index of a column
integer :: nstep
integer :: ixcldice, ixcldliq ! constituent indices for cloud liquid and ice water.
integer :: lchnk ! chunk identifier
integer :: ncol ! number of atmospheric columns
integer :: itim ! for physics buffer fields
real(r8) :: ftem(pcols,pver) ! Temporary workspace for outfld variables
real(r8) :: ntprprd(pcols,pver) ! evap outfld: net precip production in layer
real(r8) :: ntsnprd(pcols,pver) ! evap outfld: net snow production in layer
real(r8) :: tend_s_snwprd (pcols,pver) ! Heating rate of snow production
real(r8) :: tend_s_snwevmlt(pcols,pver) ! Heating rate of evap/melting of snow
real(r8) :: fake_dpdry(pcols,pver) ! used in convtran call
! physics types
type(physics_state) :: state1 ! locally modify for evaporation to use, not returned
type(physics_ptend) :: ptend_loc ! package tendencies
! physics buffer fields
real(r8), pointer, dimension(:) :: prec ! total precipitation
real(r8), pointer, dimension(:) :: snow ! snow from ZM convection
real(r8), pointer, dimension(:,:) :: cld
real(r8), pointer, dimension(:,:) :: ql ! wg grid slice of cloud liquid water.
real(r8), pointer, dimension(:,:) :: rprd ! rain production rate
real(r8), pointer, dimension(:,:,:) :: fracis ! fraction of transported species that are insoluble
real(r8), pointer, dimension(:,:) :: evapcdp ! Evaporation of deep convective precipitation
real(r8), pointer, dimension(:,:) :: flxprec ! Convective-scale flux of precip at interfaces (kg/m2/s)
real(r8), pointer, dimension(:,:) :: flxsnow ! Convective-scale flux of snow at interfaces (kg/m2/s)
real(r8), pointer, dimension(:,:) :: dp_cldliq
real(r8), pointer, dimension(:,:) :: dp_cldice
real(r8) :: jctop(pcols) ! o row of top-of-deep-convection indices passed out.
real(r8) :: jcbot(pcols) ! o row of base of cloud indices passed out.
real(r8) :: pcont(pcols), pconb(pcols), freqzm(pcols)
! history output fields
real(r8) :: cape(pcols) ! w convective available potential energy.
real(r8) :: mu_out(pcols,pver)
real(r8) :: md_out(pcols,pver)
! used in momentum transport calculation
real(r8) :: winds(pcols, pver, 2)
real(r8) :: wind_tends(pcols, pver, 2)
real(r8) :: pguall(pcols, pver, 2)
real(r8) :: pgdall(pcols, pver, 2)
real(r8) :: icwu(pcols,pver, 2)
real(r8) :: icwd(pcols,pver, 2)
real(r8) :: seten(pcols, pver)
logical :: l_windt(2)
real(r8) :: tfinal1, tfinal2
integer :: ii
logical :: lq(pcnst)
zm_conv_tend子例程第一部分的代码,其中主要看关于输入输出的部分
输入包括physics_state和physics_ptend,状态变量和梯度还有物理缓冲区指针pbuf
其余四个输入参数,除了2 delta t和陆地部分,就是pblt和tpert,两个刚刚取出的变量
5个输出变量很明显是描述云物理、降水、对流和大气湍流等过程的变量,因为我不怎么关心物理过程,所以先跳过
然后是一些无关紧要的初始化和指针获取
正式调用:
这里调用了对流参数化方案,传递了一系列输入参数,包括温度、湿度、降水等,并接收了一系列输出参数,如对流量、凝结-蒸发量、CAPE等。
并可以明显看出后续做了以下几件事:
- 将得到的CAPE(对流可利用位能)存储在文件中,以供后续分析使用。
- 计算并输出Zhang-McFarlane对流的频率(
freqzm
),并将其存储在文件中。 - 将对流量(
mcon
)从以毫巴/秒为单位转换为以千克/平方米/秒为单位,并存储在数组mcon
中。 - 将上升和下降的质量通量存储在未整理的数组
mu_out
和md_out
中,并进行单位转换。 - 将温度和水汽趋势输出到文件中,用于后续的诊断和分析。
一位学姐之前的工作就是改进了CAPE的计算。所以接下来我重点关注CAPE的计算过程
这部分对于每个大气柱初始化每个CAPE
这部分选择调用计算CAPE的过程,现在基本使用CAM4或者5甚至6了,基本都是用
buoyan_dilute
子例程用于计算温度 tp
、饱和特定湿度 qstp
、气块的浮力、CAPE、LCL、LEL 等参数。
buoyan_dilute子例程计算CAPE的代码如下:
首先,它使用对流上升的气块从云底到云顶的积分来计算CAPE。这个积分是通过对每个层级的浮力与该层级到下一个层级的压强差取对数的乘积来计算的。
然后,它在每个网格点上找到了最大的CAPE值,并将其作为最终的CAPE值。最后,为了诊断目的,它对CAPE施加了下限,以确保CAPE值不会小于零。
总体来看就是一个积分计算过程。