在交错网格上使用数据时计算以网格为中心的值

时间:2016-06-02 09:32:08

标签: python netcdf

我正在与MITgcm合作进行一些模拟,特别是与内部波浪模型一起工作;我的结果得到了.nc文件,但有些变量的坐标不完全相同。我将解释自己:我想弄清楚速度的组成部分,但由于一些我不完全理解的数值原因,水平速度坐标位于单元格的左侧,而垂直坐标位于机器人的垂直坐标上细胞的一面。要使用速度数据进行操作,我需要统一所有坐标的参考。

我想过做这样的事情

 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)

所以我的坐标全部位于细胞的中心并且位于相同的参考中。

我不知道怎么做,使用python,编辑NetCDF文件。我很乐意提取所有 u v 数据,像我说的那样进行编辑,只用这两个变量创建一个新的NetCDF文件。

这可能吗?我怎样才能做到这一点?

编辑:添加了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 ;
}

2 个答案:

答案 0 :(得分:2)

该模型使用staggered grid,其中u-velocity在西/东网格面上求解,而v-velocity在北/南面求解。

您说得对,现在您需要对组件进行后处理,以便将u-和v-分别放置在每个网格单元的中心。

让我们将nx定义为x维度中的网格单元格数(即u元素在其中求解的位置),并将ny定义为y-中网格单元格的数量维度(即解决v分量的位置)。 nz是垂直模型图层的数量。

然后u维度为nx+1 x ny x nzv维度为nx x ny+1 x {{ 1}}。这是一个简单的平均值,然后将nzu放入每个单元格的中心:

v

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])

答案 1 :(得分:0)

如果使用移位函数结合整体平均函数,使用cdo使用2点平均值从命令行执行此操作?

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:如果您的字段是全局字段,那么您希望使用以下方法在经度方向上执行循环移位:

cdo ensmean -shiftx,1,cyclic u.nc u.nc ucen.nc