通过 ncview 在 netcdf 文件中显示错误的初始化值

Wrong initialized values showing in netcdf file via ncview

我正在尝试测试简单的 leapfrog 2D 平流方案。我正在做的是将每个时间步的值写入 netCDF4 文件。初始状态设置为正方形的值 5.0。当我打印数组的初始状态时,它看起来不错,但是当它用 netCDF4 编写并查看 ncview 时,它看起来是倾斜的。我不明白为什么会这样。我怀疑它可能与我将每个时间步长值写入 netCDF4 数据的部分有关(在函数 nc_put_vara_double 中传递 p_tf[0][0])。我在 Unidata 网站上的编码示例中使用了函数 nc_put_vara_double

这个问题是否与 p_tf[0][0] 和它的索引有关?为什么这个函数要用[0][0]

下面是代码

#include <netcdf.h>


// netCDF constants
#define err(e) {printf("Error: %s\n", nc_strerror(e)); return(2);}

#define fname "leap2d.nc"

// Variable sizes and dimensions (constants)
#define Nx 10
#define Ny 10
#define Nt 2000
#define ndims 3

int main()
{
int printf ( const char * format, ... );
int    i,j,t;
double u = 5.0,
       v = 0.0,
       C = 0.01;

// p_tf : p at future
// p_tn : p at now
// p_tp : p at past
double q_tf[Ny+2][Nx+2];
double q_tn[Ny+2][Nx+2];
double q_tp[Ny+2][Nx+2];

double (*p_tf)[Nx+2] = q_tf;
double (*p_tn)[Nx+2] = q_tn;
double (*p_tp)[Nx+2] = q_tp;


// netCDF variables
int    ncid, retval, varid, x_dimid, y_dimid, t_dimid;
int    dimids[ndims];
size_t start[ndims], count[ndims];

// netCDF file operation
// Creating netCDF file
if ((retval = nc_create(fname, NC_CLOBBER, &ncid)))
   err(retval);

// Define dimensions
if ((retval = nc_def_dim(ncid, "y", Ny, &y_dimid)))
   err(retval);
if ((retval = nc_def_dim(ncid, "x", Nx, &x_dimid)))
   err(retval);
if ((retval = nc_def_dim(ncid, "t", NC_UNLIMITED, &t_dimid)))
   err(retval);

// Dimension ids
dimids[0] = t_dimid;
dimids[1] = y_dimid;
dimids[2] = x_dimid;


// Variable for writing netCDF data one timestep at a time
count[0] = 1;     // For time dimension : 1 timestep
count[1] = Ny;    // For y              : write everything
count[2] = Nx;    // For x              : write everything

start[1] = 0;     // For y              : don't do anything
start[2] = 0;     // For x              : don't do anything

if ((retval = nc_def_var(ncid, "data", NC_DOUBLE, ndims, dimids, &varid)))
   err(retval);

if ((retval = nc_enddef(ncid)))
   err(retval);



// Array initialization
for(j=3;j<7;j++)
{
   for(i=3;i<7;i++)
   {
      p_tf[j][i] = 5.0;
      p_tn[j][i] = 5.0;
      p_tp[j][i] = 5.0;
   }
}


for(j=0;j<10;j++)
{
   for(i=0;i<10;i++)
   {
      printf("%1.0f   ",p_tf[j][i]);
   }

   printf("\n");

}

start[0] = 0;

if (retval = nc_put_vara_double(ncid, varid, start, count, &p_tf[0][0]))
   err(retval);



// Euler scheme for the first time step
for(j=1;j<Ny+1;j++)
{
   for(i=1;i<Nx+1;i++)
   {
      p_tf[j][i] = p_tn[j][i] - u * C * (p_tn[j][i] - p_tn[j][i-1])
                              - v * C * (p_tn[j][i] - p_tn[j-1][i]);
   
      // Periodic boundary condition for x
      p_tf[0][i]    = p_tf[Ny][i];
      p_tf[Ny+1][i] = p_tf[1][i];
   }

   // Periodic boundary condition for y
   p_tf[j][0]    = p_tf[j][Nx];
   p_tf[j][Nx+1] = p_tf[j][1];
}

p_tp = p_tn;
p_tn = p_tf;


start[0] = 1;

if (retval = nc_put_vara_double(ncid, varid, start, count, &p_tf[0][0]))
   err(retval);


// Leapfrog scheme
for(t=2;t<Nt;t++)
{
   for (j=0;j<Ny+2;j++)
   {
      for(i=0;i<Nx+2;i++)
      {
         p_tf[j][i] = p_tp[j][i] - u * C * (p_tn[j][i+1] - p_tn[j][i-1])
                                 - v * C * (p_tn[j+1][i] - p_tn[j-1][i]);

            
         // Periodic boundary condition for x
         p_tf[0][i]    = p_tf[Ny][i];
         p_tf[Ny+1][i] = p_tf[1][i];
      }

      // Periodic boundary condition for y
      p_tf[j][0]    = p_tf[j][Nx];
      p_tf[j][Nx+1] = p_tf[j][1];
   }

   p_tp = p_tn;
   p_tn = p_tf;

   start[0] = t;
   if ((retval = nc_put_vara_double(ncid, varid, start, count, &p_tf[0][0])))
      err(retval);

}

if ((retval = nc_close(ncid)))
   err(retval);


printf("\nDone\n");


return 0;
}

谢谢。

它可能被移动了,因为你的计数是 Nx*Ny,但你似乎正在传递一个指向大小为 (Nx+2)*(Ny+2) 的内存 space 的指针,而 nc_put_var_double() 没有办法知道 :)