source: lmdz_wrf/WRFV3/phys/module_bl_temf.F @ 1

Last change on this file since 1 was 1, checked in by lfita, 10 years ago
  • -- --- Opening of the WRF+LMDZ coupling repository --- -- -

WRF: version v3.3
LMDZ: version v1818

More details in:

File size: 64.8 KB
Line 
1!wrf:model_layer:physics
2!
3!
4!
5!
6module module_bl_temf
7contains
8!
9!-------------------------------------------------------------------
10!
11   subroutine temfpbl(u3d,v3d,th3d,t3d,qv3d,qc3d,qi3d,p3d,p3di,pi3d,rho,      &
12                  rublten,rvblten,rthblten,                                    &
13                  rqvblten,rqcblten,rqiblten,flag_qi,                          &
14                  g,cp,rcp,r_d,r_v,cpv,                                   &
15                  z,xlv,psfc,                                          &
16                  mut,p_top,                                           &
17                  znt,ht,ust,zol,hol,hpbl,psim,psih,                         &
18                  xland,hfx,qfx,tsk,qsfc,gz1oz0,wspd,br,                    &
19                  dt,dtmin,kpbl2d,                                             &
20                  svp1,svp2,svp3,svpt0,ep1,ep2,karman,eomeg,stbolt,            &
21                  kh_temf,km_temf,                                            &
22                  u10,v10,t2,                                                  &
23                  te_temf,shf_temf,qf_temf,uw_temf,vw_temf,                    &
24                  wupd_temf,mf_temf,thup_temf,qtup_temf,qlup_temf,            &
25                  cf3d_temf,cfm_temf,                                         &
26                  hd_temf,lcl_temf,hct_temf,                            &
27                  flhc,flqc,exch_temf,                                &
28                  fCor,                                                        &
29                  ids,ide, jds,jde, kds,kde,                                   &
30                  ims,ime, jms,jme, kms,kme,                                   &
31                  its,ite, jts,jte, kts,kte                                   &
32                  )
33!-------------------------------------------------------------------
34      implicit none
35!-------------------------------------------------------------------
36! New variables for TEMF
37!-- te_temf     Total energy from this scheme
38!-- shf_temf    Sensible heat flux profile from this scheme (kinematic)
39!-- qf_temf     Moisture flux profile from this scheme (kinematic)
40!-- uw_temf     U momentum flux component from this scheme
41!-- vw_temf     V momentum flux component from this scheme
42!-- kh_temf     Exchange coefficient for heat (3D)
43!-- km_temf     Exchange coefficient for momentum (3D)
44!-- wupd_temf     Updraft velocity from TEMF BL scheme
45!-- mf_temf       Mass flux from TEMF BL scheme
46!-- thup_temf   Updraft thetal from TEMF BL scheme
47!-- qtup_temf   Updraft qt from TEMF BL scheme
48!-- qlup_temf   Updraft ql from TEMF BL scheme
49!-- cf3d_temf   3D cloud fraction from TEMF BL scheme
50!-- cfm_temf    Column cloud fraction from TEMF BL scheme
51!-- exch_temf   Surface exchange coefficient (as for moisture) from TEMF surface layer scheme
52!-- flhc        Surface exchange coefficient for heat (needed by surface scheme)
53!-- flqc        Surface exchange coefficient for moisture (including moisture availablity)
54!-- fCor        Coriolis parameter (from grid%f)
55!
56!-- u3d         3d u-velocity interpolated to theta points (m/s)
57!-- v3d         3d v-velocity interpolated to theta points (m/s)
58!-- th3d               3d potential temperature (k)
59!-- t3d         temperature (k)
60!-- qv3d        3d water vapor mixing ratio (kg/kg)
61!-- qc3d        3d cloud mixing ratio (kg/kg)
62!-- qi3d        3d ice mixing ratio (kg/kg)
63!               (note: if P_QI<PARAM_FIRST_SCALAR this should be zero filled)
64!-- p3d         3d pressure (pa)
65!-- p3di        3d pressure (pa) at interface level
66!-- pi3d        3d exner function (dimensionless)
67!-- rho         3d dry air density (kg/m^3)
68!-- rublten     u tendency due to
69!               pbl parameterization (m/s/s)
70!-- rvblten     v tendency due to
71!               pbl parameterization (m/s/s)
72!-- rthblten    theta tendency due to
73!               pbl parameterization (K/s)
74!-- rqvblten    qv tendency due to
75!               pbl parameterization (kg/kg/s)
76!-- rqcblten    qc tendency due to
77!               pbl parameterization (kg/kg/s)
78!-- rqiblten    qi tendency due to
79!               pbl parameterization (kg/kg/s)
80!-- cp          heat capacity at constant pressure for dry air (j/kg/k)
81!-- g           acceleration due to gravity (m/s^2)
82!-- rovcp       r/cp
83!-- r_d          gas constant for dry air (j/kg/k)
84!-- rovg        r/g
85!-- z           height above sea level (m)
86!-- xlv         latent heat of vaporization (j/kg)
87!-- r_v                 gas constant for water vapor (j/kg/k)
88!-- psfc        pressure at the surface (pa)
89!-- znt         roughness length (m)
90!-- ht          terrain height ASL (m)
91!-- ust         u* in similarity theory (m/s)
92!-- zol         z/l height over monin-obukhov length
93!-- hol         pbl height over monin-obukhov length
94!-- hpbl        pbl height (m)
95!-- psim        similarity stability function for momentum
96!-- psih        similarity stability function for heat
97!-- xland       land mask (1 for land, 2 for water)
98!-- hfx         upward heat flux at the surface (w/m^2)
99!-- qfx         upward moisture flux at the surface (kg/m^2/s)
100!-- tsk         surface temperature (k)
101!-- qsfc        surface specific humidity (kg/kg)
102!-- gz1oz0      log(z/z0) where z0 is roughness length
103!-- wspd        wind speed at lowest model level (m/s)
104!-- u10         u-wind speed at 10 m (m/s)
105!-- v10         v-wind speed at 10 m (m/s)
106!-- br          bulk richardson number in surface layer
107!-- dt          time step (s)
108!-- dtmin       time step (minute)
109!-- rvovrd      r_v divided by r_d (dimensionless)
110!-- svp1        constant for saturation vapor pressure (kpa)
111!-- svp2        constant for saturation vapor pressure (dimensionless)
112!-- svp3        constant for saturation vapor pressure (k)
113!-- svpt0       constant for saturation vapor pressure (k)
114!-- ep1         constant for virtual temperature (r_v/r_d - 1) (dimensionless)
115!-- ep2         constant for specific humidity calculation
116!-- karman      von karman constant
117!-- eomeg       angular velocity of earths rotation (rad/s)
118!-- stbolt      stefan-boltzmann constant (w/m^2/k^4)
119!-- ids         start index for i in domain
120!-- ide         end index for i in domain
121!-- jds         start index for j in domain
122!-- jde         end index for j in domain
123!-- kds         start index for k in domain
124!-- kde         end index for k in domain
125!-- ims         start index for i in memory
126!-- ime         end index for i in memory
127!-- jms         start index for j in memory
128!-- jme         end index for j in memory
129!-- kms         start index for k in memory
130!-- kme         end index for k in memory
131!-- its         start index for i in tile
132!-- ite         end index for i in tile
133!-- jts         start index for j in tile
134!-- jte         end index for j in tile
135!-- kts         start index for k in tile
136!-- kte         end index for k in tile
137!-------------------------------------------------------------------
138! Arguments
139!
140   integer,  intent(in   )   ::      ids,ide, jds,jde, kds,kde,                &
141                                     ims,ime, jms,jme, kms,kme,                &
142                                     its,ite, jts,jte, kts,kte
143!
144   real,     intent(in   )   ::      dt,dtmin,g,cp,rcp,r_d,r_v,xlv,cpv
145!
146   real,     intent(in )     ::      svp1,svp2,svp3,svpt0
147   real,     intent(in )     ::      ep1,ep2,karman,eomeg,stbolt
148!
149   real,     dimension( ims:ime, kms:kme, jms:jme )                          , &
150             intent(in   )   ::      qv3d, qc3d, qi3d, &
151                                     p3d, pi3d, th3d, t3d, &
152                                     z, rho
153!
154   real,     dimension( ims:ime, kms:kme, jms:jme )                          , &
155             intent(inout)   ::      te_temf
156   real,     dimension( ims:ime, kms:kme, jms:jme )                          , &
157             intent(  out)   ::      shf_temf, qf_temf, uw_temf, vw_temf     , &
158                                     wupd_temf, mf_temf, thup_temf, qtup_temf, &
159                                     qlup_temf,cf3d_temf
160   real,     dimension( ims:ime, jms:jme )                          , &
161             intent(inout)   ::      flhc, flqc, exch_temf
162   real,     dimension( ims:ime, jms:jme )                                   , &
163             intent(in   )   ::      fCor
164   real,     dimension( ims:ime, jms:jme )                                   , &
165             intent(  out)   ::      hd_temf, lcl_temf, hct_temf, cfm_temf
166!
167   real,     dimension( ims:ime, kms:kme, jms:jme )                          , &
168             intent(in   )   ::      p3di
169!
170   real,     dimension( ims:ime, kms:kme, jms:jme )                          , &
171             intent(inout)   ::      rublten, rvblten, &
172                                     rthblten, &
173                                     rqvblten, rqcblten, rqiblten
174!
175   real,     dimension( ims:ime, kms:kme, jms:jme )                          , &
176             intent(inout)   ::      kh_temf, km_temf
177   real,     dimension( ims:ime, jms:jme )                                   , &
178             intent(inout)   ::      u10, v10, t2
179!
180   real,     dimension( ims:ime, jms:jme )                                   , &
181             intent(in   )   ::      xland, &
182                                     psim, psih, gz1oz0, br, &
183                                     psfc, tsk, qsfc
184!
185   real,     dimension( ims:ime, jms:jme )                                   , &
186             intent(inout)   ::      hfx, qfx
187   real,     dimension( ims:ime, jms:jme )                                   , &
188             intent(inout)   ::      hol, ust, hpbl, znt, wspd, zol
189   real,     dimension( ims:ime, jms:jme )                                   , &
190             intent(in   )   ::      ht
191!
192  real,      dimension( ims:ime, kms:kme, jms:jme )                          , &
193             intent(in   )   ::      u3d, v3d
194!
195  integer,   dimension( ims:ime, jms:jme )                                   , &
196             intent(out  )   ::      kpbl2d
197!
198     logical, intent(in)        ::   flag_qi
199!
200!   real,     dimension( ims:ime, kms:kme, jms:jme ), &
201!             optional                              , &
202!             intent(inout)   ::      rqiblten
203!
204   real,     dimension( ims:ime, jms:jme )                                   , &
205             optional                                                        , &
206             intent(in   )   ::      mut
207!
208   real,     optional, intent(in   )   ::  p_top
209!
210!-------------------------------------------------------
211! Local variables
212   integer :: j
213
214   do j = jts,jte
215      call temf2d(J=j,ux=u3d(ims,kms,j),vx=v3d(ims,kms,j)                      &
216              ,tx=t3d(ims,kms,j),thx=th3d(ims,kms,j)                           &
217              ,qvx=qv3d(ims,kms,j),qcx=qc3d(ims,kms,j)                         &
218              ,qix=qi3d(ims,kms,j)                                             &
219              ,p2d=p3d(ims,kms,j),p2di=p3di(ims,kms,j)                         &
220              ,pi2d=pi3d(ims,kms,j),rho=rho(ims,kms,j)                         &
221              ,rubltenx=rublten(ims,kms,j),rvbltenx=rvblten(ims,kms,j)         &
222              ,rthbltenx=rthblten(ims,kms,j),rqvbltenx=rqvblten(ims,kms,j)     &
223              ,rqcbltenx=rqcblten(ims,kms,j),rqibltenx=rqiblten(ims,kms,j)     &
224              ,g=g,cp=cp,rcp=rcp,r_d=r_d,r_v=r_v,cpv=cpv            &
225              ,z2d=z(ims,kms,j)                         &
226              ,xlv=xlv                                                   &
227              ,psfcpa=psfc(ims,j),znt=znt(ims,j),zsrf=ht(ims,j),ust=ust(ims,j) &
228              ,zol=zol(ims,j),hol=hol(ims,j),hpbl=hpbl(ims,j)                  &
229              ,psim=psim(ims,j)                           &
230              ,psih=psih(ims,j),xland=xland(ims,j)                             &
231              ,hfx=hfx(ims,j),qfx=qfx(ims,j)                                   &
232              ,tsk=tsk(ims,j),qsfc=qsfc(ims,j),gz1oz0=gz1oz0(ims,j)           &
233              ,wspd=wspd(ims,j),br=br(ims,j)                                   &
234              ,dt=dt,dtmin=dtmin,kpbl1d=kpbl2d(ims,j)                          &
235              ,svp1=svp1,svp2=svp2,svp3=svp3,svpt0=svpt0                       &
236              ,ep1=ep1,ep2=ep2,karman=karman,eomeg=eomeg                       &
237              ,stbolt=stbolt                                                   &
238              ,kh_temfx=kh_temf(ims,kms,j),km_temfx=km_temf(ims,kms,j)         &
239              ,u10=u10(ims,j),v10=v10(ims,j),t2=t2(ims,j)                      &
240              ,te_temfx=te_temf(ims,kms,j)                                     &
241              ,shf_temfx=shf_temf(ims,kms,j),qf_temfx=qf_temf(ims,kms,j)       &
242              ,uw_temfx=uw_temf(ims,kms,j),vw_temfx=vw_temf(ims,kms,j)       &
243              ,wupd_temfx=wupd_temf(ims,kms,j),mf_temfx=mf_temf(ims,kms,j)   &
244              ,thup_temfx=thup_temf(ims,kms,j),qtup_temfx=qtup_temf(ims,kms,j) &
245              ,qlup_temfx=qlup_temf(ims,kms,j) &
246              ,cf3d_temfx=cf3d_temf(ims,kms,j),cfm_temfx=cfm_temf(ims,j)       &
247              ,hd_temfx=hd_temf(ims,j),lcl_temfx=lcl_temf(ims,j)       &
248              ,hct_temfx=hct_temf(ims,j),exch_temfx=exch_temf(ims,j)    &
249              ,flhc=flhc(ims,j),flqc=flqc(ims,j)                     &
250              ,fCor=fCor(ims,j)                                              &
251              ,ids=ids,ide=ide, jds=jds,jde=jde, kds=kds,kde=kde               &
252              ,ims=ims,ime=ime, jms=jms,jme=jme, kms=kms,kme=kme               &
253              ,its=its,ite=ite, jts=jts,jte=jte, kts=kts,kte=kte   )
254   enddo
255!
256   end subroutine temfpbl
257!
258!-------------------------------------------------------------------
259!
260   subroutine temf2d(j,ux,vx,tx,thx,qvx,qcx,qix,p2d,p2di,pi2d,rho,            &
261                  rubltenx,rvbltenx,rthbltenx,                                 &
262                  rqvbltenx,rqcbltenx,rqibltenx,                               &
263                  g,cp,rcp,r_d,r_v,cpv,                            &
264                  z2d,                                                  &
265                  xlv,psfcpa,                                    &
266                  znt,zsrf,ust,zol,hol,hpbl,psim,psih,                      &
267                  xland,hfx,qfx,tsk,qsfc,gz1oz0,wspd,br,                   &
268                  dt,dtmin,kpbl1d,                                             &
269                  svp1,svp2,svp3,svpt0,ep1,ep2,karman,eomeg,stbolt,            &
270                  kh_temfx,km_temfx,                                         &
271                  u10,v10,t2,                                                 &
272                  te_temfx,shf_temfx,qf_temfx,uw_temfx,vw_temfx,               &
273                  wupd_temfx,mf_temfx,thup_temfx,qtup_temfx,qlup_temfx,       &
274                  cf3d_temfx,cfm_temfx,                                        &
275                  hd_temfx,lcl_temfx,hct_temfx,exch_temfx,           &
276                  flhc,flqc,                                                 &
277                  fCor,                                                        &
278                  ids,ide, jds,jde, kds,kde,                                   &
279                  ims,ime, jms,jme, kms,kme,                                   &
280                  its,ite, jts,jte, kts,kte                                   &
281                  )
282!-------------------------------------------------------------------
283   implicit none
284!-------------------------------------------------------------------
285!
286! This is the Total Energy - Mass Flux (TEMF) PBL scheme.
287! Initial implementation 2010 by Wayne Angevine, CIRES/NOAA ESRL.
288! References:
289!    Angevine et al., 2010, MWR
290!    Angevine, 2005, JAM
291!    Mauritsen et al., 2007, JAS
292!
293!-------------------------------------------------------------------
294!
295   integer,  intent(in   )   ::      ids,ide, jds,jde, kds,kde,                &
296                                     ims,ime, jms,jme, kms,kme,                &
297                                     its,ite, jts,jte, kts,kte, j
298!
299   real,     intent(in   )   ::      dt,dtmin,g,cp,rcp,r_d,r_v,cpv,xlv
300!
301   real,     intent(in )     ::      svp1,svp2,svp3,svpt0
302   real,     intent(in )     ::      ep1,ep2,karman,eomeg,stbolt
303!
304   real,     dimension( ims:ime, kms:kme ),                                    &
305             intent(in)      ::      z2d
306!
307   real,     dimension( ims:ime, kms:kme )                                   , &
308             intent(in   )   ::      ux, vx
309   real,     dimension( ims:ime, kms:kme )                                   , &
310             intent(inout)   ::      te_temfx
311   real,     dimension( ims:ime, kms:kme )                                   , &
312             intent(  out)   ::      shf_temfx, qf_temfx, uw_temfx, vw_temfx , &
313                                     wupd_temfx, mf_temfx,thup_temfx,          &
314                                     qtup_temfx, qlup_temfx, cf3d_temfx
315   real,     dimension( ims:ime )                                   , &
316             intent(  out)   ::      hd_temfx, lcl_temfx, hct_temfx, cfm_temfx
317   real,     dimension( ims:ime )                                   , &
318             intent(in   )   ::      fCor
319   real,     dimension( ims:ime )                                   , &
320             intent(inout)   ::      flhc, flqc, exch_temfx
321   real,     dimension( ims:ime, kms:kme )                                   , &
322             intent(in   )   ::      tx, thx, qvx, qcx, qix, pi2d, rho
323   real,     dimension( ims:ime, kms:kme )                                 , &
324             intent(in   )   ::      p2di, p2d
325!
326   real,     dimension( ims:ime, kms:kme )                                   , &
327             intent(inout)   ::      rubltenx, rvbltenx, rthbltenx,            &
328                                     rqvbltenx, rqcbltenx, rqibltenx
329!
330   real,     dimension( ims:ime )                                            , &
331             intent(inout)   ::      hol, ust, hpbl, znt
332   real,     dimension( ims:ime )                                            , &
333             intent(in   )   ::      xland, zsrf
334   real,     dimension( ims:ime )                                            , &
335             intent(inout)   ::      hfx, qfx
336!
337   real,     dimension( ims:ime ), intent(inout)   ::  wspd
338   real,     dimension( ims:ime ), intent(in  )    ::  br
339!
340   real,     dimension( ims:ime ), intent(in   )   ::  psim, psih
341   real,     dimension( ims:ime ), intent(in   )   ::  gz1oz0
342!
343   real,     dimension( ims:ime ), intent(in   )   ::  psfcpa
344   real,     dimension( ims:ime ), intent(in   )   ::  tsk, qsfc
345   real,     dimension( ims:ime ), intent(inout)   ::  zol
346   integer,  dimension( ims:ime ), intent(out  )   ::  kpbl1d
347   real,     dimension( ims:ime, kms:kme )                                   , &
348             intent(inout)   ::        kh_temfx, km_temfx
349!
350   real,     dimension( ims:ime )                                            , &
351             intent(inout)    ::        u10, v10, t2
352!
353!
354!-----------------------------------------------------------
355! Local variables
356!
357! TE model constants
358   logical, parameter :: MFopt = .true.  ! Use mass flux or not
359!   real, parameter :: visc_temf = 1.57e-5
360!   real, parameter :: conduc_temf = 1.57e-5 / 0.733
361   real, parameter :: visc_temf = 1.57e-4   ! WA TEST bigger minimum K
362   real, parameter :: conduc_temf = 1.57e-4 / 0.733
363   real, parameter :: Pr_temf = 0.733
364   real, parameter :: TEmin = 1e-3
365   real, parameter :: ftau0 = 0.17
366   real, parameter :: fth0 = 0.145
367!   real, parameter :: fth0 = 0.12    ! WA 10/13/10 to make PrT0 ~= 1
368   real, parameter :: critRi = 0.25
369   real, parameter :: Cf = 0.185
370   real, parameter :: CN = 2.0
371!   real, parameter :: Ceps = ftau0**1.5
372   real, parameter :: Ceps = 0.070
373   real, parameter :: Cgamma = Ceps
374   real, parameter :: Cphi = Ceps
375!   real, parameter :: PrT0 = Cphi/Ceps * ftau0**2. / 2 / fth0**2.
376   real, parameter :: PrT0 = Cphi/Ceps * ftau0**2 / 2. / fth0**2
377! EDMF constants
378   real, parameter :: CM = 0.03      ! Proportionality constant for subcloud MF
379   real, parameter :: Cdelt = 0.006  ! Prefactor for detrainment rate
380   real, parameter :: Cw = 0.5       ! Prefactor for surface wUPD
381   real, parameter :: Cc = 3.0       ! Prefactor for convective length scale
382   real, parameter :: lasymp = 200.0 ! Asymptotic length scale WA 11/20/09
383   real, parameter :: hmax = 4000.0  ! Max hd,hct WA 11/20/09
384!
385   integer :: i, k, kt   ! Loop variable
386   integer, dimension( its:ite) ::  h0idx
387   real, dimension( its:ite)    ::  h0
388   real, dimension( its:ite)    ::  wstr, ang, wm
389   real, dimension( its:ite)    ::  hd,lcl,hct,ht
390   real, dimension( its:ite)    ::  convection_TKE_surface_src, sfcFTE
391   real, dimension( its:ite)    ::  sfcTHVF
392   real, dimension( its:ite)    ::  z0t
393   integer, dimension( its:ite) ::  hdidx,lclidx,hctidx,htidx
394   integer, dimension( its:ite) ::  tval
395   ! real, dimension( its:ite )   ::  sfcHF, sfcQF
396   real, dimension( its:ite, kts:kte) :: thetal, qt
397   real, dimension( its:ite, kts:kte) :: u_temf, v_temf
398   real, dimension( its:ite, kts:kte) :: rv, rl, rt
399   real, dimension( its:ite, kts:kte) :: chi_poisson, gam
400   real, dimension( its:ite, kts:kte) :: dthdz, dqtdz, dudz, dvdz
401   real, dimension( its:ite, kts:kte) :: lepsmin
402   real, dimension( its:ite, kts:kte) :: thetav
403   real, dimension( its:ite, kts:kte) :: MFCth, MFCq, MFCu, MFCv
404   real, dimension( its:ite, kts:kte) :: MFCql, MFCthv, MFCTE
405   real, dimension( its:ite, kts:kte) :: epsmf, deltmf, dMdz
406   real, dimension( its:ite, kts:kte) :: UUPD, VUPD
407   real, dimension( its:ite, kts:kte) :: thetavUPD, qlUPD, TEUPD
408   real, dimension( its:ite, kts:kte) :: thetavUPDmoist, wupd_dry
409   real, dimension( its:ite, kts:kte) :: B, Bmoist
410   real, dimension( its:ite, kts:kte) :: zm, zt, dzm, dzt
411   real, dimension( its:ite, kts:kte) :: dthUPDdz, dqtup_temfxdz, dwUPDdz
412   real, dimension( its:ite, kts:kte) :: dwUPDmoistdz
413   real, dimension( its:ite, kts:kte) :: dUUPDdz, dVUPDdz, dTEUPDdz
414   real, dimension( its:ite, kts:kte) :: TUPD, rstUPD, rUPD, rlUPD, qstUPD
415   real, dimension( its:ite, kts:kte) :: N2, S, Ri, beta, ftau, fth, ratio
416   real, dimension( its:ite, kts:kte) :: TKE, TE2
417   real, dimension( its:ite, kts:kte) :: ustrtilde, linv, leps
418   real, dimension( its:ite, kts:kte) :: km, kh
419   real, dimension( its:ite, kts:kte) :: Fz, QFK, uwk, vwk
420   real, dimension( its:ite, kts:kte) :: km_conv, kh_conv, lconv
421   real, dimension( its:ite, kts:kte) :: alpha2, beta2   ! For thetav flux calculation
422   real, dimension( its:ite, kts:kte) :: THVF, buoy_src, srcs
423   real, dimension( its:ite, kts:kte) :: u_new, v_new
424   real, dimension( its:ite, kts:kte) :: thx_new, qvx_new, qcx_new
425   real, dimension( its:ite, kts:kte) :: thup_new, qvup_new
426   real, dimension( its:ite, kts:kte) :: beta1 ! For saturation humidity calculations
427   real Cepsmf    ! Prefactor for entrainment rate
428   real red_fact  ! WA TEST for reducing MF components
429   logical is_convective
430   ! Vars for cloud fraction calculation
431   real, dimension( its:ite, kts:kte) :: au, sigq, qst, satdef
432   real sigq2, rst
433
434!----------------------------------------------------------------------
435! Grid staggering:  Matlab version has mass and turbulence levels.
436! WRF has full levels (with w) and half levels (u,v,theta,q*).  Both
437! sets of levels use the same indices (kts:kte).  See pbl_driver or
438! WRF Physics doc for (a few) details. 
439! So *mass levels correspond to half levels.*
440! WRF full levels are ignored, we define our own turbulence levels
441! in order to put the first one below the first half level.
442! Another difference is that
443! the Matlab version (and the Mauritsen et al. paper) consider the
444! first mass level to be at z0 (effectively the surface).  WRF considers
445! the first half level to be above the effective surface.  The first half
446! level, at k=1, has nonzero values of u,v for example.  Here we convert
447! all incoming variables to internal ones with the correct indexing
448! in order to make the code consistent with the Matlab version.  We
449! already had to do this for thetal and qt anyway, so the only additional
450! overhead is for u and v.
451! I use suffixes m for mass and t for turbulence as in Matlab for things
452! like indices.
453! Note that zsrf is the terrain height ASL, from Registry variable ht.
454! Translations (Matlab to WRF):
455!     dzt -> calculated below
456!     dzm -> not supplied, calculated below
457!     k -> karman
458!     z0 -> znt
459!     z0t -> not in WRF, calculated below
460!     zt -> calculated below
461!     zm -> (z2d - zsrf) but NOTE zm(1) is now z0 (znt) and zm(2) is
462!                                 z2d(1) - zsrf
463!
464! WA I take the temperature at z0 to be
465! TSK.  This isn't exactly robust.  Also I pass out the surface
466! exchange coefficients flhc, flqc for the surface scheme to use in the
467! next timestep.
468! WA 2/16/11 removed calculation of flhc, flqc which are not needed here.
469! These should be removed from the calling sequence someday.
470!
471! Other notes:
472! - I have often used 1 instead of kts below, because the scheme demands
473!   to know where the surface is.  It won't work if kts .NE. 1.
474
475
476   do i = its,ite      ! Main loop
477
478      ! Get incoming surface theta from TSK (WA for now)
479      thetal(i,1) = tsk(i) / pi2d(i,1)  ! WA really should use Exner func. at z0
480      if (exch_temfx(i) > 1.0e-12) then
481         qt(i,1) = qfx(i) / exch_temfx(i) + qvx(i,1)  ! WA assumes no liquid at z0
482      else
483         qt(i,1) = qvx(i,1)
484      end if
485      rv(i,1) = qt(i,1) / (1.-qt(i,1))   ! Water vapor
486      rl(i,1) = 0.
487      rt(i,1) = rv(i,1) + rl(i,1)        ! Total water (without ice)
488      chi_poisson(i,1) = rcp * (1.+rv(i,1)/ep2) / (1.+rv(i,1)*cpv/cp)
489      gam(i,1) = rv(i,1) * r_v / (cp + rv(i,1)*cpv)
490      ! thetav(i,1) = thetal(i,1) * (1. + 0.608*qt(i,1))  ! WA Assumes ql(env)=0, what if it isn't?
491      thetav(i,1) = thetal(i,1) * (1. + 0.608*qt(i,1) - qcx(i,1))  ! WA 4/6/10 allow environment liquid
492      ! WA TEST (R5) set z0t = z0
493      ! z0t(i) = znt(i) / 10.0   ! WA this is hard coded in Matlab version
494      z0t(i) = znt(i)
495
496      ! Convert incoming theta to thetal and qv,qc to qt
497      ! NOTE this is where the indexing gets changed from WRF to TEMF basis
498      do k = kts+1,kte
499         ! Convert specific humidities to mixing ratios
500         rv(i,k) = qvx(i,k-1) / (1.-qvx(i,k-1))   ! Water vapor
501         rl(i,k) = qcx(i,k-1) / (1.-qcx(i,k-1))   ! Liquid water
502         rt(i,k) = rv(i,k) + rl(i,k)        ! Total water (without ice)
503         chi_poisson(i,k) = rcp * (1.+rv(i,k)/ep2) / (1.+rv(i,k)*cpv/cp)
504         gam(i,k) = rt(i,k) * r_v / (cp + rt(i,k)*cpv)
505         thetal(i,k) = thx(i,k-1) * ((ep2+rv(i,k))/(ep2+rt(i,k)))**chi_poisson(i,k) * (rv(i,k)/rt(i,k))**(-gam(i,k)) * exp( -xlv*rl(i,k) / ((cp + rt(i,k)*cpv) * tx(i,k)))
506         qt(i,k) = qvx(i,k-1) + qcx(i,k-1)
507         ! thetav(i,k) = thetal(i,k) * (1. + 0.608*qt(i,k))  ! WA Assumes ql(env)=0, what if it isn't?
508         thetav(i,k) = thetal(i,k) * (1. + 0.608*qt(i,k) - qcx(i,k-1))  ! WA 4/6/10 allow environment liquid
509      end do
510
511      ! Convert incoming u,v to internal u_temf, v_temf
512      ! NOTE this is where the indexing gets changed from WRF to TEMF basis
513      u_temf(i,1) = 0.   ! zero winds at z0
514      v_temf(i,1) = 0.
515      do k = kts+1,kte
516         u_temf(i,k) = ux(i,k-1)
517         v_temf(i,k) = vx(i,k-1)
518      end do
519
520      ! Get delta height at half (mass) levels
521      zm(i,1) = znt(i)
522      dzt(i,1) = z2d(i,1) - zsrf(i) - zm(i,1)
523      ! Get height and delta at turbulence levels
524      zt(i,1) = (z2d(i,1) - zsrf(i) - znt(i)) / 2.
525      do kt = kts+1,kte
526         zm(i,kt) = z2d(i,kt-1) - zsrf(i) ! Convert indexing from WRF to TEMF
527         zt(i,kt) = (zm(i,kt) + z2d(i,kt) - zsrf(i)) / 2.
528         dzm(i,kt) = zt(i,kt) - zt(i,kt-1)
529         dzt(i,kt) = z2d(i,kt+1) - z2d(i,kt)
530      end do
531      dzm(i,1) = dzm(i,2)  ! WA why?
532      dzt(i,kte) = dzt(i,kte-1)    ! WA 12/23/09
533
534      ! Gradients at first level
535      dthdz(i,1) = (thetal(i,2)-thetal(i,1)) / (zt(i,1) * log10(zm(i,2)/z0t(i)))
536      dqtdz(i,1) = (qt(i,2)-qt(i,1)) / (zt(i,1) * log10(zm(i,2)/z0t(i)))
537      dudz(i,1) = (u_temf(i,2)-u_temf(i,1)) / (zt(i,1) * log10(zm(i,2)/znt(i)))
538      dvdz(i,1) = (v_temf(i,2)-v_temf(i,1)) / (zt(i,1) * log10(zm(i,2)/znt(i)))
539
540      ! Surface thetaV flux from Stull p.147
541      sfcTHVF(i) = hfx(i)/(rho(i,1)*cp) * (1.+0.608*(qvx(i,1)+qcx(i,1))) + 0.608*thetav(i,1)*qf_temfx(i,1)
542
543      ! WA use hd_temf to calculate w* instead of finding h0 here????
544      ! Watch initialization!
545      h0idx(i) = 1
546      h0(i) = zm(i,1)
547
548      ! WA TEST (R4) remove lower limit on leps
549      ! lepsmin(i,kts) = min(0.4*zt(i,kts), 5.)
550      lepsmin(i,kts) = 0.
551
552      do k = kts+1,kte-1
553         ! WA TEST (R4) remove lower limit on leps
554         ! lepsmin(i,k) = min(0.4*zt(i,k), 5.)
555         lepsmin(i,k) = 0.
556         ! lepsmin(i,k) = min(zt(i,k), 20.)  ! WA to deal with runaway
557
558         ! Mean gradients
559         ! dthdz(i,k) = (thx(i,k) - thx(i,k-1)) / dzt(i,k)  ! WA 1/12/10
560         dthdz(i,k) = (thetal(i,k+1) - thetal(i,k)) / dzt(i,k)
561         dqtdz(i,k) = (qt(i,k+1) - qt(i,k)) / dzt(i,k)
562         dudz(i,k) = (u_temf(i,k+1) - u_temf(i,k)) / dzt(i,k)
563         dvdz(i,k) = (v_temf(i,k+1) - v_temf(i,k)) / dzt(i,k)
564
565         ! Find h0 (should eventually be interpolated for smoothness)
566         if (thetav(i,k) > thetav(i,1) .AND. h0idx(i) .EQ. 1) then
567            h0idx(i) = k
568            h0(i) = zm(i,k)
569         end if
570      end do
571
572      ! Gradients at top level   
573
574      dthdz(i,kte) = dthdz(i,kte-1)
575      dqtdz(i,kte) = dqtdz(i,kte-1)
576      dudz(i,kte) = dudz(i,kte-1)
577      dvdz(i,kte) = dvdz(i,kte-1)
578
579      if ( hfx(i) > 0.) then
580         ! wstr(i) = (g * h0(i) / thetav(i,2) * shf_temfx(i,1) ) ** (1./3.)
581         wstr(i) = (g * h0(i) / thetav(i,2) * hfx(i)/(rho(i,1)*cp) ) ** (1./3.)
582      else
583         wstr(i) = 0.
584      end if
585     
586
587      ! Set flag convective or not for use below
588      is_convective = wstr(i) > 0. .AND. MFopt .AND. dthdz(i,1)<0. .AND. dthdz(i,2)<0.  ! WA 12/16/09 require two levels of negative (unstable) gradient
589
590      ! Find stability parameters and length scale (on turbulence levels)
591      do kt = 1,kte-1
592         N2(i,kt) = 2. * g / (thetav(i,kt) + thetav(i,kt+1))*dthdz(i,kt)
593         S(i,kt) = sqrt(dudz(i,kt)**2. + dvdz(i,kt)**2.)
594         Ri(i,kt) = N2(i,kt) / S(i,kt)**2.
595         if (S(i,kt) < 1e-15) then
596            if (N2(i,kt) >= 0) then
597               Ri(i,kt) = 10.
598            else
599               Ri(i,kt) = -1.
600            end if
601         end if
602         beta(i,kt) = 2. * g / (thetav(i,kt)+thetav(i,kt+1))
603         if (Ri(i,kt) > 0) then
604            ratio(i,kt) = Ri(i,kt)/(Cphi**2.*ftau0**2./(2.*Ceps**2.*fth0**2.)+3.*Ri(i,kt))
605            ftau(i,kt) = ftau0 * ((3./4.) / (1.+4.*Ri(i,kt)) + 1./4.)
606            fth(i,kt) = fth0 / (1.+4.*Ri(i,kt))
607            TE2(i,kt) = 2. * te_temfx(i,kt) * ratio(i,kt) * N2(i,kt) / beta(i,kt)**2.
608         else
609            ratio(i,kt) = Ri(i,kt)/(Cphi**2.*ftau0**2./(-2.*Ceps**2.*fth0**2.)+2.*Ri(i,kt))
610            ftau(i,kt) = ftau0
611            fth(i,kt) = fth0
612            TE2(i,kt) = 0.
613         end if
614         TKE(i,kt) = te_temfx(i,kt) * (1. - ratio(i,kt))
615         ustrtilde(i,kt) = sqrt(ftau(i,kt) * TKE(i,kt))
616         if (N2(i,kt) > 0.) then
617            linv(i,kt) = 1./karman / zt(i,kt) + abs(fCor(i)) / (Cf*ustrtilde(i,kt)) + sqrt(N2(i,kt))/(CN*ustrtilde(i,kt)) + 1./lasymp  ! WA Test 11/20/09
618         else
619            linv(i,kt) = 1./karman / zt(i,kt) + abs(fCor(i)) / (Cf*ustrtilde(i,kt)) + 1./lasymp  ! WA Test 11/20/09
620         end if
621         leps(i,kt) = 1./linv(i,kt)
622         leps(i,kt) = max(leps(i,kt),lepsmin(i,kt))
623      end do
624      S(i,kte) = 0.0
625      N2(i,kte) = 0.0
626      TKE(i,kte) = 0.0
627      linv(i,kte) = linv(i,kte-1)
628      leps(i,kte) = leps(i,kte-1)
629
630
631      ! Find diffusion coefficients
632      ! First use basic formulae for stable and neutral cases,
633      ! then for convective conditions, and finally choose the larger
634      ! WA 12/23/09 use convective form up to hd/2 always
635      ! WA 12/28/09 after restructuring, this block is above MF block,
636      ! so hd is not yet available for this timestep, must use h0,
637      ! or use hd from previous timestep but be careful about initialization.
638      do kt = 1,kte-1    ! WA 12/22/09
639         ! WA 4/8/10 remove beta term to avoid negative and huge values
640         ! of km due to very small denominator.  This is an interim fix
641         ! until we find something better (more theoretically sound).
642         ! km(i,kt) = TKE(i,kt)**1.5 * ftau(i,kt)**2. / (-beta(i,kt) * fth(i,kt) * sqrt(TE2(i,kt)) + Ceps * sqrt(TKE(i,kt)*te_temfx(i,kt)) / leps(i,kt))
643         km(i,kt) = TKE(i,kt)**1.5 * ftau(i,kt)**2. / (Ceps * sqrt(TKE(i,kt)*te_temfx(i,kt)) / leps(i,kt))
644         kh(i,kt) = 2. * leps(i,kt) * fth(i,kt)**2. * TKE(i,kt) / sqrt(te_temfx(i,kt)) / Cphi
645         if ( is_convective) then
646            if (kt <= h0idx(i)) then
647               lconv(i,kt) = 1. / (1. / (karman*zt(i,kt)) + Cc / (karman * (h0(i) - zt(i,kt))))
648            else
649               lconv(i,kt) = 0.
650            end if
651            ! WA 12/15/09 use appropriate coeffs to match kh_conv and kh at neutral
652            kh_conv(i,kt) = ftau0**2. / Ceps / PrT0 * sqrt(TKE(i,kt)) * lconv(i,kt)
653            if (kh_conv(i,kt) < 0.) then
654               kh_conv(i,kt) = 0.
655            end if
656            km_conv(i,kt) = PrT0 * kh_conv(i,kt)
657            if (zt(i,kt) <= h0(i)/2.) then
658               km(i,kt) = km_conv(i,kt)
659               kh(i,kt) = kh_conv(i,kt)
660            end if
661            ! WA TEST 1/11/10 go back to max in upper BL
662            if (zt(i,kt) > h0(i)/2. .AND. kt <= h0idx(i)) then
663               km(i,kt) = max(km(i,kt),km_conv(i,kt),visc_temf)
664               kh(i,kt) = max(kh(i,kt),kh_conv(i,kt),conduc_temf)
665            end if
666         end if  ! is_convective
667         km(i,kt) = max(km(i,kt),visc_temf)
668         kh(i,kt) = max(kh(i,kt),conduc_temf)
669         Fz(i,kt) = -kh(i,kt) * dthdz(i,kt)  ! Diffusive heat flux
670      end do
671      km(i,kte) = km(i,kte-1)  ! WA 12/22/09
672      kh(i,kte) = kh(i,kte-1)
673      Fz(i,kte) = 0.0          ! WA 4/2/10
674
675
676      !*** Mass flux block starts here ***
677
678      if ( is_convective) then
679
680         Cepsmf = 2. / max(200.,h0(i))
681         Cepsmf = max(Cepsmf,0.002)    ! WA 7/20/10
682         do k = kts,kte
683            ! Calculate lateral entrainment fraction for subcloud layer
684            ! epsilon and delta are defined on mass grid (half levels)
685            epsmf(i,k) = Cepsmf
686         end do
687
688         ! Initialize updraft
689         thup_temfx(i,1) = thetal(i,1)    ! No excess
690         qtup_temfx(i,1) = qt(i,1)            ! No excess
691         rUPD(i,1) = qtup_temfx(i,1) / (1. - qtup_temfx(i,1))
692         wupd_temfx(i,1) = Cw * wstr(i)
693         wupd_dry(i,1) = Cw * wstr(i)
694         UUPD(i,1) = u_temf(i,1)
695         VUPD(i,1) = v_temf(i,1)
696         thetavUPD(i,1) = thup_temfx(i,1) * (1. + 0.608*qtup_temfx(i,1))  ! WA Assumes no liquid
697         thetavUPDmoist(i,1) = thup_temfx(i,1) * (1. + 0.608*qtup_temfx(i,1))  ! WA Assumes no liquid
698         TEUPD(i,1) = te_temfx(i,1) + g / thetav(i,1) * sfcTHVF(i)
699         ! qlUPD(i,1) = 0.
700         qlUPD(i,1) = qcx(i,1)  ! WA allow environment liquid
701         TUPD(i,1) = thup_temfx(i,1) * pi2d(i,1)   
702         rstUPD(i,1) = rsat(p2d(i,1),TUPD(i,1),ep2) 
703         rlUPD(i,1) = 0.
704
705         ! Calculate updraft parameters counting up
706         do k = 2,kte
707            dthUPDdz(i,k-1) = -epsmf(i,k) * (thup_temfx(i,k-1) - thetal(i,k-1))
708            thup_temfx(i,k) = thup_temfx(i,k-1) + dthUPDdz(i,k-1) * dzm(i,k-1)
709            dqtup_temfxdz(i,k-1) = -epsmf(i,k) * (qtup_temfx(i,k-1) - qt(i,k-1))
710            qtup_temfx(i,k) = qtup_temfx(i,k-1) + dqtup_temfxdz(i,k-1) * dzm(i,k-1)
711            thetavUPD(i,k) = thup_temfx(i,k) * (1. + 0.608*qtup_temfx(i,k))  ! WA Assumes no liquid
712            B(i,k-1) = g * (thetavUPD(i,k) - thetav(i,k)) / thetav(i,k)
713            if ( wupd_dry(i,k-1) < 1e-15 ) then
714               wupd_dry(i,k) = 0.
715            else
716               dwUPDdz(i,k-1) = -2. *epsmf(i,k)*wupd_dry(i,k-1) + 0.33*B(i,k-1)/wupd_dry(i,k-1)
717               wupd_dry(i,k) = wupd_dry(i,k-1) + dwUPDdz(i,k-1) * dzm(i,k-1)
718            end if
719            dUUPDdz(i,k-1) = -epsmf(i,k) * (UUPD(i,k-1) - u_temf(i,k-1))
720            UUPD(i,k) = UUPD(i,k-1) + dUUPDdz(i,k-1) * dzm(i,k-1)
721            dVUPDdz(i,k-1) = -epsmf(i,k) * (VUPD(i,k-1) - v_temf(i,k-1))
722            VUPD(i,k) = VUPD(i,k-1) + dVUPDdz(i,k-1) * dzm(i,k-1)
723            dTEUPDdz(i,k-1) = -epsmf(i,k) * (TEUPD(i,k-1) - te_temfx(i,k-1))
724            TEUPD(i,k) = TEUPD(i,k-1) + dTEUPDdz(i,k-1) * dzm(i,k-1)
725            ! Alternative updraft velocity based on moist thetav
726            ! Need thetavUPDmoist, qlUPD
727            rUPD(i,k) = qtup_temfx(i,k) / (1. - qtup_temfx(i,k))
728            ! WA Updraft temperature assuming no liquid
729            TUPD(i,k) = thup_temfx(i,k) * pi2d(i,k)   
730            ! Updraft saturation mixing ratio
731            ! rstUPD(i,k) = rsat(p2d(i,k),TUPD(i,k),ep2)  ! WA 4/19/10
732            rstUPD(i,k) = rsat(p2d(i,k-1),TUPD(i,k),ep2) 
733            ! Correct to actual temperature (Sommeria & Deardorff 1977)
734            beta1(i,k) = 0.622 * (xlv/(r_d*TUPD(i,k))) * (xlv/(cp*TUPD(i,k)))
735            rstUPD(i,k) = rstUPD(i,k) * (1.0+beta1(i,k)*rUPD(i,k)) / (1.0+beta1(i,k)*rstUPD(i,k))
736            qstUPD(i,k) = rstUPD(i,k) / (1. + rstUPD(i,k))
737            if (rUPD(i,k) > rstUPD(i,k)) then
738               rlUPD(i,k) = rUPD(i,k) - rstUPD(i,k)
739               qlUPD(i,k) = rlUPD(i,k) / (1. + rlUPD(i,k))
740               thetavUPDmoist(i,k) = (thup_temfx(i,k) + ((xlv/cp)*qlUPD(i,k)/pi2d(i,k))) * (1. + 0.608*qstUPD(i,k) - qlUPD(i,k))
741            else
742               rlUPD(i,k) = 0.
743               ! qlUPD(i,k) = 0.
744               qlUPD(i,k) = qcx(i,k-1)   ! WA 4/6/10 allow environment liquid
745               ! WA does this make sense?  Should be covered above?
746               thetavUPDmoist(i,k) = thup_temfx(i,k) * (1. + 0.608*qtup_temfx(i,k))
747            end if
748            Bmoist(i,k-1) = g * (thetavUPDmoist(i,k) - thetav(i,k)) / thetav(i,k)
749            if ( wupd_temfx(i,k-1) < 1e-15 ) then
750               wupd_temfx(i,k) = 0.
751            else
752               dwUPDmoistdz(i,k-1) = -2. *epsmf(i,k)*wupd_temfx(i,k-1) + 0.33*Bmoist(i,k-1)/wupd_temfx(i,k-1)
753               wupd_temfx(i,k) = wupd_temfx(i,k-1) + dwUPDmoistdz(i,k-1) * dzm(i,k-1)
754            end if
755         end do
756
757         ! Find hd based on wUPD
758         if (wupd_dry(i,1) == 0.) then
759            hdidx(i) = 1
760         else
761            hdidx(i) = kte  ! In case wUPD <= 0 not found
762            do k = 2,kte
763               ! if (wupd_dry(i,k) <= 0.) then
764               if (wupd_dry(i,k) <= 0. .OR. zm(i,k) > hmax) then  ! WA Test
765                  hdidx(i) = k
766                  goto 100   ! FORTRAN made me do it!
767               end if
768            end do
769         end if
770100      hd(i) = zm(i,hdidx(i))
771         ! kpbl1d(i) = hd(i)        ! WA not sure if this is what I want for diagnostic out to larger WRF universe....and it's not right if not convective
772         kpbl1d(i) = hdidx(i)  ! WA 5/11/10 kpbl should be index
773         hpbl(i) = hd(i)       ! WA 5/11/10 hpbl is height.  Should still be replaced by something that works whether convective or not.
774
775         ! Find LCL, hct, and ht
776         lclidx(i) = kte   ! In case LCL not found
777         do k = kts,kte
778            if (rUPD(i,k) > rstUPD(i,k)) then
779               lclidx(i) = k
780               goto 200
781            end if
782         end do
783200      lcl(i) = zm(i,lclidx(i))
784
785         if (hd(i) > lcl(i)) then   ! Forced cloud (at least) occurs
786            ! Find hct based on wUPDmoist
787            if (wupd_temfx(i,1) == 0.) then
788               hctidx(i) = 1
789            else
790               hctidx(i) = kte  ! In case wUPD <= 0 not found
791               do k = 2,kte
792                  if (wupd_temfx(i,k) <= 0. .OR. zm(i,k) > hmax) then  ! WA Test
793                     hctidx(i) = k
794                     goto 300   ! FORTRAN made me do it!
795                  end if
796               end do
797            end if
798   300      hct(i) = zm(i,hctidx(i))
799            if (hctidx(i) <= hdidx(i)+1) then   ! No active cloud
800               hct(i) = hd(i)
801               hctidx(i) = hdidx(i)
802            else
803            end if
804         else   ! No cloud
805            hct(i) = hd(i)
806            hctidx(i) = hdidx(i)
807         end if
808         ht(i) = max(hd(i),hct(i))
809         htidx(i) = max(hdidx(i),hctidx(i))
810
811         ! Now truncate updraft at ht with taper
812         do k = 1,kte
813            if (zm(i,k) < 0.9*ht(i)) then  ! Below taper region
814               tval(i) = 1
815            else if (zm(i,k) >= 0.9*ht(i) .AND. zm(i,k) <= 1.0*ht(i)) then
816               ! Within taper region
817               tval(i) = 1. - ((zm(i,k) - 0.9*ht(i)) / (1.0*ht(i) - 0.9*ht(i)))
818            else  ! Above taper region
819               tval(i) = 0.
820            end if
821            thup_temfx(i,k) = tval(i) * thup_temfx(i,k) + (1-tval(i))*thetal(i,k)
822            thetavUPD(i,k) = tval(i) * thetavUPD(i,k) + (1-tval(i))*thetav(i,k)
823            qtup_temfx(i,k) = tval(i) * qtup_temfx(i,k) + (1-tval(i)) * qt(i,k)
824            qlUPD(i,k) = tval(i) * qlUPD(i,k) + (1-tval(i)) * qcx(i,k-1)
825            UUPD(i,k) = tval(i) * UUPD(i,k) + (1-tval(i)) * u_temf(i,k)
826            VUPD(i,k) = tval(i) * VUPD(i,k) + (1-tval(i)) * v_temf(i,k)
827            TEUPD(i,k) = tval(i) * TEUPD(i,k) + (1-tval(i)) * te_temfx(i,k)
828            if (zm(i,k) > ht(i)) then  ! WA this is just for cleanliness
829               wupd_temfx(i,k) = 0.
830               dwUPDmoistdz(i,k) = 0.
831               wupd_dry(i,k) = 0.
832               dwUPDdz(i,k) = 0.
833            end if
834         end do
835
836         ! Calculate lateral detrainment rate for cloud layer
837         deltmf(i,1) = Cepsmf
838         do k = 2,kte-1
839            if (hctidx(i) > hdidx(i)+1) then      ! Some cloud
840               deltmf(i,k) = 0.9 * Cepsmf + Cdelt * (atan((zm(i,k)-(lcl(i)+(hct(i)-lcl(i))/1.5))/((hct(i)-lcl(i))/8))+(3.1415926/2))/3.1415926
841            else if (k < hdidx(i)) then   ! No cloud, below hd
842               deltmf(i,k) = Cepsmf + 0.05 * 1. / (hd(i) - zm(i,k))
843            else if (k >= hdidx(i)) then    ! No cloud, above hd
844               deltmf(i,k) = deltmf(i,k-1)
845            end if
846         end do
847
848         ! Calculate mass flux (defined on turbulence levels)
849         mf_temfx(i,1) = CM * wstr(i)
850         do kt = 2,kte-1
851            dMdz(i,kt) = (epsmf(i,kt) - deltmf(i,kt)) * mf_temfx(i,kt-1) * dzt(i,kt)
852            mf_temfx(i,kt) = mf_temfx(i,kt-1) + dMdz(i,kt)
853         end do
854
855         ! WA 12/28/09 If mass flux component > diffusive
856         ! component at second level,
857         ! reduce M to prevent a stable layer
858         MFCth(i,2) = mf_temfx(i,2) * (thup_temfx(i,2)-thetal(i,2) + thup_temfx(i,3)-thetal(i,3)) / 2.
859         if (MFCth(i,2) > Fz(i,2)) then
860            red_fact = Fz(i,2) / MFCth(i,2)
861            do kt = 1,kte
862               mf_temfx(i,kt) = mf_temfx(i,kt) * red_fact
863            end do
864         end if  ! Reduce M to prevent stable layer at second level
865
866         ! Calculate mass flux contributions to fluxes (defined on turb levels)
867         ! Use log interpolation at first level
868         MFCth(i,1) = mf_temfx(i,1) * (thup_temfx(i,1)-thetal(i,1) + (thup_temfx(i,2)-thetal(i,2) - (thup_temfx(i,1)-thetal(i,1))) * log(zt(i,1)/znt(i))/log(zm(i,2)/znt(i)))
869         MFCq(i,1) = mf_temfx(i,1) * (qtup_temfx(i,1)-qt(i,1) + (qtup_temfx(i,2)-qt(i,2) - (qtup_temfx(i,1)-qt(i,1))) * log(zt(i,1)/znt(i))/log(zm(i,2)/znt(i)))
870         MFCu(i,1) = mf_temfx(i,1) * (UUPD(i,1)-u_temf(i,1) + (UUPD(i,2)-u_temf(i,2) - (UUPD(i,1)-u_temf(i,1))) * log(zt(i,1)/znt(i))/log(zm(i,2)/znt(i)))
871         MFCv(i,1) = mf_temfx(i,1) * (VUPD(i,1)-v_temf(i,1) + (VUPD(i,2)-v_temf(i,2) - (VUPD(i,1)-v_temf(i,1))) * log(zt(i,1)/znt(i))/log(zm(i,2)/znt(i)))
872         MFCql(i,1) = mf_temfx(i,1) * (qlUPD(i,1)-qcx(i,1) + (qlUPD(i,2)-qcx(i,2) - (qlUPD(i,1)-qcx(i,1))) * log(zt(i,1)/znt(i))/log(zm(i,2)/znt(i)))
873         MFCTE(i,1) = mf_temfx(i,1) * (TEUPD(i,1)-te_temfx(i,1) + (TEUPD(i,2)-te_temfx(i,2) - (TEUPD(i,1)-te_temfx(i,1))) * log(zt(i,1)/znt(i))/log(zm(i,2)/znt(i)))  ! WA Check this
874         do kt = 2,kte-1
875            MFCth(i,kt) = mf_temfx(i,kt) * (thup_temfx(i,kt)-thetal(i,kt) + thup_temfx(i,kt+1)-thetal(i,kt+1)) / 2.
876            MFCq(i,kt) = mf_temfx(i,kt) * (qtup_temfx(i,kt)-qt(i,kt) + qtup_temfx(i,kt+1)-qt(i,kt+1)) / 2.
877            MFCu(i,kt) = mf_temfx(i,kt) * (UUPD(i,kt)-u_temf(i,kt) + UUPD(i,kt+1)-u_temf(i,kt+1)) / 2.
878            MFCv(i,kt) = mf_temfx(i,kt) * (VUPD(i,kt)-v_temf(i,kt) + VUPD(i,kt+1)-v_temf(i,kt+1)) / 2.
879            MFCql(i,kt) = mf_temfx(i,kt) * (qlUPD(i,kt)-qcx(i,kt-1) + qlUPD(i,kt+1)-qcx(i,kt)) / 2.
880            MFCTE(i,kt) = mf_temfx(i,kt) * (TEUPD(i,kt)-te_temfx(i,kt)) ! TE is on turb levels
881         end do
882         MFCth(i,kte) = 0
883         MFCq(i,kte) = 0
884         MFCu(i,kte) = 0
885         MFCv(i,kte) = 0
886         MFCql(i,kte) = 0
887         MFCTE(i,kte) = 0
888
889         ! Calculate cloud fraction (on mass levels)
890         cf3d_temfx(i,1) = 0.0
891         cfm_temfx(i) = 0.0
892         do k = 2,kte
893            ! if (wupd_temfx(i,k-1) >= 1.0e-15 .AND. wupd_temfx(i,k) >= 1.0e-15 .AND. .NOT. isnan(wupd_temfx(i,k-1)) .AND. .NOT. isnan(wupd_temfx(i,k))) then
894            if (wupd_temfx(i,k-1) >= 1.0e-15 .AND. wupd_temfx(i,k) >= 1.0e-15) then
895               au(i,k) = ((mf_temfx(i,k-1)+mf_temfx(i,k))/2.0) / ((wupd_temfx(i,k-1)+wupd_temfx(i,k))/2.0)  ! WA average before divide, is that best?
896            else
897               au(i,k) = 0.0
898            end if
899            sigq2 = au(i,k) * (qtup_temfx(i,k)-qt(i,k))
900            if (sigq2 > 0.0) then
901               sigq(i,k) = sqrt(sigq2)
902            else
903               sigq(i,k) = 0.0
904            end if
905            ! rst = rsat(p2d(i,k),thx(i,k)*pi2d(i,k),ep2)
906            rst = rsat(p2d(i,k-1),thx(i,k-1)*pi2d(i,k-1),ep2)
907            qst(i,k) = rst / (1. + rst)
908            satdef(i,k) = qt(i,k) - qst(i,k)
909            if (satdef(i,k) <= 0.0) then
910               if (sigq(i,k) > 1.0e-15) then
911                  cf3d_temfx(i,k) = max(0.5 + 0.36 * atan(1.55*(satdef(i,k)/sigq(i,k))),0.0)
912               else
913                  cf3d_temfx(i,k) = 0.0
914               end if
915            else
916               cf3d_temfx(i,k) = 1.0
917            end if
918            if (zm(i,k) < lcl(i)) then
919               cf3d_temfx(i,k) = 0.0
920            end if
921            ! Put max value so far into cfm
922            if (zt(i,k) <= hmax) then
923               cfm_temfx(i) = max(cf3d_temfx(i,k),cfm_temfx(i))
924            end if
925         end do
926
927      else    ! not is_convective, no MF components
928         do kt = 1,kte
929            MFCth(i,kt) = 0
930            MFCq(i,kt) = 0
931            MFCu(i,kt) = 0
932            MFCv(i,kt) = 0
933            MFCql(i,kt) = 0
934            MFCTE(i,kt) = 0
935         end do
936         lcl(i) = zm(i,kte-1)
937         hct(i) = zm(i,1)
938         hctidx(i) = 1
939         hd(i) = zm(i,1)
940         hdidx(i) = 1
941         ht(i) = hd(i)
942         ! Cloud fraction calculations
943         cf3d_temfx(i,1) = 0.0
944         cfm_temfx(i) = 0.0
945         do k = 2,kte
946            if (qcx(i,k-1) > 1.0e-15) then
947               cf3d_temfx(i,k) = 1.0
948            else
949               cf3d_temfx(i,k) = 0.0
950            end if
951            ! Put max value so far into cfm
952            if (zt(i,k) <= hmax) then
953               cfm_temfx(i) = max(cf3d_temfx(i,k),cfm_temfx(i))
954            end if
955         end do
956
957      end if   ! MF components or not
958      cf3d_temfx(i,kte) = 0.0
959      ! Mass flux block ends here
960
961      ! Flux profiles
962      do kt = 2,kte
963         ! Fz(i,kt) = -kh(i,kt) * dthdz(i,kt)
964         shf_temfx(i,kt) = Fz(i,kt) + MFCth(i,kt)
965         QFK(i,kt) = -kh(i,kt) * dqtdz(i,kt)
966         qf_temfx(i,kt) = QFK(i,kt) + MFCq(i,kt)
967         uwk(i,kt) = -km(i,kt) * dudz(i,kt)
968         uw_temfx(i,kt) = uwk(i,kt) + MFCu(i,kt)
969         vwk(i,kt) = -km(i,kt) * dvdz(i,kt)
970         vw_temfx(i,kt) = vwk(i,kt) + MFCv(i,kt)
971      end do
972
973      ! Surface momentum fluxes
974      ust(i) = sqrt(ftau(i,1)/ftau0) * sqrt(u_temf(i,2)**2. + v_temf(i,2)**2.) * leps(i,1) / log(zm(i,2)/znt(i)) / zt(i,1)
975      ang(i) = atan2(v_temf(i,2),u_temf(i,2))
976      uw_temfx(i,1) = -cos(ang(i)) * ust(i)**2.
977      vw_temfx(i,1) = -sin(ang(i)) * ust(i)**2.
978
979      ! Calculate mixed scaling velocity (Moeng & Sullivan 1994 JAS p.1021)
980      ! Replaces ust everywhere (WA need to reconsider?)
981      ! wm(i) = (1./5. * (wstr(i)**3. + 5. * ust(i)**3.)) ** (1./3.)
982      ! WA TEST (R2,R11) 7/23/10 reduce velocity scale to fix excessive fluxes
983      wm(i) = 0.5 * (1./5. * (wstr(i)**3. + 5. * ust(i)**3.)) ** (1./3.)
984      ! WA TEST 2/14/11 limit contribution of w*
985      ! wm(i) = 0.5 * (1./5. * (min(0.8,wstr(i))**3. + 5. * ust(i)**3.)) ** (1./3.)
986      ! WA TEST (R3-R11) 7/23/10 wm = u*
987      ! wm(i) = ust(i)
988
989      ! Specified flux versions (flux is modified by land surface)
990      shf_temfx(i,1) = hfx(i)/(rho(i,1)*cp) + (shf_temfx(i,2) - hfx(i)/(rho(i,1)*cp)) * (zt(i,2)-zt(i,1)) / (zt(i,2)-znt(i))
991      qf_temfx(i,1) = qfx(i)/rho(i,1) + (qf_temfx(i,2)-qfx(i)/rho(i,1)) * (zt(i,2)-zt(i,1)) / (zt(i,2)-znt(i))
992      Fz(i,1) = shf_temfx(i,1) - MFCth(i,1)
993      QFK(i,1) = qf_temfx(i,1) - MFCq(i,1)
994
995
996      ! Calculate thetav and its flux
997      ! From Lewellen 2004 eq. 3
998      ! WA The constants and combinations below should probably be replaced
999      ! by something more consistent with the WRF system, but for now
1000      ! I don't want to take the chance of breaking something.
1001      do kt = 2,kte-1
1002         alpha2(i,kt) = 0.61 * (thetal(i,kt) + thetal(i,kt+1)) / 2.
1003         beta2(i,kt) = (100000. / p2di(i,kt))**0.286 * 2.45e-6 / 1004.67 - 1.61 * (thetal(i,kt) + thetal(i,kt+1)) / 2.
1004      end do
1005      alpha2(i,1) = 0.61 * (thetal(i,1) + (thetal(i,2)-thetal(i,1)) * (zt(i,2) - znt(i)) / (zm(i,2) - znt(i)))
1006      alpha2(i,kte) = 0.61 * thetal(i,kte)
1007      beta2(i,1) = (100000. / p2di(i,1))**0.286 * 2.45e-6 / 1004.67 - 1.61 * (thetal(i,1) + (thetal(i,2) - thetal(i,1))  * (zt(i,2) - znt(i)) / (zm(i,2) - znt(i)))
1008      beta2(i,kte) = (100000. / p2di(i,kte))**0.286 * 2.45e-6 / 1004.67 - 1.61 * thetal(i,kte)
1009      if ( is_convective ) then ! Activate EDMF components
1010         do kt = 1,kte-1
1011            MFCthv(i,kt) = (1. + 0.61 * (qtup_temfx(i,kt)+qtup_temfx(i,kt+1))) / 2. * MFCth(i,kt) + alpha2(i,kt) * MFCq(i,kt) + beta2(i,kt) * MFCql(i,kt)
1012         end do
1013         MFCthv(i,kte) = 0.
1014      else    ! No MF components
1015         do kt = 1,kte
1016            MFCthv(i,kt) = 0.
1017         end do
1018      end if
1019
1020      do kt = 1,kte
1021         THVF(i,kt) = (1. + 0.61 * qt(i,kt)) * Fz(i,kt) + alpha2(i,kt) * QFK(i,kt) + MFCthv(i,kt)
1022      end do
1023
1024      ! Update mean variables:
1025      ! This is done with implicit solver for diffusion part followed
1026      ! by explicit solution for MF terms.
1027      ! Note that Coriolis terms that were source terms for u and v
1028      ! in Matlab code are now handled by WRF outside this PBL context.
1029
1030      u_new(i,:) = u_temf(i,:)
1031      call solve_implicit_temf(km(i,kts:kte-1),u_new(i,kts+1:kte),uw_temfx(i,1),dzm(i,kts:kte-1),dzt(i,kts:kte-1),kts,kte-1,dt,.FALSE.)
1032      do k = 2,kte-1
1033         u_new(i,k) = u_new(i,k) + dt * (-(MFCu(i,k)-MFCu(i,k-1))) / dzm(i,k)
1034      end do
1035
1036      v_new(i,:) = v_temf(i,:)
1037      call solve_implicit_temf(km(i,kts:kte-1),v_new(i,kts+1:kte),vw_temfx(i,1),dzm(i,kts:kte-1),dzt(i,kts:kte-1),kts,kte-1,dt,.FALSE.)
1038      do k = 2,kte-1
1039         v_new(i,k) = v_new(i,k) + dt * (-(MFCv(i,k)-MFCv(i,k-1))) / dzm(i,k)
1040      end do
1041
1042      call solve_implicit_temf(kh(i,kts:kte-1),thetal(i,kts+1:kte),Fz(i,1),dzm(i,kts:kte-1),dzt(i,kts:kte-1),kts,kte-1,dt,.FALSE.)
1043      do k = 2,kte-1
1044         thetal(i,k) = thetal(i,k) + dt * (-(MFCth(i,k)-MFCth(i,k-1))) / dzm(i,k)
1045      end do
1046
1047      call solve_implicit_temf(kh(i,kts:kte-1),qt(i,kts+1:kte),QFK(i,1),dzm(i,kts:kte-1),dzt(i,kts:kte-1),kts,kte-1,dt,.FALSE.)
1048      do k = 2,kte-1
1049         qt(i,k) = qt(i,k) + dt * (-(MFCq(i,k)-MFCq(i,k-1))) / dzm(i,k)
1050      end do
1051
1052      ! Stepping TE forward is a bit more complicated
1053      te_temfx(i,1) = ust(i)**2. / ftau(i,1) * (1. + ratio(i,1))
1054      if ( is_convective ) then
1055         ! WA currently disabled if MFopt=false, is that right?
1056         convection_TKE_surface_src(i) = 2. * beta(i,1) * shf_temfx(i,1)
1057      else
1058         convection_TKE_surface_src(i) = 0.
1059      end if
1060      te_temfx(i,1) = max(te_temfx(i,1), (leps(i,1) / Cgamma * (ust(i)**2. * S(i,1) + convection_TKE_surface_src(i)))**(2./3.))
1061      sfcFTE(i) = -(km(i,1)+km(i,2)) / 2. * (te_temfx(i,2)-te_temfx(i,1)) / dzm(i,2)
1062
1063      do kt = 1,kte
1064         if (THVF(i,kt) >= 0) then
1065            buoy_src(i,kt) = 2. * g / thetav(i,kt) * THVF(i,kt)
1066         else
1067            buoy_src(i,kt) = 0.  ! Cancel buoyancy term when locally stable
1068         end if
1069         srcs(i,kt) = -uw_temfx(i,kt) * dudz(i,kt) - vw_temfx(i,kt) * dvdz(i,kt) - Cgamma * te_temfx(i,kt)**1.5 * linv(i,kt) + buoy_src(i,kt)
1070      end do
1071      call solve_implicit_temf((km(i,kts:kte-1)+km(i,kts+1:kte))/2.0,te_temfx(i,kts+1:kte),sfcFTE(i),dzt(i,kts+1:kte),dzt(i,kts:kte-1),kts,kte-1,dt,.false.)
1072      do kt = 2,kte-1
1073         te_temfx(i,kt) = te_temfx(i,kt) + dt * srcs(i,kt)
1074         te_temfx(i,kt) = te_temfx(i,kt) + dt * (-(MFCTE(i,kt)-MFCTE(i,kt-1))) / dzt(i,kt)
1075         if (te_temfx(i,kt) < TEmin) te_temfx(i,kt) = TEmin
1076      end do
1077      te_temfx(i,kte) = 0.0   ! WA 4/2/10
1078      do kt = 2,kte-1
1079         if (te_temfx(i,kt) > 30.0) then      ! WA DEBUG
1080            te_temfx(i,kt) = 30.0    ! WA TEST limit max TE
1081         end if
1082      end do
1083
1084      ! Done with updates, now convert internal variables back to WRF vars
1085      do k = kts,kte
1086         ! Populate kh_temfx, km_temfx from kh, km
1087         kh_temfx(i,k) = kh(i,k)
1088         km_temfx(i,k) = km(i,k)
1089      end do
1090
1091      ! Convert thetal, qt back to theta, qv, qc
1092      ! See opposite conversion at top of subroutine
1093      ! WA this accounts for offset of indexing between
1094      ! WRF and TEMF, see notes at top of this routine.
1095      call thlqt2thqvqc(thetal(i,kts+1:kte),qt(i,kts+1:kte),thx_new(i,kts:kte-1),qvx_new(i,kts:kte-1),qcx_new(i,kts:kte-1),p2d(i,kts:kte-1),pi2d(i,kts:kte-1),kts,kte-1,ep2,xlv,cp)
1096
1097      do k = kts,kte-1
1098         ! Calculate tendency terms
1099         ! WA this accounts for offset of indexing between
1100         ! WRF and TEMF, see notes at top of this routine.
1101         rubltenx(i,k) = (u_new(i,k+1) - u_temf(i,k+1)) / dt
1102         rvbltenx(i,k) = (v_new(i,k+1) - v_temf(i,k+1)) / dt
1103         rthbltenx(i,k) = (thx_new(i,k) - thx(i,k)) / dt
1104         rqvbltenx(i,k) = (qvx_new(i,k) - qvx(i,k)) / dt
1105         rqcbltenx(i,k) = (qcx_new(i,k) - qcx(i,k)) / dt
1106      end do
1107      rubltenx(i,kte) = 0.
1108      rvbltenx(i,kte) = 0.
1109      rthbltenx(i,kte) = 0.
1110      rqvbltenx(i,kte) = 0.
1111      rqcbltenx(i,kte) = 0.
1112
1113      ! Populate surface exchange coefficient variables to go back out
1114      ! for next time step of surface scheme
1115      ! Unit specifications in SLAB and sfclay are conflicting and probably
1116      ! incorrect.  This will give a dynamic heat flux (W/m^2) or moisture
1117      ! flux (kg(water)/(m^2*s)) when multiplied by a difference.
1118      ! These formulae are the same as what's used above to get surface
1119      ! flux from surface temperature and specific humidity.
1120      ! WA 2/16/11 removed, not needed in BL
1121      ! flhc(i) = rho(i,1) * cp * fth(i,1)/fth0 * wm(i) * leps(i,1) / PrT0 / log(zm(i,2)/z0t(i)) / zt(i,1)
1122      ! flqc(i)  = rho(i,1) * fth(i,1)/fth0 * wm(i) * leps(i,1) / PrT0 / log(zm(i,2)/z0t(i)) / zt(i,1)
1123      ! WA Must exchange coeffs be limited to avoid runaway in some
1124      ! (convective?) conditions?  Something like this is done in sfclay.
1125      ! Doing nothing for now.
1126
1127      ! Populate 10 m winds and 2 m temp
1128      ! WA Note this only works if first mass level is above 10 m
1129      u10(i) = u_new(i,2) * log(10.0/znt(i)) / log(zm(i,2)/znt(i))
1130      v10(i) = v_new(i,2) * log(10.0/znt(i)) / log(zm(i,2)/znt(i))
1131      t2(i) = (tsk(i)/pi2d(i,1) + (thx_new(i,1) - tsk(i)/pi2d(i,1)) * log(2.0/z0t(i)) / log(zm(i,2)/z0t(i))) * pi2d(i,1)  ! WA this should also use pi at z0
1132
1133      ! Populate diagnostic variables
1134      hd_temfx(i) = hd(i)
1135      lcl_temfx(i) = lcl(i)
1136      hct_temfx(i) = hct(i)
1137
1138      ! Send updraft liquid water back
1139      if ( is_convective) then
1140         do k = kts,kte-1
1141            qlup_temfx(i,k) = qlUPD(i,k)
1142         end do
1143      else
1144         qlup_temfx(i,1) = qcx(i,1)
1145         do k = kts+1,kte-1
1146            qlup_temfx(i,k) = qcx(i,k-1)
1147         end do
1148      end if
1149      qlup_temfx(i,kte) = qcx(i,kte)
1150
1151   end do  ! Main (i) loop
1152
1153   end subroutine temf2d
1154!
1155!--------------------------------------------------------------------
1156!
1157   subroutine thlqt2thqvqc(thetal,qt,theta,qv,qc,p,piex,kbot,ktop,ep2,Lv,Cp)
1158
1159!  Calculates theta, qv, qc from thetal, qt.
1160!  Originally from RAMS (subroutine satadjst) by way of Hongli Jiang.
1161
1162   implicit none
1163   integer, intent(in   ) :: kbot, ktop
1164   real,    dimension( kbot:ktop ), intent(in   ) :: thetal, qt
1165   real,    dimension( kbot:ktop ), intent(  out) :: theta, qv, qc
1166   real,    dimension( kbot:ktop ), intent(in   ) :: p, piex
1167   real,    intent(in   ) :: ep2, Lv, Cp
1168!
1169!  Local variables
1170   integer :: k, iterate
1171   real :: T1, Tt
1172   real, dimension( kbot:ktop) :: rst
1173   real, dimension( kbot:ktop) :: Tair, rc, rt, rv
1174!
1175   do k = kbot,ktop
1176      T1 = thetal(k) * piex(k)   ! First guess T is just thetal converted to T
1177      Tair(k) = T1
1178      rt(k) = qt(k) / (1. - qt(k))
1179
1180      do iterate = 1,20
1181         rst(k) = rsat(p(k),Tair(k),ep2)
1182         rc(k) = max(rt(k) - rst(k), 0.)
1183         Tt = 0.7*Tair(k) + 0.3*T1 * (1.+Lv*rc(k) / (Cp*max(Tair(k),253.)))
1184         if ( abs(Tt - Tair(k)) < 0.001) GOTO 100
1185         Tair(k) = Tt
1186      end do
1187100   continue
1188      rv(k) = rt(k) - rc(k)
1189      qv(k) = rv(k) / (1. + rv(k))
1190      qc(k) = rc(k) / (1. + rc(k))
1191      theta(k) = Tair(k) / piex(k)
1192   end do ! k loop
1193   return
1194   end subroutine thlqt2thqvqc
1195!
1196!--------------------------------------------------------------------
1197!
1198   subroutine findhct_te( thetavenv,thetaparin,qpar, &
1199                          rpar,hdidx,paridx,zm,hct,hctidx,p,piex,ep2,kbot,ktop)
1200
1201! Calculates the cloud top height (limit of convection) for the
1202! updraft properties.  hct is the level at which a parcel lifted
1203! at the moist adiabatic rate where it is saturated and at the dry
1204! adiabatic rate otherwise, first has thetav cooler than the environment.
1205! Loops start at LCL (paridx).
1206
1207   implicit none
1208   integer, intent(in) :: kbot, ktop
1209   integer, intent(in) :: paridx, hdidx
1210   real, intent(in)    :: ep2
1211   real, dimension( kbot:ktop), intent(in) :: thetavenv
1212   real, dimension( kbot:ktop), intent(in) :: thetaparin
1213   real, dimension( kbot:ktop), intent(in) :: qpar, rpar, zm, p, piex
1214   real, intent(out)    :: hct
1215   integer, intent(out) :: hctidx
1216! Local variables
1217   integer k
1218   real, dimension( kbot:ktop) :: thetapar, thetavpar, qlpar, Tpar, rsatpar
1219   real, dimension( kbot:ktop) :: qsatpar
1220   real :: gammas, TparC
1221
1222   thetapar(paridx) = thetaparin(paridx)
1223   Tpar(paridx) = thetapar(paridx) * piex(paridx)
1224   hctidx = ktop   ! In case hct not found
1225   do k = paridx+1,ktop
1226      ! Find saturation mixing ratio at parcel temperature
1227      rsatpar(k) = rsat(p(k-1),Tpar(k-1),ep2)
1228      qsatpar(k) = rsatpar(k) / (1. + rsatpar(k))
1229
1230      ! When parcel is unsaturated, its temperature changes
1231      ! at dry adiabatic rate (in other words, theta is constant).
1232      if (rpar(k) <= rsatpar(k)) then
1233         thetapar(k) = thetapar(k-1)
1234         Tpar(k) = thetapar(k) * piex(k)
1235         thetavpar(k) = thetapar(k) * (1.+0.608*qpar(k))
1236      else
1237         ! When parcel is saturated, its temperature changes at
1238         ! moist adiabatic rate
1239         ! Calculate moist adiabatic lapse rate according to Gill A4.12
1240         ! Requires T in deg.C
1241         TparC = Tpar(k-1) - 273.15
1242         gammas = 6.4 - 0.12 * TparC + 2.5e-5 * TparC**3. + (-2.4 + 1.e-3 * (TparC-5.)**2.) * (1. - p(k-1)/100000.)
1243         Tpar(k) = Tpar(k-1) - gammas/1000. * (zm(k)-zm(k-1))
1244         thetapar(k) = Tpar(k) / piex(k)
1245         qlpar(k) = qpar(k) - qsatpar(k)  ! Liquid water in parcel
1246         thetavpar(k) = thetapar(k) * (1. + 0.608 * qsatpar(k) - qlpar(k))
1247      end if
1248      if (thetavenv(k) >= thetavpar(k)) then
1249         hctidx = k
1250         goto 1000
1251      end if
1252   end do
12531000  hct = zm(hctidx)
1254   return
1255   end subroutine findhct_te
1256!
1257!--------------------------------------------------------------------
1258!
1259   real function rsat(p,T,ep2)
1260
1261!  Calculates the saturation mixing ratio with respect to liquid water
1262!  Arguments are pressure (Pa) and absolute temperature (K)
1263!  Uses the formula from the ARM intercomparison setup.
1264!  Converted from Matlab by WA 7/28/08
1265
1266implicit none
1267real p, T, ep2
1268real temp, x
1269real, parameter :: c0 = 0.6105851e+3
1270real, parameter :: c1 = 0.4440316e+2
1271real, parameter :: c2 = 0.1430341e+1
1272real, parameter :: c3 = 0.2641412e-1
1273real, parameter :: c4 = 0.2995057e-3
1274real, parameter :: c5 = 0.2031998e-5
1275real, parameter :: c6 = 0.6936113e-8
1276real, parameter :: c7 = 0.2564861e-11
1277real, parameter :: c8 = -0.3704404e-13
1278
1279temp = T - 273.15
1280
1281x =c0+temp*(c1+temp*(c2+temp*(c3+temp*(c4+temp*(c5+temp*(c6+temp*(c7+temp*c8)))))))
1282rsat = ep2*x/(p-x)
1283
1284return
1285end function rsat
1286!
1287!--------------------------------------------------------------------
1288!
1289   subroutine solve_implicit_temf(Khlf,psi_n,srf_flux,dzm,dzt,kbot,ktop,dt,print_flag)
1290
1291!  Implicit solution of vertical diffusion for conserved variable
1292!  psi given diffusivity Khlf on turbulence levels,
1293!  and surface flux srf_flux.
1294!  dzm is delta_z of mass levels, dzt is delta_z of turbulence levels.
1295!  dt is timestep (s).
1296
1297   implicit none
1298   integer  :: kbot, ktop
1299   logical  :: print_flag
1300   real :: srf_flux, dt
1301   real,    dimension( kbot:ktop ), intent(in   ) :: Khlf
1302   real,    dimension( kbot:ktop ), intent(in   ) :: dzm, dzt
1303   real,    dimension( kbot:ktop ), intent(inout) :: psi_n
1304!
1305!  Local variables
1306   integer :: k
1307   real,    dimension( kbot:ktop ) :: AU, BU, CU, YU
1308!
1309   AU(kbot) = Khlf(kbot) / (dzm(kbot)*dzt(kbot))
1310   BU(kbot) = -1.0/dt - Khlf(kbot+1)/(dzm(kbot+1)*dzt(kbot+1))
1311   CU(kbot) = Khlf(kbot+1)/(dzm(kbot)*dzt(kbot+1))
1312   YU(kbot) = -psi_n(kbot)/dt - srf_flux/dzm(kbot)
1313
1314   do k = kbot+1,ktop-1
1315      ! Subdiagonal (A) vector
1316      AU(k) = Khlf(k) / (dzm(k) * dzt(k))
1317      ! Main diagonal (B) vector
1318      BU(k) = -1.0/dt - (Khlf(k)/dzt(k) + Khlf(k+1)/dzt(k+1)) / dzm(k)
1319      ! Superdiagonal (C) vector
1320      CU(k) = Khlf(k+1) / (dzm(k)*dzt(k+1))
1321      ! Result vector
1322      YU(k) = -psi_n(k)/dt
1323   end do ! k loop
1324
1325   AU(ktop) = 0.
1326   BU(ktop) = -1.0 / dt
1327   YU(ktop) = -psi_n(ktop) / dt
1328
1329   ! Compute result with tridiagonal routine
1330   psi_n = trid(AU,BU,CU,YU,kbot,ktop)
1331
1332   return
1333   end subroutine solve_implicit_temf
1334!
1335!--------------------------------------------------------------------
1336!
1337   function trid(a,b,c,r,kbot,ktop)
1338
1339!  Solves tridiagonal linear system.
1340!  Inputs are subdiagonal vector a, main diagonal b, superdiagonal c,
1341!  result r, column top and bottom indices kbot and ktop.
1342!  Originally from Numerical Recipes section 2.4.
1343
1344   implicit none
1345   real,    dimension( kbot:ktop ) :: trid
1346   integer  :: kbot, ktop
1347   real,    dimension( kbot:ktop ), intent(in   ) :: a, b, c, r
1348!
1349!  Local variables
1350   integer :: k
1351   real    :: bet
1352   real,    dimension( kbot:ktop ) :: gam, u
1353!
1354   bet = b(kbot)
1355   u(kbot) = r(kbot) / bet
1356
1357   do k = kbot+1,ktop
1358      gam(k) = c(k-1) / bet
1359      bet = b(k) - a(k)*gam(k)
1360      u(k) = (r(k) - a(k)*u(k-1)) / bet
1361   end do
1362
1363   do k = ktop-1,kbot,-1
1364      u(k) = u(k) - gam(k+1)*u(k+1)
1365   end do
1366
1367   trid = u
1368
1369   return
1370   end function trid
1371!
1372!--------------------------------------------------------------------
1373!
1374   subroutine temfinit(rublten,rvblten,rthblten,rqvblten,                      &
1375                      rqcblten,rqiblten,p_qi,p_first_scalar,                   &
1376                      restart, allowed_to_read,                                &
1377                      te_temf, cf3d_temf,                                     &
1378                      ids, ide, jds, jde, kds, kde,                            &
1379                      ims, ime, jms, jme, kms, kme,                            &
1380                      its, ite, jts, jte, kts, kte                 )
1381!-------------------------------------------------------------------
1382   implicit none
1383!-------------------------------------------------------------------
1384!
1385   logical , intent(in)          :: restart, allowed_to_read
1386   integer , intent(in)          ::  ids, ide, jds, jde, kds, kde,             &
1387                                     ims, ime, jms, jme, kms, kme,             &
1388                                     its, ite, jts, jte, kts, kte
1389   integer , intent(in)          ::  p_qi,p_first_scalar
1390   real , dimension( ims:ime , kms:kme , jms:jme ), intent(out) ::             &
1391                                                                      rublten, &
1392                                                                      rvblten, &
1393                                                                     rthblten, &
1394                                                                     rqvblten, &
1395                                                                     rqcblten, &
1396                                                                     rqiblten, &
1397                                                                     te_temf, &
1398                                                                     cf3d_temf
1399! Local variables
1400   integer :: i, j, k, itf, jtf, ktf
1401   real, parameter :: TEmin = 1e-3
1402!
1403   jtf = min0(jte,jde-1)
1404   ktf = min0(kte,kde-1)
1405   itf = min0(ite,ide-1)
1406!
1407   if(.not.restart)then
1408     do j = jts,jtf
1409     do k = kts,ktf
1410     do i = its,itf
1411        rublten(i,k,j) = 0.
1412        rvblten(i,k,j) = 0.
1413        rthblten(i,k,j) = 0.
1414        rqvblten(i,k,j) = 0.
1415        rqcblten(i,k,j) = 0.
1416        te_temf(i,k,j) = TEmin
1417        cf3d_temf(i,k,j) = 0.
1418     enddo
1419     enddo
1420     enddo
1421   endif
1422!
1423   if (p_qi .ge. p_first_scalar .and. .not.restart) then
1424      do j = jts,jtf
1425      do k = kts,ktf
1426      do i = its,itf
1427         rqiblten(i,k,j) = 0.
1428      enddo
1429      enddo
1430      enddo
1431   endif
1432!
1433   end subroutine temfinit
1434!-------------------------------------------------------------------
1435end module module_bl_temf
Note: See TracBrowser for help on using the repository browser.