!--------------------------------------------------------------------- ! The GFIP algorithm computes the probability of icing within a model ! column given the follow input data ! ! 2-D data: convective precip (xacp), ! non-convective precip (xncp) ! the topography height (xalt) ! the latitude and longitude (xlat and xlon) ! d (xlat and xlon) ! the number of vertical levels (num_z) = 47 in my GFS file ! 3-D data ! pressure(num_z) in PA ! temperature(num_z) in K ! rh(num_z) in % ! hgt(num_z) in GPM) ! cwat(num_z) in kg/x kg ! vv(num_z) in Pa/sec !----------------------------------------------------------------------- ! !-----------------------------------------------------------------------+ ! This subroutine calculates the icing potential for a GFS column ! First the topography is mapped to the model's vertical coordinate ! in (topoK) ! Then cloud layers are defined in (cloud_layer) ! up to 12 layers are possible ! The icing is computed in (icing_pot). The icing ! output should range from 0 - 1. ! !-----------------------------------------------------------------------+ !234567890 subroutine icing_algo(i,j,pres,temp,rh,hgt,cwat,vv,num_z,xlat,xlon, & xalt,xncp,xacp,ice_pot) implicit none integer i,j, l integer num_z,surface,region,num_lyr integer,dimension(12) :: cld_top, cld_base real xlat, xlon, xalt, xncp, xacp, topok real,dimension(12) :: ctt, cbt, thick real,dimension(num_z) :: pres, hgt, rh, temp, cwat, vv, ice_pot if(i==50 .and. j==50)then print*,'sample input to FIP ',i,j,num_z,xlat,xlon,xalt,xncp, & xacp do l=1,num_z print*,'l,P,T,RH,H,CWM,VV',l,pres(l),temp(l),rh(l),hgt(l),cwat(l),vv(l) end do end if surface = topoK(hgt,xalt,num_z) call cloud_layer(xlat,xlon,hgt,rh,temp,surface,num_z,cwat, & region,num_lyr,cld_top,ctt,cld_base,cbt,thick) call icing_pot(hgt,rh,temp,surface,num_z,cwat,vv, & region,num_lyr,cld_top,ctt,cld_base,ice_pot) return end !-----------------------------------------------------------------------+ real function dew_pt(t,rh) real tc, eps, vapr, top, bottom, td tc = t - 273.15 if (rh.lt.0.0001) then rh = 0.0001 endif eps = 6.112 vapr = rh * (vapor_press(tc)/100.0) top = 243.5 * (log(eps) - log(vapr)) bottom = log(vapr) - log(eps) - 17.67 dew_pt = top/bottom return end !-----------------------------------------------------------------------+ ! press in mb, T and Td in degrees C real function thetae(press, t, td) real rmix, e, thtam real mix_ratio press = press/100.0 t = t - 273.15 td = td - 273.15 rmix = mix_ratio(td,press) e = (2.0/7.0) * ( 1 - (0.001 * 0.28 * rmix)) thtam = (t + 273.15) * ((1000.0/press)**e) thetae = thtam * exp( (3.376/tLCL(t,td) - 0.00254) * & (rmix * (1 + (81 * 0.001 * rmix)) )) return end !-----------------------------------------------------------------------+ real function vapor_press(t); vapor_press = 6.112 * exp( (17.67*t)/(t+243.5)); return end !-----------------------------------------------------------------------+ real function tLCL(t, td); real tk, dk tk = t + 273.15; dk = td + 273.15; tLCL = ( 1 / (1/(dk - 56) + log(tk/dk)/800.0)) + 56.0; return end !-----------------------------------------------------------------------+ real function mix_ratio(td, press); real corr, e corr = 1.001 + ( (press - 100) /900) * 0.0034; e = vapor_press(td) * corr; mix_ratio = 0.62197 * (e/(press-e)) * 1000; return end !-----------------------------------------------------------------------+ real function topoK(hgt,alt,num_z) real hgt(num_z) integer k topoK = num_z do 110 k=2,num_z if ((hgt(k-1).gt.alt).and.(hgt(k).le.alt)) then topoK = k-1 endif 110 continue return end !-----------------------------------------------------------------------+ subroutine cloud_layer(xlat,xlon,hgt,rh,temp,surface,num_z,cwat, & region,num_lyr,cld_top,ctt,cld_base,cbt,thick) real hgt(num_z),rh(num_z),temp(num_z),cwat(num_z) real ctt(12),cbt(12),t_rh,thick(12) integer cloud(num_z),in_cld,cur_base,surface integer region,cld_top(12),cld_base(12),num_lyr ! get the global region and set the RH thresholds if (abs(xlat).lt.23.5) then t_rh = 80.0 region = 1 elseif ( (abs(xlat).ge.23.5).and.(abs(xlat).lt.66)) then t_rh = 75.0 region =2 else t_rh = 70.0 region =2 endif ! zero the clouid_on flag do 115 k=1,num_z cloud(k) = 0 115 continue ! loop from the top (start at 2 so we can have n+1) ) ! bottom is num+z and top is 1 num_lyr = 0 in_cld = 0 cur_base = 1 do 120 k=2,surface if (cur_base.le.k) then if ((rh(k-1).lt.t_rh).and.(in_cld.eq.0)) then if ((rh(k).ge.t_rh).and.(rh(k+1).ge.t_rh)) then num_lyr = num_lyr + 1 in_cld = 1 cld_top(num_lyr) = k ctt(num_lyr) = temp(k) ! find the cloud base do 125 kk=cld_top(num_lyr),surface-1 if ((rh(kk-1).ge.t_rh).and.(rh(kk).lt.t_rh)) then if ((rh(kk+1).lt.t_rh).and.(in_cld.eq.1)) then cld_base(num_lyr) = kk cur_base = kk cbt(num_lyr) = temp(kk) in_cld = 0 endif endif 125 continue endif endif endif 120 continue ! if the loop exits still in cloud make the cloud base the surface if (in_cld.eq.1) then cld_base(num_lyr) = surface cbt(num_lyr) = temp(surface) endif ! get the cloud thickness do 130 n=1,num_lyr thick(n) = hgt(cld_top(n)) - hgt(cld_base(n)) 130 continue return end !-----------------------------------------------------------------------+ subroutine icing_pot(hgt,rh,temp,surface,num_z,cwat,vv, & region,num_lyr,cld_top,ctt,cld_base,ice_pot) real hgt(num_z),rh(num_z),temp(num_z),cwat(num_z),vv(num_z) real ctt(num_lyr),cbt(num_lyr),t_rh,thick(num_lyr) real ice_pot(num_z),ice_ctt(num_z), slw(num_z), slw_fac(num_z) real vv_fac(num_z) integer surface integer region,cld_top(num_lyr),cld_base(num_lyr),num_lyr do 200 k=1,num_z ice_pot(k) = 0.0 ice_ctt(k) = 0.0 vv_fac(k) = 0.0 slw_fac(k) = 0.0 200 continue ! apply the cloud top temperature to the cloud layer do 205 n=1,num_lyr do 210 k=cld_top(n),cld_base(n) ice_ctt(k) = ctt(n) 210 continue 205 continue ! convert the cwater to slw if the CTT > -14C do 212 k=1,num_z if((ice_ctt(k).ge.259.15).and.(ice_ctt(k).le.273.15)) then slw(k) = cwat(k) * 1000.0 else slw(k) = 0.0 endif 212 continue ! run the icing algorithm do 215 n=1,num_lyr do 220 k=cld_top(n),cld_base(n) ice_pot(k) = tmap(temp(k))*rh_map(rh(k))*ctt_map(ice_ctt(k)) ! add the VV map if (vv_map(vv(k)).ge.0.0) then vv_fac(k) = (1.0-ice_pot(k))*(0.25*vv_map(vv(k))) else vv_fac(k) = ice_pot(k) * (0.25 * vv_map(vv(k))) endif ! add the slw slw_fac(k) = (1.0 - ice_pot(k))*(0.4*slw_map(slw(k))) ! calculate the final icing potential if (ice_pot(k).gt.0.001) then ice_pot(k) = ice_pot(k) + vv_fac(k) + slw_fac(k) endif ! make sure the values don't exceed 1.0 if (ice_pot(k).gt.1.0) then ice_pot(k) = 1.0 endif ! print *,ice_pot(k),temp(k),tmap(temp(k)),rh(k),rh_map(rh(k)) ! * , ice_ctt(k),ctt_map(ice_ctt(k)),vv(k),vv_map(vv(k)) ! * , cwat(k), slw(k), slw_map(slw(k)) 220 continue 215 continue return end !-----------------------------------------------------------------------+ real function tmap(temp) real temp if((temp.ge.248.15).and.(temp.le.263.15)) then tmap=((temp-248.15)/15.0)**1.5 elseif((temp.gt.263.15).and.(temp.lt.268.15)) then tmap=1.0 elseif((temp.gt.268.15).and.(temp.lt.273.15)) then tmap=((273.15 - temp)/5.0)**0.75 else tmap=0.0; endif return end !-----------------------------------------------------------------------+ real function rh_map(rh) real rhmap if (rh.gt.95.0) then rh_map=1.0 elseif ( (rh.le.95.0).and.(rh.ge.50.0) ) then rh_map=((20/9) * ((rh/100.0)-0.5))**3.0 else rh_map=0.0 endif return end !-----------------------------------------------------------------------+ real function ctt_map(cldtops) if((cldtops.ge.261.0).and.(cldtops.lt.280.)) then ctt_map = 1.0 elseif((cldtops.gt.223.0).and.(cldtops.lt.261.0 )) then ctt_map = 0.2 + 0.8*(((cldtops - 223.0)/38.0)**2.0) elseif(cldtops.lt.223.0) then ctt_map = 0.2 else ctt_map = 0.0 endif return end !-----------------------------------------------------------------------+ real function vv_map(vv) if (vv.gt.0.0) then vv_map = 0.0 elseif (vv.lt.-0.5) then vv_map = 1.0 else vv_map = -1.0 * (vv/0.5); endif return end !-----------------------------------------------------------------------+ real function slw_map(slw) if(slw.gt.0.2) then slw_map = 1.0 elseif (slw.le.0.001) then slw_map = 0.0 else slw_map = slw/0.2; endif return end