首页 > 解决方案 > 使用 malloc() 定义的指针写入 netcdf 3D 数据

问题描述

我一直坚持编写用malloc(). 在 netCDF-C 示例中,多维数组被定义为arr[nz][ny][nx],而不是malloc()。有没有办法以某种方式改变

float *arr = malloc(ny * nx * sizeof(float))

进入

float arr0[ny][nx]?

它在 netcdf 参考上说该函数nc_put_vara_float()接受const float *op变量输入。但似乎我的做法是不允许的,因为我得到

Error: NetCDF: Start+count exceeds dimension bound

错误。

以下是代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netcdf.h>
#include <ctype.h>

int *arange_int(int start, int end, int stride);
float *arange_float(float start, float end, float stride);
float fld_mean(float *in_fld, int in_nx, int in_ny, int x_start, int x_end, int y_start, int y_end);
float *fld_init(float *in_fld, int in_nx, int in_ny, float in_thres, int in_res, char *in_var);
int blobcntr(float *in_fld, int in_nx, int in_ny, int in_i, int in_j, int in_tag);
void prnt_2darr(float *in_fld, int in_nx, int in_ny);

// resolution setting
#define res 288
#define nres 12
#define grd_siz 4000.0

// variable
#define ndim 3
#define var_nm "LWNT"
#define var_thres 250.0
#define x_nm "x"
#define y_nm "y"
#define t_nm "time"


