1 ''' The vapor_utils module contains: 2 mag3d - calculate magnitude of 3-vector 3 mag2d - calculate magnitude of 2-vector 4 deriv_findiff - calculate derivative using 6th order finite differences 5 curl_findiff - calculate curl using 6th order finite differences 6 div_findiff - calculate divergence using 6 order finite differences 7 grad_findiff - calculate gradient using 6th order finite differences. 8 deriv_var_findiff - calculate a derivative of one 3D 9 variable with respect to another variable. 10 interp3d - interpolate a 3D variable to a vertical level surface of another variable. 11 vector_rotate - rotate and scale vector field for lat-lon grid. 15 '''Calculate the magnitude of a 3-vector. 16 Calling sequence: MAG = mag3d(A,B,C) 17 Where: A, B, and C are float32 numpy arrays. 18 Result MAG is a float32 numpy array containing the square root 19 of the sum of the squares of A, B, and C.''' 20 from numpy
import sqrt
21 return sqrt(a1*a1 + a2*a2 + a3*a3)
24 '''Calculate the magnitude of a 2-vector. 25 Calling sequence: MAG = mag2d(A,B) 26 Where: A, and B are float32 numpy arrays. 27 Result MAG is a float32 numpy array containing the square root 28 of the sum of the squares of A and B.''' 29 from numpy
import sqrt
30 return sqrt(a1*a1 + a2*a2)
33 ''' Function that calculates first-order derivatives 34 using 2nd order finite differences in regular Cartesian grids.''' 38 aprime = numpy.array(a)
47 aprime[:,:,i] = (-a[:,:,i]+a[:,:,i+1]) / (dx)
50 for i
in range(1,s[2]-1):
51 aprime[:,:,i] = (-a[:,:,i-1]+a[:,:,i+1])/(2*dx)
54 for i
in range(s[2]-1,s[2]):
55 aprime[:,:,i] = (a[:,:,i-1]-a[:,:,i]) /(dx)
63 aprime[:,i,:] = (-a[:,i,:]+a[:,i+1,:]) / (dx)
66 for i
in range(1,s[1]-1):
67 aprime[:,i,:] = (-a[:,i-1,:]+a[:,i+1,:])/(2*dx)
70 for i
in range(s[1]-1,s[1]):
71 aprime[:,i,:] = (a[:,i-1,:]-a[:,i,:]) /(dx)
79 aprime[i,:,:] = (-a[i,:,:]+a[i+1,:,:]) / (dx)
82 for i
in range(1,s[0]-1):
83 aprime[i,:,:] = (-a[i-1,:,:]+a[i+1,:,:])/(2*dx)
86 for i
in range(s[0]-1,s[0]):
87 aprime[i,:,:] = (a[i-1,:,:]-a[i,:,:]) /(dx)
92 ''' Function that calculates first-order derivatives 93 using 4th order finite differences in regular Cartesian grids.''' 97 aprime = numpy.array(a)
106 aprime[:,:,i] = (-3*a[:,:,i]+4*a[:,:,i+1]-a[:,:,i+2]) / (2*dx)
109 for i
in range(2,s[2]-2):
110 aprime[:,:,i] = (a[:,:,i-2]-8*a[:,:,i-1]+8*a[:,:,i+1]-a[:,:,i+2])/(12*dx)
113 for i
in range(s[2]-2,s[2]):
114 aprime[:,:,i] = (a[:,:,i-2]-4*a[:,:,i-1]+3*a[:,:,i]) /(2*dx)
122 aprime[:,i,:] = (-3*a[:,i,:]+4*a[:,i+1,:]-a[:,i+2,:]) / (2*dx)
125 for i
in range(2,s[1]-2):
126 aprime[:,i,:] = (a[:,i-2,:]-8*a[:,i-1,:]+8*a[:,i+1,:]-a[:,i+2,:])/(12*dx)
129 for i
in range(s[1]-2,s[1]):
130 aprime[:,i,:] = (a[:,i-2,:]-4*a[:,i-1,:]+3*a[:,i,:]) /(2*dx)
138 aprime[i,:,:] = (-3*a[i,:,:]+4*a[i+1,:,:]-a[i+2,:,:]) / (2*dx)
141 for i
in range(2,s[0]-2):
142 aprime[i,:,:] = (a[i-2,:,:]-8*a[i-1,:,:]+8*a[i+1,:,:]-a[i+2,:,:])/(12*dx)
145 for i
in range(s[0]-2,s[0]):
146 aprime[i,:,:] = (a[i-2,:,:]-4*a[i-1,:,:]+3*a[i,:,:]) /(2*dx)
152 ''' Function that calculates first-order derivatives 153 using sixth order finite differences in regular Cartesian grids. 154 Calling sequence: deriv = deriv_findiff(ary,dir,delta, order=6) 155 ary is a 3-dimensional float32 numpy array 156 dir is 1, 2, or 3 (for X, Y, or Z directions in user coordinates) 157 delta is the grid spacing in the direction dir. 158 order is the accuracy order (one of 6,4,2) 159 Returned array 'deriv' is the derivative of ary in the 160 specified direction dir. ''' 170 aprime = numpy.array(a)
177 return numpy.zeros_like(a)
185 aprime[:,:,i] = (-11*a[:,:,i]+18*a[:,:,i+1]-9*a[:,:,i+2]+2*a[:,:,i+3]) / (6*dx)
188 for i
in range(3,s[2]-3):
189 aprime[:,:,i] = (-a[:,:,i-3]+9*a[:,:,i-2]-45*a[:,:,i-1]+45*a[:,:,i+1] -9*a[:,:,i+2]+a[:,:,i+3])/(60*dx)
192 for i
in range(s[2]-3,s[2]):
193 aprime[:,:,i] = (-2*a[:,:,i-3]+9*a[:,:,i-2]-18*a[:,:,i-1]+11*a[:,:,i]) /(6*dx)
200 return numpy.zeros_like(a)
207 aprime[:,i,:] = (-11*a[:,i,:]+18*a[:,i+1,:]-9*a[:,i+2,:]+2*a[:,i+3,:]) /(6*dx)
209 for i
in range(3,s[1]-3):
210 aprime[:,i,:] = (-a[:,i-3,:]+9*a[:,i-2,:]-45*a[:,i-1,:]+45*a[:,i+1,:] -9*a[:,i+2,:]+a[:,i+3,:])/(60*dx)
212 for i
in range(s[1]-3,s[1]):
213 aprime[:,i,:] = (-2*a[:,i-3,:]+9*a[:,i-2,:]-18*a[:,i-1,:]+11*a[:,i,:]) /(6*dx)
220 return numpy.zeros_like(a)
227 aprime[i,:,:] = (-11*a[i,:,:]+18*a[i+1,:,:]-9*a[i+2,:,:]+2*a[i+3,:,:]) /(6*dx)
229 for i
in range(3,s[0]-3):
230 aprime[i,:,:] = (-a[i-3,:,:]+9*a[i-2,:,:]-45*a[i-1,:,:]+45*a[i+1,:,:] -9*a[i+2,:,:]+a[i+3,:,:])/(60*dx)
232 for i
in range(s[0]-3,s[0]):
233 aprime[i,:,:] = (-2*a[i-3,:,:]+9*a[i-2,:,:]-18*a[i-1,:,:]+11*a[i,:,:]) /(6*dx)
238 ''' Function that calculates first-order derivatives 239 using 2nd order finite differences in regular Cartesian grids.''' 243 aprime = numpy.array(a)
252 aprime[:,:,i] = (-a[:,:,i]+a[:,:,i+1]) / (-var[:,:,i]+var[:,:,i+1])
255 for i
in range(1,s[2]-1):
256 aprime[:,:,i] = (-a[:,:,i-1]+a[:,:,i+1])/(-var[:,:,i-1]+var[:,:,i+1])
259 for i
in range(s[2]-1,s[2]):
260 aprime[:,:,i] = (a[:,:,i-1]-a[:,:,i]) / (var[:,:,i-1]-var[:,:,i])
268 aprime[:,i,:] = (-a[:,i,:]+a[:,i+1,:]) / (-var[:,i,:]+var[:,i+1,:])
271 for i
in range(1,s[1]-1):
272 aprime[:,i,:] = (-a[:,i-1,:]+a[:,i+1,:])/(-var[:,i-1,:]+var[:,i+1,:])
275 for i
in range(s[1]-1,s[1]):
276 aprime[:,i,:] = (a[:,i-1,:]-a[:,i,:]) / (var[:,i-1,:]-var[:,i,:])
284 aprime[i,:,:] = (-a[i,:,:]+a[i+1,:,:]) / (-var[i,:,:]+var[i+1,:,:])
287 for i
in range(1,s[0]-1):
288 aprime[i,:,:] = (-a[i-1,:,:]+a[i+1,:,:])/ (-var[i-1,:,:]+var[i+1,:,:])
291 for i
in range(s[0]-1,s[0]):
292 aprime[i,:,:] = (a[i-1,:,:]-a[i,:,:]) / (var[i-1,:,:]-var[i,:,:])
299 ''' Function that calculates first-order derivatives of a variable 300 with respect to another variable 'var' 301 using 4th order finite differences in regular Cartesian grids.''' 305 aprime = numpy.array(a)
314 aprime[:,:,i] = (-3*a[:,:,i]+4*a[:,:,i+1]-a[:,:,i+2]) / (-3*var[:,:,i]+4*var[:,:,i+1]-var[:,:,i+2])
317 for i
in range(2,s[2]-2):
318 aprime[:,:,i] = (a[:,:,i-2]-8*a[:,:,i-1]+8*a[:,:,i+1]-a[:,:,i+2])/(var[:,:,i-2]-8*var[:,:,i-1]+8*var[:,:,i+1]-var[:,:,i+2])
321 for i
in range(s[2]-2,s[2]):
322 aprime[:,:,i] = (a[:,:,i-2]-4*a[:,:,i-1]+3*a[:,:,i]) / (var[:,:,i-2]-4*var[:,:,i-1]+3*var[:,:,i])
330 aprime[:,i,:] = (-3*a[:,i,:]+4*a[:,i+1,:]-a[:,i+2,:]) / (-3*var[:,i,:]+4*var[:,i+1,:]-var[:,i+2,:])
333 for i
in range(2,s[1]-2):
334 aprime[:,i,:] = (a[:,i-2,:]-8*a[:,i-1,:]+8*a[:,i+1,:]-a[:,i+2,:])/ (var[:,i-2,:]-8*var[:,i-1,:]+8*var[:,i+1,:]-var[:,i+2,:])
337 for i
in range(s[1]-2,s[1]):
338 aprime[:,i,:] = (a[:,i-2,:]-4*a[:,i-1,:]+3*a[:,i,:]) / (var[:,i-2,:]-4*var[:,i-1,:]+3*var[:,i,:])
346 aprime[i,:,:] = (-3*a[i,:,:]+4*a[i+1,:,:]-a[i+2,:,:]) / (-3*var[i,:,:]+4*var[i+1,:,:]-var[i+2,:,:])
349 for i
in range(2,s[0]-2):
350 aprime[i,:,:] = (a[i-2,:,:]-8*a[i-1,:,:]+8*a[i+1,:,:]-a[i+2,:,:])/ (var[i-2,:,:]-8*var[i-1,:,:]+8*var[i+1,:,:]-var[i+2,:,:])
353 for i
in range(s[0]-2,s[0]):
354 aprime[i,:,:] = (a[i-2,:,:]-4*a[i-1,:,:]+3*a[i,:,:]) / (var[i-2,:,:]-4*var[i-1,:,:]+3*var[i,:,:])
360 ''' Function that calculates first-order derivatives of a variable 361 with respect to another variable 'var' 362 using sixth order finite differences in regular Cartesian grids. 363 The variable var should be increasing or decreasing in the 364 specified coordinate. 365 Calling sequence: aprime = deriv_var_findiff(a,var,dir,order) 366 a and var are 3-dimensional float32 numpy arrays 367 dir is 1, 2, or 3 (for X, Y, or Z directions in user coords. 368 order is the accuracy order, one of (2,4 or 6) 369 Note that these correspond to Z,Y,X directions in python coords. 371 Returned array 'aprime' is the derivative of a wrt var. ''' 382 aprime = numpy.array(a)
389 return numpy.zeros_like(a)
397 aprime[:,:,i] = (-11*a[:,:,i]+18*a[:,:,i+1]-9*a[:,:,i+2]+2*a[:,:,i+3]) / (-11*var[:,:,i]+18*var[:,:,i+1]-9*var[:,:,i+2]+2*var[:,:,i+3])
400 for i
in range(3,s[2]-3):
401 aprime[:,:,i] = (-a[:,:,i-3]+9*a[:,:,i-2]-45*a[:,:,i-1]+45*a[:,:,i+1] -9*a[:,:,i+2]+a[:,:,i+3])/(-var[:,:,i-3]+9*var[:,:,i-2]-45*var[:,:,i-1]+45*var[:,:,i+1] -9*var[:,:,i+2]+var[:,:,i+3])
404 for i
in range(s[2]-3,s[2]):
405 aprime[:,:,i] = (-2*a[:,:,i-3]+9*a[:,:,i-2]-18*a[:,:,i-1]+11*a[:,:,i]) /(-2*var[:,:,i-3]+9*var[:,:,i-2]-18*var[:,:,i-1]+11*var[:,:,i])
412 return numpy.zeros_like(a)
419 aprime[:,i,:] = (-11*a[:,i,:]+18*a[:,i+1,:]-9*a[:,i+2,:]+2*a[:,i+3,:]) /(-11*var[:,i,:]+18*var[:,i+1,:]-9*var[:,i+2,:]+2*var[:,i+3,:])
421 for i
in range(3,s[1]-3):
422 aprime[:,i,:] = (-a[:,i-3,:]+9*a[:,i-2,:]-45*a[:,i-1,:]+45*a[:,i+1,:] -9*a[:,i+2,:]+a[:,i+3,:])/(-var[:,i-3,:]+9*var[:,i-2,:]-45*var[:,i-1,:]+45*var[:,i+1,:] -9*var[:,i+2,:]+var[:,i+3,:])
424 for i
in range(s[1]-3,s[1]):
425 aprime[:,i,:] = (-2*a[:,i-3,:]+9*a[:,i-2,:]-18*a[:,i-1,:]+11*a[:,i,:]) /(-2*var[:,i-3,:]+9*var[:,i-2,:]-18*var[:,i-1,:]+11*var[:,i,:])
432 return numpy.zeros_like(a)
439 aprime[i,:,:] = (-11*a[i,:,:]+18*a[i+1,:,:]-9*a[i+2,:,:]+2*a[i+3,:,:]) /(-11*var[i,:,:]+18*var[i+1,:,:]-9*var[i+2,:,:]+2*var[i+3,:,:])
441 for i
in range(3,s[0]-3):
442 aprime[i,:,:] = (-a[i-3,:,:]+9*a[i-2,:,:]-45*a[i-1,:,:]+45*a[i+1,:,:] -9*a[i+2,:,:]+a[i+3,:,:])/(-var[i-3,:,:]+9*var[i-2,:,:]-45*var[i-1,:,:]+45*var[i+1,:,:] -9*var[i+2,:,:]+var[i+3,:,:])
444 for i
in range(s[0]-3,s[0]):
445 aprime[i,:,:] = (-2*a[i-3,:,:]+9*a[i-2,:,:]-18*a[i-1,:,:]+11*a[i,:,:]) /(-2*var[i-3,:,:]+9*var[i-2,:,:]-18*var[i-1,:,:]+11*var[i,:,:])
450 ''' Operator that calculates the curl of a vector field 451 using 6th order finite differences, on a regular Cartesian grid. 452 Calling sequence: curlfield = curl_findiff(A,B,C,order) 454 A,B,C are three 3-dimensional float32 arrays that define a 456 order is the accuracy order (6,4, or 2) 457 curlfield is a 3-tuple of 3-dimensional float32 arrays that is 458 returned by this operator.''' 460 ext = (vapor.BOUNDS[3]-vapor.BOUNDS[0], vapor.BOUNDS[4]-vapor.BOUNDS[1],vapor.BOUNDS[5]-vapor.BOUNDS[2])
461 usrmax =
vapor.MapVoxToUser([vapor.BOUNDS[3],vapor.BOUNDS[4],vapor.BOUNDS[5]],vapor.REFINEMENT,vapor.LOD)
462 usrmin =
vapor.MapVoxToUser([vapor.BOUNDS[0],vapor.BOUNDS[1],vapor.BOUNDS[2]],vapor.REFINEMENT,vapor.LOD)
463 dx = (usrmax[2]-usrmin[2])/ext[2]
464 dy = (usrmax[1]-usrmin[1])/ext[1]
465 dz = (usrmax[0]-usrmin[0])/ext[0]
479 return outx, outy, outz
484 ''' Operator that calculates the divergence of a vector field 485 using 6th order finite differences. 486 Calling sequence: DIV = div_findiff(A,B,C) 488 A, B, and C are 3-dimensional float32 arrays defining a vector field. 489 order is the accuracy order, one of (6,4, or 2) 490 Resulting DIV is a 3-dimensional float3d array consisting of 491 the divergence of the triple (A,B,C).''' 493 ext = (vapor.BOUNDS[3]-vapor.BOUNDS[0], vapor.BOUNDS[4]-vapor.BOUNDS[1],vapor.BOUNDS[5]-vapor.BOUNDS[2])
494 usrmax =
vapor.MapVoxToUser([vapor.BOUNDS[3],vapor.BOUNDS[4],vapor.BOUNDS[5]],vapor.REFINEMENT,vapor.LOD)
495 usrmin =
vapor.MapVoxToUser([vapor.BOUNDS[0],vapor.BOUNDS[1],vapor.BOUNDS[2]],vapor.REFINEMENT,vapor.LOD)
496 dx = (usrmax[2]-usrmin[2])/ext[2]
497 dy = (usrmax[1]-usrmin[1])/ext[1]
498 dz = (usrmax[0]-usrmin[0])/ext[0]
504 ''' Operator that calculates the gradient of a scalar field 505 using 6th order finite differences. 506 Calling sequence: GRD = grad_findiff(A) 508 A is a float32 array defining a scalar field. 509 order is the accuracy order, one of (6,4,or 2) 510 Result GRD is a triple of 3 3-dimensional float3d arrays consisting of 511 the gradient of A.''' 513 ext = (vapor.BOUNDS[3]-vapor.BOUNDS[0], vapor.BOUNDS[4]-vapor.BOUNDS[1],vapor.BOUNDS[5]-vapor.BOUNDS[2])
514 usrmax =
vapor.MapVoxToUser([vapor.BOUNDS[3],vapor.BOUNDS[4],vapor.BOUNDS[5]],vapor.REFINEMENT,vapor.LOD)
515 usrmin =
vapor.MapVoxToUser([vapor.BOUNDS[0],vapor.BOUNDS[1],vapor.BOUNDS[2]],vapor.REFINEMENT,vapor.LOD)
516 dx = (usrmax[2]-usrmin[2])/ext[2]
517 dy = (usrmax[1]-usrmin[1])/ext[1]
518 dz = (usrmax[0]-usrmin[0])/ext[0]
524 return aux1,aux2,aux3
536 interpVal = numpy.empty(ss,numpy.float32)
537 ratio = numpy.zeros(ss,numpy.float32)
540 LEVEL = numpy.empty(ss,numpy.int32)
542 for K
in range(s[0]):
544 LEVNEED = numpy.logical_and(numpy.less(LEVEL,0), numpy.less(PR[K,:,:] , val))
546 ratio[LEVNEED] = (val-PR[K,LEVNEED])/(PR[K-1,LEVNEED]-PR[K,LEVNEED])
547 interpVal[LEVNEED] = ratio[LEVNEED]*A[K,LEVNEED]+(1-ratio[LEVNEED])*A[K-1,LEVNEED]
548 LEVNEED = numpy.greater(LEVEL,0)
550 LEVNEED = numpy.less(LEVEL,0)
551 interpVal[LEVNEED] = A[s[0]-1,LEVNEED]
555 '''Rotate and scale vectors u,v for integration on 558 rotfield=vector_rotate(angleRad, latDeg, u,v) 560 angleRad: 2D var, rotation from East in radians 561 latDeg: 2D var, latitude in degrees 562 u,v: 3D vars, x,y components of a vector field 563 rotfield is a 2-tuple of 3-dimensional float32 arrays, 564 representing rotation of u,v, returned by this operator. 568 umod = numpy.cos(angleRad)*u + numpy.sin(angleRad)*v
569 vmod = -numpy.sin(angleRad)*u + numpy.cos(angleRad)*v
570 umod = umod/numpy.cos(latDeg*math.pi/180.)
def MapVoxToUser(voxcoord, refinementLevel, lod)
def vector_rotate(angleRad, latDeg, u, v)
def deriv_findiff4(a, dir, dx)
def deriv_var_findiff2(a, var, dir)
def deriv_findiff2(a, dir, dx)
def deriv_var_findiff(a, var, dir, order=6)
def grad_findiff(A, order=6)
def curl_findiff(A, B, C, order=6)
def deriv_findiff(a, dir, dx, order=6)
def deriv_var_findiff4(a, var, dir)
def div_findiff(A, B, C, order=6)