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 real(kind=kind_phys) psfck,tdchk,a,tdkl,tdpre,tlmhk,twrmk,areas8,areap4, &
285 surfw,surfc,dzkl,area1,pintk1,pintk2,pm150,pkl,tkl,qkl
311 if (pkl < 50000.0 .or. pkl > psfck-7000.0) cycle
312 a = log(qkl*pkl/(6.1078*(0.378*qkl+0.622)))
313 tdkl = (237.3*a) / (17.269-a) + 273.15
315 if (tdpre < tdchk .and. tkl < tcold) tcold = tkl
316 if (tdpre < tdchk .and. tkl > twarm) twarm = tkl
317 if (tdpre < tdchk .and. l < licee) licee = l
323 if (tcold == t(lm) .and. tdchk < 6.0)
then
335 if (tcold > 269.15)
then
336 if (tlmhk <= 273.15)
then
385 area1 = (twet(l)-269.15) * (zint(l)-zint(l+1))
386 if (twet(l) >= 269.15) areap4 = areap4 + area1
389 if (areap4 < 3000.0)
then
402 pm150 = psfck - 15000.
406 if (pintk1 >= pm150)
then
407 dzkl = zint(l)-zint(l+1)
409 if (pintk2 < pm150) &
410 dzkl = t(l)*(q(l)*d608+1.0)*rog*log(pintk1/pm150)
411 area1 = (twet(l)-273.15)*dzkl
412 areas8 = areas8 + area1
426 if (ifrzl == 0 .and. t(l) < 273.15) ifrzl = 1
427 if (iwrml == 0 .and. t(l) >= twrmk) iwrml = 1
429 if (iwrml == 0 .or. ifrzl == 0)
then
431 dzkl = zint(l)-zint(l+1)
432 area1 = (twet(l)-273.15)*dzkl
433 if(ifrzl == 0 .and. twet(l) >= 273.15) surfw = surfw + area1
434 if(iwrml == 0 .and. twet(l) <= 273.15) surfc = surfc + area1
437 if(surfc < -3000.0 .or. (areas8 < -3000.0 .and. surfw < 50.0))
then
443 elseif(tlmhk < 273.15)
then
474 subroutine calwxt_ramer(lm,lp1,t,q,pmid,rh,td,pint,ptyp)
487 use machine ,
only : kind_phys
490 real(kind=kind_phys),
parameter :: twice=266.55,rhprcp=0.80,deltag=1.02, &
491 & emelt=0.045,rlim=0.04,slim=0.85
492 real(kind=kind_phys),
parameter :: twmelt=273.15,tz=273.15,efac=1.0
494 integer*4 i, k1, lll, k2, toodry
496 real(kind=kind_phys) xxx ,mye, icefrac
497 integer,
intent(in) :: lm,lp1
498 real(kind=kind_phys),
dimension(lm),
intent(in) :: t,q,pmid,rh,td
499 real(kind=kind_phys),
dimension(lp1),
intent(in) :: pint
500 integer,
intent(out) :: ptyp
502 real(kind=kind_phys),
dimension(lm) :: tq,pq,rhq,twq
505 real(kind=kind_phys) rhmax,twmax,ptop,dpdrh,twtop,rhtop,wgt1,wgt2, &
506 rhavg,dtavg,dpk,ptw,pbot
524 pq(lev) = pmid(l) * 0.01
538 if (rhq(1) < rhprcp)
then
550 if (xxx < -500.)
return
551 twq(l) = xmytw(tq(l),xxx,pq(l))
552 twmax = max(twq(l),twmax)
553 if (pq(l) >= 400.0)
then
554 if (rhq(l) > rhmax)
then
560 if (rhq(l) >= rhprcp .or. toodry == 0)
then
561 if (toodry /= 0)
then
562 dpdrh = log(pq(l)/pq(l-1)) / (rhq(l)-rhq(l-1))
563 pbot = exp(log(pq(l))+(rhprcp-rhq(l))*dpdrh)
567 else if (rhq(l)>= rhprcp)
then
571 dpdrh = log(pq(l)/pq(l-1)) / (rhq(l)-rhq(l-1))
572 ptw = exp(log(pq(l))+(rhprcp-rhq(l))*dpdrh)
579 if (pbot/ptw >= deltag)
then
591 if (twq(1) >= 273.15+2.0)
then
597 if (twmax <= twice)
then
607 if (ptop == pq(k1))
then
615 wgt1 = log(ptop/pq(k2)) / log(pq(k1)/pq(k2))
617 twtop = twq(k1) * wgt1 + twq(k2) * wgt2
618 rhtop = rhq(k1) * wgt1 + rhq(k2) * wgt2
623 twmax = max(twq(l),twmax)
629 if (twtop <= twice)
then
631 if (twmax <= twmelt)
then
644 if (icefrac >= 1.0)
then
645 if (twq(k1) < twmelt)
go to 40
646 if (twq(k1) == twtop)
go to 40
647 wgt1 = (twmelt-twq(k1)) / (twtop-twq(k1))
648 rhavg = rhq(k1) + wgt1 * (rhtop-rhq(k1)) * 0.5
649 dtavg = (twmelt-twq(k1)) * 0.5
650 dpk = wgt1 * log(pq(k1)/ptop)
652 mye = emelt * rhavg ** efac
653 icefrac = icefrac + dpk * dtavg / mye
654 else if (icefrac <= 0.0)
then
657 if (twq(k1) > twice)
go to 40
658 if (twq(k1) == twtop)
then
661 wgt1 = (twice-twq(k1)) / (twtop-twq(k1))
663 rhavg = rhq(k1) + wgt1 * (rhtop-rhq(k1)) * 0.5
664 dtavg = twmelt - (twq(k1)+twice) * 0.5
665 dpk = wgt1 * log(pq(k1)/ptop)
667 mye = emelt * rhavg ** efac
668 icefrac = icefrac + dpk * dtavg / mye
669 else if ((twq(k1) <= twmelt).and.(twq(k1) < twmelt))
then
670 rhavg = (rhq(k1)+rhtop) * 0.5
671 dtavg = twmelt - (twq(k1)+twtop) * 0.5
672 dpk = log(pq(k1)/ptop)
674 mye = emelt * rhavg ** efac
675 icefrac = icefrac + dpk * dtavg / mye
677 if (twq(k1) == twtop)
go to 40
678 wgt1 = (twmelt-twq(k1)) / (twtop-twq(k1))
680 rhavg = rhtop + wgt2 * (rhq(k1)-rhtop) * 0.5
681 dtavg = (twmelt-twtop) * 0.5
682 dpk = wgt2 * log(pq(k1)/ptop)
684 mye = emelt * rhavg ** efac
685 icefrac = icefrac + dpk * dtavg / mye
686 icefrac = min(1.0,max(icefrac,0.0))
687 if (icefrac <= 0.0)
then
689 if (twq(k1) > twice)
go to 40
690 wgt1 = (twice-twq(k1)) / (twtop-twq(k1))
691 dtavg = twmelt - (twq(k1)+twice) * 0.5
693 dtavg = (twmelt-twq(k1)) * 0.5
695 rhavg = rhq(k1) + wgt1 * (rhtop-rhq(k1)) * 0.5
696 dpk = wgt1 * log(pq(k1)/ptop)
698 mye = emelt * rhavg ** efac
699 icefrac = icefrac + dpk * dtavg / mye
702 icefrac = min(1.0,max(icefrac,0.0))
718 if (icefrac >= slim)
then
724 else if (icefrac <= rlim)
then
725 if (twq(1).lt.tz)
then
731 if (twq(1) < tz)
then
753 function xmytw(t,td,p)
755 use machine ,
only : kind_phys
759 real(kind=kind_phys) f, c0, c1, c2, k, kd, kw, ew, t, td, p, ed, fp, s, &
761 data f, c0, c1, c2 /0.0006355, 26.66082, 0.0091379024, 6106.3960/
777 ed = c0 - c1 * kd - c2 / kd
778 if (ed < -14.0 .or. ed > 7.0)
return
780 ew = c0 - c1 * k - c2 / k
781 if (ew < -14.0 .or. ew > 7.0)
return
785 kw = (k*fp+kd*s) / (fp+s)
788 ew = c0 - c1 * kw - c2 / kw
789 if (ew < -14.0 .or. ew > 7.0)
return
791 de = fp * (k-kw) + ed - ew
792 if (abs(de/ew) < 1e-5)
exit
793 s = ew * (c1-c2/(kw*kw)) - fp
878 subroutine calwxt_bourg(lm,lp1,rn,g,t,q,pmid,pint,zint,ptype)
879 use machine ,
only : kind_phys
883 integer,
intent(in) :: lm,lp1
884 real(kind=kind_phys),
intent(in) :: g,rn(2)
885 real(kind=kind_phys),
intent(in),
dimension(lm) :: t, q, pmid
886 real(kind=kind_phys),
intent(in),
dimension(lp1) :: pint, zint
889 integer,
intent(out) :: ptype
891 integer ifrzl,iwrml,l,lhiwrm
892 real(kind=kind_phys) pintk1,areane,tlmhk,areape,pintk2,surfw,area1,dzkl,psfck,r1,r2
909 if (tlmhk >= 273.15)
then
911 if (t(l) >= 273.15 .and. t(l-1) < 273.15 .and. &
912 & iwrml == lm+1) iwrml = l
922 if (t(l) >= 273.15 .and. pmid(l) > 25000.) lhiwrm = l
948 if (ifrzl == 0 .and. t(l) <= 273.15) ifrzl = 1
950 dzkl = zint(l)-zint(l+1)
951 if (t(l) >= 273.15 .and. pmid(l) > 25000.)
then
952 area1 = log(t(l)/273.15) * g * dzkl
954 areape = areape + area1
956 surfw = surfw + area1
958 elseif (l > lhiwrm)
then
959 area1 = log(t(l)/273.15) * g * dzkl
960 areane = areane + abs(area1)
968 if (areape < 2.0)
then
970 if (surfw < 5.6)
then
972 else if (surfw > 13.2)
then
987 if (areane > 66.0+0.66*areape)
then
991 if (surfw < 5.6)
then
993 elseif (surfw > 13.2)
then
1003 elseif (areane < 46.0+0.66*areape)
then
1005 if (tlmhk < 273.15)
then
1015 if (surfw < 5.6)
then
1017 else if (surfw > 13.2)
then
1030 if (tlmhk < 273.15)
then
1048 subroutine calwxt_revised(lm,lp1,t,q,pmid,pint, &
1049 d608,rog,epsq,zint,twet,iwx)
1078 use machine ,
only : kind_phys
1089 integer,
intent(in) :: lm,lp1
1090 real(kind=kind_phys),
dimension(lm),
intent(in) :: t,q,pmid,twet
1091 real(kind=kind_phys),
dimension(lp1),
intent(in) :: pint,zint
1092 real(kind=kind_phys),
intent(in) :: d608,rog,epsq
1101 integer,
intent(out) :: iwx
1104 real(kind=kind_phys),
parameter :: d00=0.0
1106 real(kind=kind_phys) tcold,twarm
1108 integer l,lmhk,lice,iwrml,ifrzl
1109 real(kind=kind_phys) psfck,tdchk,a,tdkl,tdpre,tlmhk,twrmk,areas8,areap4,area1, &
1110 surfw,surfc,dzkl,pintk1,pintk2,pm150,qkl,tkl,pkl,area0,areap0
1148 if (pkl < 50000.0 .or. pkl > psfck-7000.0) cycle
1149 a = log(qkl*pkl/(6.1078*(0.378*qkl+0.622)))
1150 tdkl = (237.3*a)/(17.269-a)+273.15
1152 if (tdpre < tdchk .and. tkl < tcold) tcold = tkl
1153 if (tdpre < tdchk .and. tkl > twarm) twarm = tkl
1154 if (tdpre < tdchk .and. l < licee) licee = l
1160 if (tcold == t(lmhk) .and. tdchk < 6.0)
then
1173 if (tcold > 269.15)
then
1174 if (tlmhk <= 273.15)
then
1220 dzkl = zint(l)-zint(l+1)
1221 area1 = (twet(l)-269.15)*dzkl
1222 area0 = (twet(l)-273.15)*dzkl
1223 if (twet(l) >= 269.15) areap4 = areap4 + area1
1224 if (twet(l) >= 273.15) areap0 = areap0 + area0
1233 if (areap0 < 350.0)
then
1241 pm150 = psfck - 15000.
1245 if(pintk1 >= pm150)
then
1246 dzkl = zint(l)-zint(l+1)
1250 if(pintk2 < pm150) dzkl = t(l)*(q(l)*d608+1.0)*rog* &
1252 area1 = (twet(l)-273.15)*dzkl
1253 areas8 = areas8 + area1
1267 if (ifrzl == 0 .and. t(l) < 273.15) ifrzl = 1
1268 if (iwrml == 0 .and. t(l) >= twrmk) iwrml = 1
1270 if (iwrml == 0 .or. ifrzl == 0)
then
1272 dzkl = zint(l)-zint(l+1)
1273 area1 = (twet(l)-273.15)*dzkl
1274 if(ifrzl == 0 .and. twet(l) >= 273.15) surfw = surfw + area1
1275 if(iwrml == 0 .and. twet(l) <= 273.15) surfc = surfc + area1
1278 if (surfc < -3000.0 .or. &
1279 & (areas8 < -3000.0 .and. surfw < 50.0))
then
1287 if (tlmhk < 273.15)
then