def calc_thetaOnEPV_column(data,time,hCell,nLevels): #Ertel PV is (wLocal+wEarth).grad(tracer)/rho #local and absolute vorticity vort = calc_lstsq_vort_column(data, time, hCell, nLevels) #vort[l,dirs] for l in xrange(nLevels): vort[l,2] += 2.*omeg_e #absolute with earth #gradient of tracer theta_xyz = calc_lstsqDeriv_column(data, time, hCell, 'theta', nLevels) #coeffs[l,dirs] #form epv rho = data.variables['rho'][time,hCell,:] epv = np.empty(nLevels) for l in xrange(nLevels): epv[l] = np.dot(vort[l,:],theta_xyz[l,:])/rho[l] #looks like sign depends on hemisphere, but actually going by north/south is baffling about the equator epv = abs(epv*1e6) ''' #going by hemisphere is tricky since I'm not sure what to assign and sign(0)=0 sgn = np.sign(data.variables['zCell'][hCell]) if (sgn==0.0):#python treats 0==0.0 as True as well sgn=1 #I'm not really sure what to do at equator!!! epv *= sgn*1e6 ''' (l,dl) = output_data.calcIndexOfValue(2.0,epv, nLevels) #index on 2PVU surface #print "For hcell {0}, dynamic tropopause at verticalIndex {1},{2}\n".format(hCell,l,dl) theta = data.variables['theta'][time,hCell,:] val = output_data.calcValueOfIndex(l,dl,theta) return val
def findOwner_coord(r, data, vLevels): #find the horizontal owner and then the owner in that column. #return (horizIndex, vertLevel) hCell = findOwner_horizNbrs(r, data, 0); #initial guess of cell 0 could be better? zInterface = data.variables['zgrid'][:] (l,dl) = output_data.calcIndexOfValue(r[2],zInterface[hCell,:], vLevels+1) #this might be buggy outside top and bottom boundaries return(hCell,l)
def derivedSfcs(ncfname, vtkfname): #write some derived surfaces to file data = output_data.open_netcdf_data(ncfname) #header info fvtk = output_data.write_vtk_header_polydata(vtkfname, ncfname) nNodes = output_data.write_vtk_xyzNodes(fvtk, data) nCells = output_data.write_vtk_polygons(fvtk, data) nLevels = len(data.dimensions['nVertLevels']) #cell data fvtk.write('\nCELL_DATA '+str(nCells)+'\n') #geo for reference output_data.write_vtk_staticGeoFields(f,data,nCells) time = 0 #500 mb output_data.write_vtk_pressureHeights(fvtk, data, nCells, time, vLevels, 50000.) #theta on dynamic tropopause pv = np.empty((nCells,nLevels), dtype=float) for hcell in range(nCells): for l in range(nLevels): pv[hcell,l] = vars.calc_ertelPV(data, 'theta', time, hcell, l, nLevels) # pvuVal = 2. thetaVal = np.empty(nCells) for hcell in range(nCells): (l,dl) = output_data.calcIndexOfValue(pvuVal,pv[hcell,:], nLevels) thetaVal[hcell] = output_data.calcValueOfIndex(l,dl,data.variables['theta'][time,hcell,:]) output_data.write_levelData_float('theta_pv', fvtk, thetaVal, nCells) #slp slp = np.empty(nCells) for hcell in range(nCells): slp[hcell] = vars.calc_slp(data, hcell, nLevels, time) output_data.write_levelData_float('slp', fvtk, slp, nCells) #close da files fvtk.close() data.close()
def compare_mpas_pHgts(): f = '/arctic1/nick/cases/vduda/x4/x4.t.output.2006-08-01_00.00.00.nc' data = netCDF4.Dataset(f,'r') nLevels = len(data.dimensions['nVertLevels']) nCells = len(data.dimensions['nCells']) iTime = 0 hgt_mpas = data.variables['height_500hPa'][iTime,:] zgrid = data.variables['zgrid'][:] zMid = .5*(zgrid[:,0:-1]+zgrid[:,1:]) p = data.variables['pressure_p'][iTime,:,:]+data.variables['pressure_base'][iTime,:,:] hgt_calc = np.empty(nCells,dtype=float) pLev = 50000. for iCell in xrange(nCells): (l,dl) = output_data.calcIndexOfValue(pLev, p[iCell,:], nLevels) z = output_data.calcValueOfIndex(l,dl,zMid[iCell,:]) hgt_calc[iCell] = z diff = hgt_calc-hgt_mpas return diff
def calc_height_theta_2PVU(data, t0): # vertical height of sign(lat)*2PVU surface. # return height of cell center in column using interpolation from top pvuTrop = 2.0 nCells = len(data.dimensions["nCells"]) nLevels = len(data.dimensions["nVertLevels"]) epv = data.variables["ertel_pv"][t0, :, :] latCell = data.variables["latCell"][:] zgrid = data.variables["zgrid"][:, :] theta = data.variables["theta"][t0, :, :] # hColumn = np.empty(nLevels,dtype='float') epv_ht = np.empty(nCells, dtype="float") theta_trop = np.empty(nCells, dtype="float") for i in xrange(nCells): # calc ht of cell centers # for k in xrange(nLevels): # hColumn[k] = .5*(zgrid[i,k]+zgrid[i,k+1]) hColumn = 0.5 * (zgrid[i, 0:nLevels] + zgrid[i, 1 : nLevels + 1]) pvuVal = pvuTrop if latCell[i] < 0: pvuVal = -pvuTrop # don't really trust top and bottom levels so don't count those for interpolation # interpLevs = range(0,nLevels); nInterpLevs = len(interpLevs) interpLevs = range(1, nLevels - 1) nInterpLevs = len(interpLevs) (l, dl) = output_data.calcIndexOfValue(pvuVal, epv[i, interpLevs], nInterpLevs) # (l,dl) = output_data.calcIndexOfValue_fromBottom(pvuVal,epv[i,interpLevs], nInterpLevs) # (l,dl) = output_data.calcIndexOfValue(pvuTrop,np.abs(epv[i,interpLevs]), nInterpLevs) # print "Cell {0} has l,dl = {1},{2}".format(i, l, dl) epv_ht[i] = output_data.calcValueOfIndex(l, dl, hColumn[interpLevs]) theta_trop[i] = output_data.calcValueOfIndex(l, dl, theta[i, interpLevs]) return (epv_ht, theta_trop)
def driver_arctic(): #plot epv on a polar cap ncfname = '/arctic1/nick/cases/163842/testDuda/x1.163842.output.2006-07-15_00.00.00.nc' #ncfname = '/arctic1/mduda/60km/x1.163842.output.2006-07-08_00.00.00.nc' #ncfname = '/home/nickszap/research/mpas/output.2010-10-23_00:00:00.nc' data = netCDF4.Dataset(ncfname,'r') nCellsTotal = len(data.dimensions['nCells']) nVerticesTotal = len(data.dimensions['nVertices']); nLevels = len(data.dimensions['nVertLevels']) nEdgesOnCell = data.variables['nEdgesOnCell'][:]; cellsOnCell = data.variables['cellsOnCell'][:]-1; latThresh = 45.*np.pi/180. #latThresh = 70.*np.pi/180. latCell = data.variables['latCell'][:] cells = conn.gatherArcticCells(latCell, nCellsTotal, latThresh) nCells = len(cells) #open the output vtk file and write header. vtkfname = 'test.arctic.pv_approx.vtk' fvtk = output_data.write_vtk_header_polydata(vtkfname, ncfname) #write nodes and cells output_data.write_vtk_polyHorizConn_domain(data, fvtk, cells, nEdgesOnCell,nVerticesTotal) #cell values and connectivity for this domain haloCells = conn.get_arcticHalo(cells, latCell, latThresh, cellsOnCell, nEdgesOnCell) g2lCell = conn.make_global2localMap(cells, haloCells, nCellsTotal) c2c = conn.make_localDomainNbrs(nCells, cellsOnCell[cells,:], nEdgesOnCell[cells], g2lCell) neededCells = cells.tolist(); neededCells.extend(haloCells) #has to be domain then halo (as in g2l map) #I'm having memory errors. #gc.collect() #load data for domain and halo ----------------------------- timeInd = 0 print "Loading data for domain {0} with {1} cells\n".format('arctic', len(neededCells)) #print neededCells state = loadFields(data, timeInd, neededCells, nLevels) #compute derived variables ------------------------------- #theta on dynamic tropopause pv = np.empty((nCells,nLevels), dtype=float) #make_localDomainNbrs(nCells, cellsOnCell_local, nEdgesOnCell_local, g2lMap) for hCell in xrange(nCells): hNbrs = c2c[hCell,0:nEdgesOnCell[cells[hCell]]] pvColumn = driverErtel(state, hCell, hNbrs, nLevels) #pvColumn = driverErtel_column(state, hCell, hNbrs, nLevels) for l in range(nLevels): pv[hCell,l] = pvColumn[l] # pvuVal = 2.; #pv = np.abs(pv) #don't need questionable hack for southern hemisphere thetaVal = np.empty(nCells) for hCell in xrange(nCells): (l,dl) = output_data.calcIndexOfValue(pvuVal,pv[hCell,:], nLevels) thetaVal[hCell] = output_data.calcValueOfIndex(l,dl,state.theta[hCell,:]) #write some cell data ---------------- fvtk.write('\nCELL_DATA '+str(nCells)+'\n') output_data.write_levelData_float('theta_2pvu', fvtk, thetaVal, nCells) fvtk.close() data.close()
def driver_domains(nSeeds): # ncfname = '/arctic1/mduda/60km/x1.163842.output.2006-07-09_12.00.00.nc' #ncfname = '/home/nickszap/research/mpas/output.2010-10-23_00:00:00.nc' data = netCDF4.Dataset(ncfname,'r') nCellsTotal = len(data.dimensions['nCells']) nVerticesTotal = len(data.dimensions['nVertices']); nLevels = len(data.dimensions['nVertLevels']) nEdgesOnCell = data.variables['nEdgesOnCell'][:]; cellsOnCell = data.variables['cellsOnCell'][:]-1; seed0 = 0 #seed0 = np.argmax(data.variables['meshDensity'][:]) #seems like a decent heuristic cell2Site,seeds = conn.partition_max(seed0, cellsOnCell, nEdgesOnCell,nCellsTotal, nSeeds) for domainInd in xrange(nSeeds): #output domain mesh ------------------------ cells = np.array(xrange(nCellsTotal))[cell2Site==seeds[domainInd]] nCells = len(cells) #open the output vtk file and write header. vtkfname = 'test'+str(domainInd)+'.vtk' fvtk = output_data.write_vtk_header_polydata(vtkfname, ncfname) #write nodes and cells output_data.write_vtk_polyHorizConn_domain(data, fvtk, cells, nEdgesOnCell,nVerticesTotal) #cell values and connectivity for this domain haloCells = conn.getHalo(seeds[domainInd], cell2Site, cellsOnCell, nEdgesOnCell, nCellsTotal) g2lCell = conn.make_global2localMap(cells, haloCells, nCellsTotal) c2c = conn.make_localDomainNbrs(nCells, cellsOnCell[cells,:], nEdgesOnCell[cells], g2lCell) neededCells = cells.tolist(); neededCells.extend(haloCells) #has to be domain then halo (as in g2l map) #I'm having memory errors. #gc.collect() #load data for domain and halo ----------------------------- timeInd = 0 print "Loading data for domain {0} with {1} cells\n".format(domainInd, len(neededCells)) #print neededCells state = loadFields(data, timeInd, neededCells, nLevels) #compute derived variables ------------------------------- #theta on dynamic tropopause pv = np.empty((nCells,nLevels), dtype=float) #make_localDomainNbrs(nCells, cellsOnCell_local, nEdgesOnCell_local, g2lMap) for hCell in xrange(nCells): hNbrs = c2c[hCell,0:nEdgesOnCell[cells[hCell]]] pvColumn = driverErtel(state, hCell, hNbrs, nLevels) for l in range(nLevels): pv[hCell,l] = pvColumn[l] # pvuVal = 2.; pv = np.abs(pv) #questionable hack for southern hemisphere thetaVal = np.empty(nCells) for hCell in range(nCells): (l,dl) = output_data.calcIndexOfValue(pvuVal,pv[hCell,:], nLevels) thetaVal[hCell] = output_data.calcValueOfIndex(l,dl,state.theta[hCell,:]) #write some cell data ---------------- fvtk.write('\nCELL_DATA '+str(nCells)+'\n') output_data.write_levelData_float('theta_2pvu', fvtk, thetaVal, nCells) fvtk.close() data.close()
def calc_slp(data, hcell, nLevels, time): #wrapper for calculating sea level (h=0m) pressure. #Given (unjustified) assumptions on lapse rate, hydrostatic, #the issue is how to find the pressure at below model levels. This boils down to #what reference level to move down from. #Following that described in slp_ben.m from Ryan Torn, #T is moved from 2km above ground to the ground using the standard lapse rate. #If surface cell is higher than 2km (eg Tibet), use that cell. #Advantage of height is to alleviate diurnal effects (on temperature at surface, right???) print "This might be buggy!!!" refHt = 2000.; #2km #get t and p at sfc theta = data.variables['theta'][time,hcell,:] #p = data.variables['pressure_base'][time,hcell,:]+data.variables['pressure_p'][time,hcell,:] p = calcPressure_column(data,hcell,time,nLevels) t = np.empty(nLevels) for l in range(nLevels): t[l] = calc_temperature(theta[l], p[l]) # hg = .5*(data.variables['zgrid'][hcell,0]+data.variables['zgrid'][hcell,1]) #these values get changed below. #here we're just setting them to my heart's content so they're in the proper scope ph = 70000.; th = 280.; h = refHt; if (hg>refHt): #have to use cell as reference to move to sfc (could NaNs if slp not meaningful) h = hg #ph = p[0] th = t[0] else: #interpolate to height #zgrid is at faces of cells instead of midpts of layers. #need to adjust index into centered arrays since cell_l0=layer_l0+.5 h = refHt (l,dl) = output_data.calcIndexOfValue(refHt,data.variables['zgrid'][hcell,:], nLevels+1) if (dl>=.5): #same level, just shift dl = dl-.5 else: #have to shift into neighbor l = l-1 dl = dl+.5 #account for indices out of bounds. this shouldn't happen w/ height at center. #adjusting accounts for: vals[l+1]-vals[l] in calcValueOfIndex if (l>nLevels-2): #extrapolation up dl = dl+(l-(nLevels-1)) l = nLevels-2; elif (l<0): #extrapolation down dl = dl+(l-0) l=0; #interpolate to height #ph = calcValueOfIndex(l,dl,p) th = output_data.calcValueOfIndex(l,dl,t) # #move temperature to sfc and calc slp tSurf = calc_temperatureFromLapse(th, hg-h) pSurf = p[0] #could also data.variables['surface_pressure'][time,ncells] tRef = calc_temperatureFromLapse(tSurf, -hg/2.) #half way between surface and sea level slp = calc_pressureHypsometric(tRef, pSurf, -hg) return slp