Пример #1
0
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
Пример #2
0
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)
Пример #3
0
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()
Пример #4
0
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
Пример #5
0
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()
Пример #6
0
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()
Пример #7
0
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