ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc cc cc SUBROUTINE get_new_fog: implemented based on Zhou and Ferrier 's aysmptotic formulation cc 2008 on JAMC but add advection term cc cc Input: grid-wide u,v component profile and surface values, temperature and RH profiles cc and surface values, surface height, and previous time step temperature profile cc and surface values (are used to compute cooling rate). cc Output: fog LWC cc cc cc This code is for grid or point-wide computation as following steps: cc cc (1) Search for which (pressure)levels the surface height is located cc (2) Search for which (pressure)levels the suturated top above the surface is located cc and get the fog layer (saturated layer) depth, if its depth > 800m, not cc a fog but reture, otherwise cc (3) Search from the fog layer top downward to see if its bottom reach the ground cc if its bottom not touch the ground and > 800m, it is not a fog but return, cc otherwise cc (4) Compute averaged cooling rate within the fog layer using current and previous cc time step's temperature profiles and surface (in C/hr) cc (5) Based on temperaure at nearest level from the fog top and 2m to compute cc averag temperature with the fog layer, based on which parameter beta is computed cc (5.1) From cooling rate, fog depth and beta, the critical turb exch. ceoff Kc can cc be computed cc (6) Based on the u,v at nearest level from the fog top and 10m u,v, to compute cc wind speeds at the fog top and the surface cc (7) Based on T, wind speeds at nearest level from the fog top and 2m, Ri is computed cc from which stability function Fm(Ri) is computed, from which turbulent excahnge cc coefficient K is computed cc (7.1) If won't further compute LWC, using K and Kc, fog exists or not can be determined cc at this step (K>Kc, K<Kc?), otherwise, cc (8) With K, cooling rate, beta, fog boundary layer FBL can be computed cc (9) From the FBL, cooling rate, fog depth, LWC profile with the fog layer are computed cc cc Language: Fortran 77/90 cc cc Origninal author: Binbin Zhou, EMC/NCEP/NOAA cc August 28, 2010 cc cc Modifcation history: cc Sept 9, 2010 by B. Zhou: cc Add startus cloud layer checking (< 400m), if yes, use modeled cloud layer as fog layer cc instead of using RH to check saturated layer as fog layer. This imply the modeled cloud cc depth is assumed correct but just adjust its LWC distrbution cc If clout top < 400m and cloud bottm < 50 m above the ground, cc find whcih level the cloud top is located, then repeat the above steps from cc step (4) cc cc Oct. 10, 2010 by B. Zhou: cc Add LWC advection term from RH or specific humidity field into the Kc and LWC cc computations cc cc cc cc Description diagram: cc cc kp and kp+1: the level just below and abobe the surcae cc kfog: fog top level cc cc (1) Clear sky case cc cc ---------------------------------------------------------------------------- k=14, hp(14) cc cc ..................................................... ..... cc cc ------------ fog top---100%-------------- kfog (=4 in this case)------------ k=4, hp(4) cc ^ ^ cc | | cc ------|-------------- 100%----------|--- kp+1 (=3 in this case)------------ k=3, hp(3) cc depth_fog=z_RH-hsfc | cc | ............ o-o (10m) | cc | ^ ....[2m] | z_RH=hp(kfog) cc ___v___|____^___Y__|_____________|___________________________ surface level (hsfc) cc / | | | \ cc-------------|----|--------------------|---kp (=2 in this case) --------------- k=2, hp(2) \ cc / | z2m=2+hsfc | \ cc / | | | \ cc / z10m=10+hsfc | \ cc ------------|----|--------------------|-----------------------------------------k=1, hp(1) cc/ | | | \ cc ____________v____v____________________v__________________________________\______sea level cc||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc cc cc cc (2) Stratus cloud case (cloud top: cldt<400m) cc cc ~~~~~~~cloud top (cldt < 400m)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc ^ ^ cc | | cc -kfog-|- (level just below cldt) ---|---------------------------------------k=4. hp(4) cc | | cc | | cc depth_fog=cldt (i.e. z_RH-hsfc) | cc | | cc -------|-----------------------------|----------------------------------------k=3, hp(3) cc | | cc | ............ o-o (10m) | cc | ^ ....[2m] | z_RH=cldt+hsfc cc ___v___|____^___Y__|_____________|___________________________ surface level (hsfc) cc / | | | \ cc-------------|----|--------------------|---kp (=2 in this case) --------------- k=2, hp(2) \ cc / | z2m=2+hsfc | \ cc / | | | \ cc / z10m=10+hsfc | \ cc ------------|----|--------------------|-----------------------------------------k=1, hp(1) cc/ | | | \ cc ____________v____v____________________v__________________________________\______sea level cc|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc subroutine get_new_fog(igrid,up,vp,hp,u10,v10,hsfc, + rhp,rh2,t2,tp,dt2,dtp,interval,lv,cldt,cldb, + adv,rhthr,lwc) c + fog_depth,cooling_rate,lwc_max,dwdz, c + lamda,FBL,Km,bx,cx) parameter (Rd = 287.0, Rv=416.0, Ro=1.2) c Input c up,vp : u,v on pressure levels c hp : height of pressure levels c u10,v10 : 10m u and v c hsfc : sfc height c tp : current temperature on pressure levels c rhp : RH on pressure levels c t2 : current temperature at 2m c dt2 : 2m temperature change c dtp : temperature change on pressure levels c rh2 : previous and current RH at 2m c interval: time step interval (in hours) c cldb: cloud base c cldt: cloud top c adv : advection term c rhthr : RH threshold deponding on regions c Output c lwc : fog LWC c c c Modification 20130304: Binbin ZHou: To save space, use temperature c change and current temperature instead of store temperature c in all forecast hours. Also use only current LWCfield instead c of store LWC in all forecast hours c INTEGER lv,interval REAL up(lv),vp(lv),hp(lv),rhp(lv),tp(lv) REAL u10,v10,hsfc,lwc,rh2,t2,cooling_rate, + Km,lamda_1,lamda,lwc_max,Kc,cldt,cldb, + dt2,dtp(lv) real rhthr real cooling(lv+1) character*15 ftype integer maybefog !write(*,*) 'in get_new_fog ' c if(igrid.eq.1) then c write(*,*) igrid,u10,v10,t2,rh2,hsfc, c + cldt,cldb,adv,rhthr,dt,dt2 c do k=1,14 c write(*,'(6f9.2)') up(k),vp(k),hp(k),rhp(k), c + tp(k),dtp(k) c end do c end if NFOG1=110591 !Wenatchee WA (EAT Airport) NFOG2=52101 !Sherman TX NFOG3=75679 !Dulles NFOG4=67443 !Chanute, KS NFOG5=103040 !BISMARK, ND NFOG6=83368 !JFK NFOG7=82440 !University park Airport, PA NFOG8=84178 !Chicago, IL NFOG9=75834 !San Fracisco, CA NFOG10=39464 !Austin, TX ftype='FOG0' lwc=0.0 cooling=-9.9 !20130306: add it to fix bug if (igrid.eq.NFOG1 + .or.igrid.eq.NFOG2 + .or.igrid.eq.NFOG3 + .or.igrid.eq.NFOG4 + .or.igrid.eq.NFOG5 + .or.igrid.eq.NFOG6 + .or.igrid.eq.NFOG7 + .or.igrid.eq.NFOG8 + .or.igrid.eq.NFOG9 + .or.igrid.eq.NFOG10) then write(*,'(i7,a6,f6.2,a6,10f6.2,a6,f6.2)') igrid, + ' RH2=',rh2, 'RHp=',(rhp(i),i=1,10), ' rhthr=',rhthr end if c rhthr = 98.0 !assumened saturated c rhthr = 90.0 !it seems that 95% is too large to capture some fogs. c search sfc in which pressure layers z10m = 10. + hsfc z2m = 2. + hsfc if(cldt.le.cldb) cldt=cldb if (z10m .lt. hp(1) ) then kp = 0 else do k = 1,lv-1 if(z10m.ge.hp(k).and.z10m.lt.hp(k+1)) then kp = k end if end do end if if(cldt.lt.400.0.and.cldb.lt.50.0) then !yes there is stratus cloud case c if(cldt.lt.800.0.and.cldb.lt.50.0) then !yes there is stratus cloud case kfog=0 ftype='SFC_STRA' z_RH=cldt+hsfc !seach which level the cloud top is below do k = 1, lv-1 if(z_RH.ge.hp(k).and.z_RH.lt.hp(k+1)) then kfog = k+1 end if end do if(rh2.ge.rhthr) then !new add 20130306 searhc saturated layer inside stratus maybefog=1 goto 1000 else do k=1,kfog if(rhp(k).ge.rhthr) then maybefog=1 goto 1000 end if end do return end if goto 1000 end if c CCCCCCCCCC following is non-stratus but fog situation: CCCCCCCCCCCCCCCCCCCCC c hp(kp+1) : the pressure level just above the surface level c hp(kfog) : the pressure level just above the fog top c search RH=100% (rhthr) depth above the sfc and averaged cooling rate c if(cldb.lt.2000.or.cldt.lt.5000.) then c rhthr=99.5 !20130207: under stratus, using higher threshold c end if z_RH=hsfc kfog=0 do k = 1, lv-1 if(rhp(k).ge.rhthr.and. + rhp(k+1).lt.rhthr ) then kfog=k !find which pressure level is saturated z_RH = hp(kfog) end if end do if((z_RH-hsfc).gt.800.0) then !DEEP STRATUS' !if (igrid.eq.NFOG2) then ! write(*,*)' DEP_STRA', + ! 'z_RH-hsfc=',z_RH-hsfc !end if return !not a fog layer but a stratus cloud end if !now search from fog top downward to find fog bottom reach the ground? kbottom=0 if(kfog.ge.2) then do k = kfog,1,-1 if (rhp(k).lt.rhthr) then kbottom=k+1 goto 100 end if end do else kbottom=1 goto 100 end if 100 continue if(rh2.ge.rhthr) then touch_down=0. else touch_down=hp(kbottom)-hsfc end if if(touch_down.gt.100.0) then if (igrid.eq.NFOG1 + .or.igrid.eq.NFOG2 + .or.igrid.eq.NFOG3 + .or.igrid.eq.NFOG4 + .or.igrid.eq.NFOG5 + .or.igrid.eq.NFOG6 + .or.igrid.eq.NFOG7 + .or.igrid.eq.NFOG8 + .or.igrid.eq.NFOG9 + .or.igrid.eq.NFOG10) then write(*,17)' NO_TROUCH_DOWN STRA', + ' z_RH-hsfc=',z_RH-hsfc,'touch_down=',touch_down 17 format(a41,a11,f8.1,a11,f8.1) end if return !not a fog layer but a stratus cloud end if if(cldt.lt.5000.) then ftype='BLW_STRA' else ftype='PURE_FOG' end if 1000 continue if(z_RH.le.z2m) then if(rh2.ge.rhthr) then depth_fog = 2.0 cooling_rate=-dt2/interval !in C/hr tfog=t2 else depth_fog = 0.0 return end if else depth_fog = z_RH - hsfc c cooling_rate= -dtp(kfog)- dt2/interval/2.0 c tfog=(tp(kfog)+t2)/2.0 !Jan 25, 2013: Binbin Zhou: !Some users (East region WFO, Geoff Manikin etc) !complain fog prob and visibility<1km are not !consistent. Fogs are not there but visibility shows < 1km !Seems the above under-estimate the cooling rate !Modified as search for maximum cooling below the fog depth: do k=kp+1,kfog+1 c test do k=kp+1,kfog cooling(k)=-dtp(k)/interval end do cooling(kfog+2)=-dt2/interval !just stored 2m cooling there cooling_rate=maxval (cooling) c if(igrid.eq.NFOG5) then c write(*,14) ' crate-profile=',(cooling(m),m=1,kfog+2) c14 format(a20,14f7.3) c write(*,'(a12,f7.3)') 'max-cooling=',cooling_rate c end if c cooling_rate=0. c nn=0 c do k=kp+1,kfog+2 c cooling_rate=cooling_rate+cooling(k) c nn=nn+1 c end do c cooling_rate=cooling_rate/nn tfog=0. nn=0 do k=kp+1,kfog tfog=tfog+tp(k) nn=nn+1 end do tfog=tfog+t2 tfog=tfog/(nn+1) end if if (igrid.eq.NFOG1 + .or.igrid.eq.NFOG2 + .or.igrid.eq.NFOG3 + .or.igrid.eq.NFOG4 + .or.igrid.eq.NFOG5 + .or.igrid.eq.NFOG6 + .or.igrid.eq.NFOG7 + .or.igrid.eq.NFOG8 + .or.igrid.eq.NFOG9 + .or.igrid.eq.NFOG10) then write(*,15) ftype,'cldtp=',cldt,'cldbs=',cldb, + ' fogdpth=',depth_fog, 'crate=',cooling_rate,'adv=',adv 15 format(a38,a8,f8.1,a8,f8.1,a10,f8.1,a8,f7.3,a5,d11.4) end if c tt=7.45*tfog/(235.0 + tfog) C Use WMO recommended formulation (2008) C Guide to Metteorological Instruments and Methods of C Observation (CIMO Guide): if( tfog.ge.0.0) then tt=17.62*tfog/(243.12 + tfog) !over liquid water else tt=22.46*tfog/(272.62 + tfog) !over ice, assume no supercooled water end if es = 6.112 *2.71828 ** tt Tk=tfog + 273.17 beta = 622.0* 2.5e6 * es / (Rv*Tk*Tk*1000) c_adv=beta*cooling_rate/3600.0 + adv/1000.0 if(c_adv.lt.0.0) then lwc=0.0 return end if lwc_max = sqrt(c_adv*depth_fog/0.062) c compute FBL (Fog Boundary Layer, delta) if ( depth_fog .le. 2.0 ) then wp=sqrt(up(kp+1)*up(kp+1)+vp(kp+1)*vp(kp+1)) w10=sqrt(u10*u10+v10*v10) dwdz=(wp-w10)/(hp(kp+1)-z10m) dtdz=(tp(kp+1)-t2)/(hp(kp+1)-z2m) else wp=sqrt(up(kfog)*up(kfog)+vp(kfog)*vp(kfog)) w10=sqrt(u10*u10+v10*v10) dwdz=(wp-w10)/(hp(kfog)-z10m) dtdz=(tp(kfog)-t2)/(hp(kfog)-z2m) end if dwdz=abs(dwdz) if(dwdz.eq.0.0) dwdz=0.001 Ri = (9.8/Tk)*(dtdz+0.01)/dwdz/dwdz if (Ri.le.0.0) then !Unstable case: Beljaars: "The parameterization z=hp(kp+1)-hsf !of the planetary boundary layer", May 1992, ECMWF report y=(1.0+z/0.02) !You can use other formulation Ch=12.0*sqrt(y)/(log(y)*log(y)) Fm=1.0-10.0*Ri/(1.+Ch*sqrt(-Ri)) else !Stable case: Holtslag, et al. BLM 2006, vol. 118 c Fm=1.0/(1.0+10.0*Ri) !take long tail format, this leads to higher turbulence !and fog LWC becomes smaller or dispersed !You can use other formulation if(Ri.ge.0.0.and.Ri.lt.0.1) then !Sharp tail (Ric ~ 0.25) Fm=(1.0-5.0*Ri)*(1.0-5.0*Ri) else Fm=(1.0/20.0/Ri)*(1.0/20.0/Ri) end if end if if (depth_fog.eq.2.0) depth_fog=30.0 !modify: 20130306 use 30m as shallow fog depth instead lamda_1=1./(0.4*(depth_fog+0.02)) + 1./40.0 lamda=1.0/lamda_1 Km=lamda*lamda*abs(dwdz)*Fm FBL=Km/(2.0*sqrt(0.062*c_adv*depth_fog)) Kc=1.38*sqrt(0.062*c_adv)* !not used, just for verification + depth_fog**1.5 c at last compute LWC near the surface (at z = 1.0 m) c if(depth_fog.le.2.0) then c z=1.0 c else c z=0.2*depth_fog c z=10.0 c end if z=10.0 aa=z/depth_fog ax=sqrt(1.0-aa) bx=z/FBL cx=2.0/(1.0+exp(bx)) lwc=lwc_max*(ax - cx) if (igrid.eq.NFOG1 + .or.igrid.eq.NFOG2 + .or.igrid.eq.NFOG3 + .or.igrid.eq.NFOG4 + .or.igrid.eq.NFOG5 + .or.igrid.eq.NFOG6 + .or.igrid.eq.NFOG7 + .or.igrid.eq.NFOG8 + .or.igrid.eq.NFOG9 + .or.igrid.eq.NFOG10) then write(*,16) ' c_adv=',c_adv,' Kc=',kc,' Km=',km,'LWC=',lwc 16 format(a28,d11.4,a7,f8.4,a7,f8.4,a7,f8.4) end if if (lwc.lt.1.0E-4) lwc = 0.0 end