10 subroutine calpreciptype(kdt,nrcm,im,ix,lm,lp1,randomno, &
12 gt0,gq0,prsl,prsi,prec, & !input
14 domr,domzr,domip,doms)
27 use funcphys,
only : fpvs,ftdp,fpkap,ftlcl,stma,fthe
29 use machine ,
only : kind_phys
33 real(kind=kind_phys),
parameter :: pthresh = 0.0, oneog = 1.0/con_g
34 integer,
parameter :: nalg = 5
38 integer,
intent(in) :: kdt,nrcm,im,ix,lm,lp1
39 real(kind=kind_phys),
intent(in) :: xlat(im),xlon(im)
40 real(kind=kind_phys),
intent(in) :: randomno(ix,nrcm)
41 real(kind=kind_phys),
dimension(im),
intent(in) :: prec,tskin
42 real(kind=kind_phys),
dimension(ix,lm),
intent(in) :: gt0,gq0,prsl
43 real(kind=kind_phys),
dimension(ix,lp1),
intent(in) :: prsi,phii
44 real(kind=kind_phys),
dimension(im),
intent(out) :: domr,domzr,domip,doms
46 integer,
dimension(nalg) :: sleet,rain,freezr,snow
47 real(kind=kind_phys),
dimension(lm) :: t,q,pmid
48 real(kind=kind_phys),
dimension(lp1) :: pint,zint
49 real(kind=kind_phys),
allocatable :: twet(:),rh(:),td(:)
51 integer i,iwx,isno,iip,izr,irain,k,k1
52 real(kind=kind_phys) es,qc,pv,tdpd,pr,tr,pk,tlcl,thelcl,qwet, &
53 time_vert,time_ncep,time_ramer,time_bourg,time_revised,&
54 time_dominant,btim,timef,ranl(2)
65 allocate ( twet(lm),rh(lm),td(lm) )
76 if (prec(i) > pthresh)
then
85 pv = pmid(k1)*q(k1)/(con_eps-con_epsm1*q(k1))
94 thelcl = fthe(tlcl,pk*tlcl/tr)
95 call stma(thelcl,pk,twet(k1),qwet)
100 es = min(fpvs(t(k1)), pmid(k1))
101 qc = con_eps*es / (pmid(k1)+con_epsm1*es)
102 rh(k1) = max(con_epsq,q(k1)) / qc
106 zint(k1) = phii(i,k) * oneog
109 pint(1) = prsi(i,lp1)
110 zint(1) = phii(i,lp1) * oneog
135 call calwxt(lm,lp1,t,q,pmid,pint,con_fvirt,con_rog,con_epsq,zint,iwx,twet)
137 sleet(1) = mod(iwx,4)/2
138 freezr(1) = mod(iwx,8)/4
163 call calwxt_ramer(lm,lp1,t,q,pmid,rh,td,pint,iwx)
167 sleet(2) = mod(iwx,4)/2
168 freezr(2) = mod(iwx,8)/4
176 ranl = randomno(i,1:2)
177 call calwxt_bourg(lm,lp1,ranl,con_g,t,q,pmid,pint,zint(1),iwx)
181 sleet(3) = mod(iwx,4)/2
182 freezr(3) = mod(iwx,8)/4
188 call calwxt_revised(lm,lp1,t,q,pmid,pint, &
189 con_fvirt,con_rog,con_epsq,zint,twet,iwx)
192 sleet(4) = mod(iwx,4)/2
193 freezr(4) = mod(iwx,8)/4
203 call calwxt_dominant(nalg,rain(1),freezr(1),sleet(1), &
204 snow(1),domr(i),domzr(i),domip(i),doms(i))
214 deallocate (twet,rh,td)
221 subroutine calwxt(lm,lp1,t,q,pmid,pint, &
222 d608,rog,epsq,zint,iwx,twet)
223 use machine ,
only : kind_phys
248 integer,
intent(in) :: lm,lp1
249 real(kind=kind_phys),
dimension(lm),
intent(in) :: t,q,pmid,twet
250 real(kind=kind_phys),
dimension(lp1),
intent(in) :: zint,pint
251 integer,
intent(out) :: iwx
252 real(kind=kind_phys),
intent(in) :: d608,rog,epsq
267 real(kind=kind_phys),
parameter :: d00=0.0
269 real(kind=kind_phys) tcold,twarm
283 integer l,lice,iwrml,ifrzl
284 logical :: needs_retry
285 real(kind=kind_phys) psfck,tdchk,a,tdkl,tdpre,tlmhk,twrmk,areas8,areap4, &
286 surfw,surfc,dzkl,area1,pintk1,pintk2,pm150,pkl,tkl,qkl
300 retry_loop:
do while (needs_retry)
301 needs_retry = .false.
315 if (pkl < 50000.0 .or. pkl > psfck-7000.0) cycle
316 a = log(qkl*pkl/(6.1078*(0.378*qkl+0.622)))
317 tdkl = (237.3*a) / (17.269-a) + 273.15
319 if (tdpre < tdchk .and. tkl < tcold) tcold = tkl
320 if (tdpre < tdchk .and. tkl > twarm) twarm = tkl
321 if (tdpre < tdchk .and. l < licee) licee = l
327 if (tcold == t(lm) .and. tdchk < 6.0)
then
340 if (tcold > 269.15)
then
341 if (tlmhk <= 273.15)
then
388 area1 = (twet(l)-269.15) * (zint(l)-zint(l+1))
389 if (twet(l) >= 269.15) areap4 = areap4 + area1
392 if (areap4 < 3000.0)
then
405 pm150 = psfck - 15000.
409 if (pintk1 >= pm150)
then
410 dzkl = zint(l)-zint(l+1)
412 if (pintk2 < pm150) &
413 dzkl = t(l)*(q(l)*d608+1.0)*rog*log(pintk1/pm150)
414 area1 = (twet(l)-273.15)*dzkl
415 areas8 = areas8 + area1
429 if (ifrzl == 0 .and. t(l) < 273.15) ifrzl = 1
430 if (iwrml == 0 .and. t(l) >= twrmk) iwrml = 1
432 if (iwrml == 0 .or. ifrzl == 0)
then
434 dzkl = zint(l)-zint(l+1)
435 area1 = (twet(l)-273.15)*dzkl
436 if(ifrzl == 0 .and. twet(l) >= 273.15) surfw = surfw + area1
437 if(iwrml == 0 .and. twet(l) <= 273.15) surfc = surfc + area1
440 if(surfc < -3000.0 .or. (areas8 < -3000.0 .and. surfw < 50.0))
then
446 elseif(tlmhk < 273.15)
then
477 subroutine calwxt_ramer(lm,lp1,t,q,pmid,rh,td,pint,ptyp)
490 use machine ,
only : kind_phys
493 real(kind=kind_phys),
parameter :: twice=266.55,rhprcp=0.80,deltag=1.02, &
494 & emelt=0.045,rlim=0.04,slim=0.85
495 real(kind=kind_phys),
parameter :: twmelt=273.15,tz=273.15,efac=1.0
497 integer*4 i, k1, lll, k2, toodry
499 real(kind=kind_phys) xxx ,mye, icefrac
500 integer,
intent(in) :: lm,lp1
501 real(kind=kind_phys),
dimension(lm),
intent(in) :: t,q,pmid,rh,td
502 real(kind=kind_phys),
dimension(lp1),
intent(in) :: pint
503 integer,
intent(out) :: ptyp
505 real(kind=kind_phys),
dimension(lm) :: tq,pq,rhq,twq
508 real(kind=kind_phys) rhmax,twmax,ptop,dpdrh,twtop,rhtop,wgt1,wgt2, &
509 rhavg,dtavg,dpk,ptw,pbot
527 pq(lev) = pmid(l) * 0.01
541 if (rhq(1) < rhprcp)
then
553 if (xxx < -500.)
return
554 twq(l) = xmytw(tq(l),xxx,pq(l))
555 twmax = max(twq(l),twmax)
556 if (pq(l) >= 400.0)
then
557 if (rhq(l) > rhmax)
then
563 if (rhq(l) >= rhprcp .or. toodry == 0)
then
564 if (toodry /= 0)
then
565 dpdrh = log(pq(l)/pq(l-1)) / (rhq(l)-rhq(l-1))
566 pbot = exp(log(pq(l))+(rhprcp-rhq(l))*dpdrh)
570 else if (rhq(l)>= rhprcp)
then
574 dpdrh = log(pq(l)/pq(l-1)) / (rhq(l)-rhq(l-1))
575 ptw = exp(log(pq(l))+(rhprcp-rhq(l))*dpdrh)
582 if (pbot/ptw >= deltag)
then
594 if (twq(1) >= 273.15+2.0)
then
600 if (twmax <= twice)
then
610 if (ptop == pq(k1))
then
618 wgt1 = log(ptop/pq(k2)) / log(pq(k1)/pq(k2))
620 twtop = twq(k1) * wgt1 + twq(k2) * wgt2
621 rhtop = rhq(k1) * wgt1 + rhq(k2) * wgt2
626 twmax = max(twq(l),twmax)
632 if (twtop <= twice)
then
634 if (twmax <= twmelt)
then
648 if (icefrac >= 1.0)
then
649 if (twq(k1) < twmelt)
exit process_level
650 if (twq(k1) == twtop)
exit process_level
651 wgt1 = (twmelt-twq(k1)) / (twtop-twq(k1))
652 rhavg = rhq(k1) + wgt1 * (rhtop-rhq(k1)) * 0.5
653 dtavg = (twmelt-twq(k1)) * 0.5
654 dpk = wgt1 * log(pq(k1)/ptop)
656 mye = emelt * rhavg ** efac
657 icefrac = icefrac + dpk * dtavg / mye
658 else if (icefrac <= 0.0)
then
661 if (twq(k1) > twice)
exit process_level
662 if (twq(k1) == twtop)
then
665 wgt1 = (twice-twq(k1)) / (twtop-twq(k1))
667 rhavg = rhq(k1) + wgt1 * (rhtop-rhq(k1)) * 0.5
668 dtavg = twmelt - (twq(k1)+twice) * 0.5
669 dpk = wgt1 * log(pq(k1)/ptop)
671 mye = emelt * rhavg ** efac
672 icefrac = icefrac + dpk * dtavg / mye
673 else if ((twq(k1) <= twmelt).and.(twq(k1) < twmelt))
then
674 rhavg = (rhq(k1)+rhtop) * 0.5
675 dtavg = twmelt - (twq(k1)+twtop) * 0.5
676 dpk = log(pq(k1)/ptop)
678 mye = emelt * rhavg ** efac
679 icefrac = icefrac + dpk * dtavg / mye
681 if (twq(k1) == twtop)
exit process_level
682 wgt1 = (twmelt-twq(k1)) / (twtop-twq(k1))
684 rhavg = rhtop + wgt2 * (rhq(k1)-rhtop) * 0.5
685 dtavg = (twmelt-twtop) * 0.5
686 dpk = wgt2 * log(pq(k1)/ptop)
688 mye = emelt * rhavg ** efac
689 icefrac = icefrac + dpk * dtavg / mye
690 icefrac = min(1.0,max(icefrac,0.0))
691 if (icefrac <= 0.0)
then
693 if (twq(k1) > twice)
exit process_level
694 wgt1 = (twice-twq(k1)) / (twtop-twq(k1))
695 dtavg = twmelt - (twq(k1)+twice) * 0.5
697 dtavg = (twmelt-twq(k1)) * 0.5
699 rhavg = rhq(k1) + wgt1 * (rhtop-rhq(k1)) * 0.5
700 dpk = wgt1 * log(pq(k1)/ptop)
702 mye = emelt * rhavg ** efac
703 icefrac = icefrac + dpk * dtavg / mye
706 icefrac = min(1.0,max(icefrac,0.0))
726 if (icefrac >= slim)
then
732 else if (icefrac <= rlim)
then
733 if (twq(1).lt.tz)
then
739 if (twq(1) < tz)
then
767 real(kind=kind_phys) f, c0, c1, c2, k, kd, kw, ew, t, td, p, ed, fp, s, &
886 subroutine calwxt_bourg(lm,lp1,rn,g,t,q,pmid,pint,zint,ptype)
887 use machine ,
only : kind_phys
891 integer,
intent(in) :: lm,lp1
892 real(kind=kind_phys),
intent(in) :: g,rn(2)
893 real(kind=kind_phys),
intent(in),
dimension(lm) :: t, q, pmid
894 real(kind=kind_phys),
intent(in),
dimension(lp1) :: pint, zint
897 integer,
intent(out) :: ptype
899 integer ifrzl,iwrml,l,lhiwrm
900 real(kind=kind_phys) pintk1,areane,tlmhk,areape,pintk2,surfw,area1,dzkl,psfck,r1,r2
917 if (tlmhk >= 273.15)
then
919 if (t(l) >= 273.15 .and. t(l-1) < 273.15 .and. &
920 & iwrml == lm+1) iwrml = l
930 if (t(l) >= 273.15 .and. pmid(l) > 25000.) lhiwrm = l
956 if (ifrzl == 0 .and. t(l) <= 273.15) ifrzl = 1
958 dzkl = zint(l)-zint(l+1)
959 if (t(l) >= 273.15 .and. pmid(l) > 25000.)
then
960 area1 = log(t(l)/273.15) * g * dzkl
962 areape = areape + area1
964 surfw = surfw + area1
966 elseif (l > lhiwrm)
then
967 area1 = log(t(l)/273.15) * g * dzkl
968 areane = areane + abs(area1)
976 if (areape < 2.0)
then
978 if (surfw < 5.6)
then
980 else if (surfw > 13.2)
then
995 if (areane > 66.0+0.66*areape)
then
999 if (surfw < 5.6)
then
1001 elseif (surfw > 13.2)
then
1011 elseif (areane < 46.0+0.66*areape)
then
1013 if (tlmhk < 273.15)
then
1023 if (surfw < 5.6)
then
1025 else if (surfw > 13.2)
then
1038 if (tlmhk < 273.15)
then
1056 subroutine calwxt_revised(lm,lp1,t,q,pmid,pint, &
1057 d608,rog,epsq,zint,twet,iwx)
1086 use machine ,
only : kind_phys
1097 integer,
intent(in) :: lm,lp1
1098 real(kind=kind_phys),
dimension(lm),
intent(in) :: t,q,pmid,twet
1099 real(kind=kind_phys),
dimension(lp1),
intent(in) :: pint,zint
1100 real(kind=kind_phys),
intent(in) :: d608,rog,epsq
1109 integer,
intent(out) :: iwx
1112 real(kind=kind_phys),
parameter :: d00=0.0
1114 real(kind=kind_phys) tcold,twarm
1115 logical :: needs_retry
1117 integer l,lmhk,lice,iwrml,ifrzl
1118 real(kind=kind_phys) psfck,tdchk,a,tdkl,tdpre,tlmhk,twrmk,areas8,areap4,area1, &
1119 surfw,surfc,dzkl,pintk1,pintk2,pm150,qkl,tkl,pkl,area0,areap0
1144 needs_retry = .true.
1146 retry_loop:
do while (needs_retry)
1147 needs_retry = .false.
1161 if (pkl < 50000.0 .or. pkl > psfck-7000.0) cycle
1162 a = log(qkl*pkl/(6.1078*(0.378*qkl+0.622)))
1163 tdkl = (237.3*a)/(17.269-a)+273.15
1165 if (tdpre < tdchk .and. tkl < tcold) tcold = tkl
1166 if (tdpre < tdchk .and. tkl > twarm) twarm = tkl
1167 if (tdpre < tdchk .and. l < licee) licee = l
1173 if (tcold == t(lmhk) .and. tdchk < 6.0)
then
1175 needs_retry = .true.
1188 if (tcold > 269.15)
then
1189 if (tlmhk <= 273.15)
then
1233 dzkl = zint(l)-zint(l+1)
1234 area1 = (twet(l)-269.15)*dzkl
1235 area0 = (twet(l)-273.15)*dzkl
1236 if (twet(l) >= 269.15) areap4 = areap4 + area1
1237 if (twet(l) >= 273.15) areap0 = areap0 + area0
1246 if (areap0 < 350.0)
then
1254 pm150 = psfck - 15000.
1258 if(pintk1 >= pm150)
then
1259 dzkl = zint(l)-zint(l+1)
1263 if(pintk2 < pm150) dzkl = t(l)*(q(l)*d608+1.0)*rog* &
1265 area1 = (twet(l)-273.15)*dzkl
1266 areas8 = areas8 + area1
1280 if (ifrzl == 0 .and. t(l) < 273.15) ifrzl = 1
1281 if (iwrml == 0 .and. t(l) >= twrmk) iwrml = 1
1283 if (iwrml == 0 .or. ifrzl == 0)
then
1285 dzkl = zint(l)-zint(l+1)
1286 area1 = (twet(l)-273.15)*dzkl
1287 if(ifrzl == 0 .and. twet(l) >= 273.15) surfw = surfw + area1
1288 if(iwrml == 0 .and. twet(l) <= 273.15) surfc = surfc + area1
1291 if (surfc < -3000.0 .or. &
1292 & (areas8 < -3000.0 .and. surfw < 50.0))
then
1300 if (tlmhk < 273.15)
then