UPP (develop)
Loading...
Searching...
No Matches
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! 2023-11 Tim Corrie, Eric James - addition of attenuation for blowing snow
95! 2024-03 Eric James - removal of extcof55 factor in visibility
96! calculation (extcof55 is all zeroes)
97! 2024-04 Eric James - correcting bug in BLSN effect (missing factor of
98! ustar_t) and removing BLSN effect for z0>0.7 (forests)
99!
100!------------------------------------------------------------------
101!
102
103 use vrbls2d, only: sno, si, ustar, z0
104 use vrbls3d, only: qqw, qqi, qqs, qqr, qqg, t, pmid, q, u, v, aextc55
105 use params_mod, only: h1, d608, rd, g
106 use ctlblk_mod, only: jm, im, jsta_2l, jend_2u, lm, modelname, spval, method_blsn,&
107 ista_2l, iend_2u
108
109 implicit none
110
111 integer :: j, i, k, ll
112 integer :: method
113 real :: tx, pol, esx, es, e
114 REAL VIS(ista_2l:iend_2u,jsta_2l:jend_2u)
115 REAL RHB(ista_2l:iend_2u,jsta_2l:jend_2u,LM)
116 REAL CZEN(ista_2l:iend_2u,jsta_2l:jend_2u)
117
118 real :: z, ustar_t, u_p, lamda, r_bar, alpha
119 real :: rho_sno
120 real :: z_r, Q_s, C_r, c_z, c_alpha, vis_blsn, BETABLSN
121
122 real celkel,tice,coeflc,coeflp,coeffc,coeffp,coeffg
123 real exponlc,exponlp,exponfc,exponfp,exponfg,const1
124 real rhoice,rhowat,qrain,qsnow,qgraupel,qclw,qclice,tv,rhoair, &
125 vovermd,conclc,conclp,concfc,concfp,concfg,betav
126
127 real coeffp_dry, coeffp_wet, shear_fac, temp_fac
128 real coef_snow, shear
129
130 real coefrh,qrh,visrh
131 real rhmax,shear5_cnt, shear8_cnt
132 real shear5_cnt_lowvis, shear8_cnt_lowvis
133 real shear4_cnt, shear4_cnt_lowvis
134 integer night_cnt, lowsun_cnt
135
136 real visrh10_cnt, vis1km_cnt, visrh_lower
137 real vis3km_cnt
138 real vis5km_cnt
139 real vis_min, visrh_min
140 real vis_night, zen_fac
141!------------------------------------------------------------------
142
143! Method used for clear-air visibility with extension for aerosols
144 method = 3
145! RH-only method (1),
146! Aerosol method (2),
147! Smoke added to RH method for clear air (3)
148! 3 - option to add reducted visibility from smoke-based aerosols.
149
150 celkel = 273.15
151 tice = celkel-10.
152 coeflc = 144.7
153 coeflp = 2.24
154 coeffc = 327.8
155 coeffp = 10.36
156
157! - Initialize counters
158
159 shear4_cnt = 0
160 shear5_cnt = 0
161 shear8_cnt = 0
162 shear4_cnt_lowvis = 0
163 shear5_cnt_lowvis = 0
164 shear8_cnt_lowvis = 0
165 night_cnt = 0
166 lowsun_cnt = 0
167 visrh10_cnt = 0
168 visrh_lower = 0
169 vis1km_cnt = 0
170 vis3km_cnt = 0
171 vis5km_cnt = 0
172
173! - snow-based vis attenuation - coefficient values from Roy Rasmussen - Dec 2003
174! COEFFP_dry = 17.7
175! COEFFP_wet = 4.18
176! - modified number - Stan B. - Dec 2007
177! after quick talks with John Brown and Ismail Gultepe
178 coeffp_dry = 10.0
179 coeffp_wet = 6.0
180
181! COEFFg = 8.0
182! - values from Roy Rasmussen - Dec 2003
183! Rasmussen et al. 2003, J. App. Meteor.
184! Snow Nowcasting Using a Real-Time Correlation of Radar Reflectivity with Snow Gauge Accumulation
185 coeffg = 4.0
186
187 exponlc = 0.8800
188 exponlp = 0.7500
189 exponfc = 1.0000
190! EXPONFP = 0.7776
191! - new value from Roy Rasmussen - Dec 2003
192 exponfp = 1.0
193
194 exponfg = 0.75
195! CONST1=-LOG(.02)
196! CONST1=3.912
197 const1= 3.000
198
199! visibility with respect to RH is
200! calculated from optical depth linearly
201! related to RH as follows:
202
203! vis = 60 exp (-2.5 * (RH-15)/80)
204! changed on 3/14/01
205
206! coefficient of 3 gives visibility of 5 km
207! at 95% RH
208
209! Total visibility is minimum of vis-rh (developed by Benjamin, Brown, Smirnova)
210! and vis-hydrometeors from Stoelinga/Warner
211
212 rhoice=917.
213 rhowat=1000.
214
215 vis_min = 1.e6
216 visrh_min = 1.e6
217
218 DO j=jsta_2l,jend_2u
219 DO i=ista_2l,iend_2u
220 vis(i,j)=spval
221! -checking undedined points
222 if(t(i,j,lm)<spval .and. u(i,j,lm)<spval .and. v(i,j,lm)<spval &
223 .and. pmid(i,j,lm)<spval) then
224! - take max hydrometeor mixing ratios in lowest 3 levels (lowest 13 hPa, 100m with RAP/HRRR
225 qrain = 0.
226 qsnow = 0.
227 qgraupel = 0.
228 qclw = 0.
229 qclice = 0.
230
231 do k = 1,3
232 ll=lm-k+1
233 if(qqw(i,j,ll)<spval)qclw = max(qclw, qqw(i,j,ll) )
234 if(qqi(i,j,ll)<spval)qclice = max(qclice, qqi(i,j,ll) )
235 if(qqs(i,j,ll)<spval)qsnow = max(qsnow, qqs(i,j,ll) )
236 if(qqr(i,j,ll)<spval)qrain = max(qrain, qqr(i,j,ll) )
237 if(qqg(i,j,ll)<spval)qgraupel = max(qgraupel, qqg(i,j,ll) )
238! - compute relative humidity
239 tx=t(i,j,ll)-273.15
240 rhb(i,j,ll)=0.
241 pol = 0.99999683 + tx*(-0.90826951e-02 + &
242 tx*(0.78736169e-04 + tx*(-0.61117958e-06 + &
243 tx*(0.43884187e-08 + tx*(-0.29883885e-10 + &
244 tx*(0.21874425e-12 + tx*(-0.17892321e-14 + &
245 tx*(0.11112018e-16 + tx*(-0.30994571e-19)))))))))
246 if(abs(pol) > 0.) THEN
247 esx = 6.1078/pol**8
248
249 es = esx
250 e = pmid(i,j,ll)/100.*q(i,j,ll)/(0.62197+q(i,j,ll)*0.37803)
251 rhb(i,j,ll) = 100.*amin1(1.,e/es)
252 ENDIF
253
254 enddo
255
256! - take max RH of levels 1 and 2 near the sfc
257 rhmax = max(rhb(i,j,lm),rhb(i,j,lm-1))
258 qrh = max(0.0,min(0.8,(rhmax/100.-0.15)))
259
260!tgs 23 feb 2017 - increase of base value to 90 km to reduce attenuation
261! from RH for clear-air visibility. (i.e., increase clear-air vis overall)
262 visrh = 90. * exp(-2.5*qrh)
263
264! -- add term to increase RH vis term for
265! low-level wind shear increasing from 4 to 6 ms-1
266! (using Evan Kuchera's paper as a guideline)
267
268! -- calculate term for shear between levels 1 and 4
269! (about 25 hPa for HRRR/RAP)
270 shear = sqrt( (u(i,j,lm-3)-u(i,j,lm))**2 &
271 +(v(i,j,lm-3)-v(i,j,lm))**2 )
272
273 shear_fac = min(1.,max(0.,(shear-4.)/2.) )
274 if (visrh<10.) visrh = visrh + (10.-visrh)* &
275 shear_fac
276
277 if (shear>4.) shear4_cnt = shear4_cnt +1
278 if (shear>5.) shear5_cnt = shear5_cnt +1
279 if (shear>6.) shear8_cnt = shear8_cnt +1
280
281 if (shear>4..and.visrh<10) &
282 shear4_cnt_lowvis = shear4_cnt_lowvis +1
283 if (shear>5..and.visrh<10) &
284 shear5_cnt_lowvis = shear5_cnt_lowvis +1
285 if (shear>6..and.visrh<10) &
286 shear8_cnt_lowvis = shear8_cnt_lowvis +1
287
288 if (visrh<10.) visrh10_cnt = visrh10_cnt+1
289 if (czen(i,j)<0.) night_cnt = night_cnt + 1
290 if (czen(i,j)<0.1) lowsun_cnt = lowsun_cnt + 1
291
292 tv=t(i,j,lm)*(h1+d608*q(i,j,lm))
293
294 rhoair=pmid(i,j,lm)/(rd*tv)
295
296 vovermd=(1.+q(i,j,lm))/rhoair+(qclw+qrain)/rhowat+ &
297! VOVERMD=(1.+Q(I,J,1))/RHOAIR+(QCLW+QRAIN)/RHOWAT+
298 (qgraupel+qclice+qsnow)/rhoice
299 conclc=qclw/vovermd*1000.
300 conclp=qrain/vovermd*1000.
301 concfc=qclice/vovermd*1000.
302 concfp=qsnow/vovermd*1000.
303 concfg=qgraupel/vovermd*1000.
304
305 temp_fac = min(1.,max((t(i,j,lm)-271.15),0.) )
306
307 coef_snow = coeffp_dry*(1.-temp_fac) &
308 + coeffp_wet* temp_fac
309
310 if (t(i,j,lm)< 270. .and. temp_fac==1.) &
311 write (6,*) 'Problem w/ temp_fac - calvis'
312
313! Key calculation of attenuation from blowing snow -- updated 5 August 2022 by Tim Corrie
314! Framework is from Letcher et al (2021)
315
316 ustar_t = 0.2
317 u_p = 2.8*ustar_t
318 lamda = 0.45
319 z = 2.0
320 alpha = 15.0
321 r_bar = 0.0002
322
323! print *, i,j
324
325
326 if (si(i,j)<spval .and. si(i,j) .ge. 1.0 .and. ustar(i,j) > ustar_t .and. z0(i,j) .le. 0.7) then
327 z_r = 1.6*(ustar(i,j)**2./(2.*g))
328 q_s = max((0.68/ustar(i,j))*(rhoair/g)*ustar_t*(ustar(i,j)**2.-ustar_t**2.),0.0)
329 c_r = (q_s/u_p)*(lamda*g/ustar(i,j)**2.)*exp(-lamda*z_r*g/ustar(i,j)**2.)
330 c_z = max(c_r * exp(-1.55*((0.05628*ustar(i,j))**-0.544 - z**-0.544)),1e-15)
331 c_alpha = alpha/(alpha+2) !simplified version of (6) in Letcher et al (2021)
332 rho_sno = sno(i,j)/(si(i,j)/1.0e3)
333 rho_sno = rho_sno*2. + 10.*max(0.,rho_sno-150.0)
334 vis_blsn = (5.217*rho_sno*r_bar**1.011)/(1.82*c_z*c_alpha)
335 betablsn = 3.912/(vis_blsn/1000.0)
336 ! print to ensure quality
337 !print *, "z_r", z_r
338 !print *, "Q_s", Q_s
339 !print *, "C_r", C_r
340 !print *, "c_z", c_z
341 !print *, "c_alpha", c_alpha
342 !print *, "sno/SWE", sno(i,j)
343 !print *, "si/SNOD", si(i,j)/1.0e3
344 !print *, "rho_sno", rho_sno
345 !print *, "vis_blsn", vis_blsn
346 !print *, "BETABLSN", BETABLSN
347 !print *, "ustar", ustar(i,j)
348 else
349 betablsn = 0
350 !print *, "BETABLSN", BETABLSN
351 end if
352
353! Key calculation of attenuation from each hydrometeor type (cloud, snow, graupel, rain, ice)
354 betav=coeffc*concfc**exponfc &
355 + coef_snow*concfp**exponfp &
356 + coeflc*conclc**exponlc + coeflp*conclp**exponlp &
357 + coeffg*concfg**exponfg +1.e-10
358
359! Addition of attenuation from aerosols if option selected
360 if(method == 2 .or. method == 3)then ! aerosol method
361 betav = betav + aextc55(i,j,lm)*1000.
362 if(method_blsn) then ! BLSN method, updated 8 August 2022 by Tim Corrie
363 betav = betav + betablsn
364 endif
365 endif
366
367! Calculation of visibility based on hydrometeor and aerosols. (RH effect not yet included.)
368 vis(i,j)=min(90.,const1/betav) ! max of 90km
369
370 if (vis(i,j)<vis_min) vis_min = vis(i,j)
371 if (visrh<visrh_min) visrh_min = visrh
372
373 if (visrh<vis(i,j)) visrh_lower = visrh_lower + 1
374
375
376! -- Dec 2003 - Roy Rasmussen (NCAR) expression for night vs. day vis
377! 1.609 factor is number of km in mile.
378 vis_night = 1.69 * ((vis(i,j)/1.609)**0.86) * 1.609
379
380 zen_fac = min(0.1,max(czen(i,j),0.))/ 0.1
381 vis(i,j) = zen_fac * vis(i,j) + (1.-zen_fac)*vis_night
382
383 if(method == 1 .or. method == 3)then ! RH method (if lower vis)
384 vis(i,j) = min(vis(i,j),visrh)
385 endif
386
387 if (vis(i,j)<1.) vis1km_cnt = vis1km_cnt + 1
388 if (vis(i,j)<3.) vis3km_cnt = vis3km_cnt + 1
389 if (vis(i,j)<5.) vis5km_cnt = vis5km_cnt + 1
390! convert vis from km to [m]
391 vis(i,j) = vis(i,j) * 1000.
392
393 endif !end checking undefined points
394 ENDDO
395 ENDDO
396
397! write (6,*)
398! write (6,*) ' Visibility diagnostics follow: ------------'
399! write (6,*) ' -------------------------------------------'
400! write (6,*) &
401! ' any vis / vis < 10 km '
402! write (6,*)'No. of grid pts with shear (lev4-1) > 4m/s', &
403! shear4_cnt, shear4_cnt_lowvis
404! write (6,*)'No. of grid pts with shear (lev4-1) > 5m/s', &
405! shear5_cnt, shear5_cnt_lowvis
406! write (6,*)'No. of grid pts with shear (lev4-1) > 6m/s', &
407! shear8_cnt, shear8_cnt_lowvis
408! write (6,*)
409! write (6,*)'No. of grid pts with vis-RH < 10 km', &
410! visrh10_cnt
411! write (6,*)'No. of grid pts with vis < 1 km', &
412! vis1km_cnt
413! write (6,*)'No. of grid pts with vis < 3 km', &
414! vis3km_cnt
415! write (6,*)'No. of grid pts with vis < 5 km', &
416! vis5km_cnt
417! write (6,*)
418! write (6,*)'Min vis-hydrometeor, vis-RH', vis_min, visrh_min
419!
420! write (6,*)'No. of grid pts with visRH < vis(hydrometeor)', &
421! visrh_lower
422! write (6,*)'% grid pts with night/cos(zen) < 0.1', &
423! float(night_cnt)/float(IM*JM),float(lowsun_cnt)/ &
424! float(IM*JM)
425! write (6,*)
426!
427 RETURN
428 END