通过 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()
没有办法知道 :)
我正在尝试测试简单的 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()
没有办法知道 :)