// netcdf error detection
#define err(e) {printf("Error: %s\n", nc_strerror(e)); return 2;}
int main()
{
   // file resolution and output resolution settings
   int nt      = 2400,
       nx      = res,
       ny      = res,
       nres_x  = nx/nres, 
       nres_y  = ny/nres;


   // file directory and names
   char in_dir[50] = "/home/rangke/temp/sa.rce/data",
        out_dir[50] = "/home/rangke/work/sa/output",
        in_file_pfix[50]   =  "2d.pw.lwnt.tb.ze.sa.rce",
        out_file_pfix[50]  =  "cluster",
        in_file_nm[90],
        out_file_nm[90];


   // microphysics and temperatures (in array)
   const char *mic_list[4],
              *tmp_list[8];


   // netcdf operations
   int retval,
       in_ncid, out_ncid,
       in_var_id, out_var_id,
       in_x_id, in_y_id, in_t_id, 
       out_x_id, out_y_id, out_t_id,
       out_x_dimid, out_y_dimid, out_t_dimid,
       dimids[ndim];
   size_t start[ndim] = {0,0,0}, 
          count[ndim] = {1,ny,nx};


   // variable
   float *x_in    = malloc(nx * sizeof(float)), 
         *y_in    = malloc(ny * sizeof(float)), 
         *t_in    = malloc(nt * sizeof(float)), 
         *x_out, 
         *y_out,
         *in_var  = malloc(ny * nx * sizeof(float)),
         *out_var = malloc(nres_y * nres_y * sizeof(float));


   // loop variable
   int i,j,t;


   // blob counter variable
   int size, tag, blbgrp;


   mic_list[0] = "s1";
   mic_list[1] = "m2";
   mic_list[2] = "th";
   mic_list[3] = "p3";


   tmp_list[0] = "285";
   tmp_list[1] = "288";
   tmp_list[2] = "291";
   tmp_list[3] = "294";
   tmp_list[4] = "297";
   tmp_list[5] = "300";
   tmp_list[6] = "303";
   tmp_list[7] = "306";


   for(j=0;j<1;j++)
      for(i=0;i<1;i++)
      {
         snprintf(in_file_nm, sizeof(in_file_nm), "%s/%dx%d/%s.%dx%d.%s.%sk.old.nc", 
                  in_dir, res, res, in_file_pfix, res, res, mic_list[j], tmp_list[i]);
         printf("%s\n",in_file_nm);

         snprintf(out_file_nm, sizeof(out_file_nm), "%s/%s.%s.%s.%sk.%dx%dto%dx%d.nc", 
                  out_dir, out_file_pfix, var_nm, mic_list[j], tmp_list[i], nx, ny, nres_x, nres_y);
         printf("%s\n",out_file_nm);


         if ((retval = nc_open(in_file_nm, NC_NOWRITE, &in_ncid))) err(retval);
         if ((retval = nc_create(out_file_nm, NC_CLOBBER, &out_ncid))) err(retval);

         if ((retval = nc_inq_varid(in_ncid, var_nm, &in_var_id))) err(retval);
         if ((retval = nc_inq_varid(in_ncid, x_nm, &in_x_id))) err(retval);
         if ((retval = nc_inq_varid(in_ncid, y_nm, &in_y_id))) err(retval);
         if ((retval = nc_inq_varid(in_ncid, t_nm, &in_t_id))) err(retval);

         if ((retval = nc_get_var_float(in_ncid, in_x_id, x_in))) err(retval);
         if ((retval = nc_get_var_float(in_ncid, in_y_id, y_in))) err(retval);
         if ((retval = nc_get_var_float(in_ncid, in_t_id, t_in))) err(retval);


         // create netcdf dimensions
         if ((retval = nc_def_dim(out_ncid, y_nm, nres_y, &out_y_dimid))) err(retval);
         if ((retval = nc_def_dim(out_ncid, x_nm, nres_x, &out_x_dimid))) err(retval);
         if ((retval = nc_def_dim(out_ncid, t_nm, NC_UNLIMITED, &out_t_id))) err(retval);


         // create netcdf variables
         if ((retval = nc_def_var(out_ncid, y_nm, NC_FLOAT, 1, &out_y_dimid, &out_y_id))) err(retval);
         if ((retval = nc_def_var(out_ncid, x_nm, NC_FLOAT, 1, &out_x_dimid, &out_x_id))) err(retval);

         dimids[0] = out_t_id;
         dimids[1] = out_y_id;
         dimids[2] = out_x_id;

         if ((retval = nc_def_var(out_ncid, var_nm, NC_FLOAT, ndim, dimids, &out_var_id)))


         // write netcdf variable attributes
         if ((retval = nc_put_att_text(out_ncid, out_y_id, "units", strlen("m"), "m"))) err(retval);
         if ((retval = nc_put_att_text(out_ncid, out_x_id, "units", strlen("m"), "m"))) err(retval);
         if ((retval = nc_put_att_text(out_ncid, out_var_id, "long_name", strlen("LWNT cluster"), "LWNT cluster"))) err(retval);
         if ((retval = nc_put_att_text(out_ncid, out_var_id, "units", strlen("#"), "#"))) err(retval);

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

         x_out = arange_float(0.0,x_in[nx-1] + (grd_siz * nres), grd_siz * nres);
         y_out = arange_float(0.0,y_in[ny-1] + (grd_siz * nres), grd_siz * nres);

         // write netcdf variable values
         if ((retval = nc_put_var_float(out_ncid, out_y_id, &y_out[0]))) err(retval);
         if ((retval = nc_put_var_float(out_ncid, out_x_id, &x_out[0]))) err(retval);


         for(t=1200;t<nt;t++)
         {
            size     = 0;
            tag      = 1;
            blbgrp   = 0;

            start[0] = t;
            if ((retval = nc_get_vara_float(in_ncid, in_var_id, start, count, &in_var[0]))) err(retval);

            out_var = fld_init((float*)in_var, nx, ny, var_thres, nres, var_nm);

            for(j=0;j<nres_y;j++)
            {
               for(i=0;i<nres_x;i++)
               {
                  size = blobcntr((float*)out_var,nres_x,nres_y,i,j,tag);
      
                  if (size > 0)
                  {
                     blbgrp += 1;
                     tag += 1;
                     printf("timestep: %d  blbgrp: %d  size : %d\n",t,blbgrp,size);
                  }
               }
            }

         printf("\n=== t = %d ===",t);
         prnt_2darr((float*)out_var,nres_x,nres_y);
            
         if ((retval = nc_put_vara_float(out_ncid, out_var_id, start, count, &out_var[0]))) err(retval);

         }

         if ((retval = nc_close(in_ncid))) err(retval);
         if ((retval = nc_close(out_ncid))) err(retval);

      }

   free(x_in);
   free(y_in);
   free(t_in);
   free(x_out);
   free(y_out);
   free(in_var);
   free(out_var);

   return 0;
}

if ((retval = nc_put_vara_float(out_ncid, out_var_id, start, count, &out_var[0]))) err(retval);

是我得到错误的部分。

谢谢。

标签: c

解决方案


nc_put_vara_float(out_ncid, out_var_id, start, count

计数=[1,288,288]

nc_def_dim(out_ncid, y_nm, nres_y, &out_y_dimid))

昏暗=288/12

计数大于尺寸长度,这似乎不对


推荐阅读