17 type :: precipitations_t
22 integer :: convection = 4
23 end type precipitations_t
25 type(precipitations_t
),
parameter :: PRECIPS = precipitations_t()
61 subroutine derive_fields(imp_physics,t, rh, pres, hgt, totalWater, totalCond,&
62 nz, topok, hprcp, hcprcp, cin, cape, &
63 ept, wbt, twp, pc, kx, lx, tott, prcptype)
67 integer,
intent(in) :: imp_physics
68 integer,
intent(in) :: nz, topok
69 real,
intent(in),
dimension(nz) :: t, rh, pres, hgt
70 real,
intent(in),
dimension(nz) :: totalwater,totalcond
71 real,
intent(in) :: hprcp, hcprcp, cin, cape
72 real,
intent(out) :: ept(nz), wbt(nz), twp(nz)
73 real,
intent(out) :: pc, kx, lx, tott
74 integer,
intent(out) :: prcptype
76 real,
allocatable :: td(:), tlc(:), wvm(:)
83 td(:) = getdewpointtemp(t(:), rh(:))
84 tlc(:) = get_tlcl(t(:), td(:))
87 ept(:) = getthetae(pres(:), t(:), wvm(:), tlc(:))
88 wbt(:) = getthetaw(t(:), td(:), pres(:))
90 call calc_totalwaterpath(hgt, pres, t, totalwater, nz, twp)
93 pc = getprecipcond(totalcond, nz, topok)
96 call calc_indice(t, td, pres, wvm, nz, topok, kx, lx, tott)
98 prcptype=getpreciptype(imp_physics,pres,hgt,t,rh,wbt,nz,&
99 hprcp,hcprcp,pc,cin,cape,lx)
111 elemental real function getdewpointtemp(t, rh)
113 real,
intent(in) :: t, rh
120 vapr = (max(1.0e-6,rh) / 100.0) * getvaporpres(t)
123 getdewpointtemp = 243.5 * rm / (17.67 - rm) + 273.15
126 end function getdewpointtemp
133 elemental real function getthetae(pres, t, wvm, tAtLCL)
135 real,
intent(in) :: pres, t, wvm, tatlcl
141 e = (2.0/7.0) * ( 1.0 - 0.28 * rmix * 0.001)
142 thtam = t * ((100000.0/pres)**e)
143 getthetae = thtam * exp( (3.376/tatlcl - 0.00254) * &
144 (rmix * (1. + (.81 * rmix * 0.001)) ))
147 end function getthetae
152 elemental real function getvaporpres(t)
154 real,
intent(in) :: t
160 getvaporpres = 611.2 * exp( 17.67*tc/(tc+243.5))
163 end function getvaporpres
168 elemental real function get_tlcl(t, td)
170 real,
intent(in) :: t, td
172 get_tlcl = 1. / (1./(td - 56.) + log(t/td)/800.0) + 56.0
175 end function get_tlcl
184 real,
intent(in) :: td, pres
188 corr = 1.001 + ( (pres/100.0 - 100) /900.) * 0.0034
189 e = getvaporpres(td) * corr
199 elemental real function getthetaw(t, td, pres)
201 real,
intent(in) :: t, td, pres
203 real :: vl, cp, dt, top, bottom, twet, twetnew
216 twet = (top + bottom) / 2.0
220 twetnew = t - (vl/cp) * (smixr-rmixr)
221 if(twetnew < twet)
then
227 dt = abs(twet - twetnew)
236 end function getthetaw
240 real function getprecipcond(totalCond, nz, topoK)
242 real,
intent(in) :: totalcond(nz)
243 integer,
intent(in) :: nz, topok
249 do k = topok, topok-2, -1
250 getprecipcond = totalcond(k) + getprecipcond
254 end function getprecipcond
260 subroutine calc_indice(t, td, pres, wvm, nz, topoK, &
261 kindex, liftedindex, totaltotals)
263 integer,
intent(in) :: nz, topok
264 real,
intent(in) :: t(nz), td(nz), pres(nz), wvm(nz)
265 real,
intent(out) :: kindex, liftedindex, totaltotals
268 real :: t500hpa, t700hpa, t850hpa, dpt700hpa, dpt850hpa
270 real :: surfacetemp,surfacedewpttemp,surfacepressure,surfacemixr
271 real :: tempatlcl, theta, pressatlcl, thetaeatlcl, tempfromthetae, tem
285 if ((pres(k)- 50000.0 >= 0.) .and. (pres(k-1)- 50000.0 < 0.) )
then
286 if (abs(pres(k)- 50000.0) <= 0.1)
then
288 elseif (abs(pres(k-1)- 50000.0) <= 0.1)
then
291 t500hpa = t(k) - ((pres(k)-50000.0)/(pres(k)-pres(k-1))) * (t(k)-t(k-1))
296 if ((pres(k)- 70000.0 >= 0.) .and. (pres(k-1)- 70000.0 < 0.) )
then
297 if (abs(pres(k)- 70000.0) <= 0.1)
then
300 elseif (abs(pres(k-1)- 70000.0) <= 0.1)
then
304 tem = (pres(k)-70000.0)/(pres(k)-pres(k-1))
305 t700hpa = t(k) - tem * (t(k)-t(k-1))
306 dpt700hpa = td(k) - tem * (td(k)-td(k-1))
311 if ((pres(k)- 85000.0 >= 0.) .and. (pres(k-1)- 85000.0 < 0.) )
then
312 if (abs(pres(k)- 85000.0) <= 0.1)
then
315 elseif (abs(pres(k-1)- 85000.0) <= 0.1)
then
319 tem = (pres(k)-85000.0)/(pres(k)-pres(k-1))
320 t850hpa = t(k) - tem * (t(k)-t(k-1))
321 dpt850hpa = td(k) - tem * (td(k)-td(k-1))
328 kindex = (t850hpa-t500hpa) + (dpt850hpa-273.15) - (t700hpa-dpt700hpa)
331 totaltotals = t850hpa + dpt850hpa - t500hpa * 2.0
335 surfacetemp = t(topok)
336 surfacedewpttemp = td(topok)
337 surfacepressure = pres(topok)
338 surfacemixr = wvm(topok)
340 tempatlcl = get_tlcl(surfacetemp, surfacedewpttemp)
341 theta = surfacetemp * (100000.0/surfacepressure)**0.286
342 pressatlcl = 100000.0 * (tempatlcl / theta)**3.4965
343 thetaeatlcl = getthetae(pressatlcl,tempatlcl,surfacemixr,tempatlcl)
345 tempfromthetae = gettemperature(thetaeatlcl, 50000.0)
347 liftedindex = t500hpa - tempfromthetae
350 end subroutine calc_indice
353 real function gettemperature(thetaE, pres)
355 real,
intent(in) :: thetae, pres
357 real :: guess, w1, w2, thetae1, thetae2, cor
360 guess = (thetae - 0.5 * (max(thetae - 270.0, 0.0))**1.05) * &
364 w1 = calcrsubs(pres, guess)
365 w2 = calcrsubs(pres, guess + 1.0)
366 thetae1 = getthetae(pres, guess, w1, guess)
367 thetae2 = getthetae(pres, guess + 1.0, w2, guess + 1.0)
368 cor = (thetae - thetae1)/(thetae2 - thetae1)
371 if (abs(cor) < 0.01)
then
376 gettemperature = guess
379 end function gettemperature
382 elemental real function calcrsubs(pres, temp)
384 real,
intent(in) :: pres, temp
388 esubs = calcesubs(temp)
389 calcrsubs = (0.622*esubs)/(pres - esubs)
392 end function calcrsubs
395 elemental real function calcesubs(temp)
397 real,
intent(in) :: temp
400 real,
parameter :: coeffs(9) = &
401 (/ 610.5851, 44.40316, 1.430341, 0.02641412, 2.995057e-4,&
402 2.031998e-6, 6.936113e-9, 2.564861e-12, -3.704404e-14 /)
405 x= max(-80.0, temp - 273.15)
407 calcesubs = coeffs(1) + x*(coeffs(2) + x*(coeffs(3) + x*(coeffs(4) + &
408 x*(coeffs(5) + x*(coeffs(6) + x*(coeffs(7) + &
409 x*(coeffs(8) + x*coeffs(9))))))))
411 end function calcesubs
414 subroutine calc_totalwaterpath(hgt, pres, t, totalWater, nz, twp)
416 integer,
intent(in) :: nz
417 real,
intent(in) :: hgt(nz), pres(nz), t(nz), totalwater(nz)
418 real,
intent(out):: twp(nz)
420 real :: condensateintegrated
421 integer :: topidx, baseidx
431 lp200:
do m = k, 2, -1
432 if (totalwater(m) > 0.001)
then
440 if (totalwater(m) > 0.001)
then
448 if(topidx == -1 .or. baseidx == -1) cycle
449 condensateintegrated = 0.0
450 lp400:
do m = topidx, baseidx
451 if (t(m) <= 273.15)
then
452 condensateintegrated = condensateintegrated + &
453 ( ((totalwater(m)*pres(m)) / (287.05 * t(m)) ) * &
454 (hgt(m-1) - hgt(m) + 0.001))
458 twp(k) = condensateintegrated
463 end subroutine calc_totalwaterpath
466 integer function getpreciptype(imp_physics,pres, hgt, t, rh, wbt, nz, &
467 hprcp, hcprcp, pc, cin, cape, lx)
469 integer,
intent(in) :: imp_physics
470 integer,
intent(in) :: nz
471 real,
intent(in) :: pres(nz), hgt(nz), t(nz), rh(nz), wbt(nz)
472 real,
intent(in) :: hprcp,hcprcp, pc, cin, cape, lx
474 integer,
allocatable :: wxtype(:)
476 integer :: idxmelt, idxrefz, iceidx
477 real :: coldtemp, tcoldarea, wetbuldarea
479 real :: precip, precip_standard
488 if(imp_physics == 98 .or. imp_physics == 99)
then
490 precip_standard =0.045
491 else if(imp_physics == 11 .or. imp_physics == 8)
then
493 precip_standard = 0.01
497 if_conv:
if ( hcprcp >= 1.0 .and. cape >= 1000.0 .and. cin > -100. &
499 getpreciptype = precips% CONVECTION
504 if( wbt(k) > 273.15)
then
508 if (t(m) < 273.15)
then
519 lp200:
do k = nz, 1, -1
523 if_pres_wbt:
if ( pres(k) >= 15000. .or. &
524 (wbt(k) >= 200. .and. wbt(k) <= 1000.))
then
532 if( (pres(m)>=30000. .or. (hgt(m)>hgt(nz)+700.))&
533 .and. (rh(m) > 90.) .and. (t(m) < coldtemp))
then
540 if_iceidx:
if (iceidx /= k)
then
546 if (wbt(m) >= 273.15)
then
547 tcoldarea = tcoldarea + (wbt(m)-273.15) * &
556 if ( (hgt(m) <= hgt(nz)+1500) .and. &
558 wetbuldarea = wetbuldarea + (wbt(m)-273.15) * &
564 if (coldtemp > 265.15)
then
565 wxtype(k) = precips% OTHER
566 else if (tcoldarea < 350.)
then
567 if(t(k) <= 273.15)
then
568 wxtype(k) = precips% SNOW
570 wxtype(k) = precips% RAIN
572 else if (wetbuldarea <= -250.)
then
573 wxtype(k) = precips% OTHER
574 else if(t(k) <= 273.15)
then
575 wxtype(k) = precips% OTHER
577 wxtype(k) = precips% RAIN
581 wxtype(k) = precips% NONE
587 getpreciptype = precips% NONE
590 if(precip >= precip_standard)
then
592 if (wxtype(k) > getpreciptype)
then
593 getpreciptype = wxtype(k)
602 end function getpreciptype
619 integer,
parameter :: maxlayers = 30
630 real,
allocatable :: layerq(:)
633 integer :: topidx(maxlayers)
635 integer :: baseidx(maxlayers)
637 real :: ctt(maxlayers)
647 integer,
intent(in) :: nz, topok
648 real,
intent(in) :: rh(nz),t(nz),pres(nz), ept(nz), vv(nz)
649 real,
intent(in) :: xlat,xlon
650 integer,
intent(out) :: region
651 type(clouds_t
),
intent(inout) :: clouds
654 integer :: in_cld,cur_base, num_lyr
656 integer :: k, kk, n, kstart
659 if (abs(xlat)<23.5)
then
662 elseif ( (abs(xlat)>=23.5).and.(abs(xlat)<66))
then
678 if((rh(1) >= t_rh) .and. (rh(2) >= t_rh))
then
679 num_lyr = num_lyr + 1
682 clouds%topIdx(num_lyr) = 1
683 clouds%ctt(num_lyr) = t(1)
687 if ((rh(kk-1)>=t_rh).and.(rh(kk)<t_rh))
then
688 if ((rh(kk+1)<t_rh).and.(in_cld==1))
then
689 clouds%baseIdx(num_lyr) = kk
696 kstart = cur_base + 1
698 do k = kstart, topok-1
699 if (cur_base<=k)
then
700 if ((rh(k-1)<t_rh).and.(in_cld==0))
then
701 if ((rh(k)>=t_rh).and.(rh(k+1)>=t_rh))
then
702 num_lyr = num_lyr + 1
705 clouds%topIdx(num_lyr) = k
706 clouds%ctt(num_lyr) = t(k)
709 do kk=clouds%topIdx(num_lyr),topok-1
710 if ((rh(kk-1)>=t_rh).and.(rh(kk)<t_rh))
then
711 if ((rh(kk+1)<t_rh).and.(in_cld==1))
then
712 clouds%baseIdx(num_lyr) = kk
726 clouds%baseIdx(num_lyr) = topok
729 clouds%nLayers = num_lyr
731 clouds%wmnIdx = getwarmnoseidx(t, nz)
736 clouds%avv = getaveragevertvel(t, vv, nz, &
737 clouds%topIdx(num_lyr), clouds%baseIdx(num_lyr))
743 call calc_layerq(t, rh, pres, ept, nz, clouds)
761 integer function getwarmnoseidx(t, nz)
763 integer,
intent(in) :: nz
764 real,
intent(in) :: t(nz)
766 logical :: abovefreezing
771 abovefreezing = .false.
779 if(t(k) <= 273.15)
then
780 if (abovefreezing)
then
781 getwarmnoseidx = tmpindex
786 abovefreezing = .false.
788 if(.not. abovefreezing) tmpindex = k
789 abovefreezing = .true.
795 end function getwarmnoseidx
802 real function getaveragevertvel(t,vv,nz, topIdx_lowest,baseIdx_lowest)
804 integer,
intent(in) :: nz
805 real,
intent(in) :: t(nz), vv(nz)
806 integer,
intent(in) :: topidx_lowest,baseidx_lowest
808 integer :: numvertvel, k, start_base
816 if(baseidx_lowest == nz)
then
819 start_base = baseidx_lowest
822 do k = start_base, topidx_lowest, -1
823 if ( t(k) <= 260.15 .and. t(k) >= 257.15)
then
824 sumvertvel = sumvertvel + vv(k)
825 numvertvel = numvertvel + 1
826 else if (t(k) < 257.15)
then
827 sumvertvel = sumvertvel + vv(k) + vv(k+1)
833 if (numvertvel == 0)
then
834 getaveragevertvel = 0.0
836 getaveragevertvel = sumvertvel / numvertvel
840 end function getaveragevertvel
843 subroutine calc_layerq(t, rh, pres, ept, nz, clouds)
845 integer,
intent(in) :: nz
846 real,
intent(in) :: t(nz), rh(nz), pres(nz), ept(nz)
847 type(clouds_t
),
intent(inout) :: clouds
850 real :: mean_rh, te_map, rh_map, adj_q
851 real :: totalq, testthetae, q_top, q_base, q_layer, delta_te, sum_rh
852 integer :: base_k, test_k, num_layers
854 integer :: k, m, n, kk
856 clouds%layerQ(:) = 0.0
859 lp_nlayers:
do n = 1, clouds%nLayers
860 lp_k_inlayer:
do k = clouds%topIdx(n), clouds%baseIdx(n)-1
866 base_k = clouds%baseIdx(n)
868 if((testthetae-ept(m)>4.) .and. (clouds%baseIdx(n)<=m))
then
875 lp_kk:
do kk = k, base_k-1
878 q_layer = q_base - q_top
881 q_layer = q_layer * (pres(kk)/(287.05 * t(kk)))
883 if (q_layer < 0.0) q_layer = 0.0
885 delta_te = testthetae - ept(kk+1)
892 num_layers = num_layers + 1
893 sum_rh = sum_rh + rh(m)
896 if (num_layers == 0)
then
899 mean_rh = sum_rh / num_layers
902 te_map = dq_delta_te_map(delta_te)
903 rh_map = dq_rh_map(mean_rh)
904 adj_q = q_layer * te_map * rh_map
906 totalq = totalq + adj_q
909 clouds%layerQ(k) = totalq
914 end subroutine calc_layerq
918 real function dq_rh_map(rh)
920 real,
intent(in) :: rh
924 else if( rh >= 100.)
then
927 dq_rh_map = (rh-70.)/30.
931 end function dq_rh_map
935 real function dq_delta_te_map(delTE)
937 real,
intent(in) :: delte
939 if (delte <= 0.0)
then
940 dq_delta_te_map = 1.0
941 else if (delte <= 4.0)
then
942 dq_delta_te_map = (4. - delte) / 4.0
944 dq_delta_te_map = 0.0
948 end function dq_delta_te_map
972 subroutine icing_pot(hgt, rh, t, liqCond, vv, nz, clouds, ice_pot)
974 integer,
intent(in) :: nz
975 real,
intent(in) :: hgt(nz), rh(nz), t(nz), liqcond(nz), vv(nz)
976 type(clouds_t
),
intent(in) :: clouds
977 real,
intent(out) :: ice_pot(nz)
979 real :: ctt, slw, slw_fac, vv_fac
983 real :: mapt,maprh,mapctt,mapvv,mapslw
988 lp_n:
do n = 1, clouds%nLayers
993 lp_k:
do k = clouds%topIdx(n), clouds%baseIdx(n)
996 if ( ctt>=259.15 .and. ctt<=273.15 )
then
1002 ice_pot(k) = tmap(t(k)) * rh_map(rh(k)) * ctt_map(ctt)
1005 if (vv_map(vv(k))>=0.0)
then
1006 vv_fac = (1.0-ice_pot(k)) * (0.25*vv_map(vv(k)))
1008 vv_fac = ice_pot(k) * (0.25*vv_map(vv(k)))
1012 slw_fac = (1.0 - ice_pot(k))*(0.4*slw_map(slw))
1015 if (ice_pot(k)>0.001)
then
1016 ice_pot(k) = ice_pot(k) + vv_fac + slw_fac
1020 if (ice_pot(k)>1.0)
then
1044 real function tmap(temp)
1046 real,
intent(in) :: temp
1048 if((temp>=248.15).and.(temp<=263.15))
then
1049 tmap=((temp-248.15)/15.0)**1.5
1050 elseif((temp>263.15).and.(temp<268.15))
then
1052 elseif((temp>268.15).and.(temp<273.15))
then
1053 tmap=((273.15 - temp)/5.0)**0.75
1063 real function rh_map(rh)
1065 real,
intent(in) :: rh
1069 elseif ( (rh<=95.0).and.(rh>=50.0) )
then
1070 rh_map=((20./9.) * ((rh/100.0)-0.5))**3.0
1080 real function ctt_map(ctt)
1082 real,
intent(in) :: ctt
1084 if((ctt>=261.0).and.(ctt<280.))
then
1086 elseif((ctt>223.0).and.(ctt<261.0 ))
then
1087 ctt_map = 0.2 + 0.8*(((ctt - 223.0)/38.0)**2.0)
1088 elseif(ctt<223.0)
then
1095 end function ctt_map
1100 real function vv_map(vv)
1102 real,
intent(in) :: vv
1106 elseif (vv<-0.5)
then
1109 vv_map = -1.0 * (vv/0.5)
1118 real function slw_map(slw)
1120 real,
intent(in) :: slw
1124 elseif (slw<=0.001)
then
1131 end function slw_map
1146 integer :: NO_PRECIPITAION = 0
1148 integer :: PRECIPITAION_BELOW_WARMNOSE = 1
1150 integer :: PRECIPITAION_ABOVE_WARMNOSE = 2
1152 integer :: ALL_SNOW = 3
1154 integer :: COLD_RAIN = 4
1156 integer :: WARM_PRECIPITAION = 5
1158 integer :: FREEZING_PRECIPITAION = 6
1160 integer :: CONVECTION = 7
1174 real,
intent(in) :: v
1175 integer,
intent(in) :: scenario
1177 select case (scenario)
1178 case(scenarios%PRECIPITAION_ABOVE_WARMNOSE, scenarios%ALL_SNOW, &
1179 scenarios%COLD_RAIN, scenarios%FREEZING_PRECIPITAION)
1183 else if( v < 1000.)
then
1188 case( scenarios%WARM_PRECIPITAION)
1192 else if( v < 500.)
then
1205 real,
intent(in) :: v
1206 integer,
intent(in) :: scenario
1208 select case (scenario)
1209 case(scenarios%PRECIPITAION_BELOW_WARMNOSE)
1211 if(v <= 269.15)
then
1213 elseif( v <= 273.15)
then
1214 t_map = (273.15 - v ) / 4.0
1222 if(v <= 248.15)
then
1224 elseif( v <= 248.65)
then
1225 t_map = (49.162215 - 0.1961*v) * 2.
1226 elseif( v <= 249.15)
then
1227 t_map = (20.617195 - 0.0813*v) * 2.
1228 elseif(v <= 251.15)
then
1229 t_map = (52.02265 - 0.203*v) / 2.0
1230 elseif(v <= 253.15)
then
1231 t_map = (36.14997 - 0.1398*v) / 2.0
1232 elseif(v <= 255.15)
then
1233 t_map = (29.51744 - 0.1136*v) / 2.0
1234 elseif(v <= 257.15)
then
1235 t_map = (25.613645-0.0983*v) / 2.0
1236 elseif(v <= 259.15)
then
1237 t_map = (22.91357 - 0.0878*v) / 2.0
1238 elseif( v <= 261.15)
then
1239 t_map = (20.918115 - 0.0801*v) / 2.
1251 real,
intent(in) :: v
1252 integer,
intent(in) :: scenario
1254 select case (scenario)
1255 case(scenarios%NO_PRECIPITAION)
1257 case(scenarios%PRECIPITAION_BELOW_WARMNOSE, scenarios%COLD_RAIN, &
1258 scenarios%PRECIPITAION_ABOVE_WARMNOSE)
1262 elseif(v <= 0.2)
then
1267 case(scenarios%ALL_SNOW)
1271 elseif(v <= 0.25)
then
1276 case(scenarios%WARM_PRECIPITAION, scenarios%FREEZING_PRECIPITAION)
1280 elseif(v <= 0.15)
then
1292 real,
intent(in) :: v
1293 integer,
intent(in) :: scenario
1295 select case (scenario)
1296 case (scenarios%NO_PRECIPITAION, scenarios%WARM_PRECIPITAION)
1300 else if(v <= 1828.8)
then
1305 case(scenarios%PRECIPITAION_BELOW_WARMNOSE)
1312 case(scenarios%ALL_SNOW)
1316 else if(v <= 2743.2)
then
1321 case(scenarios%COLD_RAIN, scenarios%FREEZING_PRECIPITAION)
1325 else if(v <= 4267.2)
then
1341 real function ctt_map(v)
1343 real,
intent(in) :: v
1344 if(v <= 223.15)
then
1346 elseif(v <= 233.15)
then
1347 ctt_map = (20.36251 - 0.0554*v) / 10.
1348 elseif(v <= 243.15)
then
1349 ctt_map = (46.19553 - 0.1662*v) / 10.
1350 elseif(v <= 253.15)
then
1351 ctt_map = (73.13655 - 0.277*v) / 10.
1352 elseif(v <= 261.15)
then
1353 ctt_map = (78.71061 - 0.3014*v) / 8.
1357 end function ctt_map
1361 real function vv_map(v)
1363 real,
intent(in) :: v
1366 else if(v <= 0.)
then
1379 real,
intent(in) :: v
1380 if( v <= 609.6)
then
1382 elseif( v <= 3048.)
then
1395 real,
intent(in) :: v
1396 if( v <= 304.8)
then
1398 elseif( v <= 1524.)
then
1409 real,
intent(in) :: v
1412 elseif( v <= 1.0)
then
1422 real,
intent(in) :: rh, liqcond, icecond, pres, t
1423 real :: liq_m3, ice_m3, rhfactor, liqfactor,icefactor
1425 liq_m3 = (liqcond * pres) / (287.05 * t)
1426 ice_m3 = (icecond * pres) / (287.05 * t)
1427 rhfactor = 0.5 * rh_map(rh)
1438 real,
intent(in) :: rh, cwat, pres, t
1439 real :: cwat_m3, rhfactor, cwatfactor
1441 cwat_m3 = (cwat * pres) / (287.05 * t)
1442 rhfactor = 0.5 * rh_map(rh)
1451 real function rh_map(v)
1453 real,
intent(in) :: v
1456 else if(v <= 100)
then
1457 rh_map = (v - 70.) / 30.
1468 real,
intent(in) :: v
1471 elseif( v <= 0.2)
then
1488 real,
intent(in) :: v
1489 if(v <= 243.15)
then
1491 else if(v <= 265.15)
then
1493 else if(v <= 269.15)
then
1495 else if(v <= 270.15)
then
1497 else if(v <= 271.15)
then
1499 else if(v <= 272.15)
then
1501 else if(v <= 273.15)
then
1513 real,
intent(in) :: v
1516 else if(v <= 3.0)
then
1527 real,
intent(in) :: v
1529 if (v <= 1000.0)
then
1531 else if(v <= 2500.)
then
1543 real,
intent(in) :: v
1546 else if(v <= 0.)
then
1558 real,
intent(in) :: v
1561 else if(v <= 40.0)
then
1572 real,
intent(in) :: v
1575 else if( v <= 55.0)
then
1597 real,
parameter :: cold_prcp_t_thld = 261.15
1601 real :: ctt, layerq, avv
1602 integer :: nlayers, topidx, baseidx, wmnidx
1604 real :: deltaz, cloudtopdist
1606 logical :: lowestcloud
1615 subroutine icing_sev(imp_physics,hgt, rh, t, pres, vv, liqCond, iceCond, twp, &
1616 ice_pot, nz, hcprcp, cape, lx, kx, tott, pc, prcptype, clouds, &
1619 integer,
intent(in) :: imp_physics
1620 integer,
intent(in) :: nz
1621 real,
intent(in) :: hgt(nz), rh(nz), t(nz), pres(nz), vv(nz)
1622 real,
intent(in) :: liqcond(nz), icecond(nz), twp(nz), ice_pot(nz)
1623 real,
intent(in) :: hcprcp, cape, lx, kx, tott, pc
1624 integer,
intent(in) :: prcptype
1625 type(clouds_t
),
intent(in) :: clouds
1626 real,
intent(out) :: iseverity(nz)
1635 lowestcloud = .false.
1638 lp_n:
do n = 1, clouds%nLayers
1641 wmnidx = clouds%wmnIdx
1643 if (n == clouds%nLayers) lowestcloud = .true.
1646 topidx = clouds%topIdx(n)
1647 baseidx = clouds%baseIdx(n)
1649 lp_k:
do k = topidx, baseidx
1650 if (ice_pot(k) < 0.001) cycle
1655 layerq = clouds%layerQ(k)
1657 deltaz = hgt(k) - hgt(baseidx)
1658 cloudtopdist = hgt(topidx) - hgt(k)
1661 if(imp_physics == 98 .or. imp_physics == 99)
then
1667 if(isconvection(prcptype))
then
1668 call convectionscenario &
1669 (t(k), hcprcp, cape, lx, kx, tott, severity)
1670 elseif(isclassicprcpblwwmn(prcptype, k))
then
1671 call classicprcpblwwmnscenario &
1672 (t(k), avv, pc, ice_pot(k), severity)
1673 elseif(isclassicprcpabvwmn(prcptype, k))
then
1674 call classicprcpabvwmnscenario &
1675 (twp(k), vv(k), t(k), pc, ice_pot(k),severity)
1676 elseif(isnoprecip(prcptype))
then
1677 call noprcpscenario &
1678 (vv(k), t(k), pc, ice_pot(k), severity)
1679 elseif(issnow(prcptype))
then
1681 (twp(k), vv(k), t(k), pc, ice_pot(k), severity)
1682 elseif(iscoldrain(prcptype))
then
1683 call coldrainscenario &
1684 (twp(k), vv(k), t(k), pc, ice_pot(k), severity)
1685 elseif(iswarmprecip(prcptype))
then
1686 call warmprecipscenario &
1687 (twp(k), vv(k), t(k), pc, ice_pot(k), severity)
1688 elseif(isfreezingprecip(prcptype))
then
1689 call freezingprecipscenario &
1690 (twp(k), vv(k), t(k), pc, ice_pot(k), severity)
1726 iseverity(k)=min(1., severity)
1727 iseverity(k)=max(0., severity)
1736 logical function isconvection(prcpType)
1738 integer,
intent(in) :: prcptype
1740 isconvection = prcptype == precips%CONVECTION
1743 end function isconvection
1746 subroutine convectionscenario(t, hcprcp, cape, lx, kx, tott, severity)
1748 real,
intent(in) :: t, hcprcp, cape, lx, kx, tott
1749 real,
intent(out) :: severity
1753 real :: tint, prcpint, capeint, lxint, kxint,tottint
1755 real :: weights(6) = (/ 4.0, 3.0, 5.0, 5.0, 2.0, 2.0 /)
1757 sumweight = sum(weights)
1767 scenario = scenarios%CONVECTION
1769 severity = (weights(1) * tint + weights(2) * prcpint + &
1770 weights(3) * capeint + weights(4) * lxint + &
1771 weights(5) * kxint + weights(6) * tottint) / &
1774 end subroutine convectionscenario
1778 logical function isclassicprcpblwwmn(prcpType, k)
1780 integer,
intent(in) :: prcptype, k
1783 if ((prcptype /= precips%NONE .and. prcptype /= precips%SNOW) .and.&
1784 (wmnidx > 0 .and. k <= wmnidx .and. topidx > wmnidx) .and. &
1785 (ctt < cold_prcp_t_thld))
then
1786 isclassicprcpblwwmn = .true.
1788 isclassicprcpblwwmn = .false.
1792 end function isclassicprcpblwwmn
1795 subroutine classicprcpblwwmnscenario(t, vv, pc, ice_pot, severity)
1797 real,
intent(in) :: t, pc, vv, ice_pot
1798 real,
intent(out) :: severity
1802 real :: tint, pcint, dzint
1803 real :: cttint, vvint
1807 real :: weights(7) = (/ 3.0, 4.0, 3.0, 3.0, 3.5, 2.5, 2.0 /)
1809 sumweight = sum(weights)
1811 scenario = scenarios%PRECIPITAION_BELOW_WARMNOSE
1813 tint =
t_map(t, scenario)
1816 cttint = ctt_map(ctt)
1819 severity = (weights(1) * tint + weights(2) * pcint + &
1820 weights(3) * dzint + weights(4) * cttint + &
1821 weights(5) * moistint + weights(6) * vvint + &
1822 weights(7) * ice_pot) / sumweight
1825 end subroutine classicprcpblwwmnscenario
1830 logical function isclassicprcpabvwmn(prcpType, k)
1832 integer,
intent(in) :: prcptype, k
1835 if((prcptype /= precips%NONE .and. prcptype /= precips%SNOW) .and.&
1836 (wmnidx > 0 .and. k > wmnidx .and. topidx > wmnidx) .and. &
1837 (ctt < cold_prcp_t_thld))
then
1838 isclassicprcpabvwmn = .true.
1840 isclassicprcpabvwmn = .false.
1844 end function isclassicprcpabvwmn
1848 subroutine classicprcpabvwmnscenario(twp, vv, t, pc, ice_pot, severity)
1850 real,
intent(in) :: twp, vv, t, pc, ice_pot
1851 real,
intent(out) :: severity
1854 real :: twpint, vvint
1855 real :: tempadj, cttadj, pcadj
1859 real :: weights(4) = (/ 3.0, 3.5, 4.0, 2.0 /)
1861 sumweight = sum(weights)
1863 scenario = scenarios%PRECIPITAION_ABOVE_WARMNOSE
1865 twpint =
twp_map(twp, scenario)
1872 call cal_dampingfactors(scenario, t, pc, tempadj, cttadj, pcadj)
1874 severity = (weights(1) * twpint + weights(2) * vvint + &
1875 weights(3) * moistint + weights(4) * ice_pot) / &
1876 (sumweight + 6.5*tempadj + 3.0*cttadj + 3.0*pcadj)
1879 end subroutine classicprcpabvwmnscenario
1884 logical function isnoprecip(prcpType)
1886 integer,
intent(in) :: prcptype
1888 isnoprecip = prcptype == precips%NONE
1891 end function isnoprecip
1896 subroutine noprcpscenario(vv, t, pc, ice_pot, severity)
1898 real,
intent(in) :: vv, t, pc, ice_pot
1899 real,
intent(out) :: severity
1903 real :: dqint, dzint, vvint
1904 real :: tempadj, cttadj, pcadj
1908 real :: weights(5) = (/ 3.0, 3.5, 4.0, 4.0, 3.0 /)
1910 sumweight = sum(weights)
1912 scenario = scenarios%NO_PRECIPITAION
1922 call cal_dampingfactors(scenario, t, pc, tempadj, cttadj, pcadj)
1924 severity = (weights(1) * dqint + weights(2) * dzint + &
1925 weights(3) * vvint + weights(4) * moistint + &
1926 weights(5) * ice_pot) / &
1927 (sumweight + 9.0*tempadj + 4.5*cttadj)
1930 end subroutine noprcpscenario
1935 logical function issnow(prcpType)
1937 integer,
intent(in) :: prcptype
1939 issnow = prcptype == precips%SNOW
1946 subroutine snowscenario(twp, vv, t, pc, ice_pot, severity)
1948 real,
intent(in) :: twp, vv, t, pc, ice_pot
1949 real,
intent(out) :: severity
1953 real :: twpint, dzint, vvint
1954 real :: tempadj, cttadj, pcadj
1958 real :: weights(5) = (/ 3.0, 3.5, 3.5, 4.0, 3.0 /)
1960 sumweight = sum(weights)
1962 scenario = scenarios%ALL_SNOW
1964 twpint =
twp_map(twp, scenario)
1972 call cal_dampingfactors(scenario, t, pc, tempadj, cttadj, pcadj)
1974 severity = (weights(1) * twpint + weights(2) * dzint + &
1975 weights(3) * vvint + weights(4) * moistint + &
1976 weights(5) * ice_pot) / &
1977 (sumweight + 9.0*tempadj + 4.0*cttadj + 4.0*pcadj)
1980 end subroutine snowscenario
1984 logical function iscoldrain(prcpType)
1986 integer,
intent(in) :: prcptype
1989 iscoldrain = prcptype == precips%RAIN .and. ctt < cold_prcp_t_thld
1992 end function iscoldrain
1996 subroutine coldrainscenario(twp, vv, t, pc, ice_pot, severity)
1998 real,
intent(in) :: twp, vv, t, pc, ice_pot
1999 real,
intent(out) :: severity
2003 real :: twpint, dzint, vvint
2004 real :: tempadj, cttadj, pcadj
2008 real :: weights(5) = (/ 3.0, 3.5, 3.5, 4.0, 2.0 /)
2010 sumweight = sum(weights)
2012 scenario = scenarios%COLD_RAIN
2014 twpint =
twp_map(twp, scenario)
2022 call cal_dampingfactors(scenario, t, pc, tempadj, cttadj, pcadj)
2024 severity = (weights(1) * twpint + weights(2) * dzint + &
2025 weights(3) * vvint + weights(4) * moistint + &
2026 weights(5) * ice_pot) / &
2027 (sumweight + 8.0*tempadj + 4.0*cttadj + 4.0*pcadj)
2030 end subroutine coldrainscenario
2038 logical function iswarmprecip(prcpType)
2040 integer,
intent(in) :: prcptype
2043 if((prcptype == precips%RAIN .or. prcptype == precips%OTHER) .and. &
2044 (ctt >= cold_prcp_t_thld))
then
2045 iswarmprecip = .true.
2046 elseif((prcptype /= precips%NONE .and. prcptype /= precips%SNOW).and.&
2047 (wmnidx > 0 .and. topidx <= wmnidx) .and. &
2048 (ctt >= cold_prcp_t_thld))
then
2049 iswarmprecip = .true.
2051 iswarmprecip = .false.
2055 end function iswarmprecip
2059 subroutine warmprecipscenario(twp, vv, t, pc, ice_pot, severity)
2061 real,
intent(in) :: twp, vv, t, pc, ice_pot
2062 real,
intent(out) :: severity
2066 real :: twpint, dzint, vvint, dqint
2067 real :: tempadj, cttadj, pcadj
2071 real :: weights(6) = (/ 3.0, 3.0, 3.0, 3.5, 4.0, 2.0 /)
2073 sumweight = sum(weights)
2075 scenario = scenarios%WARM_PRECIPITAION
2077 twpint =
twp_map(twp, scenario)
2086 call cal_dampingfactors(scenario, t, pc, tempadj, cttadj, pcadj)
2088 severity = (weights(1) * twpint + weights(2) * dzint + &
2089 weights(3) * vvint + weights(4) * moistint + &
2090 weights(5) * ice_pot + weights(6) * dqint) / &
2091 (sumweight + 9.0*tempadj + 4.5*cttadj + 4.5*pcadj)
2094 end subroutine warmprecipscenario
2098 logical function isfreezingprecip(prcpType)
2100 integer,
intent(in) :: prcptype
2103 if (prcptype == precips%OTHER .and. ctt < cold_prcp_t_thld)
then
2104 isfreezingprecip = .true.
2106 isfreezingprecip = .false.
2110 end function isfreezingprecip
2115 subroutine freezingprecipscenario(twp, vv, t, pc, ice_pot, severity)
2117 real,
intent(in) :: twp, vv, t, pc, ice_pot
2118 real,
intent(out) :: severity
2122 real :: twpint, dzint, vvint
2123 real :: tempadj, cttadj, pcadj
2127 real :: weights(5) = (/ 3.0, 3.5, 3.5, 4.0, 2.0 /)
2129 sumweight = sum(weights)
2131 scenario = scenarios%FREEZING_PRECIPITAION
2133 twpint =
twp_map(twp, scenario)
2141 call cal_dampingfactors(scenario, t, pc, tempadj, cttadj, pcadj)
2143 severity = (weights(1) * twpint + weights(2) * dzint + &
2144 weights(3) * vvint + weights(4) * moistint + &
2145 weights(5) * ice_pot) / &
2146 (sumweight + 8.0*tempadj + 4.0*cttadj + 4.0*pcadj)
2149 end subroutine freezingprecipscenario
2167 subroutine cal_dampingfactors(scenario, t, pc, tempAdj,cttAdj,condAdj)
2169 integer,
intent(in) :: scenario
2170 real,
intent(in) :: t, pc
2171 real,
intent(out) :: tempadj, cttadj, condadj
2174 tempadj =
t_map(t, scenario)
2178 if (lowestcloud)
then
2185 end subroutine cal_dampingfactors
2193 subroutine icing_algo(i,j,pres,temp,rh,hgt,omega,wh,&
2194 q,cwat,qqw,qqi,qqr,qqs,qqg,&
2195 nz,xlat,xlon,xalt,prate,cprate,&
2196 cape,cin, ice_pot, ice_sev)
2197 use ctlblk_mod, only: imp_physics, spval, dtq2,me
2198 use physcons_post,only: g => con_g, fv => con_fvirt, rd => con_rd
2242 integer,
intent(in) :: i,j, nz
2243 real,
intent(in),
dimension(nz) :: pres,temp,rh,hgt,omega,wh
2245 real,
intent(in),
dimension(nz) :: q,cwat,qqw,qqi,qqr,qqs,qqg
2246 real,
intent(in) :: xlat, xlon, xalt
2247 real,
intent(in) :: prate, cprate
2248 real,
intent(in) :: cape, cin
2249 real,
intent(out) :: ice_pot(nz), ice_sev(nz)
2251 real :: hprcp, hcprcp
2252 integer :: topok, region, prcptype
2253 real,
allocatable :: vv(:), ept(:), wbt(:), twp(:)
2254 real,
allocatable :: icecond(:),liqcond(:), totwater(:),totcond(:)
2255 real :: pc, kx, lx, tott
2256 type(clouds_t
) :: clouds
2266 allocate(icecond(nz),liqcond(nz))
2267 allocate(totwater(nz),totcond(nz))
2269 allocate(clouds%layerQ(nz))
2286 hprcp = prate * 1000. / dtq2 * 3600.
2287 hcprcp = cprate * 1000. / dtq2 * 3600.
2289 if(imp_physics == 98 .or. imp_physics == 99)
then
2295 if(cwat(k) == spval)
then
2302 if(temp(k) >=259.15)
then
2303 liqcond(k) = cwat(k) * 1000.
2307 icecond(k) = cwat(k) * 1000.
2310 totwater(k) = cwat(k) * 1000.
2312 totcond(k) = cwat(k) * 1000.
2314 else if(imp_physics == 11 .or. imp_physics == 8)
then
2319 if(vv(k) /= spval)
then
2320 tv = temp(k)*(1.+q(k)*fv)
2321 vv(k)=-vv(k)*g*(pres(k)/(rd*tv))
2324 if(qqw(k) /= spval .and. qqr(k) /= spval)
then
2325 liqcond(k) = (qqw(k) + qqr(k)) * 1000.
2330 if(qqi(k) /= spval .and. qqs(k) /= spval .and. qqg(k) /= spval)
then
2331 icecond(k) = (qqi(k) + qqs(k) + qqg(k)) * 1000.
2336 if(liqcond(k) /= spval .and. icecond(k) /= spval)
then
2337 totwater(k) = liqcond(k) + icecond(k)
2342 if(qqr(k) /= spval .and. qqs(k) /= spval .and. qqg(k) /= spval)
then
2343 totcond(k) = (qqr(k) + qqs(k) + qqg(k)) * 1000.
2349 print *,
"This schema is not supported. imp_physics=", imp_physics
2353 call
derive_fields(imp_physics,temp, rh, pres, hgt, totwater,totcond, &
2354 nz, topok, hprcp, hcprcp, cin, cape,&
2355 ept, wbt, twp, pc, kx, lx, tott, prcptype)
2365 call
icing_pot(hgt, rh, temp, liqcond, vv, nz, clouds, ice_pot)
2368 call
icing_sev(imp_physics, hgt, rh, temp, pres, vv, liqcond, icecond, twp, &
2369 ice_pot, nz, hcprcp, cape, lx, kx, tott, pc, prcptype, clouds, &
2389 deallocate(icecond,liqcond)
2390 deallocate(totwater,totcond)
2391 deallocate(clouds%layerQ)
2394 end subroutine icing_algo
2406 real,
intent(in) :: hgt(nz)
2407 real,
intent(in) :: alt
2408 integer,
intent(in) :: nz
2412 if(hgt(nz) >= alt)
then
2416 if ((hgt(k-1) > alt) .and. (hgt(k) <= alt))
then
real function convect_totals_map(v)
convect_totals_map()
subroutine, public icing_sev(imp_physics, hgt, rh, t, pres, vv, liqCond, iceCond, twp, ice_pot, nz, hcprcp, cape, lx, kx, tott, pc, prcpType, clouds, iseverity)
icing_sev
real function convect_kidx_map(v)
convectkIdx_map()
real function convect_cape_map(v)
convect_cape_map()
real function condensate_map(v)
condensate_map()
real function deltaz_map(v, scenario)
deltaz_map()
real function moisture_map_cwat(rh, cwat, pres, t)
moisture_map_cwat()
subroutine, public calc_cloudlayers(rh, t, pres, ept, vv, nz, topoK, xlat, xlon, region, clouds)
calc_CloudLayers()
real function cldtopdist_map(v)
cldTopDist_map()
real function convect_liftedidx_map(v)
convect_liftedIdx_map()
real function moisture_map_cond(rh, liqCond, iceCond, pres, t)
moisture_map_cond()
subroutine, public derive_fields(imp_physics, t, rh, pres, hgt, totalWater, totalCond, nz, topoK, hprcp, hcprcp, cin, cape, ept, wbt, twp, pc, kx, lx, tott, prcpType)
derive_fields() calculates several derived fields.
real function t_map(v, scenario)
t_map()
real function convect_t_map(v)
convect_t_map()
real function deltaq_map(v)
deltaQ_map()
real function prcpcondensate_map(v, scenario)
prcpcondensate_map()
subroutine, public icing_pot(hgt, rh, t, liqCond, vv, nz, clouds, ice_pot)
icing_pot
elemental real function, public mixing_ratio(td, pres)
mixing_ratio()
real function twp_map(v, scenario)
twp_map()
integer function gettopok(hgt, alt, nz)
getTopoK() Map the topography height to the model's vertical coordinate
real function cldbasedist_map(v)
cldBaseDist_map()
real function convect_qpf_map(v)
convect_qpf_map()