1 ''' vapor_wrf module includes following WRF-based utilities:
2 CTT - cloud-top temperature (2D)
3 DBZ - radar reflectivity
4 DBZ_MAX - max radar reflectivity over vertical column
5 ETH - equivalent potential temperature
7 PV - potential vorticity
8 SHEAR - horizontal wind shear
9 SLP - sea-level pressure (2D)
10 TD - dewpoint temperature
11 TK - temperature in degrees Kelvin.
12 CTHGT - cloud-top height
13 wrf_deriv_findiff - 6th order finite-difference derivative wrf_curl_findiff - finite-difference curl
14 wrf_grad_findiff - finite-difference gradient
15 wrf_div_findiff - finite-difference divergence'''
20 def CTT(P,PB,T,QCLOUD,QICE):
21 '''Calculate cloud-top temperature using WRF variables.
22 Calling sequence: VAL=CTT(P,PB,T,QCLOUD,QICE)
23 Where P,PB,T,QCLOUD,QICE are 3D WRF variables.
24 (Replace QICE by 0 if not in data)
25 Result VAL is a 2D variable.'''
37 tmk = (T+300.0)*numpy.power(pf*.00001,c)
41 WRF_CTT = tmk[0,:,:]-celkel
42 opdepthd = numpy.zeros(ss,numpy.float32)
43 opdepthu = numpy.zeros(ss,numpy.float32)
46 for k
in range(s[0]-2,-1,-1):
47 dp =100.*(pf[k,:,:]-pf[k+1,:,:])
48 opdepthd=opdepthu+(abscoef*QCLOUD[k,:,:]+abscoefi*QICE[k,:,:])*dp/grav
49 logArray= numpy.logical_and(opdepthd > 1.0,opdepthu <= 1.0)
51 WRF_CTT = numpy.where(logArray,tmk[k,:,:]-celkel,WRF_CTT[:,:])
54 for k
in range(s[0]-2,-1,-1):
55 dp =100.*(pf[k,:,:]-pf[k+1,:,:])
56 logArray1 = tmk[k,:,:]<celkel
57 opdepthd= numpy.where(logArray1,opdepthu+abscoefi*QCLOUD[k,:,:]*dp/grav,opdepthu+abscoef*QCLOUD[k,:,:]*dp/grav)
58 logArray= numpy.logical_and(opdepthd > 1.0,opdepthu <= 1.0)
60 WRF_CTT = numpy.where(logArray,tmk[k,:,:]-celkel,WRF_CTT[:,:])
64 def CTHGT(P,PB,T,QCLOUD,QICE,ELEVATION):
65 '''Calculate cloud-top height using WRF variables.
66 Calling sequence: VAL=CTHGT(P,PB,T,QCLOUD,QICE,ELEVATION)
67 Where P,PB,T,QCLOUD,QICE are 3D WRF variables.
68 (Replace QICE by 0 if not in data)
69 Result VAL is a 2D variable.'''
82 tmk = (T+300.0)*numpy.power(pf*.00001,c)
86 CTHT = numpy.zeros(ss,numpy.float32)
87 opdepthd = numpy.zeros(ss,numpy.float32)
88 opdepthu = numpy.zeros(ss,numpy.float32)
91 for k
in range(s[0]-2,-1,-1):
92 dp =100.*(pf[k,:,:]-pf[k+1,:,:])
93 opdepthd=opdepthu+(abscoef*QCLOUD[k,:,:]+abscoefi*QICE[k,:,:])*dp/grav
94 logArray= numpy.logical_and(opdepthd > 1.0,opdepthu <= 1.0)
96 CTHT = numpy.where(logArray,ELEVATION[k,:,:],CTHT[:,:])
99 for k
in range(s[0]-2,-1,-1):
100 dp =100.*(pf[k,:,:]-pf[k+1,:,:])
101 logArray1 = tmk[k,:,:]<celkel
102 opdepthd= numpy.where(logArray1,opdepthu+abscoefi*QCLOUD[k,:,:]*dp/grav,opdepthu+abscoef*QCLOUD[k,:,:]*dp/grav)
103 logArray= numpy.logical_and(opdepthd > 1.0,opdepthu <= 1.0)
105 CTHT = numpy.where(logArray,ELEVATION[k,:,:],CTHT[:,:])
109 def DBZ(P,PB,QRAIN,QGRAUP,QSNOW,T,QVAPOR,iliqskin=0,ivarint=0):
110 ''' Calculates 3D radar reflectivity based on WRF variables.
112 VAL = DBZ(P,PB,QRAIN,QGRAUP,QSNOW,T,QVAPOR,iliqskin=0,ivarint=0)
113 Where P,PB,QRAIN,QGRAUP,QSNOW,T,and QVAPOR are WRF 3D variables.
114 Optional arguments iliqskin and ivarint default to 0
115 if iliqskin=1, then frozen particles above freezing are
116 assumed to scatter as a liquid particle. If ivarint = 1 then
117 intercept parameters are calculated based on Thompson, Rasmussen
118 and Manning, as described in 2004 Monthly Weather Review.
119 Result VAL is 3D variable on same grid as WRF variables.
120 If QGRAUP or QSNOW are not available then replace them by 0.'''
138 RON_DELQR0 = 0.25*RON_QR0
139 RON_CONST1R = (RON2-RON_MIN)*0.5
140 RON_CONST2R = (RON2+RON_MIN)*0.5
151 pi = 3.141592653589793
153 FACTOR_R = GAMMA_SEVEN*1.e18*numpy.power((1./(pi*RHO_R)),1.75)
154 FACTOR_S = GAMMA_SEVEN*1.e18*numpy.power((1./(pi*RHO_S)),1.75)*numpy.power((RHO_S/RHOWAT),2.*ALPHA)
155 FACTOR_G = GAMMA_SEVEN*1.e18*numpy.power((1./(pi*RHO_G)),1.75)*numpy.power((RHO_G/RHOWAT),2.*ALPHA)
158 TK = (T+300.)*numpy.power(PRESS*.00001,c)
160 QVAPOR = numpy.maximum(QVAPOR,0.0)
161 QSNOW = numpy.maximum(QSNOW,0.0)
162 QRAIN = numpy.maximum(QRAIN,0.0)
164 QGRAUP = numpy.maximum(QGRAUP,0.0)
168 TestT = numpy.less(TK,CELKEL)
169 QSNOW = numpy.where(TestT,QRAIN, QSNOW)
170 QRAIN = numpy.where(TestT,0.0, QRAIN)
171 VIRTUAL_T = TK*(0.622 + QVAPOR)/(0.622*(1.+QVAPOR))
172 RHOAIR = PRESS/(RD*VIRTUAL_T)
176 FACTORB_S = numpy.float32(numpy.where(TestT,FACTOR_S,FACTOR_S/ALPHA))
177 FACTORB_G = numpy.float32(numpy.where(TestT,FACTOR_G, FACTOR_G/ALPHA))
179 TEMP_C = numpy.minimum(-.001, TK-CELKEL)
180 SONV = numpy.minimum(2.e8,2.e6*numpy.exp(-.12*TEMP_C))
181 TestG = numpy.less(R1, QGRAUP)
182 GONV = numpy.where(TestG,2.38*numpy.power(pi*RHO_G/(RHOAIR*QGRAUP),0.92),GON)
183 GONV = numpy.where(TestG,numpy.maximum(1.e4,numpy.minimum(GONV,GON)),GONV)
185 RONV = numpy.where(numpy.greater(QRAIN,R1),RON_CONST1R*numpy.tanh((RON_QR0-QRAIN)/RON_DELQR0) + RON_CONST2R,RON2)
190 Z_E = FACTOR_R*numpy.power(RHOAIR*QRAIN,1.75)/numpy.power(RONV,0.75)
191 Z_E = Z_E+FACTORB_S*numpy.power(RHOAIR*QSNOW,1.75)/numpy.power(SONV,0.75)
192 Z_E = Z_E+FACTORB_G*numpy.power(RHOAIR*QGRAUP,1.75)/numpy.power(GONV,0.75)
193 Z_E = numpy.maximum(Z_E, 0.001)
195 WRF_DBZ = 10.0*numpy.log10(Z_E)
198 def DBZ_MAX(P,PB,QRAIN,QGRAUP,QSNOW,T,QVAPOR,iliqskin=0,ivarint=0):
199 ''' Calculates 2D radar reflectivity based on WRF variables.
200 Calling sequence: VAL = DBZ_MAX(P,PB,QRAIN,QGRAUP,QSNOW,T,QVAPOR)
201 Where P,PB,QRAIN,QGRAUP,QSNOW,T,and QVAPOR are WRF 3D variables.
202 Optional arguments iliqskin and ivarint default to 0, as
203 described in help(DBZ)
204 Result VAL is 2D variable on 2D grid of WRF variables.
205 VAL is the maximum over a vertical column of DBZ.
206 If QGRAUP or QSNOW are not available then replace them by 0.'''
207 WRF_DBZ =
DBZ(P,PB,QRAIN,QGRAUP,QSNOW,T,QVAPOR)
208 WRF_DBZ_MAX = numpy.amax(WRF_DBZ,axis=0)
213 ''' Program to calculate equivalent potential temperature using WRF
214 variables P, PB, T, QVAPOR.
215 Calling sequence: WRF_ETH = ETH(P,PB,T,QVAPOR)
216 Result WRF_ETH is a 3D variable on same grid as P,PB,T,QVAPOR.'''
220 GAMMA = 287.04/1004.0
221 GAMMAMD = 0.608 -0.887
232 TK = TH*numpy.power(PRESS*.001,c)
233 Q = numpy.maximum(QVAPOR, 1.e-15)
235 TLCL = TLCLC4+ TLCLC1/(numpy.log(numpy.power(TK,TLCLC2)/E)-TLCLC3)
236 EXPNT = (THTECON1/TLCL - THTECON2)*Q*(1.0+THTECON3*Q)
237 WRF_ETH = TK*numpy.power(1000.0/PRESS,GAMMA*(1.0+GAMMAMD*Q))*numpy.exp(EXPNT)
240 def PV(T,P,PB,U,V,ELEV,F):
241 ''' Routine that calculates potential vorticity using WRF variables.
242 Calling sequence: WRF_PV = PV(T,P,PB,U,V,ELEV,F)
243 Where T,P,PB,U,V are WRF 3D variables, F is WRF 2D variable.
244 ELEV is the VAPOR ELEVATION variable (PH+PHB)/g
245 Result is 3D variable WRF_PV.'''
247 from vapor_utils
import deriv_var_findiff
256 AVORT = DVDX - DUDY + F
257 WRF_PVO = numpy.float32(-9.81*(DTHDP*AVORT-DVDP*DTHDX+DUDP*DTHDY)*10000.)
260 def RH(P,PB,T,QVAPOR):
261 ''' Calculation of relative humidity.
262 Calling sequence WRF_RH = RH(P,PB,T,QVAPOR),
263 where P,PB,T,QVAPOR are standard WRF 3D variables,
264 result WRF_RH is 3D variable on same grid as inputs.'''
274 TK = TH*numpy.power(PRESS*.00001,c)
275 ES = 10*SVP1*numpy.exp(SVP2*(TK-SVPT0)/(TK-SVP3))
276 QVS = EP_3*ES/(0.01*PRESS - (1.-EP_3)*ES)
277 WRF_RH = 100.0*numpy.maximum(numpy.minimum(QVAPOR/QVS,1.0),0)
281 def SHEAR(U,V,P,PB,level1=200.,level2=850.):
282 '''Program calculates horizontal wind shear
283 Calling sequence: SHR = SHEAR(U,V,P,PB,level1,level2)
284 where U and V are 3D wind velocity components, and
285 result SHR is 3D wind shear.
286 Shear is defined as the RMS difference between the horizontal
287 velocity interpolated to the specified pressure levels,
288 level1 and level2 (in millibars) which default to 200 and 850.'''
289 from numpy
import sqrt
295 result = (uinterp1-uinterp2)*(uinterp1-uinterp2)+(vinterp1-vinterp2)*(vinterp1-vinterp2)
296 result = sqrt(result)
299 def SLP(P,PB,T,QVAPOR,ELEVATION):
300 '''Calculation of Sea-level pressure.
301 Calling sequence: WRF_SLP = SLP(P,PB,T,QVAPOR,ELEVATION)
302 where P,PB,T,QVAPOR are WRF 3D variables and ELEVATION is
303 the VAPOR variable indicating the elevation in meters above sea level.
304 Result is a 2D variable with same horizonal extents as input variables.'''
316 TK = (T+300.0)*numpy.power(PR*.00001,c)
321 WRF_SLP = numpy.empty(ss,numpy.float32)
322 LEVEL = numpy.empty(ss,numpy.int32)
324 RIDTEST = numpy.empty(ss,numpy.int32)
325 PLO = numpy.empty(ss, numpy.float32)
326 ZLO = numpy.empty(ss,numpy.float32)
327 TLO = numpy.empty(ss,numpy.float32)
328 PHI = numpy.empty(ss,numpy.float32)
329 ZHI = numpy.empty(ss,numpy.float32)
330 THI = numpy.empty(ss,numpy.float32)
332 for K
in range(s[0]):
333 KHI = numpy.minimum(K+1, s[0]-1)
334 LEVNEED = numpy.logical_and(numpy.less(LEVEL,0), numpy.less(PR[K,:,:] , PR[0,:,:] - PCONST))
336 PLO=numpy.where(LEVNEED,PR[K,:,:],PLO[:,:])
337 TLO=numpy.where(LEVNEED,TK[K,:,:]*(1.+0.608*QVAPOR[K,:,:]), TLO[:,:])
338 ZLO=numpy.where(LEVNEED,ELEVATION[K,:,:],ZLO[:,:])
339 PHI=numpy.where(LEVNEED,PR[KHI,:,:],PHI[:,:])
340 THI=numpy.where(LEVNEED,TK[KHI,:,:]*(1.+0.608*QVAPOR[KHI,:,:]), THI[:,:])
341 ZHI=numpy.where(LEVNEED,ELEVATION[KHI,:,:],ZHI[:,:])
342 P_AT_PCONST = PR[0,:,:]-PCONST
343 T_AT_PCONST = THI - (THI-TLO)*numpy.log(P_AT_PCONST/PHI)*numpy.log(PLO/PHI)
344 Z_AT_PCONST = ZHI - (ZHI-ZLO)*numpy.log(P_AT_PCONST/PHI)*numpy.log(PLO/PHI)
345 T_SURF = T_AT_PCONST*numpy.power((PR[0,:,:]/P_AT_PCONST),(GAMMA*R/G))
346 T_SEA_LEVEL = T_AT_PCONST + GAMMA*Z_AT_PCONST
347 RIDTEST = numpy.logical_and(T_SURF <= TC, T_SEA_LEVEL >= TC)
348 T_SEA_LEVEL = numpy.where(RIDTEST, TC, TC - .005*(T_SURF -TC)**2)
349 Z_HALF_LOWEST=ELEVATION[0,:,:]
350 WRF_SLP = 0.01*(PR[0,:,:]*numpy.exp(2.*G*Z_HALF_LOWEST/(R*(T_SEA_LEVEL+T_SURF))))
354 ''' Calculation of dewpoint temperature based on WRF variables.
355 Calling sequence: WRFTD = TD(P,PB,QVAPOR)
356 where P,PB,QVAPOR are WRF 3D variables, and result WRFTD
357 is a 3D variable on the same grid.'''
363 QV = numpy.maximum(QVAPOR,0.0)
364 TDC = 0.01*QV*(P+PB)/(0.622+QV)
365 TDC = numpy.maximum(TDC,0.001)
366 WRF_TD =(243.5*numpy.log(TDC) - 440.8)/(19.48 - numpy.log(TDC))
371 ''' Calculation of temperature in degrees kelvin using WRF variables.
372 Calling sequence: TMP = TK(P,PB,T)
373 Where P,PB,T are WRF 3D variables, result TMP is a 3D variable
374 indicating the temperature in degrees Kelvin.'''
379 WRF_TK = TH*numpy.power((P+PB)*.00001,c)
383 ''' Operator that calculates the derivative of a WRF (or layered) variable A
384 in the direction dir (user coordinates; in Python the direction is reversed)
385 ELEV is the ELEVATION variable. '''
391 ext = (vapor.BOUNDS[3]-vapor.BOUNDS[0], vapor.BOUNDS[4]-vapor.BOUNDS[1],vapor.BOUNDS[5]-vapor.BOUNDS[2])
392 usrmax =
vapor.MapVoxToUser([vapor.BOUNDS[3],vapor.BOUNDS[4],vapor.BOUNDS[5]],vapor.REFINEMENT,vapor.LOD)
393 usrmin =
vapor.MapVoxToUser([vapor.BOUNDS[0],vapor.BOUNDS[1],vapor.BOUNDS[2]],vapor.REFINEMENT,vapor.LOD)
394 dx = (usrmax[2]-usrmin[2])/ext[2]
395 dy = (usrmax[1]-usrmin[1])/ext[1]
401 ans = dadx_eta -dadz*dzdx_eta
409 ans = dady_eta - dadz*dzdy_eta
413 ''' Operator that calculates the gradient of a scalar field
414 using 6th order finite differences on a WRF (layered) grid
415 Calling sequence: GRD = grad_findiff(A,ELEV)
417 A is a float32 array defining a scalar field.
418 ELEV is the corresponding ELEVATION array
419 Result GRD is a triple of 3 3-dimensional float3d arrays consisting of
420 the gradient of A.'''
425 return aux1,aux2,aux3
429 ''' Operator that calculates the divergence of a vector field
430 using 6th order finite differences.
431 Calling sequence: DIV = wrf_div_findiff(A,B,C,ELEV)
433 A, B, and C are 3-dimensional float32 arrays defining a vector field.
434 A is the x-component, B is y, C is z (in user coordinates)
435 ELEV is the ELEVATION variable
436 Resulting DIV is a 3-dimensional float3d array consisting of
437 the divergence of the triple (A,B,C).'''
444 ''' Operator that calculates the curl of a vector field
445 using 6th order finite differences, on a layered (e.g. WRF) grid.
446 Calling sequence: curlfield = wrf_curl_findiff(A,B,C,ELEV)
448 A,B,C are three 3-dimensional float32 arrays that define a
449 vector field on a layered grid
450 ELEV is the ELEVATION variable for the layered grid.
451 curlfield is a 3-tuple of 3-dimensional float32 arrays that is
452 returned by this operator.'''
455 ext = (vapor.BOUNDS[3]-vapor.BOUNDS[0], vapor.BOUNDS[4]-vapor.BOUNDS[1],vapor.BOUNDS[5]-vapor.BOUNDS[2])
456 usrmax =
vapor.MapVoxToUser([vapor.BOUNDS[3],vapor.BOUNDS[4],vapor.BOUNDS[5]],vapor.REFINEMENT,vapor.LOD)
457 usrmin =
vapor.MapVoxToUser([vapor.BOUNDS[0],vapor.BOUNDS[1],vapor.BOUNDS[2]],vapor.REFINEMENT,vapor.LOD)
458 dx = (usrmax[2]-usrmin[2])/ext[2]
459 dy = (usrmax[1]-usrmin[1])/ext[1]
460 dz = (usrmax[0]-usrmin[0])/ext[0]
474 outx = dcdy_eta - dcdz*dzdy_eta -dbdz
483 outy = dadz - dcdx_eta + dcdz*dzdx_eta
492 outz = dbdx_eta - dbdz*dzdx_eta -dady_eta + dadz*dzdy_eta
494 return outx, outy, outz
def SLP(P, PB, T, QVAPOR, ELEVATION)
def MapVoxToUser(voxcoord, refinementLevel, lod)
def PV(T, P, PB, U, V, ELEV, F)
def ETH(P, PB, T, QVAPOR)
def CTHGT(P, PB, T, QCLOUD, QICE, ELEVATION)
def CTT(P, PB, T, QCLOUD, QICE)
def wrf_deriv_findiff(A, ELEV, dir)
def wrf_div_findiff(A, B, C, ELEV)
def VariableExists(timestep, varname, refinement, lod)
def wrf_grad_findiff(A, ELEV)
def wrf_curl_findiff(A, B, C, ELEV)