1 MODULE module_cu_camzm_driver
3 !Roughly based on zm_conv_intr.F90 from CAM
5 !-------------------------------------------
6 !Future Modifications and important warning (BSINGH:02/01/2013: Notes from WIG):
7 !===========================================
8 !1. Fracis is hardwired to 1 for first 3 constituents (vapor,liq mass,ice mass)
9 ! for WRF_CHEM simulations and first 5 constituents(liq # and ice #) for WRF
10 ! physcis ONLY runs. Should be generalized for other constituents (like snow,graupel etc.)
12 !2. In CAM model, ZM scheme only acts up to 40 mb. In WRF, it will function all the way
13 ! to the model top no matter how high it is. We could do a better job at capping this
14 ! by checking to see where 40 mb roughly occurs during initialization. It won't change
15 ! too dramatically over time. Also, WRF often uses a top of 50 mb, so we rarely hit 40 mb.
16 ! This is a minor issue.
17 !3. ZM is set to never do convection w/in the PBL. In CAM model, this is dependent on the
18 ! use of UW shallow. Should this be a conditional setting in WRF or hard-wired as it
20 !-----------------------------------------
23 USE module_cam_support, only: pcnst =>pcnst_runtime, pcols, pver, pverp
25 USE module_cam_support, only: cam_mam_aerosols
27 USE shr_kind_mod, only: r8 => shr_kind_r8
28 USE module_cu_camzm, only: convtran, momtran, zm_conv_evap, zm_convr
32 PRIVATE !Default to private
33 PUBLIC :: & !Public entities
40 !Module level variables which are required for zm_conv_tend_2 subrouine
41 integer :: ixcldliq, ixcldice, ixnumliq, ixnumice
45 !------------------------------------------------------------------------
46 SUBROUTINE camzm_driver( &
47 ids,ide, jds,jde, kds,kde &
48 ,ims,ime, jms,jme, kms,kme &
49 ,its,ite, jts,jte, kts,kte &
50 ,itimestep, bl_pbl_physics, sf_sfclay_physics &
51 ,th, t_phy, tsk, tke_pbl, ust, qv, qc, qi &
52 ,mavail, kpbl, pblh, xland, z &
53 ,z_at_w, dz8w, ht, p, p8w, pi_phy, psfc &
54 ,u_phy, v_phy, hfx, qfx, cldfra, cldfra_mp_all &
55 ,is_CAMMGMP_used, tpert_camuwpbl &
56 ,dx, dt, stepcu, cudt, curr_secs, adapt_step_flag&
58 ,cape_out, mu_out, md_out, zmdt, zmdq &
60 ,pconvb, pconvt, cubot, cutop, raincv, pratec &
62 ,rthcuten, rqvcuten, rqccuten, rqicuten &
63 ,rqcncuten, rqincuten &
64 ,evaptzm, fzsntzm, evsntzm, evapqzm, zmflxprc &
65 ,zmflxsnw, zmntprpd, zmntsnpd, zmeiheat &
66 ,cmfmc, cmfmcdzm, preccdzm, precz &
67 ,zmmtu, zmmtv, zmupgu, zmupgd, zmvpgu, zmvpgd &
68 ,zmicuu, zmicud, zmicvu, zmicvd &
70 !Following intent-OUT variables are required by wet scavenging code of WRF_CHEM package- Balwinder.Singh@pnnl.gov
71 ,evapcdp3d, icwmrdp3d, rprddp3d &
72 !Following intent-OUT variables are required by zm_conv_tend_2 call
73 ,dp3d, du3d, ed3d, eu3d, md3d, mu3d, dsubcld2d &
74 ,ideep2d, jt2d, maxg2d, lengath2d )
76 ! This routine is based on zm_conv_tend in CAM. It handles the mapping of
77 ! variables from the WRF to the CAM framework for the Zhang-McFarlane
78 ! convective parameterization.
80 ! Author: William.Gustafson@pnl.gov, Nov. 2009
81 ! Last modified: William.Gustafson@pnl.gov, Nov. 2010
82 !------------------------------------------------------------------------
83 USE physconst, only: latice,cpair, gravit
84 USE wv_saturation, only: fqsatd,epsqs, polysvp
85 USE wv_saturation, only: fqsatd,epsqs, polysvp
87 ! Subroutine arguments...
88 logical, intent(in) :: is_CAMMGMP_used
89 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde, &
90 ims,ime, jms,jme, kms,kme, &
91 its,ite, jts,jte, kts,kte, &
92 bl_pbl_physics, & !pbl scheme
93 itimestep, & !time step index
94 sf_sfclay_physics, & !surface layer scheme
95 stepcu !number of time steps between Cu calls
97 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN) :: &
98 cldfra, & !cloud fraction
99 cldfra_mp_all, & !cloud fraction from CAMMGMP microphysics
100 dz8w, & !height between interfaces (m)
101 p, & !pressure at mid-level (Pa)
102 p8w, & !pressure at level interface (Pa)
103 pi_phy, & !exner function, (p/p0)^(R/cpair) (none)
104 qv, & !water vapor mixing ratio (kg/kg-dry air)
105 th, & !potential temperature (K)
106 tke_pbl, & !turbulent kinetic energy from PBL (m2/s2)
107 t_phy, & !temperature (K)
108 u_phy, & !zonal wind component on T points (m/s)
109 v_phy, & !meridional wind component on T points (m/s)
110 z, & !height above sea level at mid-level (m)
111 z_at_w !height above sea level at interface (m)
113 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(IN), OPTIONAL :: &
114 qc, & !cloud droplet mixing ratio (kg/kg-dry air)
115 qi !cloud ice crystal mixing ratio (kg/kg-dry air)
117 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(INOUT) :: &
118 dlf_out, & !detraining cloud water tendendcy
119 evaptzm, & !temp. tendency - evap/snow prod from ZM (K/s)
120 fzsntzm, & !temp. tendency - rain to snow conversion from ZM (K/s)
121 evsntzm, & !temp. tendency - snow to rain conversion from ZM (K/s)
122 evapqzm, & !spec. humidity tend. - evaporation from ZM (kg/kg/s)
123 zmflxprc, & !flux of precipitation from ZM (kg/m2/s)
124 zmflxsnw, & !flux of snow from ZM (kg/m2/s)
125 zmntprpd, & !net precipitation production from ZM (kg/kg/s)
126 zmntsnpd, & !net snow production from ZM (kg/kg/s)
127 zmeiheat, & !heating by ice and evaporation from ZM (W/kg)
128 cmfmc, & !convective mass flux--m sub c, deep here but ultimately deep+shallow (kg/m2/s)
129 cmfmcdzm, & !convection mass flux from ZM deep (kg/m2/s)
130 md_out, & !output convective downdraft mass flux (kg/m2/s)
131 mu_out, & !output convective updraft mass flux (kg/m2/s)
132 rucuten, & !UNcoupled zonal wind tendency due to Cu scheme (m/s2)
133 rvcuten, & !UNcoupled meridional wind tendency due to Cu scheme (m/s2)
134 rthcuten, & !UNcoupled potential temperature tendendcy due to cu scheme (K/s)
135 rqvcuten, & !UNcoupled water vapor mixing ratio tendency due to Cu scheme (kg/kg/s)
136 zmdt, & !temp. tendency from moist convection (K/s)
137 zmdq, & !spec. humidity tendency from moist convection (kg/kg/s)
138 zmmtu, & !U tendency from ZM convective momentum transport (m/s2)
139 zmmtv, & !V tendency from ZM convective momentum transport (m/s2)
140 zmupgu, & !zonal force from ZM updraft pressure gradient term (m/s2)
141 zmupgd, & !zonal force from ZM downdraft pressure gradient term (m/s2)
142 zmvpgu, & !meridional force from ZM updraft pressure gradient term (m/s2)
143 zmvpgd, & !meridional force from ZM downdraft pressure gradient term (m/s2)
144 zmicuu, & !ZM in-cloud U updrafts (m/s)
145 zmicud, & !ZM in-cloud U downdrafts (m/s)
146 zmicvu, & !ZM in-cloud V updrafts (m/s)
147 zmicvd, & !ZM in-cloud V downdrafts (m/s)
148 zmdice, & !ZM cloud ice tendency (kg/kg/s)
149 zmdliq !ZM cloud liquid tendency (kg/kg/s)
151 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(INOUT), OPTIONAL :: &
152 rqccuten, & !UNcoupled cloud droplet mixing ratio tendency due to Cu scheme (kg/kg/s)
153 rqicuten, & !UNcoupled ice crystal mixing ratio tendency due to Cu scheme (kg/kg/s)
158 !variables required by wet scavenging in WRF_CHEM -Balwinder.Singh@pnnl.gov
159 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(OUT) :: &
160 evapcdp3d, & !Evaporation of deep convective precipitation (kg/kg/s)
161 icwmrdp3d, & !Deep Convection in-cloud water mixing ratio (kg/m2)
162 rprddp3d !dq/dt due to deep convective rainout (kg/kg/s)
164 !variables required by zm_conv_tend_2 call
165 REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), INTENT(OUT) :: &
174 REAL, DIMENSION( ims:ime, jms:jme ), INTENT(IN) :: &
175 hfx, & !upward heat flux at sfc (W/m2)
176 ht, & !terrain height (m)
177 xland, & !land/water mask, 1=land, 2=water
178 mavail, & !soil moisture availability
179 pblh, & !planetary boundary layer height (m)
180 psfc, & !surface pressure (Pa)
181 qfx, & !upward moisture flux at sfc (kg/m2/s)
182 tpert_camuwpbl, & !temperature perturbation from UW CAM PBL
183 tsk, & !skin temperature (K)
184 ust !u* in similarity theory (m/s)
186 REAL, DIMENSION( ims:ime, jms:jme ), INTENT(INOUT) :: &
187 cape_out, & !convective available potential energy (J/kg)
188 cubot, & !level number of base of convection
189 cutop, & !level number of top of convection
190 pconvb, & !pressure of base of convection (Pa)
191 pconvt, & !pressure of top of convection (Pa)
192 pratec, & !rain rate returned to WRF for accumulation (mm/s)
193 preccdzm, & !convection precipitation rate from ZM deep (m/s)
194 precz, & !total precipitation rate from ZM (m/s)
195 raincv, & !time-step convective rain amount (mm)
196 rliq_out !vertical integral of reserved cloud water
197 REAL, DIMENSION( ims:ime, jms:jme ), INTENT(OUT) :: &
200 REAL, INTENT(IN) :: &
201 cudt, & !cumulus time step (min)
202 curr_secs, & !current forecast time (s)
203 dt, & !domain time step (s)
206 REAL, INTENT (INOUT) :: &
207 cudtacttime !for adaptive time stepping, next to to run scheme (s)
209 INTEGER, DIMENSION( ims:ime, jms:jme), INTENT(IN) :: &
210 kpbl !index of PBL level
212 INTEGER, DIMENSION( ims:ime, jms:jme), INTENT(OUT) :: &
218 LOGICAL, INTENT(IN), OPTIONAL :: &
219 adapt_step_flag !using adaptive time steps?
222 !Variables dimensioned for input to ZM routines
223 REAL(r8), DIMENSION(pcols, kte+1) :: &
224 mcon, & !convective mass flux--m sub c (sub arg out in CAM)
225 pflx, & !scattered precip flux at each level (sub arg out in CAM)
226 pint8, & !pressure at layer interface (Pa)
227 zi8, & !height above sea level at mid-level (m)
228 flxprec, & !evap outfld: convective-scale flux of precip at interfaces (kg/m2/s)
229 flxsnow !evap outfld: convective-scale flux of snow at interfaces (kg/m2/s)
232 REAL(r8), DIMENSION(pcols, kte, pcnst) :: &
233 qh8 !specific humidity (kg/kg-moist air)
235 REAL(r8), DIMENSION(pcols, kte, 3) :: &
236 cloud, & !holder for cloud water and ice (q in CAM)
237 cloudtnd !holder for cloud tendencies (ptend_loc%q in CAM)
239 !BSINGH - 02/18/2013: FRACIS is used for qv,qc and qi for WRF_CHEM simulation but for
240 ! WRF simulations it is used for qnc and qni also
241 #if ( WRF_CHEM == 1 )
242 REAL(r8), DIMENSION(pcols, kte, 3) :: &
244 REAL(r8), DIMENSION(pcols, kte, 5) :: &
246 fracis !fraction of cloud species that are insoluble
249 REAL(r8), DIMENSION(pcols, kte, 2) :: &
250 icwu, & !in-cloud winds in upraft (m/s)
251 icwd, & !in-cloud winds in downdraft (m/s)
252 pguall, & !apparent force from updraft pres. gradient (~units?)
253 pgdall, & !apparent force from downdraft pres. gradient (~units?)
254 winds, & !wind components (m/s)
255 wind_tends !wind component tendencies (m/s2)
257 REAL(r8), DIMENSION(pcols, kte) :: &
258 cld8, & !cloud fraction
259 cme, & !cmf condensation - evaporation (~units?, sub arg out in CAM)
260 dlf, & !scattered version of the detraining cld h2o tendency (~units?)
261 fake_dpdry, & !place holder for dpdry, delta pres. of dry atmos.
262 ntprprd, & !evap outfld: net precip production in layer (kg/kg/s)
263 ntsnprd, & !evap outfld: net snow production in layer (kg/kg/s)
264 pdel8, & !pressure thickness of layer (between interfaces, Pa)
265 pmid8, & !pressure at layer middle (Pa)
266 ql8, & !in cloud liquid water (~units?)
267 ql8prm, & !cloud liquid water (~units?)
268 qi8, & !cloud ice (~units?)
269 t8, & !temperature (K)
270 zm8, & !height above ground at mid-level (m)
271 qtnd, & !specific humidity tendency (kg/kg/s)
272 rprd, & !rain production rate (kg/kg/s, comes from pbuf array in CAM, add to restart?~)
273 stnd, & !heating rate (dry static energy tendency, W/kg)
274 tend_s_snwprd, & !heating rate of snow production (~units?)
275 tend_s_snwevmlt, & !heating rate of evap/melting of snow (~units?)
276 zdu, & !detraining mass flux (~units? sub arg out in CAM)
277 evapcdp !Evaporation of deep convective precipitation (kg/kg/s)
279 REAL(r8), DIMENSION(pcols, kte) :: &
280 esl, & !saturation vapor pressure
281 qvs, & !saturation specific humidity
287 REAL(r8), DIMENSION(pcols) :: &
288 cape, & !convective available potential energy (J/kg)
289 jctop, & !row of top-of-deep-convection indices passed out (sub arg out in CAM)
290 jcbot, & !row of base of cloud indices passed out (sub arg out in CAM)
291 landfrac, & !land fraction
292 pblh8, & !planetary boundary layer height (m)
293 phis, & !geopotential at terrain height (m2/s2)
294 prec, & !convective-scale precipitation rate from ZM (m/s)
295 rliq, & !reserved liquid (not yet in cldliq) for energy integrals (units? sub arg out in CAM)
296 snow, & !convective-scale snowfall rate from ZM (m/s)
297 tpert !thermal (convective) temperature excess (K)
299 REAL(r8), DIMENSION(pcols, kte, (ime-ims+1)*(jme-jms+1)) :: &
300 dp, & !layer pres. thickness between interfaces (mb)
307 REAL(r8), DIMENSION(pcols, (ime-ims+1)*(jme-jms+1)) :: &
308 dsubcld ! layer pres. thickness between LCL and maxi (mb)
310 INTEGER, DIMENSION(pcols, (ime-ims+1)*(jme-jms+1)) :: &
311 ideep, & ! holds position of gathered points
312 jt, & ! top-level index of deep cumulus convection
313 maxg ! gathered values of maxi
315 INTEGER, DIMENSION((ime-ims+1)*(jme-jms+1)) :: &
316 lengath ! number of gathered points
319 REAL(r8):: dum1,cudts,hcudts
320 INTEGER :: i, j, k, kflip, n, ncnst
321 INTEGER :: lchnk !chunk identifier, used to map 2-D to 1-D arrays in WRF
322 INTEGER :: ncol !number of atmospheric columns in chunk
323 LOGICAL, DIMENSION(3) :: l_qt !logical switches for constituent tendency presence
324 LOGICAL, DIMENSION(2) :: l_windt !logical switches for wind tendency presence
325 LOGICAL :: run_param , & !flag for handling alternate cumulus call freq.
326 doing_adapt_dt , decided
328 ! Check to see if this is a convection timestep...
331 ! Initialization for adaptive time step.
333 if (cudt .eq. 0.) then
341 doing_adapt_dt = .FALSE.
342 IF ( PRESENT(adapt_step_flag) ) THEN
343 IF ( adapt_step_flag ) THEN
344 doing_adapt_dt = .TRUE.
345 IF ( cudtacttime .EQ. 0. ) THEN
346 cudtacttime = curr_secs + cudt*60.
351 ! Do we run through this scheme or not?
353 ! Test 1: If this is the initial model time, then yes.
355 ! Test 2: If the user asked for the cumulus to be run every time step, then yes.
357 ! Test 3: If not adaptive dt, and this is on the requested cumulus frequency, then yes.
358 ! MOD(ITIMESTEP,STEPCU)=0
359 ! Test 4: If using adaptive dt and the current time is past the last requested activate cumulus time, then yes.
360 ! CURR_SECS >= CUDTACTTIME
362 ! If we do run through the scheme, we set the flag run_param to TRUE and we set the decided flag
363 ! to TRUE. The decided flag says that one of these tests was able to say "yes", run the scheme.
364 ! We only proceed to other tests if the previous tests all have left decided as FALSE.
366 ! If we set run_param to TRUE and this is adaptive time stepping, we set the time to the next
371 IF ( ( .NOT. decided ) .AND. &
372 ( itimestep .EQ. 1 ) ) THEN
377 IF ( ( .NOT. decided ) .AND. &
378 ( ( cudt .EQ. 0. ) .OR. ( stepcu .EQ. 1 ) ) ) THEN
383 IF ( ( .NOT. decided ) .AND. &
384 ( .NOT. doing_adapt_dt ) .AND. &
385 ( MOD(itimestep,stepcu) .EQ. 0 ) ) THEN
390 IF ( ( .NOT. decided ) .AND. &
391 ( doing_adapt_dt ) .AND. &
392 ( curr_secs .GE. cudtacttime ) ) THEN
395 cudtacttime = curr_secs + cudt*60
398 !Leave the subroutine if it is not yet time to call the cumulus param
399 if( .not. run_param ) return
403 ncol = 1 !chunk size in WRF is 1 since we loop over all columns in a tile
405 cape_out(its:ite, jts:jte) = 0.
406 mu_out(its:ite, kts:kte, jts:jte) = 0.
407 md_out(its:ite, kts:kte, jts:jte) = 0.
408 zmdt(its:ite, kts:kte, jts:jte) = 0.
410 ! Map variables to inputs for zm_convr and call it...
411 ! Loop over the points in the tile and treat them each as a CAM chunk.
415 lchnk = (j-jts)*(ite-its+1) + (i-its+1) !1-D index location from the 2-D tile
417 !Flip variables on the layer middles
420 if(is_CAMMGMP_used) then
421 cld8(1,kflip) = cldfra_mp_all(i,k,j)
423 cld8(1,kflip) = cldfra(i,k,j)
425 if (itimestep .eq. 1) cld8(1,kflip) =0.
426 pdel8(1,kflip) = p8w(i,k,j) - p8w(i,k+1,j)
427 pmid8(1,kflip) = p(i,k,j)
428 qh8(1,kflip,1) = max( qv(i,k,j)/(1.+qv(i,k,j)), 1e-30 ) !values of 0 cause a crash in entropy
429 if( present(qc) ) then
430 ql8prm(1,kflip) = qc(i,k,j)/(1.+qv(i,k,j)) !Convert to moist mix ratio
434 if( present(qi) ) then
435 qi8(1,kflip) = qi(i,k,j)/(1.+qv(i,k,j)) !Used in convtran, ditto for conversion
439 t8(1,kflip) = t_phy(i,k,j)
440 zm8(1,kflip) = z(i,k,j) - ht(i,j) !Height above the ground at midlevels
442 dp(1,kflip,lchnk) = 0.0_r8
443 du(1,kflip,lchnk) = 0.0_r8
444 ed(1,kflip,lchnk) = 0.0_r8
445 eu(1,kflip,lchnk) = 0.0_r8
446 md(1,kflip,lchnk) = 0.0_r8
447 mu(1,kflip,lchnk) = 0.0_r8
450 !Flip variables on the layer interfaces
454 pint8(1,kflip) = p8w(i,k,j)
455 zi8(1,kflip) = z_at_w(i,k,j) -ht(i,j) !Height above the ground at interfaces
458 !Other necessary conversions for input to ZM
459 if( xland(i,j)==2 ) then
460 landfrac(1) = 1. !land, WRF is all or nothing
462 landfrac(1) = 0. !water
465 phis(1) = ht(i,j)*gravit
467 call get_tpert(bl_pbl_physics, sf_sfclay_physics, dx, &
468 mavail(i,j), kpbl(i,j), pblh(i,j), &
469 dz8w(i,1,j), psfc(i,j), qv(i,1,j), t_phy(i,1,j), &
470 th(i,1,j), tsk(i,j), tke_pbl(i,:,j), ust(i,j), &
471 u_phy(i,1,j), v_phy(i,1,j), hfx(i,j), qfx(i,j), &
472 tpert_camuwpbl(i,j), kte, &
475 !Call the Zhang-McFarlane (1996) convection parameterization
476 !PMA: pass in 0.5 x cudt (sec)
477 !Modified by Balwinder.Singh@pnnl.gov: We are no longer using 0.5*dt
479 !PMA: pass in 0.5 x cudt (sec)
480 call zm_convr( lchnk, ncol, &
481 t8, qh8, prec, jctop, jcbot, &
482 pblh8, zm8, phis, zi8, qtnd, &
483 stnd, pmid8, pint8, pdel8, &
484 hcudts, mcon, cme, cape, &
485 tpert, dlf, pflx, zdu, rprd, &
486 mu(:,:,lchnk), md(:,:,lchnk),du(:,:,lchnk),eu(:,:,lchnk),ed(:,:,lchnk), &
487 dp(:,:,lchnk), dsubcld(:,lchnk), jt(:,lchnk), maxg(:,lchnk), ideep(:,lchnk), &
488 lengath(lchnk), ql8, rliq, landfrac )
490 !Start mapping CAM output to WRF output variables. We follow the
491 !same order as in CAM's zm_conv_tend to ease maintenance...
494 dlf(1,kflip) = max(min(1.e-6_r8,dlf(1,kflip)),0._r8)
495 dlf_out(i,k,j) = dlf(1,kflip)
497 cape_out(i,j) = cape(1)
498 rliq_out(i,j) = rliq(1)
500 !Convert mass flux from reported mb/s to kg/m2/s
501 mcon(:ncol,:pverp) = mcon(:ncol,:pverp) * 100._r8/gravit
503 ! Store upward and downward mass fluxes in un-gathered arrays
504 ! + convert from mb/s to kg/m2/s
505 do n=1,lengath(lchnk)
508 ! ii = ideep(n,lchnk) <--in WRF this is always 1 because chunk size=1
509 mu_out(i,k,j) = mu(n,kflip,lchnk) * 100._r8/gravit
510 md_out(i,k,j) = md(n,kflip,lchnk) * 100._r8/gravit
516 zmdt(i,k,j) = stnd(1,kflip)/cpair
517 zmdq(i,k,j) = qtnd(1,kflip)
520 !Top and bottom pressure of convection
521 pconvt(i,j) = p8w(i,1,j)
522 pconvb(i,j) = p8w(i,1,j)
523 do n = 1,lengath(lchnk)
524 if (maxg(n,lchnk).gt.jt(n,lchnk)) then
525 pconvt(i,j) = pmid8(ideep(n,lchnk),jt(n,lchnk)) ! gathered array (or jctop ungathered)
526 pconvb(i,j) = pmid8(ideep(n,lchnk),maxg(n,lchnk))! gathered array
529 cutop(i,j) = jctop(1)
530 cubot(i,j) = jcbot(1)
532 !Add tendency from this process to tendencies arrays. Also,
533 !increment the local state arrays to reflect additional tendency
534 !from zm_convr, i.e. the physics update call in CAM. Note that
535 !we are not readjusting the pressure levels to hydrostatic
536 !balance for the new virtual temperature like is done in CAM. We
537 !will let WRF take care of such things later for the total
542 !Convert temperature to potential temperature and
543 !specific humidity to water vapor mixing ratio
544 rthcuten(i,k,j) = zmdt(i,k,j)/pi_phy(i,k,j)
545 rqvcuten(i,k,j) = zmdq(i,k,j)*(1._r8 + qv(i,k,j))**2
547 t8(1,kflip) = t8(1,kflip) + zmdt(i,k,j)*cudts !PMA
548 qh8(1,kflip,1) = qh8(1,kflip,1) + zmdq(i,k,j)*cudts !PMA
551 ! Determine the phase of the precipitation produced and add latent heat of fusion
552 ! Evaporate some of the precip directly into the environment (Sundqvist)
553 ! Allow this to use the updated state1 (t8 and qh8 in WRF) and the fresh ptend_loc type
554 ! heating and specific humidity tendencies produced
555 qtnd = 0._r8 !re-initialize tendencies (i.e. physics_ptend_init(ptend_loc))
557 call zm_conv_evap(ncol, lchnk, &
558 t8, pmid8, pdel8, qh8(:,:,1), &
559 stnd, tend_s_snwprd, tend_s_snwevmlt, qtnd, &
560 rprd, cld8, cudts, & !PMA: This subroutine uses delt not 2xdelt, so pass in cudts
561 prec, snow, ntprprd, ntsnprd , flxprec, flxsnow)
562 evapcdp(:ncol,:pver) = qtnd(:ncol,:pver) !Added by Balwinder.Singh@pnnl.gov for assisting wetscavenging in WRF_CHEM package
564 ! Parse output variables from zm_conv_evap
568 evaptzm(i,k,j) = stnd(1,kflip)/cpair
569 fzsntzm(i,k,j) = tend_s_snwprd(1,kflip)/cpair
570 evsntzm(i,k,j) = tend_s_snwevmlt(1,kflip)/cpair
571 evapqzm(i,k,j) = qtnd(1,kflip)
572 zmflxprc(i,k,j) = flxprec(1,kflip)
573 zmflxsnw(i,k,j) = flxsnow(1,kflip)
574 zmntprpd(i,k,j) = ntprprd(1,kflip)
575 zmntsnpd(i,k,j) = ntsnprd(1,kflip)
576 zmeiheat(i,k,j) = stnd(1,kflip) !Do we really need this and evaptzm?
577 !BSINGH - Following quantities are to be stored at interfaces
578 !cmfmc(i,k,j) = mcon(1,kflip) !Set to deep value here, shallow added in UW scheme
579 !cmfmcdzm(i,k,j) = mcon(1,kflip)
580 preccdzm(i,j) = prec(1) !Rain rate from just deep
581 precz(i,j) = prec(1) !Rain rate for total convection (just deep right now)
582 pratec(i,j) = prec(1)*1e3 !Rain rate used in WRF for accumulation (mm/s)
583 raincv(i,j) = pratec(i,j)*dt !Rain amount for dynamic time step returned back to WRF !wig: fixed wrong timestep usage 3-Jun-2016
586 !BSINGH - storing quantities at interfaces
589 cmfmc(i,k,j) = mcon(1,kflip) !Set to deep value here, shallow added in UW scheme
590 cmfmcdzm(i,k,j) = mcon(1,kflip)
592 !Add tendency from zm_conv_evap to tendencies arrays. Also,
593 !increment the local state arrays to reflect additional tendency
594 !Note that we are not readjusting the pressure levels to hydrostatic
595 !balance for the new virtual temperature like is done in CAM. We
596 !will let WRF take care of such things later for the total
601 !Convert temperature to potential temperature and
602 !specific humidity to water vapor mixing ratio
603 rthcuten(i,k,j) = rthcuten(i,k,j) + &
604 evaptzm(i,k,j)/pi_phy(i,k,j)
605 rqvcuten(i,k,j) = rqvcuten(i,k,j) + &
606 evapqzm(i,k,j)*(1. + qv(i,k,j))**2
608 t8(1,kflip) = t8(1,kflip) + evaptzm(i,k,j)*cudts !PMA
609 qh8(1,kflip,1) = qh8(1,kflip,1) + evapqzm(i,k,j)*cudts !PMA
613 stnd = 0._r8 !Zero relevant tendencies in preparation
617 winds(1,k,1) = u_phy(i,kflip,j)
618 winds(1,k,2) = v_phy(i,kflip,j)
620 l_windt(1:2) = .true.
622 call momtran (lchnk, ncol, &
623 l_windt, winds, 2, mu(:,:,lchnk), md(:,:,lchnk), &
624 du(:,:,lchnk), eu(:,:,lchnk), ed(:,:,lchnk), dp(:,:,lchnk), dsubcld(:,lchnk), &
625 jt(:,lchnk),maxg(:,lchnk), ideep(:,lchnk), 1, lengath(lchnk), &
626 itimestep, wind_tends, pguall, pgdall, icwu, icwd, hcudts, stnd ) !PMA
628 !Add tendency from momtran to tendencies arrays. Also,
629 !increment the local state arrays to reflect additional tendency
630 !Note that we are not readjusting the pressure levels to hydrostatic
631 !balance for the new virtual temperature like is done in CAM. We
632 !will let WRF take care of such things later for the total
637 !Convert temperature to potential temperature and
638 !specific humidity to water vapor mixing ratio
639 rucuten(i,k,j) = wind_tends(1,kflip,1)
640 rvcuten(i,k,j) = wind_tends(1,kflip,2)
641 rthcuten(i,k,j) = rthcuten(i,k,j) + &
642 stnd(1,kflip)/cpair/pi_phy(i,k,j)
644 t8(1,kflip) = t8(1,kflip) + stnd(1,kflip)/cpair*cudts !PMA
645 !winds is not used again so do not bother updating them
648 !Parse output arrays for momtran
652 zmmtu(i,k,j) = wind_tends(1,kflip,1) !wind tendencies...
653 zmmtv(i,k,j) = wind_tends(1,kflip,2)
655 zmupgu(i,k,j) = pguall(1,kflip,1) !apparent force pres. grads...
656 zmupgd(i,k,j) = pgdall(1,kflip,1)
657 zmvpgu(i,k,j) = pguall(1,kflip,2)
658 zmvpgd(i,k,j) = pgdall(1,kflip,2)
660 zmicuu(i,k,j) = icwu(1,kflip,1) !in-cloud winds...
661 zmicud(i,k,j) = icwd(1,kflip,1)
662 zmicvu(i,k,j) = icwu(1,kflip,2)
663 zmicvd(i,k,j) = icwd(1,kflip,2)
666 !Setup for convective transport of cloud water and ice
667 !~We should set this up to use an integer pointer instead of
668 ! hard-coded numbers for each species so that we can easily
669 ! handle other species. Something to come back to later...
670 l_qt(1) = .false. !do not mix water vapor
671 l_qt(2:3) = .true. !do mix cloud water and ice
673 fracis(1,:,1:3) = 1._r8 !all cloud liquid & ice
674 #if ( WRF_CHEM != 1 )
675 !BSINGH:02/01/2013: For WRF Physics ONLY runs, the liq # and ice # should
676 !also be transpoted. Please note that liq # and ice # are transported in the
677 !zm_conv_tend_2 call for WRF_CHEM simulations (ONLY works for MAM aerosols)
679 fracis(1,:,4:5) = 1._r8
681 ncnst = 3 !number of constituents in cloud array (including vapor)
682 fake_dpdry = 0._r8 !delta pres. for dry atmos. (0 since assuming moist mix ratios)
686 cloud(1,kflip,1) = qh8(1,kflip,1) !We can either use moist mix ratios, as is
687 cloud(1,kflip,2) = ql8prm(1,kflip) !done here, or else use dry mix ratios, send
688 cloud(1,kflip,3) = qi8(1,kflip) !in appropriate dpdry values, and return the
689 !approp. response from cnst_get_type_byind
692 call convtran (lchnk, &
693 l_qt, cloud, ncnst, mu(:,:,lchnk), md(:,:,lchnk), &
694 du(:,:,lchnk), eu(:,:,lchnk), ed(:,:,lchnk), dp(:,:,lchnk), dsubcld(:,lchnk), &
695 jt(:,lchnk), maxg(:,lchnk), ideep(:,lchnk), 1, lengath(lchnk), &
696 itimestep, fracis, cloudtnd, fake_dpdry)
698 !Parse output for convtran and increment tendencies
702 esl(1,kflip) = polysvp(t8(1,kflip),0)
703 qvs(1,kflip) = epsqs*esl(1,kflip)/(pmid8(1,kflip)-(1._r8-epsqs)*esl(1,kflip))
704 if( t8(1,kflip) > 268.15_r8 ) then
706 elseif( t8(1,kflip) < 238.15_r8 ) then
709 dum1 = ( 268.15_r8 - t8(1,kflip) ) / 30._r8
711 qcten_det(1,kflip) = dlf(1,kflip) * ( 1._r8 - dum1 )
712 qiten_det(1,kflip) = dlf(1,kflip) * dum1
713 qcnten_det(1,kflip) = 3._r8 * (dlf(1,kflip) * ( 1._r8 - dum1 ) ) / (4._r8*3.14159_r8*(8.e-6_r8**3)*997._r8)
714 qinten_det(1,kflip) = 3._r8 * (dlf(1,kflip) * dum1 ) / (4._r8*3.14159_r8*(25.e-6_r8**3)*500._r8)
715 qsten_det(1,kflip) = dlf(1,kflip) * dum1 * latice ! liquid to ice heating
720 !For assisting wetscavenging in WRF_CHEM package -Balwinder.Singh@pnnl.gov
721 evapcdp3d(i,k,j) = evapcdp(1,kflip)
722 icwmrdp3d(i,k,j) = ql8(1,kflip)
723 rprddp3d(i,k,j) = rprd(1,kflip)
725 zmdice(i,k,j) = cloudtnd(1,kflip,3)+qiten_det(1,kflip)
726 zmdliq(i,k,j) = cloudtnd(1,kflip,2)+qcten_det(1,kflip)
727 rthcuten(i,k,j) = rthcuten(i,k,j) + &
728 qsten_det(1,kflip)/cpair/pi_phy(i,k,j)
730 !Convert cloud tendencies from wet to dry mix ratios
731 if( present(rqccuten) ) then
732 rqccuten(i,k,j) = (cloudtnd(1,kflip,2)+qcten_det(1,kflip))*(1. + qv(i,k,j))
734 if( present(rqicuten) ) then
735 rqicuten(i,k,j) = (cloudtnd(1,kflip,3)+qiten_det(1,kflip))*(1. + qv(i,k,j))
737 if( present(rqcncuten) ) then
738 rqcncuten(i,k,j) = qcnten_det(1,kflip)*(1. + qv(i,k,j)) !BSINGH - Added the denominator following qiten_det
740 if( present(rqincuten) ) then
741 rqincuten(i,k,j) = qinten_det(1,kflip)*(1. + qv(i,k,j)) !BSINGH - Added the denominator following qiten_det
743 !Variables required by zm_conv_tend_2 call
744 dp3d(i,k,j) = dp(1,kflip,lchnk)
745 du3d(i,k,j) = du(1,kflip,lchnk)
746 ed3d(i,k,j) = ed(1,kflip,lchnk)
747 eu3d(i,k,j) = eu(1,kflip,lchnk)
748 md3d(i,k,j) = md(1,kflip,lchnk)
749 mu3d(i,k,j) = mu(1,kflip,lchnk)
751 dsubcld2d(i,j) = dsubcld(1,lchnk)
752 ideep2d(i,j) = ideep(1,lchnk)
753 jt2d(i,j) = jt(1,lchnk)
754 maxg2d(i,j) = maxg(1,lchnk)
755 lengath2d(i,j) = lengath(lchnk)
760 END SUBROUTINE camzm_driver
763 !------------------------------------------------------------------------
764 SUBROUTINE zm_conv_init(DT, DX, rucuten, rvcuten, rthcuten, rqvcuten, &
765 rqccuten, rqicuten, rqcncuten, rqincuten, &
766 p_qc, p_qi, p_qnc, p_qni, param_first_scalar, &
768 ids, ide, jds, jde, kds, kde, &
769 ims, ime, jms, jme, kms, kme, &
770 its, ite, jts, jte, kts, kte )
771 ! Initialization routine for Zhang-McFarlane cumulus parameterization
772 ! from CAM. The routine with this name in CAM is revamped here to give
773 ! the needed functionality within WRF.
775 ! Author: William.Gustafson@pnl.gov, Nov. 2009
776 !------------------------------------------------------------------------
777 USE physconst, only: epsilo, latvap, latice, rh2o, cpair, tmelt
778 USE module_cu_camzm, only: zm_convi, zmconv_readnl
779 USE constituents, only: cnst_get_ind
781 LOGICAL , INTENT(IN) :: restart
782 INTEGER , INTENT(IN) :: ids, ide, jds, jde, kds, kde, &
783 ims, ime, jms, jme, kms, kme, &
784 its, ite, jts, jte, kts, kte, &
785 p_qc, p_qi, p_qnc, p_qni, &
788 REAL , INTENT(IN) :: DT, DX
791 REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(INOUT) :: &
801 integer :: i, itf, j, jtf, k, ktf
808 call cnst_get_ind('CLDLIQ', ixcldliq)
809 call cnst_get_ind('CLDICE', ixcldice)
810 call cnst_get_ind('NUMLIQ', ixnumliq)
811 call cnst_get_ind('NUMICE', ixnumice)
814 ! Initialize module_cam_support variables...
815 ! This could be moved to a master "cam-init" subroutine once multiple CAM
816 ! parameterizations are implemented in WRF. For now, it doesn't hurt to
817 ! have these possibly initialized more than once since they are
818 ! essentially constant.
822 !~Need code here to set limcnv to max convective level of 40 mb... To
823 ! properly set an average value for the whole domain would involve doing
824 ! a collective operation across the whole domain to get pressure averages
825 ! by level, which is difficult within the WRF framework. So, we will just
826 ! use the model top for now.
828 ! Technically, limcnv should be calculated for each grid point at each
829 ! time because the levels in WRF do not have a constant pressure, as
830 ! opposed to CAM. But, that would involve making this variable local
831 ! instead of at the module level as is currently done in CAM. For now,
832 ! we will not worry about this because WRF rarely has domains higher than
833 ! 40 mb. There is also little variability between grid points near the
834 ! model top due to the underlying topography so a constant value would
835 ! be OK across the domain. Also, remember that CAM levels are reversed in
836 ! the vertical from WRF. So, setting limcnv to 1 means the top of the
837 ! domain. Note that because of a bug in the parcel_dilute routine, limcnv
838 ! must be >=2 instead of 1. Otherwise, an array out-of-bounds occurs.
841 ! Get the ZM namelist variables (hard-wired for now)...
843 call zmconv_readnl("hard-wired")
845 !~need to determine if convection should happen in PBL and set
846 ! no_deep_pbl_in accordingly
847 call zm_convi(DT, DX, limcnv, NO_DEEP_PBL_IN=.true.)
850 ! Set initial values for arrays dependent on restart conditions
860 if( p_qc > param_first_scalar ) rqccuten(i,k,j) = 0.
861 if( p_qi > param_first_scalar ) rqicuten(i,k,j) = 0.
862 if( p_qnc > param_first_scalar ) rqcncuten(i,k,j) = 0.
863 if( p_qni > param_first_scalar ) rqincuten(i,k,j) = 0.
869 END SUBROUTINE zm_conv_init
872 !------------------------------------------------------------------------
873 SUBROUTINE get_tpert(bl_pbl_physics, sf_sfclay_physics, dx, &
874 mavail, kpbl, pblh, dzlowest, &
875 psfc, qvlowest, t_phylowest, thlowest, tsk, tke_pbl, ust, &
876 u_phylowest, v_phylowest, hfx, qfx, tpert_camuwpbl, kte, tpert)
877 ! Calculates the temperature perturbation used to trigger convection.
878 ! This should only be used if tpert is not already provided by CAM's PBL
879 ! scheme. Right now, this only works with the Mellor-Yamada boundary
880 ! layer scheme in combination with the MYJ surface scheme. This is due to
881 ! the need of TKE for the vertical velocity perturbation. This scheme has
882 ! not been generalized to handle all schemes that produce TKE at this
883 ! time, and the non-TKE schemes, e.g. YSU, could probably have an
884 ! appropriate tpert deduced but we have not taken the time yet to do it.
886 ! Author: William.Gustafson@pnl.gov, Nov. 2009
887 ! Last updated: William.Gustafson@pnl.gov, Nov. 2010
888 !------------------------------------------------------------------------
889 USE module_model_constants, only: cp, ep_1, ep_2, g, r_d, rcp, &
890 svp1, svp2, svp3, svpt0, xlv
891 USE module_state_description, ONLY : SFCLAYSCHEME &
900 ! Subroutine arguments...
902 real, dimension(:), intent(in) :: tke_pbl
903 real, intent(in) :: dx, dzlowest, hfx, mavail, pblh, psfc, qvlowest, &
904 tpert_camuwpbl, tsk, t_phylowest, thlowest, ust, u_phylowest, &
906 integer, intent(in) :: bl_pbl_physics, kpbl, kte, sf_sfclay_physics
907 real(r8),intent(inout) :: tpert
911 real, parameter :: fak = 8.5 !Constant in surface temperature excess
912 real, parameter :: tfac = 1. !Ratio of 'tpert' to (w't')/wpert
913 real, parameter :: wfac = 1. !Ratio of 'wpert' to sqrt(tke)
914 real, parameter :: wpertmin = 1.e-6 !Min PBL eddy vertical velocity perturbation
915 real :: ebrk !In CAM, net mean TKE of CL including
916 !entrainment effect (m2/s2). In WRF,
917 !average TKE within the PBL
918 real :: br2, dthvdz, e1, flux, govrth, psfccmb, qfx, qsfc, rhox, thgb, &
919 thv, tskv, tvcon, vconv, vsgd, wpert, wspd, za
921 character(len=250) :: msg
922 logical :: UnstableOrNeutral
924 ! We can get the perturbation values directly from CAMUWPBLSCHEME if
925 ! available. Otherwise, we have to calculate them.
927 if( bl_pbl_physics==CAMUWPBLSCHEME ) then
928 tpert = tpert_camuwpbl
930 !...non-CAMUWPBL. Need MYJ SFC & PBL for now until other schemes
931 ! get coded to give perturbations too.
932 ! First, we need to determine if the conditions are stable or unstable.
933 ! We will do this by mimicing the bulk Richardson calculation from
934 ! module_sf_sfclay.F because the MYJ scheme does not provide this info.
935 ! The logic borrowed from the CuP shallow cumulus scheme. Non-MYJ sfc
936 ! scheme code is commented out for now since we also require MYJ PBL
939 elseif( bl_pbl_physics==MYJPBLSCHEME ) then
941 UnstableOrNeutral = .false.
942 sfclay_case: SELECT CASE (sf_sfclay_physics)
944 ! The MYJ sfc scheme does not already provide a stability criteria.
945 ! So, we will mimic the bulk Richardson calculation from
946 ! module_sf_sfclay.F.
948 if( pblh <= 0. ) call wrf_error_fatal( &
949 "CAMZMSCHEME needs a PBL height from a PBL scheme.")
953 e1 = svp1*exp(svp2*(tsk-svpt0)/(tsk-svp3))
954 psfccmb=psfc/1000. !converts from Pa to cmb
955 qsfc = ep_2*e1/(psfccmb-e1)
956 thgb = tsk*(100./psfccmb)**rcp
957 tskv = thgb*(1.+ep_1*qsfc*mavail)
958 tvcon = 1.+ep_1*qvlowest
964 rhox = psfc/(r_d*t_phylowest*tvcon)
965 flux = max(hfx/rhox/cp + ep_1*tskv*qfx/rhox,0.)
966 vconv = (g/tsk*pblh*flux)**.33
967 vsgd = 0.32 * (max(dx/5000.-1.,0.))**.33
968 wspd = sqrt(u_phylowest*u_phylowest+v_phylowest*v_phylowest)
969 wspd = sqrt(wspd*wspd+vconv*vconv+vsgd*vsgd)
972 !And finally, the bulk Richardson number...
973 br2 = govrth*za*dthvdz/(wspd*wspd)
975 if( br2 <= 0. ) UnstableOrNeutral = .true.
978 call wrf_error_fatal("CAMZMSCHEME requires MYJSFCSCHEME or else CAMUWPBLSCHEME.")
980 END SELECT sfclay_case
982 ! The perturbation temperature for unstable conditions...
983 ! The calculation follows the one in caleddy inside eddy_diff.F90 from
986 !Check that we are using the MJY BL scheme since we are hard-wired to
987 !use TKE and u* from this scheme. At some point this dependency should
988 !be broken and a way needs to be found for other schemes to provide
989 !reasonable tpert values too.
990 if( bl_pbl_physics /= MYJPBLSCHEME ) &
991 call wrf_error_fatal("CAMZMSCHEME requires MYJPBLSCHEME or CAMUWPBLSCHEME")
994 !Recalculate rhox in case a non-MYJ scheme is used to get
995 !stability and rhox is not calculated above. Right now, this is
996 !technically reduncant, but cheap.
997 tvcon = 1.+ep_1*qvlowest
998 rhox = psfc/(r_d*t_phylowest*tvcon)
1000 if( UnstableOrNeutral ) then
1001 !1st, get avg TKE w/n the PBL as a proxy for ebrk variable in CAM
1003 do k=1,min(kpbl,kte+1) !BSINGH - Changed KTE to KTE+1 as tke_pbl is @ interfaces
1004 ebrk = ebrk + tke_pbl(k)
1006 ebrk = ebrk/real(kpbl)
1008 wpert = max( wfac*sqrt(ebrk), wpertmin )
1009 tpert = max( abs(hfx/rhox/cp)*tfac/wpert, 0. )
1011 ! Or, the perturbation temperature for stable conditions...
1013 else !Stable conditions
1014 tpert = max( hfx/rhox/cp*fak/ust, 0. )
1018 call wrf_error_fatal("CAMZMSCHEME requires MYJPBLSCHEME or CAMUWPBLSCHEME")
1022 END SUBROUTINE get_tpert
1025 !=========================================================================================
1027 #if ( WRF_CHEM == 1 )
1028 subroutine zm_conv_tend_2(itimestep, dt, p8w, fracis3d, dp3d, du3d, ed3d, eu3d, md3d, mu3d, &
1029 dsubcld2d, ideep2d, jt2d, maxg2d, lengath2d, moist, scalar, chem, &
1030 ids,ide, jds,jde, kds,kde, &
1031 ims,ime, jms,jme, kms,kme, &
1032 its,ite, jts,jte, kts,kte)
1034 use module_state_description, only: num_moist, num_scalar, num_chem, param_first_scalar, &
1035 P_QV, P_QC, P_QI, P_QNC, P_QNI, CBMZ_CAM_MAM3_NOAQ, CBMZ_CAM_MAM3_AQ, &
1036 CBMZ_CAM_MAM7_NOAQ,CBMZ_CAM_MAM7_AQ
1037 use module_data_cam_mam_asect, only: lptr_chem_to_q, factconv_chem_to_q
1038 use module_mp_cammgmp_driver, only: physics_update, physics_ptend_init
1045 integer, intent(in) :: itimestep
1046 integer, intent(in) :: ids,ide, jds,jde, kds,kde
1047 integer, intent(in) :: ims,ime, jms,jme, kms,kme
1048 integer, intent(in) :: its,ite, jts,jte, kts,kte
1050 integer, dimension(ims:ime,jms:jme), intent(in) :: ideep2d, jt2d, maxg2d, lengath2d
1052 real, intent(in) :: dt
1054 real, dimension(ims:ime,jms:jme), intent(in) :: dsubcld2d
1056 real, dimension(ims:ime,kms:kme,jms:jme), intent(in) :: p8w, dp3d, du3d, ed3d, eu3d, md3d
1057 real, dimension(ims:ime,kms:kme,jms:jme), intent(in) :: mu3d
1059 real, dimension(ims:ime,kms:kme,jms:jme,pcnst), intent(in) :: fracis3d
1062 real, dimension(ims:ime,kms:kme,jms:jme,num_moist), intent(inout) :: moist
1063 real, dimension(ims:ime,kms:kme,jms:jme,num_scalar), intent(inout) :: scalar
1064 real, dimension(ims:ime,kms:kme,jms:jme,num_chem), intent(inout) :: chem
1068 character(len=1000) :: msg
1069 character*24 :: ptend_name !ptend%name in CAM5 - used in parameterization
1070 logical :: ptend_ls !ptend%ls in CAM5 - used for calling physics_update subroutine
1071 logical :: ptend_lq(pcnst) !ptend%lq in CAM5
1073 integer :: iw, jw, kw, kflip, l, l2
1074 integer :: i, lchnk, istat
1077 real(r8) :: delta_p, multFrc, dtime
1078 real(r8) :: dpdry(pcols,kte)
1079 real(r8) :: state_pdel(pcols,kte) ! Pressure difference (Pa)
1080 real(r8) :: state_pdeldry(pcols,kte) ! dry pressure difference (1/Pa)
1081 real(r8) :: state_q(pcols,kte,pcnst)
1082 real(r8) :: state_s(pcols,kte)
1083 real(r8) :: ptend_s(pcols,kte) !Dummy arguments for physics_update call
1084 real(r8) :: ptend_q(pcols,kte,pcnst)
1086 real(r8) :: dp(pcols, kte, (ime-ims+1)*(jme-jms+1)) !layer pres. thickness between interfaces (mb)
1087 real(r8) :: du(pcols, kte, (ime-ims+1)*(jme-jms+1))
1088 real(r8) :: ed(pcols, kte, (ime-ims+1)*(jme-jms+1))
1089 real(r8) :: eu(pcols, kte, (ime-ims+1)*(jme-jms+1))
1090 real(r8) :: md(pcols, kte, (ime-ims+1)*(jme-jms+1))
1091 real(r8) :: mu(pcols, kte, (ime-ims+1)*(jme-jms+1))
1093 real(r8) :: dsubcld(pcols, (ime-ims+1)*(jme-jms+1)) ! layer pres. thickness between LCL and maxi (mb)
1095 integer :: ideep(pcols, (ime-ims+1)*(jme-jms+1)) ! holds position of gathered points
1096 integer :: jt(pcols, (ime-ims+1)*(jme-jms+1)) ! top-level index of deep cumulus convection
1097 integer :: maxg(pcols, (ime-ims+1)*(jme-jms+1)) ! gathered values of maxi
1099 integer :: lengath((ime-ims+1)*(jme-jms+1)) ! number of gathered points
1102 ! physics buffer fields
1104 real(r8), dimension(pcols,kte,pcnst) :: fracis ! fraction of transported species that are insoluble
1106 !Time step is stored in the (r8) format in dtime
1109 ! Map variables for CAM subrouine call
1110 ! Loop over the points in the tile and treat them each as a CAM chunk.
1113 !BSINGH:02/01/2013: Sanity check for Non-MAM simulations
1114 !This subroutine will not be called for chem_opt=0, so we dont need to worry about chem_opt = 0
1115 if(.NOT.cam_mam_aerosols) then
1116 write(msg,*)'CAMZM DRIVER - zm_conv_tend_2 is valid for only MAM aerosols ', &
1117 '(chem_opts:',CBMZ_CAM_MAM3_NOAQ,CBMZ_CAM_MAM3_AQ,CBMZ_CAM_MAM7_NOAQ,CBMZ_CAM_MAM7_AQ ,')'
1118 call wrf_error_fatal( msg )
1123 lchnk = (jw-jts)*(ite-its+1) + (iw-its+1) !1-D index location from the 2-D tile
1125 !Flip variables on the layer middles
1129 !Following three formulas are obtained from ported CAM's ZM cumulus scheme
1130 !Values of 0 cause a crash in entropy
1131 multFrc = 1._r8/(1._r8 + moist(iw,kw,jw,P_QV))
1132 state_q(1,kflip,1) = moist(iw,kw,jw,P_QV)*multFrc !Specific humidity
1133 state_q(1,kflip,ixcldliq) = moist(iw,kw,jw,P_QC)*multFrc !Convert to moist mix ratio-cloud liquid
1134 state_q(1,kflip,ixcldice) = moist(iw,kw,jw,P_QI)*multFrc !cloud ice
1135 state_q(1,kflip,ixnumliq) = scalar(iw,kw,jw,P_QNC)*multFrc
1136 state_q(1,kflip,ixnumice) = scalar(iw,kw,jw,P_QNI)*multFrc
1138 fracis(1,kflip,l) = fracis3d(iw,kw,jw,l)
1140 !populate state_q and qqcw arrays
1141 !Following Do-Loop is obtained from chem/module_cam_mam_aerchem_driver.F
1142 do l = param_first_scalar, num_chem
1143 l2 = lptr_chem_to_q(l)
1144 if ((l2 >= 1) .and. (l2 <= pcnst)) then
1145 fracis(1,kflip,l2) = fracis3d(iw,kw,jw,l2)
1146 state_q(1,kflip,l2) = chem(iw,kw,jw,l)*factconv_chem_to_q(l)
1150 delta_p = p8w(iw,kw,jw) - p8w(iw,kw+1,jw) !Change in pressure (Pa)
1151 state_pdel( 1,kflip) = delta_p
1152 state_pdeldry(1,kflip) = state_pdel(1,kflip)*(1._r8-state_q(1,kflip,1))
1153 !Variables required by zm_conv_tend_2 call
1154 dp(1,kflip,lchnk) = dp3d(iw,kw,jw)
1155 du(1,kflip,lchnk) = du3d(iw,kw,jw)
1156 ed(1,kflip,lchnk) = ed3d(iw,kw,jw)
1157 eu(1,kflip,lchnk) = eu3d(iw,kw,jw)
1158 md(1,kflip,lchnk) = md3d(iw,kw,jw)
1159 mu(1,kflip,lchnk) = mu3d(iw,kw,jw)
1161 dsubcld(1,lchnk) = dsubcld2d(iw,jw)
1162 ideep(1,lchnk) = ideep2d(iw,jw)
1163 jt(1,lchnk) = jt2d(iw,jw)
1164 maxg(1,lchnk) = maxg2d(iw,jw)
1165 lengath(lchnk) = lengath2d(iw,jw)
1171 call physics_ptend_init(ptend_name,ptend_q,ptend_s,ptend_lq,ptend_ls,pcnst) !! Initialize local ptend type
1174 ! Transport all constituents except cloud water and ice
1180 ! Convective transport of all trace species except cloud liquid
1181 ! and cloud ice done here because we need to do the scavenging first
1182 ! to determine the interstitial fraction.
1184 ptend_name = 'convtran2'
1185 ptend_lq(:) = .true.
1186 ptend_lq(1) = .false.
1187 ptend_lq(ixcldice) = .false.
1188 ptend_lq(ixcldliq) = .false.
1190 ! initialize dpdry for call to convtran
1191 ! it is used for tracers of dry mixing ratio type
1193 do i = 1,lengath(lchnk)
1194 dpdry(i,:) = state_pdeldry(ideep(i,lchnk),:)/100._r8
1197 call convtran (lchnk, &
1198 ptend_lq,state_q, pcnst, mu(:,:,lchnk), md(:,:,lchnk), &
1199 du(:,:,lchnk), eu(:,:,lchnk), ed(:,:,lchnk), dp(:,:,lchnk), dsubcld(:,lchnk), &
1200 jt(:,lchnk),maxg(:,lchnk),ideep(:,lchnk), 1, lengath(lchnk), &
1201 nstep, fracis, ptend_q, dpdry)
1203 !Update chem array and state constiuents
1204 !populate state_s, ptend_s, ptend_ls with dummy values (zeros) for physics update call
1205 state_s(:,:) = 0.0_r8
1206 ptend_s(:,:) = 0.0_r8
1209 call physics_update(lchnk,dtime,state_q,ptend_q,state_s,ptend_s,ptend_name,ptend_lq,ptend_ls,pcnst)
1211 !Post processing of the output to update WRF arrays
1216 !Following equation are derived following UWPBL and CAMZM schemes
1217 moist(iw,kw,jw,P_QV) = state_q(1,kflip,1) / (1.0_r8 - state_q(1,kflip,1))
1218 multFrc = 1._r8 + moist(iw,kw,jw,P_QV)
1220 moist(iw,kw,jw,P_QC) = state_q(1,kflip,2) * multFrc
1221 moist(iw,kw,jw,P_QI) = state_q(1,kflip,3) * multFrc
1223 scalar(iw,kw,jw,P_QNC) = state_q(1,kflip,4) * multFrc
1224 scalar(iw,kw,jw,P_QNI) = state_q(1,kflip,5) * multFrc
1226 do l = param_first_scalar, num_chem
1227 l2 = lptr_chem_to_q(l)
1228 if ((l2 >= 1) .and. (l2 <= pcnst)) then
1229 chem(iw,kw,jw,l) = state_q(1,kflip,l2)/factconv_chem_to_q(l)
1238 end subroutine zm_conv_tend_2
1240 END MODULE module_cu_camzm_driver