UPP  V11.0.0
 All Data Structures Files Functions Pages
CALVIS_GSD.f
1 !**********************************************************************c
2  SUBROUTINE calvis_gsd(CZEN,VIS)
3 
4 ! SUBPROGRAM: CALVIS CALCULATE HORIZONTAL VISIBILITY
5 !
6 ! PRGMMR: BENJAMIN, STAN ORG: NOAA/FSL DATE: 99-09-07
7 !
8 ! ABSTRACT:
9 !
10 ! Started with Stoelinga-Warner algorithm for hydrometeors only.
11 ! Added coefficients for graupel.
12 ! Added algorithm for clear-air RH-based visibility.
13 !
14 ! This routine computes horizontal visibility (in km) at the
15 ! surface or lowest model layer, from qc, qr, qi, qs, and qg.
16 ! qv--water vapor mixing ratio (kg/kg)
17 ! qc--cloud water mixing ratio (kg/kg)
18 ! qr--rain water mixing ratio (kg/kg)
19 ! qi--cloud ice mixing ratio (kg/kg)
20 ! qs--snow mixing ratio (kg/kg)
21 ! qg--graupel mixing ratio (kg/kg)
22 ! u/v - u/v wind components (m/s)
23 ! tb -- temperature (k)
24 ! pp--pressure (Pa)
25 ! rhb-- relative humidity (0-100%)
26 ! aextc55--aerosol extinction coefficient (m**-1)
27 !
28 !
29 ! Independent of the above definitions, the scheme can use different
30 ! assumptions of the state of hydrometeors:
31 ! meth='r': Uses the four mixing ratios qrain, qsnow, qclw,
32 ! and qclice
33 !
34 ! The routine uses the following
35 ! expressions for extinction coefficient, beta (in km**-1),
36 ! with C being the mass concentration (in g/m**3):
37 !
38 ! cloud water: beta = 144.7 * C ** (0.8800)
39 ! rain water: beta = 2.24 * C ** (0.7500)
40 ! cloud ice: beta = 327.8 * C ** (1.0000)
41 ! snow: beta = 10.36 * C ** (0.7776)
42 ! graupel: beta = 8.0 * C ** (0.7500)
43 !
44 ! These expressions were obtained from the following sources:
45 !
46 ! for cloud water: from Kunkel (1984)
47 ! for rainwater: from M-P dist'n, with No=8e6 m**-4 and
48 ! rho_w=1000 kg/m**3
49 ! for cloud ice: assume randomly oriented plates which follow
50 ! mass-diameter relationship from Rutledge and Hobbs (1983)
51 ! for snow: from Stallabrass (1985), assuming beta = -ln(.02)/vis
52 ! for graupel: guestimate by John Brown and Stan Benjamin,
53 ! similar to snow, but a smaller extinction coef seemed
54 ! reasonable. 27 Aug 99
55 !
56 ! The extinction coefficient for each water species present is
57 ! calculated, and then all applicable betas are summed to yield
58 ! a single beta. Then the following relationship is used to
59 ! determine visibility (in km), where epsilon is the threshhold
60 ! of contrast, usually taken to be .02:
61 !
62 ! vis = -ln(epsilon)/beta [found in Kunkel (1984)]
63 !
64 ! The 'aextc55' field is 3-D and is derived from the 'aod_3d' field
65 ! by dividing by dz, the vertical thickness of that model level in 'm'.
66 ! This can be handled as a 2-D field if needed to save resources.
67 !
68 ! HISTORY
69 ! PROGRAM HISTORY LOG:
70 ! 99-05- Version from Eta model and from
71 ! Mark Stoelinga and Tom Warner
72 ! 99-09-07 S. Benjamin Modified for MM5 microphysics variables
73 ! include graupel mixing ratio
74 ! 99-09 S. Benjamin Added algorithm for RH-based clear-air
75 ! visibility
76 ! 00-08 S. Benjamin Added mods for base of 60km instead of 90km,
77 ! max RH from lowest 2 levels instead of
78 ! lev 2 only, max hydrometeor mix ratio
79 ! from lowest 5 levs instead of lev 1 only
80 ! Based on Schwartz stats and Smirnova et al
81 ! paper, and on METAR verif started this week
82 ! Dec 03 S. Benjamin - updates
83 ! - day/night distinction for vis constants
84 ! from Roy Rasmussen
85 ! - low-level wind shear term
86 ! - recommended by Evan Kuchera
87 ! 2015-17 S. Benjamin, T. Smirnova - modifications for RH-based clear-air vis
88 ! 2017-12 R. Ahmadov, Steve Albers - addition for attenuation from aerosols
89 ! (not related to water vapor or RH at this point)
90 ! 2021-05 Wen Meng Unify CONST1 and VISRH.
91 ! 2021-05 Wen Meng - Add checking for undefined points invloved in computation
92 ! 2021-08 Wen Meng - Restrict divided by 0.
93 ! 2021-10 Jesse Meng - 2D DECOMPOSITION
94 !
95 !------------------------------------------------------------------
96 !
97 
98  use vrbls3d, only: qqw, qqi, qqs, qqr, qqg, t, pmid, q, u, v, extcof55, aextc55
99  use params_mod, only: h1, d608, rd
100  use ctlblk_mod, only: jm, im, jsta_2l, jend_2u, lm, modelname, spval,&
101  ista_2l, iend_2u
102 
103  implicit none
104 
105  integer :: j, i, k, ll
106  integer :: method
107  real :: tx, pol, esx, es, e
108  REAL vis(ista_2l:iend_2u,jsta_2l:jend_2u)
109  REAL rhb(ista_2l:iend_2u,jsta_2l:jend_2u,lm)
110  REAL czen(ista_2l:iend_2u,jsta_2l:jend_2u)
111 
112  real celkel,tice,coeflc,coeflp,coeffc,coeffp,coeffg
113  real exponlc,exponlp,exponfc,exponfp,exponfg,const1
114  real rhoice,rhowat,qrain,qsnow,qgraupel,qclw,qclice,tv,rhoair, &
115  vovermd,conclc,conclp,concfc,concfp,concfg,betav
116 
117  real coeffp_dry, coeffp_wet, shear_fac, temp_fac
118  real coef_snow, shear
119 
120  real coefrh,qrh,visrh
121  real rhmax,shear5_cnt, shear8_cnt
122  real shear5_cnt_lowvis, shear8_cnt_lowvis
123  real shear4_cnt, shear4_cnt_lowvis
124  integer night_cnt, lowsun_cnt
125 
126  real visrh10_cnt, vis1km_cnt, visrh_lower
127  real vis3km_cnt
128  real vis5km_cnt
129  real vis_min, visrh_min
130  real vis_night, zen_fac
131 !------------------------------------------------------------------
132 
133 ! Method used for clear-air visibility with extension for aerosols
134  method = 3
135 ! RH-only method (1),
136 ! Aerosol method (2),
137 ! Smoke added to RH method for clear air (3)
138 ! 3 - option to add reducted visibility from smoke-based aerosols.
139 
140  celkel = 273.15
141  tice = celkel-10.
142  coeflc = 144.7
143  coeflp = 2.24
144  coeffc = 327.8
145  coeffp = 10.36
146 
147 ! - Initialize counters
148 
149  shear4_cnt = 0
150  shear5_cnt = 0
151  shear8_cnt = 0
152  shear4_cnt_lowvis = 0
153  shear5_cnt_lowvis = 0
154  shear8_cnt_lowvis = 0
155  night_cnt = 0
156  lowsun_cnt = 0
157  visrh10_cnt = 0
158  visrh_lower = 0
159  vis1km_cnt = 0
160  vis3km_cnt = 0
161  vis5km_cnt = 0
162 
163 ! - snow-based vis attenuation - coefficient values from Roy Rasmussen - Dec 2003
164 ! COEFFP_dry = 17.7
165 ! COEFFP_wet = 4.18
166 ! - modified number - Stan B. - Dec 2007
167 ! after quick talks with John Brown and Ismail Gultepe
168  coeffp_dry = 10.0
169  coeffp_wet = 6.0
170 
171 ! COEFFg = 8.0
172 ! - values from Roy Rasmussen - Dec 2003
173 ! Rasmussen et al. 2003, J. App. Meteor.
174 ! Snow Nowcasting Using a Real-Time Correlation of Radar Reflectivity with Snow Gauge Accumulation
175  coeffg = 4.0
176 
177  exponlc = 0.8800
178  exponlp = 0.7500
179  exponfc = 1.0000
180 ! EXPONFP = 0.7776
181 ! - new value from Roy Rasmussen - Dec 2003
182  exponfp = 1.0
183 
184  exponfg = 0.75
185 ! CONST1=-LOG(.02)
186 ! CONST1=3.912
187  const1= 3.000
188 
189 ! visibility with respect to RH is
190 ! calculated from optical depth linearly
191 ! related to RH as follows:
192 
193 ! vis = 60 exp (-2.5 * (RH-15)/80)
194 ! changed on 3/14/01
195 
196 ! coefficient of 3 gives visibility of 5 km
197 ! at 95% RH
198 
199 ! Total visibility is minimum of vis-rh (developed by Benjamin, Brown, Smirnova)
200 ! and vis-hydrometeors from Stoelinga/Warner
201 
202  rhoice=917.
203  rhowat=1000.
204 
205  vis_min = 1.e6
206  visrh_min = 1.e6
207 
208  DO j=jsta_2l,jend_2u
209  DO i=ista_2l,iend_2u
210  vis(i,j)=spval
211 ! -checking undedined points
212  if(t(i,j,lm)<spval .and. u(i,j,lm)<spval .and. v(i,j,lm)<spval &
213  .and. pmid(i,j,lm)<spval) then
214 ! - take max hydrometeor mixing ratios in lowest 3 levels (lowest 13 hPa, 100m with RAP/HRRR
215  qrain = 0.
216  qsnow = 0.
217  qgraupel = 0.
218  qclw = 0.
219  qclice = 0.
220 
221  do k = 1,3
222  ll=lm-k+1
223  if(qqw(i,j,ll)<spval)qclw = max(qclw, qqw(i,j,ll) )
224  if(qqi(i,j,ll)<spval)qclice = max(qclice, qqi(i,j,ll) )
225  if(qqs(i,j,ll)<spval)qsnow = max(qsnow, qqs(i,j,ll) )
226  if(qqr(i,j,ll)<spval)qrain = max(qrain, qqr(i,j,ll) )
227  if(qqg(i,j,ll)<spval)qgraupel = max(qgraupel, qqg(i,j,ll) )
228 ! - compute relative humidity
229  tx=t(i,j,ll)-273.15
230  rhb(i,j,ll)=0.
231  pol = 0.99999683 + tx*(-0.90826951e-02 + &
232  tx*(0.78736169e-04 + tx*(-0.61117958e-06 + &
233  tx*(0.43884187e-08 + tx*(-0.29883885e-10 + &
234  tx*(0.21874425e-12 + tx*(-0.17892321e-14 + &
235  tx*(0.11112018e-16 + tx*(-0.30994571e-19)))))))))
236  if(abs(pol) > 0.) THEN
237  esx = 6.1078/pol**8
238 
239  es = esx
240  e = pmid(i,j,ll)/100.*q(i,j,ll)/(0.62197+q(i,j,ll)*0.37803)
241  rhb(i,j,ll) = 100.*amin1(1.,e/es)
242  ENDIF
243 
244  enddo
245 
246 ! - take max RH of levels 1 and 2 near the sfc
247  rhmax = max(rhb(i,j,lm),rhb(i,j,lm-1))
248  qrh = max(0.0,min(0.8,(rhmax/100.-0.15)))
249 
250 !tgs 23 feb 2017 - increase of base value to 90 km to reduce attenuation
251 ! from RH for clear-air visibility. (i.e., increase clear-air vis overall)
252  visrh = 90. * exp(-2.5*qrh)
253 
254 ! -- add term to increase RH vis term for
255 ! low-level wind shear increasing from 4 to 6 ms-1
256 ! (using Evan Kuchera's paper as a guideline)
257 
258 ! -- calculate term for shear between levels 1 and 4
259 ! (about 25 hPa for HRRR/RAP)
260  shear = sqrt( (u(i,j,lm-3)-u(i,j,lm))**2 &
261  +(v(i,j,lm-3)-v(i,j,lm))**2 )
262 
263  shear_fac = min(1.,max(0.,(shear-4.)/2.) )
264  if (visrh<10.) visrh = visrh + (10.-visrh)* &
265  shear_fac
266 
267  if (shear>4.) shear4_cnt = shear4_cnt +1
268  if (shear>5.) shear5_cnt = shear5_cnt +1
269  if (shear>6.) shear8_cnt = shear8_cnt +1
270 
271  if (shear>4..and.visrh<10) &
272  shear4_cnt_lowvis = shear4_cnt_lowvis +1
273  if (shear>5..and.visrh<10) &
274  shear5_cnt_lowvis = shear5_cnt_lowvis +1
275  if (shear>6..and.visrh<10) &
276  shear8_cnt_lowvis = shear8_cnt_lowvis +1
277 
278  if (visrh<10.) visrh10_cnt = visrh10_cnt+1
279  if (czen(i,j)<0.) night_cnt = night_cnt + 1
280  if (czen(i,j)<0.1) lowsun_cnt = lowsun_cnt + 1
281 
282  tv=t(i,j,lm)*(h1+d608*q(i,j,lm))
283 
284  rhoair=pmid(i,j,lm)/(rd*tv)
285 
286  vovermd=(1.+q(i,j,lm))/rhoair+(qclw+qrain)/rhowat+ &
287 ! VOVERMD=(1.+Q(I,J,1))/RHOAIR+(QCLW+QRAIN)/RHOWAT+
288  (qgraupel+qclice+qsnow)/rhoice
289  conclc=qclw/vovermd*1000.
290  conclp=qrain/vovermd*1000.
291  concfc=qclice/vovermd*1000.
292  concfp=qsnow/vovermd*1000.
293  concfg=qgraupel/vovermd*1000.
294 
295  temp_fac = min(1.,max((t(i,j,lm)-271.15),0.) )
296 
297  coef_snow = coeffp_dry*(1.-temp_fac) &
298  + coeffp_wet* temp_fac
299 
300  if (t(i,j,lm)< 270. .and. temp_fac==1.) &
301  write (6,*) 'Problem w/ temp_fac - calvis'
302 
303 ! Key calculation of attenuation from each hydrometeor type (cloud, snow, graupel, rain, ice)
304  betav=coeffc*concfc**exponfc &
305  + coef_snow*concfp**exponfp &
306  + coeflc*conclc**exponlc + coeflp*conclp**exponlp &
307  + coeffg*concfg**exponfg +1.e-10
308 
309 ! Addition of attenuation from aerosols if option selected
310  if(method == 2 .or. method == 3)then ! aerosol method
311  betav = betav + aextc55(i,j,lm)*1000.
312  endif
313 
314  if (i==290 .and. j==112) then
315  write (6,*) 'BETAV, extcof55 =',betav,extcof55(i,j,lm)
316  end if
317 
318 ! Calculation of visibility based on hydrometeor and aerosols. (RH effect not yet included.)
319  vis(i,j)=min(90.,const1/(betav+extcof55(i,j,lm))) ! max of 90km
320 
321  if (vis(i,j)<vis_min) vis_min = vis(i,j)
322  if (visrh<visrh_min) visrh_min = visrh
323 
324  if (visrh<vis(i,j)) visrh_lower = visrh_lower + 1
325 
326 
327 ! -- Dec 2003 - Roy Rasmussen (NCAR) expression for night vs. day vis
328 ! 1.609 factor is number of km in mile.
329  vis_night = 1.69 * ((vis(i,j)/1.609)**0.86) * 1.609
330 
331  zen_fac = min(0.1,max(czen(i,j),0.))/ 0.1
332  if (i==290 .and. j==112) then
333  write (6,*) 'zen_fac,vis_night, vis =',zen_fac,vis_night, vis(i,j)
334  end if
335 
336  vis(i,j) = zen_fac * vis(i,j) + (1.-zen_fac)*vis_night
337 
338  if (i==290 .and. j==112) then
339  write (6,*) 'visrh, vis =',visrh, vis(i,j)
340  end if
341 
342  if(method == 1 .or. method == 3)then ! RH method (if lower vis)
343  vis(i,j) = min(vis(i,j),visrh)
344  endif
345 
346  if (vis(i,j)<1.) vis1km_cnt = vis1km_cnt + 1
347  if (vis(i,j)<3.) vis3km_cnt = vis3km_cnt + 1
348  if (vis(i,j)<5.) vis5km_cnt = vis5km_cnt + 1
349 ! convert vis from km to [m]
350  vis(i,j) = vis(i,j) * 1000.
351 
352  endif !end checking undefined points
353  ENDDO
354  ENDDO
355 
356 ! write (6,*)
357 ! write (6,*) ' Visibility diagnostics follow: ------------'
358 ! write (6,*) ' -------------------------------------------'
359 ! write (6,*) &
360 ! ' any vis / vis < 10 km '
361 ! write (6,*)'No. of grid pts with shear (lev4-1) > 4m/s', &
362 ! shear4_cnt, shear4_cnt_lowvis
363 ! write (6,*)'No. of grid pts with shear (lev4-1) > 5m/s', &
364 ! shear5_cnt, shear5_cnt_lowvis
365 ! write (6,*)'No. of grid pts with shear (lev4-1) > 6m/s', &
366 ! shear8_cnt, shear8_cnt_lowvis
367 ! write (6,*)
368 ! write (6,*)'No. of grid pts with vis-RH < 10 km', &
369 ! visrh10_cnt
370 ! write (6,*)'No. of grid pts with vis < 1 km', &
371 ! vis1km_cnt
372 ! write (6,*)'No. of grid pts with vis < 3 km', &
373 ! vis3km_cnt
374 ! write (6,*)'No. of grid pts with vis < 5 km', &
375 ! vis5km_cnt
376 ! write (6,*)
377 ! write (6,*)'Min vis-hydrometeor, vis-RH', vis_min, visrh_min
378 !
379 ! write (6,*)'No. of grid pts with visRH < vis(hydrometeor)', &
380 ! visrh_lower
381 ! write (6,*)'% grid pts with night/cos(zen) < 0.1', &
382 ! float(night_cnt)/float(IM*JM),float(lowsun_cnt)/ &
383 ! float(IM*JM)
384 ! write (6,*)
385 !
386  RETURN
387  END