Calcolare valori della griglia centrata quando si utilizzano dati su una griglia sfalsata

voti
1

Sto lavorando con MITgcm per fare alcune simulazioni, specificamente per lavorare con i modelli di onde interne; Ho .nc file con i miei risultati, ma alcune variabili non sono esattamente le stesse coordinate. Mi spiego: voglio lavorare i componenti della velocità, ma, per alcuni motivi numerici che non capiscono fino in fondo, le coordinate di velocità orizzontali sono nella parte sinistra delle cellule e le coordinate verticali sul lato bot delle cellule . Per operare con dati di velocità devo unificare il riferimento di tutte le coordinate.

Ho pensato di fare qualcosa di simile

 u (i,j,k) = u(i,j,k) + u(i+1,j,k)
 v (i,j,k) = v(i,j,k) + v(i,j+1,k)

Così avrò le mie coordinate tutti nel centro delle cellule e lo stesso riferimento.

Non so come farlo, usando python, modifica di un file NetCDF. Potrei essere felice solo l'estrazione di tutti i u e v dei dati, la modifica come ho detto e la creazione di un nuovo file NetCDF con solo questi due variabili.

È possibile? Come lo posso fare?

Edit: Aggiunte informazioni ncdump

   netcdf state.global {
dimensions:
    T = UNLIMITED ; // (10001 currently)
    Xp1 = 61 ;
    Y = 1 ;
    Z = 20 ;
    X = 60 ;
    Yp1 = 2 ;
    Zl = 20 ;
variables:
    double Xp1(Xp1) ;
        Xp1:long_name = X-Coordinate of cell corner ;
        Xp1:units = meters ;
    double Y(Y) ;
        Y:long_name = Y-Coordinate of cell center ;
        Y:units = meters ;
    double Z(Z) ;
        Z:long_name = vertical coordinate of cell center ;
        Z:units = meters ;
        Z:positive = up ;
    double X(X) ;
        X:long_name = X-coordinate of cell center ;
        X:units = meters ;
    double Yp1(Yp1) ;
        Yp1:long_name = Y-Coordinate of cell corner ;
        Yp1:units = meters ;
    double Zl(Zl) ;
        Zl:long_name = vertical coordinate of upper cell interface ;
        Zl:units = meters ;
        Zl:positive = up ;
    double T(T) ;
        T:long_name = model_time ;
        T:units = s ;
    int iter(T) ;
        iter:long_name = iteration_count ;
    double U(T, Z, Y, Xp1) ;
        U:units = m/s ;
        U:coordinates = XU YU RC iter ;
    double V(T, Z, Yp1, X) ;
        V:units = m/s ;
        V:coordinates = XV YV RC iter ;
    double Temp(T, Z, Y, X) ;
        Temp:units = degC ;
        Temp:long_name = potential_temperature ;
        Temp:coordinates = XC YC RC iter ;
    double S(T, Z, Y, X) ;
        S:long_name = salinity ;
        S:coordinates = XC YC RC iter ;
    double Eta(T, Y, X) ;
        Eta:long_name = free-surface_r-anomaly ;
        Eta:units = m ;
        Eta:coordinates = XC YC iter ;
    double W(T, Zl, Y, X) ;
        W:units = m/s ;
        W:coordinates = XC YC RC iter ;

// global attributes:
        :MITgcm_version = **************** ;
        :build_user = ************ ;
        :build_host = ************** ;
        :build_date = ******************* ;
        :MITgcm_URL = *************** ;
        :MITgcm_tag_id = ******************* ;
        :MITgcm_mnc_ver = 0.9 ;
        :sNx = 30 ;
        :sNy = 1 ;
        :OLx = 2 ;
        :OLy = 2 ;
        :nSx = 2 ;
        :nSy = 1 ;
        :nPx = 1 ;
        :nPy = 1 ;
        :Nx = 60 ;
        :Ny = 1 ;
        :Nr = 20 ;
}
È pubblicato 02/06/2016 alle 08:32
dall'utente
In altre lingue...                            


2 risposte

voti
2

Quel modello sta usando una griglia sfalsata dove u-velocità è risolto a ovest / est griglia di volti, mentre v-velocità è risolto sul nord / sud volti.

Hai ragione che ora è necessario post-processo i componenti in modo che U e V sono ogni posto al centro di ogni cella della griglia.

Definiamo nxessere il numero di celle della griglia nella x-dimensione (cioè dove l'u-componente è risolta) e nysia il numero di celle della griglia nella dimensione y (cioè dove la v-componente è risolta). nzè il numero di livelli del modello verticali.

Poi uha dimensioni nx+1x nyx nzed vha dimensioni nxx ny+1x nz. Si tratta di una media semplice quindi per ottenere ue vnei centri di ciascuna cella:

u_center = 0.5 * (u[0:nx,:,:] + u[1:nx+1,:,:]) # now has dimensions [nx,ny,nz])

v_center = 0.5 * (v[:,0:ny,:] + v[:,1:ny+1,:]) # now has dimensions [nx,ny,nz])

import netCDF4
import numpy as np

ncfile = netCDF4.Dataset('/path/to/file/foo.nc', 'r')
u = ncfile.variables['u'][:,:,:] # nx+1 x ny x nz 
v = ncfile.variables['v'][:,:,:] # nx x ny+1 x nz 

nx = np.shape(u)[0] - 1 
ny = np.shape(v)[1] - 1 
nz = np.shape(u)[2] 

u_center = 0.5 * (u[0:nx,:,:] + u[1:nx+1,:,:]) 
v_center = 0.5 * (v[:,0:ny,:] + v[:,1:ny+1,:])

# Write out u_center and v_center into a new netCDF file
ncfile_out = netCDF4.Dataset('./output.nc', 'w')
ncfile_out.createDimension('longitude', nx)
ncfile_out.createDimension('latitude', ny)
ncfile_out.createDimension('level', nz)
u_out = ncfile_out.createVariable('u_center', 'f4', ('longitude', 'latitude', 'level')
v_out = ncfile_out.createVariable('v_center', 'f4', ('longitude', 'latitude', 'level')
u_out[:,:,:] = u_center[:,:,:]
v_out[:,:,:] = v_center[:,:,:]
ncfile_out.close()
Risposto il 02/06/2016 a 13:58
fonte dall'utente

voti
0

Che ne dite di fare questo dalla riga di comando con CDO utilizzando una media di 2 punti utilizzando la funzione di spostamento in combinazione con la funzione di media insieme?

cdo selvar,U mitfile.nc u.nc  # select the velocity fields
cdo selvar.v mitfile.nc v.nc 

# shift to the right/up and average both memberss
cdo ensmean -shiftx,1 u.nc u.nc ucen.nc 
cdo ensmean -shifty,1 v.nc v.nc vcen.nc 

# cat the files and calculate the wind:
cdo cat ucen.nc vcen.nc uv.nc
cdo expr,"wind=sqrt(U*U+V*V)" uv.nc wind.nc

ps: se i vostri campi sono globali, quindi si vuole fare un ciclico spostamento nella direzione longitudine utilizzando:

cdo ensmean -shiftx,1,cyclic u.nc u.nc ucen.nc 
Risposto il 18/10/2017 a 07:28
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more