pro grad,grid,x,y,z,grad=grad,$
xout=xout,yout=yout,zout=zout,xy=xy,$
dxy=dxy,leftright=leftright,regrid=regrid
compile_opt idl2
if ~keyword_set(grid) then begin
dprint,'grid must be set. Returning.'
return
endif
dim = dimen(grid)
if ~keyword_set(x) then begin
xc = dindgen(dim[0])
endif else begin
xc = x
endelse
if ~keyword_set(y) then begin
yc = dindgen(dim[1])
endif else begin
yc = y
endelse
if n_elements(xc) ne dim[0] then begin
dprint,'number of elements in xc must equal the number of elements in the 1st dimension of grid'
return
endif
if n_elements(yc) ne dim[1] then begin
dprint,'number of elements in yc must equal the number of elements in the 2nd dimension of grid'
return
endif
if n_elements(dim) eq 3 then begin
if ~keyword_set(z) then begin
zc = dindgen(dim[2])
endif else begin
zc = z
endelse
if n_elements(zc) ne dim[2] then begin
dprint,'number of elements in zc must equal the number of elements in the 3rd dimension of grid'
return
endif
endif
if keyword_set(leftright) then begin
xdiv = rebin(shift(xc,-1)-shift(xc,1),dim)
if n_elements(dim) eq 2 then begin
ydiv = transpose(rebin(shift(yc,-1)-shift(yc,1),dim[1],dim[0]))
gradx = (shift(grid,-1,0) - shift(grid,1,0))/xdiv
gradx[0,*] = (grid[1,*] - grid[0,*])/(xc[1]-xc[0])
gradx[dim[0]-1,*] = (grid[dim[0]-1,*] - grid[dim[0]-2,*])/(xc[dim[0]-1]-xc[dim[0]-2])
grady = (shift(grid,0,-1) - shift(grid,0,1))/ydiv
grady[*,0] = (grid[*,1] - grid[*,0])/(yc[1]-yc[0])
grady[*,dim[1]-1] = (grid[*,dim[1]-1] - grid[*,dim[1]-2])/(yc[dim[1]-1]-yc[dim[1]-2])
endif else if n_elements(dim) eq 3 then begin
ydiv = transpose(rebin(shift(yc,-1)-shift(yc,1),dim[1],dim[0],dim[2]),[1,0,2])
zdiv = transpose(rebin(shift(zc,-1)-shift(zc,1),dim[2],dim[1],dim[0]),[2,1,0])
gradx = (shift(grid,-1,0,0) - shift(grid,1,0,0))/xdiv
gradx[0,*,*] = (grid[1,*,*] - grid[0,*,*])/(xc[1]-xc[0])
gradx[dim[0]-1,*,*] = (grid[dim[0]-1,*,*] - grid[dim[0]-2,*,*])/(xc[dim[0]-1]-xc[dim[0]-2])
grady = (shift(grid,0,-1,0) - shift(grid,0,1,0))/ydiv
grady[*,0,*] = (grid[*,1,*] - grid[*,0,*])/(yc[1]-yc[0])
grady[*,dim[1]-1,*] = (grid[*,dim[1]-1,*] - grid[*,dim[1]-2,*])/(yc[dim[1]-1]-yc[dim[1]-2])
gradz = (shift(grid,0,0,-1) - shift(grid,0,0,1))/zdiv
gradz[*,*,0] = (grid[*,*,1] - grid[*,*,0])/(zc[1]-zc[0])
gradz[*,*,dim[2]-1] = (grid[*,*,dim[2]-1] - grid[*,*,dim[2]-2])/(zc[dim[2]-1]-zc[dim[2]-2])
endif else begin
dprint,'Wrong number of dimensions in grid'
return
endelse
xoff = 0
yoff = 0
zoff = 0
endif else begin
dim-= 1
xoff = shift(xc - shift(xc,1),-1) / 2.
yoff = shift(yc - shift(yc,1),-1) / 2.
dx = rebin(xc[1:dim[0]]-xc[0:dim[0]-1],dim)
if n_elements(dim) eq 2 then begin
dy = transpose(rebin(yc[1:dim[1]]-yc[0:dim[1]-1],dim[1],dim[0]))
gradx = ((grid[1:dim[0],0:dim[1]-1]+grid[1:dim[0],1:dim[1]]) - (grid[0:dim[0]-1,0:dim[1]-1] + grid[0:dim[0]-1,1:dim[1]]))/(2.*dx)
grady = ((grid[0:dim[0]-1,1:dim[1]]+grid[1:dim[0],1:dim[1]]) - (grid[0:dim[0]-1,0:dim[1]-1] + grid[1:dim[0],0:dim[1]-1]))/(2.*dy)
endif else if n_elements(dim) eq 3 then begin
dy = transpose(rebin(yc[1:dim[1]]-yc[0:dim[1]-1],dim[1],dim[0],dim[2]),[1,0,2])
dz = transpose(rebin(zc[1:dim[2]]-zc[0:dim[2]-1],dim[2],dim[1],dim[0]),[2,1,0])
gradx = (grid[1:dim[0],0:dim[1]-1,0:dim[2]-1] - grid[0:dim[0]-1,0:dim[1]-1,0:dim[2]-1]) + $
(grid[1:dim[0],1:dim[1],0:dim[2]-1] - grid[0:dim[0]-1,1:dim[1],0:dim[2]-1]) + $
(grid[1:dim[0],0:dim[1]-1,1:dim[2]] - grid[0:dim[0]-1,0:dim[1]-1,1:dim[2]]) + $
(grid[1:dim[0],1:dim[1],1:dim[2]] - grid[0:dim[0]-1,1:dim[1],1:dim[2]]) / $
(4.*dx)
grady = (grid[0:dim[0]-1,1:dim[1],0:dim[2]-1] - grid[0:dim[0]-1,0:dim[1]-1,0:dim[2]-1]) + $
(grid[1:dim[0],1:dim[1],0:dim[2]-1] - grid[1:dim[0],0:dim[1]-1,0:dim[2]-1]) + $
(grid[0:dim[0]-1,1:dim[1],1:dim[2]] - grid[0:dim[0]-1,0:dim[1]-1,1:dim[2]]) + $
(grid[1:dim[0],1:dim[1],1:dim[2]] - grid[1:dim[0],0:dim[1]-1,1:dim[2]]) / $
(4.*dy)
gradz = (grid[0:dim[0]-1,0:dim[1]-1,1:dim[2]] - grid[0:dim[0]-1,0:dim[1]-1,0:dim[2]-1]) + $
(grid[1:dim[0],0:dim[1]-1,1:dim[2]] - grid[1:dim[0],0:dim[1]-1,0:dim[2]-1]) + $
(grid[0:dim[0]-1,1:dim[1],1:dim[2]] - grid[0:dim[0]-1,1:dim[1],0:dim[2]-1]) + $
(grid[1:dim[0],1:dim[1],1:dim[2]] - grid[1:dim[0],1:dim[1],0:dim[2]-1]) / $
(4.*dz)
zoff = shift(zc - shift(zc,1),-1) / 2.
endif else begin
dprint,'Wrong number of dimensions in grid'
return
endelse
endelse
if n_elements(dim) eq 2 then begin
grad = dindgen([dim,2])
grad[*,*,0] = gradx
grad[*,*,1] = grady
xidx = indgen(dim[0]*dim[1]) mod dim[0]
yidx = indgen(dim[0]*dim[1]) / dim[0]
xout = xc + xoff
yout = yc + yoff
xarr = xout[xidx]
yarr = yout[yidx]
xout = xout[0:dim[0]-1]
yout = yout[0:dim[1]-1]
xy = [[xarr],[yarr]]
dxy = reform(grad,dim[0]*dim[1],2)
endif else begin
grad = dindgen([dim,3])
grad[*,*,*,0] = gradx
grad[*,*,*,1] = grady
grad[*,*,*,2] = gradz
xidx = indgen(dim[0]*dim[1]*dim[2]) mod dim[0]
yidx = (indgen(dim[0]*dim[1]*dim[2]) / dim[0]) mod dim[1]
zidx = (indgen(dim[0]*dim[1]*dim[2]) / dim[0]) / dim[1]
xout = xc + xoff
yout = yc + yoff
zout = zc + zoff
xarr = xout[xidx]
yarr = yout[yidx]
zarr = zout[zidx]
xout = xout[0:dim[0]-1]
yout = yout[0:dim[1]-1]
zout = zout[0:dim[2]-1]
xy = [[xarr],[yarr],[zarr]]
dxy = reform(grad,dim[0]*dim[1]*dim[2],3)
endelse
end