module uw_conv 2,1
!
! $Id$
!
use cam_logfile
, only: iulog
implicit none
private
save
!
! Public interfaces
!
public init_uw_conv ! Initialization of data for moist convection
public compute_uw_conv ! UW shallow convection
!
! Private data
!
integer, parameter :: r8 = selected_real_kind(12) ! 8 byte real
real(r8) cpair ! specific heat of dry air
real(r8) gravit ! gravitational constant
real(r8) rair ! gas constant for dry air
real(r8) latvap
real(r8) latice
real(r8) latsub
real(r8) zvir
real(r8) epsilo
real(r8) cappa
real(r8) tmelt
real(r8) rgasv
contains
subroutine init_uw_conv(kind, rair_in ,cpair_in ,gravit_in ,latvap_in, &
latice_in, zvir_in, epsilo_in, cappa_in, tmelt_in, rgasv_in )
!-----------------------------------------------------------------------
!
! Purpose:
! Initialize UW shallow convection scheme
!
!-----------------------------------------------------------------------
!
! Input arguments
!
integer, intent(in) :: kind ! kind of reals being passed in
real(r8), intent(in) :: rair_in ! gas constant for dry air
real(r8), intent(in) :: cpair_in ! specific heat of dry air
real(r8), intent(in) :: gravit_in ! acceleration due to gravity
real(r8), intent(in) :: latvap_in ! latent heat of vaporization
real(r8), intent(in) :: latice_in ! latent heat of vaporization
real(r8), intent(in) :: zvir_in
real(r8), intent(in) :: epsilo_in
real(r8), intent(in) :: cappa_in
real(r8), intent(in) :: tmelt_in
real(r8), intent(in) :: rgasv_in
if ( kind .ne. r8 ) then
write(iulog,*) 'KIND of reals passed to init_diffusvity -- exiting.'
stop 'init_eddy_diff'
endif
!
!-----------------------------------------------------------------------
!
! Initialize physical constants for moist convective mass flux procedure
!
cpair = cpair_in ! specific heat of dry air
gravit = gravit_in ! gravitational constant
rair = rair_in ! gas constant for dry air
latvap = latvap_in
latice = latice_in
latsub = latvap + latice
zvir = zvir_in
epsilo = epsilo_in
cappa = cappa_in
tmelt = tmelt_in
rgasv = rgasv_in
!
return
end subroutine init_uw_conv
subroutine compute_uw_conv(pcols, pver, ncol, ncnst, &,28
ztodt, pmid, pdel, &
zmid, pblht, tb, q, &
pint, zint, ub, vb, tkeb, cush, &
sten, qvten, &
cmf, cmfdqr, cmfsl, cmflq, prec_cmf, &
qc, toplev, botlev, cldqc, rliq, &
uten, vten, cldfrac, qsat)
!CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
!
! SHALLOW CONVECTION SCHEME
! Described in McCaa, Bretherton, and Grenier:
! (submitted to MWR, December 2001)
! For info contact Jim McCaa: mccaa@u.washington.edu
!
! Inputs: pressure, temperature, heights, vert. vel.,tke,
! specific humidity, cloud water mixing ratio, horizontal winds
!
! Outputs: updated tendencies of specific humidity, temperature,
! cloud, ice, rain, and snow mixing ratios
!
!CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
use error_function
, only: erfc
implicit none
integer, intent(in) :: pcols
integer, intent(in) :: pver
integer, intent(in) :: ncol ! number of atmospheric columns
integer, intent(in) :: ncnst
real(r8), intent(in) :: ztodt ! 2 delta-t (seconds)
real(r8), intent(in) :: pmid(pcols,pver) ! Pressure at model mid-levels (pascals)
real(r8), intent(in) :: pdel(pcols,pver) ! delta-p
real(r8), intent(in) :: zmid(pcols,pver) ! Height at model mid-levels (m)
real(r8), intent(in) :: pblht(pcols) ! pbl height
real(r8), intent(in) :: tb(pcols,pver) ! temperature profile (K)
real(r8), intent(in) :: q(pcols,pver,ncnst) ! specific humidity (g/g))
real(r8), intent(in) :: pint(pcols,pver+1) ! Pressure at model interfaces (pascals)
real(r8), intent(in) :: zint(pcols,pver+1) ! height at model interfaces (m)
real(r8), intent(in) :: ub(pcols,pver)
real(r8), intent(in) :: vb(pcols,pver) ! wind profile (m/s)
real(r8), intent(in) :: tkeb(pcols,pver+1) ! turubulence kinetic energy (m2/s2) at mid-levels
real(r8), intent(inout) :: cush(pcols) ! convective scale height (m)
real(r8), intent(out) :: sten(pcols,pver) ! tendency of dry static energy
real(r8), intent(out) :: qvten(pcols,pver) ! tendency of specific humidity
real(r8), intent(out) :: cmf(pcols,pver+1)! cloud mass flux at level above layer (kg/m2/s)
real(r8), intent(out) :: cmfdqr(pcols,pver) ! dq/dt due to moist convective rainout
real(r8), intent(out) :: cmfsl(pcols,pver) ! Moist convection lw stat energy flux
real(r8), intent(out) :: cmflq(pcols,pver) ! Moist convection total water flux
real(r8), intent(out) :: prec_cmf(pcols) ! rain rate (kg/m2/s)
real(r8), intent(out) :: qc(pcols,pver) ! dq/dt due to rainout terms (same as cmfdqr)
real(r8), intent(out) :: toplev(pcols) ! top level of cloud
real(r8), intent(out) :: botlev(pcols) ! bottom level of cloud
real(r8), intent(out) :: cldqc(pcols,pver) ! in-cloud liquid water mixing ratio
real(r8), intent(out) :: rliq(pcols)
real(r8), intent(out) :: uten(pcols,pver)! tendency of wind
real(r8), intent(out) :: vten(pcols,pver)! tendency of wind
real(r8), intent(out) :: cldfrac(pcols,pver) ! convective cloud fraction
integer, external :: qsat
!
!...DEFINE LOCAL VARIABLES...
!
! VARIABLES WHICH DESCRIBE THE SOURCE LAYER
real(r8) thlsrc,qtsrc,usrc,vsrc
! VARIABLES WHICH DESCRIBE THE UPDRAFT AT ITS LCL
real(r8) zlcl,wrel
! VARIABLES WHICH DESCRIBE THE ENVIRONMENT AT THE UPDRAFT LCL
real(r8) &
ee2,ud2,wtw, &
cldhgt,dpsum,&
xs, & ! fraction of environmental air in a neutrally buoyant mixture
cin ! convective inhibition (m2/s2)
integer &
K, & ! release level (half-sigma level just below lcl)
KLCL, & ! first half-sigma level above lcl
ktoppbl, & ! top of the
i, &
let, & ! level where buoyancy becomes negative
ltop, & ! highest level with positive vertical velocity
nk, &
j,ibeg,iend,igauss,iteration
integer iout,ik1,jk1,ik2,jk2,ik3,jk3 ! for diagnostic column output
integer kinv ! inversion level
integer km1,kthvmin
integer krel ! level of release
integer kp1,kl,klm
! And starring... (in the order of their appearance)
real(r8) scaleh,rmfk1,rmfk2,nu, tkeavg, thvuinv,qct0bot, &
thj, qvj, qlj, qij, tscaleh,ssthc0b,ssqct0b, &
pinv, zinv, cinlcl, qj,rbuoy,rdrag,exnerlcl,exnerinv, &
cbmf, wexp, wcrit, sigmaw, ufrc,ssthc0a,ssqct0a,thc0bot, &
thvj, qrj, qsj, thcten, qctten, bigc,rle,rkm,rpen,thc0top, &
qct0top,thc0lcl,qct0lcl,thv0lcl,rho0lcl,thvubot,thvutop, &
rkfre,prel,thv0rel,thv0t1,porig,dporig,thv0j,rho0j,tj,rdqsdt, &
rbeta,ths0,aquad,bquad,cquad,xs1,xs2,excessu,excess0,xsat, &
bogbot,bogtop,delbog,expfac,rhos0j,ppen,ufrcbelow, &
rmaxfrac,rlwp,qconbelow,qtdef,drage,exnj,psorig
real*4 erfarg,erfval
real(r8) latvapocp ! latent heat of vaporization/cpair
real(r8) leff
integer :: kpbl2d(pcols) ! output for uwpbl scheme
!
real(r8) & ! VARIABLES WHICH DESCRIBE THE ENVIRONMENT
P0(pver), & ! environmental pressure
PS0(0:pver), & ! environmental pressure at full sigma levels
exner0(pver), & ! (p0/p00)**kapa
exners0(0:pver), & ! (ps0/p00)**kapa
DP(pver), & ! environmental layer pressure thickness
z0(pver), & ! environmental height at half-levels
ZS0(0:pver), & ! environmental height at sigma levels
DZ(pver), & ! layer thickness, meters
rh(pver), & ! relative humidity
thv0bot(pver), & ! environmental virtual potential temperature,bottom of layer
thv0top(pver), & ! environmental virtual potential temperature,top of layer
ssthc0(pver), & ! slope of environmental liquid potential temperature
Q0, & ! environmental water vapor mixing ratio
qct0(pver), & ! environmental Total water mixing ratio
thc0(pver), & ! environmental theta_c
ssQCT0(pver), & ! slope of environmental total water mixing ratio
u0(pver), & ! environmental zonal wind speed
v0(pver), & ! environmental meridional wind speed
u1(pver), & ! environmental zonal wind speed
v1(pver), & ! environmental meridional wind speed
dudp0(2:pver-1), & ! environmental zonal wind speed vertical gradient
dvdp0(2:pver-1) ! environmental meridional wind speed vertical gradient
!
real(r8) plcl(pcols) ! pressure of lifting condensation level (Pa)
real(r8) plfc(pcols) ! pressure of level of free convection (Pa)
real(r8) cino(pcols) ! cin (m2/s2)
real(r8) & ! VARIABLES WHICH DESCRIBE THE UPDRAFT
WU(0:pver), & ! updraft vertical velocity at top of layer
UMF(0:pver) , & ! updraft mass flux at top of layer
EMF(0:pver) , & ! entrainment mass flux at top of layer
THCU(0:pver), & ! updraft liquid potential temperature at top of layer
uu(0:pver), & ! updraft zonal wind speed
vu(0:pver), & ! updraft meridional wind speed
qctu(0:pver), & ! updraft total water at top of layer
thcflx(0:pver), & ! flux of thc due to convection
qctflx(0:pver), & ! flux of qct due to convection
umflx(0:pver), & ! flux of zonal momentum due to convection
vmflx(0:pver), & ! flux of meridional momentum due to convection
THVU(0:pver), & ! updraft virtual potential temperature at top of layer
THVUT(0:pver), & ! updraft virtual potential temperature at top of layer
REI(pver), & ! updraft mixing rate of with environment
fer(pver), & ! updraft fracional entrainment rate
fdr(pver), & ! updraft fracional detrainment rate
PPTR(pver), & ! updraft production rate of rain (kg/m2/s)
cwten(pver), & ! cloud water export tendency (kg/m2/ s)
qcto(pver), & ! detraining total water
thco(pver), & ! diagnostic thc
qo(pver), & ! detraining water vapor
qlo(pver), & ! detraining liquid water
qio(pver) ! detraining cloud ice
real(r8) :: es(1) ! saturation vapor pressure
real(r8) :: qs(1) ! saturation spec. humidity
real(r8) :: gam(1) ! (L/cp)*dqs/dT
integer :: status
!------pzhu-----
real(r8) a_qvten,a_sten,dissip,a_uvten,a_uvten1,ktoppbl_1
real(r8) temsrc,esrc,tdsrc,tlcl
real(r8) thlfs,qtfs,thvfs,yy1,xbuo0,rmfk3
real(r8) sfbuoflx,wstar,cstar,cbmf0
real(r8) tem0(pver),qc0(pver),qi0(pver)
real(r8) plcl_ini
real(r8) rain_ch
integer id_check, kfree, klimit
logical, parameter :: cin_lfc = .false. ! true when lfc is used to define CIN
!------end of pzhu
!
! For lateral entrainment
!pzhu---if igauss=1 then
parameter (cstar=0.385) ! for estimating w'2
parameter (rle = 0.10) ! for critical stopping distance for entrainment
parameter (rkm = 16.0) ! for fractional mixing rate
parameter (rpen = 5.0) ! for entrainment efficiency
parameter (rkfre = 0.05) ! vertical velocity variance as fraction of tke
parameter (rmaxfrac = 0.05) ! maximum allowable updraft fraction
parameter (rbuoy = 1.0) ! for nonhydrostatic pressure effects on updraft
parameter (rdrag = 1.0)
parameter (rain_ch = 1.0e-3) ! threshold for precipitation
! For momentum transfer
parameter (bigc = 0.7)
! Some options:
! Determine mass flux with cin/gaussian closure vs cin/tke closure
! 1 = cin/gaussian, 0 = cin/tke
!-----igauss=1: using tke to compute CIN.
! igauss=2: using W* to compute CIN.
! igauss=0: This is for the mapes-style closure
! These yield results similar to my new closure: (rmfk1=0.2821,rmfk2=1.333333)
parameter(igauss = 1)
parameter (rmfk1 = 0.3, rmfk2 = 5.0, rmfk3=3.0)
! parameter (thvlmj=0.01) ! thvl minimum jump across inversion
!
real(r8) p00
DATA p00/1.E5/
latvapocp=latvap/cpair
kl=pver
klm=kl-1
!
! Start the big i loop
!
DO 2112 I=1,ncol ! start of big i loop
cino(i)=0.
toplev(i)=real(pver+1, r8)
botlev(i)=0.
plcl(i)=0.
plfc(i) = 0.
rliq(i) = 0.
prec_cmf(i) = 0.
do k=1,pver
sten(i,k)=0.
qvten(i,k)=0.
uten(i,k)=0.
vten(i,k)=0.
cldfrac(i,k)=0.0
cldqc(i,k)=0.0
cmfsl(i,k) = 0
cmflq(i,k) = 0
cmfdqr(i,k) = 0
qc(i,k) = 0
cwten(k)= 0.0
pptr(k)= 0.0
thcflx(k)=0.
qctflx(k)=0.
umflx(k)=0.
vmflx(k)=0.
cmf(i,k) = 0.0
enddo
cmf(i,pver+1) = 0.0
! There are numerous exit points to the 2112 loop, generally to save time.
!
tscaleh = cush(i)
cush(i)=-1.
!
!_____1. Get the environmental conditions
! Model layers are numbered from bottom up!
!
zs0(0) = 0.0
ps0(0) = pint(i,pver+1)
exners0(0)=(ps0(0)/p00) ** cappa
DO K=1,pver
nk=pver-k+1
p0(k)=pmid(i,nk)
ps0(k) = pint(i,nk)
zs0(k) = zint(i,nk)
dp(k)=PS0(K-1)-PS0(K)
z0(k)=zmid(i,nk)
dz(k) = zs0(k)-zs0(k-1)
qc0(k) = q(i,nk,2)
qi0(k) = q(i,nk,3)
qct0(k) = q(i,nk,1)+q(i,nk,2)+q(i,nk,3)
u0(k)=ub(i,nk)
v0(k)=vb(i,nk)
nu = max(min((268. - tb(i,nk) )/20.,1._r8),0._r8)
leff = (1-nu)*latvap + nu*latsub
exner0(k)=(p0(k)/p00) ** cappa
exners0(k)=(ps0(k)/p00) ** cappa
thc0(k)=(tb(i,nk) - leff*qc0(k)/cpair)/exner0(k) ! theta_l for enviro.
tem0(k)=tb(i,nk)
status = qsat(tb(i,nk),ps0(k),es(1),qs(1),gam(1),1)
rh(k)=qct0(k) / qs(1)
umf(k)=0.
emf(k)=0.
END DO
!--get index of PBL height!
do k = kl-1,2,-1
if ( (pblht(i)+1.-zs0(k))*(pblht(i)+1.-zs0(k+1)) .lt. 0. ) goto 106
end do
106 ktoppbl=k
ssthc0b = (thc0(2)-thc0(1))/(p0(2)-p0(1))
ssqct0b = (qct0(2)-qct0(1))/(p0(2)-p0(1))
DO K=2,KL
ssthc0a = (thc0(k)-thc0(k-1))/(p0(k)-p0(k-1))
if(ssthc0a.gt.0)then
ssthc0(k-1) = max(0._r8,min(ssthc0a,ssthc0b))
else
ssthc0(k-1) = min(0._r8,max(ssthc0a,ssthc0b))
endif
ssthc0b = ssthc0a
ssqct0a = (qct0(k)-qct0(k-1))/(p0(k)-p0(k-1))
if(ssqct0a.gt.0)then
ssqct0(k-1) = max(0._r8,min(ssqct0a,ssqct0b))
else
ssqct0(k-1) = min(0._r8,max(ssqct0a,ssqct0b))
endif
ssqct0b = ssqct0a
enddo
! Wind shear
do k = 2,kl-1
dudp0(k) = (u0(k+1)-u0(k-1))/(p0(k+1)-p0(k-1))
dvdp0(k) = (v0(k+1)-v0(k-1))/(p0(k+1)-p0(k-1))
END DO
ssthc0(kl)=ssthc0(kl-1)
ssqct0(kl)=ssqct0(kl-1)
do k = 1,kl
thc0bot = thc0(k)+ssthc0(k)*(ps0(k-1)-p0(k))
qct0bot = qct0(k)+ ssqct0(k)*(ps0(k-1)-p0(k))
call conden
(ps0(k-1),thc0bot,qct0bot,thj,qvj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thv0bot(k)= thj * (1.+zvir*qvj-qlj-qij)
thc0top = thc0(k)+ssthc0(k)*(ps0(k)-p0(k))
qct0top = qct0(k)+ ssqct0(k)*(ps0(k)-p0(k))
call conden
(ps0(k),thc0top,qct0top,thj,qvj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thv0top(k)= thj * (1.+zvir*qvj-qlj-qij)
enddo
!
!_____2. Determine precise height of the inversion. The inversion is considered
! to be the top of PBL that is defined at one interface level higher
! than the interface level with Ri<0. see BG PBL scheme for detail.
kinv = ktoppbl+1
pinv=ps0(kinv-1)
zinv=zs0(kinv-1)
!------calculate the environmental virtual potential temperature at INV
call conden
(pinv,thc0(kinv)+ssthc0(kinv)*(ps0(kinv-1)-p0(kinv)) &
,qct0(kinv)+ssqct0(kinv)*(ps0(kinv-1)-p0(kinv)),thj,qvj, &
qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thvuinv = thj * (1.+zvir*qvj-qlj-qij)
!
!_____3. Let's get some source air, and find its LCL
!
usrc = u0(ktoppbl)
vsrc = v0(ktoppbl)
!-------source air is simply set to be the first layer air, which is different
! from the Jim's code in MM5. Numerical tests indicate that such a
! difinition will produce a much stable result, i.e., results are
! insensitive to the model time step interval.
kthvmin = 1
do k=1,ktoppbl
if(thv0top(k).lt.thv0top(kthvmin))kthvmin = k
enddo
qtsrc=qct0(kthvmin)
thlsrc=thc0(kthvmin)
esrc=qtsrc*ps0(kthvmin)/100./(qtsrc+epsilo) ! water vapor pressure
tdsrc=tmelt/(1-tmelt*rgasv*log(esrc/6.11)/latvap) !dew-point of source air
temsrc=thlsrc*(ps0(kthvmin)/p00)**cappa ! temperature of source air
zlcl=123.5*(temsrc-tdsrc)+zs0(kthvmin) ! from sea-level
tlcl=temsrc-0.0098*(zlcl-zs0(kthvmin))
plcl(i)=ps0(kthvmin)*(tlcl/temsrc)**(1./cappa)
plcl_ini=plcl(i)
! if(plcl(i).ge.ps0(kinv)) then
! plcl(i)=ps0(kinv)
! endif
do k=1,kl
klcl=k !KLCL is the layer containing the lcl, i.e., ps0(klcl)<=plcl(i)
if(ps0(K).le.plcl(i))GOTO 35
END DO
GOTO 2112
35 klcl=max(klcl,2)
do k=klcl,kl
call conden
(ps0(k),thlsrc,qtsrc,thj,qvj,qlj,qij,id_check,qsat)
thv0lcl = thj * (1.+zvir*qvj-qlj-qij)
if(thv0lcl.ge.thv0bot(k)) then
go to 115
endif
enddo
go to 2112 ! no free convection level is found
115 kfree=k
if(zs0(kfree).gt.3000.) go to 2112 ! convection is not related to PBL
do k=kfree,kl
call conden
(ps0(k),thlsrc,qtsrc,thj,qvj,qlj,qij,id_check,qsat)
thv0lcl = thj * (1.+zvir*qvj-qlj-qij)
if(thv0lcl.lt.thv0bot(k)) then
go to 116
endif
enddo
go to 75
116 klimit=k
if(z0(klimit).lt.1500.) go to 2112 ! convective layer is too shallow
! and must be associated with
! stratus clouds
75 continue
!-----get environmental properties at KLCL
thc0lcl = thc0(klcl)+ssthc0(klcl)*(plcl(i)-p0(klcl))
qct0lcl = qct0(klcl)+ssqct0(klcl)*(plcl(i)-p0(klcl))
call conden
(plcl(i),thc0lcl,qct0lcl,thj,qvj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thv0lcl = thj * (1.+zvir*qvj-qlj-qij)
rho0lcl = plcl(i)/(rair*thv0lcl*(plcl(i)/p00)**cappa)
!_____4. Determine the convective inhibition (CIN)
! Initialize CIN
CIN = 0.
cinlcl = 0.
plfc(i) = 0.
if( cin_lfc ) then ! define CIN based on LFC
do k = kinv,kl-1
if(k.eq.klcl-1) then ! Klcl-1 < layer < klcl
call conden
(ps0(k),thlsrc,qtsrc,thj,qvj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thvubot=thj * (1.+zvir*qvj-qlj-qij)
call conden
(plcl(i),thlsrc,qtsrc,thj,qvj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thvutop=thj * (1.+zvir*qvj-qlj-qij)
call getbuoy
(ps0(k),thv0top(k),plcl(i),thv0lcl, &
thvubot,thvutop,plfc(i),cin)
cinlcl = cin
thvubot=thvutop
call conden
(ps0(k+1),thlsrc,qtsrc,thj,qvj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thvutop= thj * (1.+zvir*qvj-qlj-qij)
call getbuoy
(plcl(i),thv0lcl,ps0(k+1),thv0top(k+1), &
thvubot,thvutop,plfc(i),cin)
if(plfc(i).gt.0.)goto 668
else
call conden
(ps0(k),thlsrc,qtsrc,thj,qvj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thvubot=thj* (1.+zvir*qvj-qlj-qij)
call conden
(ps0(k+1),thlsrc,qtsrc,thj,qvj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thvutop=thj* (1.+zvir*qvj-qlj-qij)
call getbuoy
(ps0(k),thv0top(k),ps0(k+1),thv0top(k+1), &
thvubot,thvutop,plfc(i),cin)
if(plfc(i).gt.0.)goto 668
endif
enddo
! write(iulog,*) 'No LFC for undilute parcel ascent. Bailing.'
! go to 2112
cin=100.
else
do k=kinv,klcl-1
if(k.eq.(klcl-1)) then ! Klcl-1 < layer < klcl
call conden
(ps0(k),thlsrc,qtsrc,thj,qvj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thvubot=thj * (1.+zvir*qvj-qlj-qij)
call conden
(plcl(i),thlsrc,qtsrc,thj,qvj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thvutop=thj * (1.+zvir*qvj-qlj-qij)
! call getbuoy(ps0(k),thv0top(k),plcl(i),thv0lcl, &
call getbuoy
(ps0(k),thv0bot(k+1),plcl(i),thv0lcl, &
thvubot,thvutop,plfc(i),cin)
cinlcl = cin
else
call conden
(ps0(k),thlsrc,qtsrc,thj,qvj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thvubot=thj* (1.+zvir*qvj-qlj-qij)
call conden
(ps0(k+1),thlsrc,qtsrc,thj,qvj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thvutop=thj* (1.+zvir*qvj-qlj-qij)
! call getbuoy(ps0(k),thv0top(k),ps0(k+1),thv0top(k+1), &
call getbuoy
(ps0(k),thv0bot(k+1),ps0(k+1),thv0top(k+1), &
thvubot,thvutop,plfc(i),cin)
endif
enddo
endif ! CIN has been estimated
668 continue
!_____5. Calculate updraft cloud base mass flux
dpsum=0.
tkeavg = 0.
do K=1,ktoppbl
dpsum=dpsum+dp(k)
tkeavg = tkeavg + dp(k)*tkeb(i,pver-k+1)
enddo
tkeavg = tkeavg/dpsum
tkeavg = max(0.1_r8,tkeavg)
if(igauss.eq.0)then
! Use cin and pbl tke
cbmf = rmfk1*rho0lcl*sqrt(tkeavg)*exp(-rmfk2*cin/tkeavg)
! Updraft vertical velocity at release height depends on tke
wexp = rmfk3*sqrt(tkeavg)
elseif(igauss.eq.1)then
! Use cin and gaussian distribution of w
wcrit = sqrt(2 * cin * rbuoy)
sigmaw = sqrt(rkfre*tkeavg)
cbmf = rho0lcl * sigmaw / 2.5066 * exp(-0.5*((wcrit/sigmaw)**2))
! Diagnose updraft fraction ! sqrt(2.) = 1.4142
erfarg=wcrit / (1.4142 * sigmaw)
if(erfarg.lt.20.)then
erfval=erfc(erfarg)
ufrc = min(rmaxfrac,0.5_r8*erfval)
else
ufrc = 0.
endif
if(ufrc.gt.0.001)then
! Diagnose expected value of cloud base vertical velocity
wexp = cbmf / rho0lcl / ufrc
else
goto 2112
endif
endif
!
!_____6. Determine release height and the vertical velocity at the LCL
! Must specify: krel, prel, thv0rel, thv0t1, thvurel, wtw
if(plcl(i).gt.pinv)then
krel=kinv
prel=pinv
thv0rel = thvuinv
thv0t1 = thv0top(kinv)
else
krel=klcl
prel=plcl(i)
thv0rel = thv0lcl
thv0t1 = thv0top(krel)
endif
wexp=min(wexp,50._r8)
wtw = wexp * wexp - 2 * cin * rbuoy
!----------------------------------------------
if(wtw.le.0.)then
goto 2112
endif
wrel = sqrt(wtw)
! For these (krel-1) represents the bottom of the updraft
psorig = ps0(krel-1)
ps0(krel-1) = prel
thcu(krel-1)= thlsrc
qctu(krel-1)= qtsrc
! thvu(krel-1)= thvuinv !theta_v is not conserved.
call conden
(ps0(krel-1),thlsrc,qtsrc,thj,qvj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thvu(krel-1)=thj*(1.+zvir*qvj-qlj-qij)
uu(krel-1) = usrc
vu(krel-1) = vsrc
umf(krel-1) = cbmf
wu(krel-1) = wrel
! And for these (krel) represents the first partial updraft layer
! The first ones are special because they must be restored later
porig = p0(krel)
p0(krel) = 0.5*(prel+ps0(krel))
dporig = dp(krel)
dp(krel) = prel - ps0(krel)
!
thv0bot(krel) = thv0rel
thv0top(krel) = thv0t1
if(krel.eq.kinv)then
thc0(krel) = thc0(kinv)
qct0(krel) = qct0(kinv)
else
thc0(krel) = thc0(krel)+ssthc0(krel)*(p0(krel)-porig)
qct0(krel) = qct0(krel)+ssqct0(krel)*(p0(krel)-porig)
endif
!*******************************************************************
! *
!_____7. Compute updraft properties above the LCL
! *
!*******************************************************************
!
let=krel
scaleh = tscaleh
if(tscaleh.lt.0.0)scaleh = 1000.
DO 60 k=krel,klm
km1=k-1
!-----A. Entrainment and Detrainment
! first, to determine fraction (xsat) of mixture that is to be detrained out
! of clouds, i.e., the mixture with negative buoyancy. We consider a thin
! layer between two interfaces, so using mid-point value to represent the
! mean value of the layer. The properties of updraft at midpoint is assumed
! to be undiluted from the lower interface.
!-----calculate fraction of mixture that is just saturated
status = qsat(thcu(km1)*exner0(k),p0(k),es(1),qs(1),gam(1),1)
excessu = qctu(km1) - qs(1)
excessu = max(excessu,0._r8)
status = qsat(thc0(k)*exner0(k),p0(k),es(1),qs(1),gam(1),1)
excess0 = qct0(k) - qs(1)
if(excessu*excess0.le.0)then
xsat = -excessu/(excess0-excessu)
else
xsat = 1.0
endif
thlfs=(1.-xsat)*thcu(km1)+xsat*thc0(k)
qtfs=(1.-xsat)*qctu(km1)+xsat*qct0(k)
thvfs=thlfs*(1+zvir*qtfs)
call conden
(p0(k),thcu(km1),qctu(km1),thj,qj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thvj=thj*(1.+zvir*qj-qlj-qij) ! theta_v of updraft
call conden
(p0(k),thc0(k),qct0(k),thj,qj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thv0j=thj*(1.+zvir*qj-qlj-qij) ! theta_v of environment
rho0j = p0(k)/(rair*thv0j*(p0(k)/p00)**cappa)
!-----calculate fraction of mixture with zero buoyancy
if(thvfs.ge.thv0j) then
xbuo0=xsat
elseif(thvj.le.thv0j) then
xbuo0=0.
else
! xbuo0=xsat*(thv0j-thvfs)/(thvj-thvfs)
xbuo0=xsat*(thvj-thv0j)/(thvj-thvfs)
endif
!-----calculate fraction of mixture with negative buoyancy but can
! penetrate a critical distance lc=rle*scaleh
if(thvfs.ge.thv0j.or.xsat.le.0.05) then
xs=xsat ! mixture has to be saturated
else
aquad = wu(km1)**2
bquad=-(2*wu(km1)**2+2*rbuoy*gravit*rle*scaleh*(thvj-thvfs)/thv0j/xsat)
cquad=wu(km1)**2-2*rbuoy*gravit*rle*scaleh*(1-thvj/thv0j)
call roots
(aquad,bquad,cquad,xs1,xs2)
xs=min(xs1,xs2)
endif
xs=min(xs,xsat)
xs=max(xbuo0,xs)
xs=min(1._r8,xs)
ee2 = xs**2
ud2 = 1 - 2*xs + xs**2
rei(k) = rkm/scaleh/gravit/rho0j
fer(k)=rei(k)*ee2
fdr(k)=rei(k)*ud2
!-----B. Calculate the mass flux
umf(k)=umf(km1)*exp(dp(k)*(fer(k)-fdr(k)))
emf(k)=0.0
! write(iulog,'(7e14.6)') xs,fer(k),fdr(k),umf(k),xsat,excess0,excessu
!-----C. Now thermodynamics for the dilute plume
thcu(k)=thc0(k)-(thc0(k)-thcu(km1))*exp(-fer(k)*dp(k))
qctu(k)=qct0(k)-(qct0(k)-qctu(km1))*exp(-fer(k)*dp(k))
if(fer(k)*dp(k).lt.1.e-4)then
uu(k)=uu(km1) - dudp0(k)*dp(k)
vu(k)=vu(km1) - dvdp0(k)*dp(k)
else
uu(k)=u0(k)-bigc*dudp0(k)/fer(k)-exp(-fer(k)*dp(k))* &
(u0(k) - bigc*dudp0(k)/fer(k) - uu(km1))
vu(k)=v0(k)-bigc*dvdp0(k)/fer(k)-exp(-fer(k)*dp(k))* &
(v0(k) - bigc*dvdp0(k)/fer(k) - vu(km1))
endif
! Precip at the flux level
call conden
(ps0(k),thcu(k),qctu(k),thj,qj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
thvu(k) = thj * (1.+zvir*qj-qlj-qij)
rho0j = p0(k)/(rair*thv0j*(p0(k)/p00)**cappa)
cwten(k) = min((qlj+qij),0.5*q(i,pver+1-k,1))/ztodt
cldqc(i,pver-k+1)=cwten(k)*ztodt
pptr(k) = min(rain_ch*umf(k)*(qlj+qij+qc0(k)+qi0(k))/rho0j,cwten(k))
!
!-----D. Calculate vertical velocity
!
bogbot = (thvu(km1)/thv0bot(k) - 1.)
bogbot = bogbot*rbuoy
bogtop = (thvu(k)/thv0top(k) - 1.)
bogtop = bogtop*rbuoy
if(bogbot.gt.0.and.bogtop.gt.0)let = k
! if(bogbot.gt.0)let = k
delbog = bogtop - bogbot
drage = fer(k) * ( 1. + rdrag )
expfac = exp(-2.*drage*dp(k)) ! dp(k) = - delta p
if(drage*dp(k).gt.1.e-3)then
wtw = wtw*expfac + (delbog + (1.-expfac) * &
(bogbot+delbog/(-2.*drage*dp(k))))/(rho0j*drage)
else
wtw = wtw + dp(k) * (bogbot+bogtop)/rho0j
endif
if(wtw.le.0.) goto 65
wu(k) = sqrt(wtw)
if(wu(k).gt.100.)then
write(iulog,*) 'big wu',bogbot,bogtop,expfac,fer(k)
stop
endif
rhos0j = ps0(k) /(rair*0.5*(thv0bot(k+1)+thv0top(k))*exners0(k))
ufrc = umf(k)/(rhos0j*wu(k))
if(ufrc.gt.rmaxfrac)then
ufrc = rmaxfrac
fdr(k)= fer(k) -log(rmaxfrac*rhos0j*wu(k)/umf(km1))/dp(k)
umf(k)= rmaxfrac * rhos0j * wu(k)
endif
60 end do
! End of Updraft Loop
!... ltop is the first level with negative vertical velocity at top
65 ltop = k
umf(ltop)=0.0
cldhgt=z0(ltop)-zlcl
! convection too deep
if(cldhgt.ge.4.e3)then
goto 2112 ! Cloud too deep
endif
! Calculate convective scale height
cush(i)=z0(ltop)
! Calculate penetrative entrainment
emf(ltop)=0.0
do k=ltop-1,let,-1
qcto(k+1)=qct0(k)
! qo(k+1)=qcto(k+1)
! qlo(k+1)=0.0
! qio(k+1)=0.0
rhos0j = ps0(k) /(rair*0.5*(thv0bot(k+1)+thv0top(k))*exners0(k))
if(k.eq.ltop-1)then
! 7. Calculate ppen
bogbot = (thvu(k)/thv0bot(ltop) - 1.)
bogbot = bogbot*rbuoy
bogtop = (thvu(ltop)/thv0top(ltop) - 1.)
bogtop = bogtop*rbuoy
aquad = (bogtop - bogbot) / (ps0(ltop)-ps0(k))
bquad = 2*bogbot
cquad = -wu(k)*ps0(k)/(rair*thv0bot(ltop)*exners0(k))
call roots
(aquad,bquad,cquad,xs1,xs2)
if(xs1.le.0..and.xs2.le.0.)then
ppen = max(xs1,xs2)
else
ppen = min(xs1,xs2)
endif
ppen = min(0._r8,max(-dp(k+1),ppen))
if(xs1.eq.-9.99e33.or.xs2.eq.-9.99e33)ppen=0.
!_____8. Calculate returning mass flux
emf(k)= max(umf(k)*ppen*rei(ltop)*rpen,-0.1*rhos0j)
thcu(k)=thc0(ltop)+ssthc0(ltop)*(ps0(k)-p0(ltop))
qctu(k)=qct0(ltop)+ssqct0(ltop)*(ps0(k)-p0(ltop))
else
emf(k)=max(emf(k+1)-umf(k)*dp(k+1)*rei(k+1)*rpen,-0.1*rhos0j)
thcu(k)=(thcu(k+1)*emf(k+1)+thc0(k+1)*(emf(k)-emf(k+1)))/emf(k)
qctu(k)=(qctu(k+1)*emf(k+1)+qct0(k+1)*(emf(k)-emf(k+1)))/emf(k)
endif
! umf(k)=0.0
enddo
! Restore special values
ps0(krel-1) = psorig
p0(krel) = porig
dp(krel) = dporig
!*****************************************************************
! Done describing the updraft
!*****************************************************************
!_____9. Output to model
! Calculate Fluxes of heat, moisture, momentum
do k=1,pver
nk = pver+1-k
cmf(i,nk) = umf(k)
thcflx(k)=0.
qctflx(k)=0.
umflx(k)=0.
vmflx(k)=0.
enddo
qctflx(0)=0.0
thcflx(0)=0.0
umflx(0)=0.0
vmflx(0)=0.0
dpsum = 0.0
do k = 1, krel-1
dpsum = dpsum + dp(k)
enddo
qtdef = max(0._r8,umf(krel)*(qctu(krel) - qct0(krel)))
yy1 = min(0._r8,umf(krel)*(thcu(krel) - thc0(krel)))
do k=2,krel-1
! thcflx(k)=0.0
! qctflx(k)=0.0
thcflx(k)=thcflx(k-1) + yy1*dp(k)/dpsum
qctflx(k)=qctflx(k-1) + qtdef*dp(k)/dpsum
umflx(k)=0.0
vmflx(k)=0.0
! pptr(k)=0.0
! cwten(k)=0.0
enddo
! do k = krel,ltop-1
do k = krel,ltop
kp1 = k+1
thcflx(k)= umf(k) *(thcu(k)-(thc0(kp1)+ssthc0(kp1)*(ps0(k)-p0(kp1)))) + &
emf(k) * (thcu(k)-(thc0(k)+ssthc0(k)*(ps0(k)-p0(k))))
qctflx(k)= umf(k) *(qctu(k)-(qct0(kp1)+ssqct0(kp1)*(ps0(k)-p0(kp1)))) + &
emf(k) * (qctu(k)-(qct0(k)+ssqct0(k)*(ps0(k)-p0(k))))
umflx(k) =umf(k) * ( uu(k)- u0(kp1)) + emf(k) * ( u0(kp1)- u0(k))
vmflx(k) =umf(k) * ( vu(k)- v0(kp1)) + emf(k) * ( v0(kp1)- v0(k))
!----using top-interface
! thc0top=thc0(k)+ssthc0(k)*(ps0(k)-p0(k))
! qct0top=qct0(k)+ssqct0(k)*(ps0(k)-p0(k))
! thcflx(k)= umf(k) *(thcu(k)-thc0top)
! qctflx(k)= umf(k) *(qctu(k)-qct0top)
!----using bot-interface
! thc0bot=thc0(kp1)+ssthc0(kp1)*(ps0(k)-p0(kp1))
! qct0bot=qct0(kp1)+ssqct0(kp1)*(ps0(k)-p0(kp1))
! thcflx(k)= umf(k) *(thcu(k)-thc0bot)
! qctflx(k)= umf(k) *(qctu(k)-qct0bot)
! umflx(k) =umf(k) * (uu(k)-u0(kp1))
! vmflx(k) =umf(k) * (vu(k)-v0(kp1))
enddo
thcflx(ltop+1) = 0.0
qctflx(ltop+1) = 0.0
umflx(ltop+1) = 0.0
vmflx(ltop+1) = 0.0
!
! Calculate model tendencies
do k = ltop+1,1,-1
km1 = k-1
qctten=(qctflx(km1)-qctflx(k))*gravit/dp(k)
nk = pver+1-k
if((q(i,nk,1)+(qctten-cwten(k))*ztodt).lt.1.e-12) then
go to 2112
endif
enddo
a_qvten=0.
a_sten=0.
do k = pver,1,-1
km1 = k-1
nk = pver+1-k
uten(i,nk) = (umflx(km1)-umflx(k))*gravit/dp(k)
vten(i,nk) = (vmflx(km1)-vmflx(k))*gravit/dp(k)
u1(k)=u0(k)+uten(i,nk)*ztodt
v1(k)=v0(k)+vten(i,nk)*ztodt
enddo
! do k=pver,2,-1
do k=ltop+1,2,-1
km1 = k-1
nk = pver+1-k
dissip=(umflx(km1)*(u1(km1)-u1(k)+u0(km1)-u0(k))+ &
vmflx(km1)*(v1(km1)-v1(k)+v0(km1)-v0(k)))*0.5*ztodt
! dissip=(umflx(km1)-umflx(k))*(u1(k)+u0(k))+ &
! (vmflx(km1)-vmflx(k))*(v1(k)+v0(k))
! dissip=dissip*0.5*ztodt
thcten = ( thcflx(km1) - thcflx(k) ) *gravit/dp(k)
qctten = ( qctflx(km1) - qctflx(k) ) *gravit/dp(k)
qvten(i,nk) = qctten-cwten(k)
qc(i,nk) =cwten(k)-pptr(k)
cmfdqr(i,nk) = pptr(k)
sten(i,nk) = cpair*thcten + latvap*cwten(k) + dissip*gravit/dp(k)/ztodt
!
cmfsl(i,nk) = cpair*thcflx(k)
cmflq(i,nk) = qctflx(k)*latvap ! total water flux
! precipitation at bottom of layer
enddo
! Diagnostic Outputs, and convective cloud fields for radiation scheme
rhos0j = ps0(krel-1) / (rair*0.5*(thv0bot(krel)+thv0top(krel-1))* &
exners0(krel-1))
ufrcbelow = cbmf/(rhos0j*wu(krel-1))
ufrcbelow = cbmf
qconbelow = 0.
do k = krel, ltop-1
nk = pver - k + 1
rhos0j = ps0(k) / (rair*0.5*(thv0bot(k+1)+thv0top(k))*exners0(k))
ufrc = umf(k)/(rhos0j*wu(k))
call conden
(ps0(k),thcu(k),qctu(k),thj,qj,qlj,qij,id_check,qsat)
if(id_check.eq.1) go to 2112
cldfrac(i,nk) = 0.5*(ufrcbelow + ufrc) ! 2 * 0.5
ufrcbelow = ufrc
qconbelow = qlj+qij
enddo
toplev(i) = pver-ltop+1
botlev(i) = pver-krel+1
do k = 1, pver
rliq(i) = rliq(i) + qc(i,k)*pdel(i,k)/gravit
prec_cmf(i) = prec_cmf(i) + cmfdqr(i,k)*pdel(i,k)/gravit
end do
rliq(i) = rliq(i) /1000.
prec_cmf(i) = prec_cmf(i) /1000.
2112 end do
return
END subroutine compute_uw_conv
subroutine conden(p,thc,qt,th,qv,ql,qi,id_check,qsat) 69,6
implicit none
integer, external :: qsat
real(r8), intent(in) :: p
real(r8), intent(in) :: thc
real(r8), intent(in) :: qt
real(r8), intent(out) :: th
real(r8), intent(out) :: qv
real(r8), intent(out) :: ql
real(r8), intent(out) :: qi
integer, intent(out) :: id_check
real(r8) :: p00
real(r8) :: tc
real(r8) :: exn
real(r8) :: leff,nu,qc,temps,tc1
integer :: iteration
real(r8) :: es(1) ! saturation vapor pressure
real(r8) :: qs(1) ! saturation spec. humidity
real(r8) :: gam(1) ! (L/cp)*dqs/dT
integer :: status
DATA p00/1.E5/
exn = (p/p00)**cappa
tc = thc * exn
nu = max(min((268-tc)/20.,1._r8),0._r8)
leff = (1-nu)*latvap + nu*latsub
temps = tc
status = qsat(temps,p,es(1),qs(1),gam(1),1)
if(qs(1).gt.qt) then
id_check=0
else
do iteration = 1,20
temps = temps + ((tc-temps)*cpair/leff + (qt -qs(1)))/ &
(cpair/leff+epsilo*leff*qs(1)/rair/temps/temps)
! temps = temps + ((tc-temps)*cpair/leff + (qt -qs(1)))/ &
! (cpair/leff+1.5*leff*qs(1)/rgasv/temps/temps)
status = qsat(temps,p,es(1),qs(1),gam(1),1)
enddo
tc1=temps-leff/cpair*(qt-qs(1))
if(abs(tc1-tc).lt.1.0) then
id_check=0
else
id_check=1
endif
endif
qc = max(qt-qs(1),0._r8)
qv = qt - qc
ql = (1-nu)*qc
qi = nu*qc
th = temps/exn
return
end subroutine conden
subroutine getbuoy(pbot,thv0bot,ptop,thv0top,thvubot,thvutop,plfc,cin) 11,12
implicit none
real(r8) pbot,thv0bot,ptop,thv0top,thvubot,thvutop,plfc,cin,frc
real(r8) p00
DATA p00/1.E5/
if(thvubot.gt.thv0bot.and.thvutop.gt.thv0top)then
plfc = pbot
return
elseif(thvubot.le.thv0bot.and.thvutop.le.thv0top)then ! got cin
cin = cin - ((thvubot/thv0bot-1.)+(thvutop/thv0top-1.)) *(pbot-ptop)/ &
(pbot/(rair*thv0bot*(pbot/p00)**cappa) + ptop/(rair*thv0top*(ptop/p00)**cappa))
elseif(thvutop.le.thv0top.and.thvubot.gt.thv0bot)then ! fractional cin
frc = (thvutop/thv0top-1.) /((thvutop/thv0top-1.)-(thvubot/thv0bot-1.))
cin = cin - (thvutop/thv0top-1.) * ( (ptop + frc * (pbot-ptop)) - ptop)/ &
(pbot/(rair*thv0bot*(pbot/p00)**cappa) + ptop/(rair*thv0top*(ptop/p00)**cappa))
else ! last time through
frc = (thvubot/thv0bot-1.) /((thvubot/thv0bot-1.) - (thvutop/thv0top-1.))
plfc = pbot - frc * (pbot-ptop)
cin = cin - (thvubot/thv0bot-1.) * (pbot-plfc)/ &
(pbot/(rair*thv0bot*(pbot/p00)**cappa) + ptop/(rair*thv0top*(ptop/p00)**cappa))
endif
if(cin.lt.0)stop
return
end subroutine getbuoy
subroutine roots(a,b,c,r1,r2) 9
implicit none
real(r8) a,b,c,r1,r2,q
if(a.eq.0)then ! form b*x + c = 0
if(b.eq.0)then ! failure: c = 0
r1 = -9.99e33
else ! b*x + c = 0
r1 = -c / b
endif
r2 = r1
else
if(b.eq.0.)then ! form a*x**2 + c = 0
if(a*c.gt.0.)then ! failure: x**2 = -c/a < 0
r1 = -9.99e33
else ! x**2 = -c/a
r1 = sqrt(-c/a)
endif
r2 = -r1
else
if((b**2 - 4*a*c).lt.0.)then ! failure, no real(r8) roots
r1 = -9.99e33
r2 = -r1
else
q = - 0.5 * ( b + sign(1._r8,b) * sqrt(b**2 - 4*a*c) )
r1 = q/a
r2 = c/q
endif
endif
endif
return
end subroutine roots
end module uw_conv