grid* grid_create(void* p, int id) { gridprm* prm = (gridprm*) p; grid* g = calloc(1, sizeof(grid)); char* fname = prm->fname; int ncid; int dimid_x, dimid_y, dimid_z; int varid_x, varid_y, varid_z; int ndims_x, ndims_y, ndims_z; size_t nx, ny, nz; int varid_depth, varid_numlevels; g->name = strdup(prm->name); g->id = id; g->vtype = gridprm_getvtype(prm); g->sfactor = prm->sfactor; #if !defined(NO_GRIDUTILS) #if !defined(GRIDMAP_TYPE_DEF) #error("GRIDMAP_TYPE_DEF not defined; please update gridutils-c"); #endif if (prm->maptype == 'b' || prm->maptype == 'B') g->maptype = GRIDMAP_TYPE_BINARY; else if (prm->maptype == 'k' || prm->maptype == 'K') g->maptype = GRIDMAP_TYPE_KDTREE; else enkf_quit("unknown grid map type \"%c\"", prm->maptype); #endif ncw_open(fname, NC_NOWRITE, &ncid); ncw_inq_dimid(ncid, prm->xdimname, &dimid_x); ncw_inq_dimid(ncid, prm->ydimname, &dimid_y); ncw_inq_dimid(ncid, prm->zdimname, &dimid_z); ncw_inq_dimlen(ncid, dimid_x, &nx); ncw_inq_dimlen(ncid, dimid_y, &ny); ncw_inq_dimlen(ncid, dimid_z, &nz); ncw_inq_varid(ncid, prm->xvarname, &varid_x); ncw_inq_varid(ncid, prm->yvarname, &varid_y); ncw_inq_varid(ncid, prm->zvarname, &varid_z); ncw_inq_varndims(ncid, varid_x, &ndims_x); ncw_inq_varndims(ncid, varid_y, &ndims_y); ncw_inq_varndims(ncid, varid_z, &ndims_z); if (ndims_x == 1 && ndims_y == 1) { double* x; double* y; double* z; x = malloc(nx * sizeof(double)); y = malloc(ny * sizeof(double)); z = malloc(nz * sizeof(double)); ncw_get_var_double(ncid, varid_x, x); ncw_get_var_double(ncid, varid_y, y); ncw_get_var_double(ncid, varid_z, z); grid_setcoords(g, GRIDHTYPE_LATLON, NT_NONE, nx, ny, nz, x, y, z); } #if !defined(NO_GRIDUTILS) else if (ndims_x == 2 && ndims_y == 2) { double** x; double** y; double* z; x = gu_alloc2d(ny, nx, sizeof(double)); y = gu_alloc2d(ny, nx, sizeof(double)); z = malloc(nz * sizeof(double)); ncw_get_var_double(ncid, varid_x, x[0]); ncw_get_var_double(ncid, varid_y, y[0]); ncw_get_var_double(ncid, varid_z, z); grid_setcoords(g, GRIDHTYPE_CURVILINEAR, NT_COR, nx, ny, nz, x, y, z); } #endif else enkf_quit("%s: could not determine the grid type", fname); if (prm->depthvarname != NULL) { float** depth = alloc2d(ny, nx, sizeof(float)); ncw_inq_varid(ncid, prm->depthvarname, &varid_depth); ncw_get_var_float(ncid, varid_depth, depth[0]); g->depth = depth; } if (prm->levelvarname != NULL) { g->numlevels = alloc2d(ny, nx, sizeof(int)); ncw_inq_varid(ncid, prm->levelvarname, &varid_numlevels); ncw_get_var_int(ncid, varid_numlevels, g->numlevels[0]); if (g->vtype == GRIDVTYPE_SIGMA) { int i, j; for (j = 0; j < ny; ++j) for (i = 0; i < nx; ++i) g->numlevels[j][i] *= nz; } } ncw_close(ncid); if (g->numlevels == NULL) { g->numlevels = alloc2d(ny, nx, sizeof(int)); if (g->vtype == GRIDVTYPE_SIGMA) { int i, j; for (j = 0; j < ny; ++j) for (i = 0; i < nx; ++i) if (g->depth == NULL || g->depth[j][i] > 0.0) g->numlevels[j][i] = nz; } else { int i, j; assert(g->depth != NULL); for (j = 0; j < ny; ++j) { for (i = 0; i < nx; ++i) { double depth = g->depth[j][i]; double fk = NaN; if (depth > 0.0) { z2fk(g, j, i, depth, &fk); g->numlevels[j][i] = ceil(fk + 0.5); } } } } } gridprm_print(prm, " "); grid_print(g, " "); return g; }
grid* grid_create(void* p, int id) { gridprm* prm = (gridprm*) p; grid* g = calloc(1, sizeof(grid)); char* fname = prm->fname; int ncid; int dimid_x, dimid_y, dimid_z; int varid_x, varid_y, varid_z; int ndims_x, ndims_y, ndims_z; size_t nx, ny, nz; int varid_depth, varid_numlevels; g->name = strdup(prm->name); g->id = id; g->vtype = gridprm_getvtype(prm); ncw_open(fname, NC_NOWRITE, &ncid); ncw_inq_dimid(fname, ncid, prm->xdimname, &dimid_x); ncw_inq_dimid(fname, ncid, prm->ydimname, &dimid_y); ncw_inq_dimid(fname, ncid, prm->zdimname, &dimid_z); ncw_inq_dimlen(fname, ncid, dimid_x, &nx); ncw_inq_dimlen(fname, ncid, dimid_y, &ny); ncw_inq_dimlen(fname, ncid, dimid_z, &nz); ncw_inq_varid(fname, ncid, prm->xvarname, &varid_x); ncw_inq_varid(fname, ncid, prm->yvarname, &varid_y); ncw_inq_varid(fname, ncid, prm->zvarname, &varid_z); ncw_inq_varndims(fname, ncid, varid_x, &ndims_x); ncw_inq_varndims(fname, ncid, varid_y, &ndims_y); ncw_inq_varndims(fname, ncid, varid_z, &ndims_z); if (ndims_x == 1 && ndims_y == 1) { double* x; double* y; double* z; int i; double dx, dy; int periodic_x; x = malloc(nx * sizeof(double)); y = malloc(ny * sizeof(double)); z = malloc(nz * sizeof(double)); ncw_get_var_double(fname, ncid, varid_x, x); ncw_get_var_double(fname, ncid, varid_y, y); ncw_get_var_double(fname, ncid, varid_z, z); periodic_x = fabs(fmod(2.0 * x[nx - 1] - x[nx - 2], 360.0) - x[0]) < EPS_LON; dx = (x[nx - 1] - x[0]) / (double) (nx - 1); for (i = 1; i < (int) nx; ++i) if (fabs(x[i] - x[i - 1] - dx) / fabs(dx) > EPS_LON) break; if (i != (int) nx) grid_setcoords(g, GRIDHTYPE_LATLON_IRREGULAR, NT_NONE, periodic_x, 0, nx, ny, nz, x, y, z); else { dy = (y[ny - 1] - y[0]) / (double) (ny - 1); for (i = 1; i < (int) ny; ++i) if (fabs(y[i] - y[i - 1] - dy) / fabs(dy) > EPS_LON) break; if (i != (int) ny) grid_setcoords(g, GRIDHTYPE_LATLON_IRREGULAR, NT_NONE, periodic_x, 0, nx, ny, nz, x, y, z); else grid_setcoords(g, GRIDHTYPE_LATLON_REGULAR, NT_NONE, periodic_x, 0, nx, ny, nz, x, y, z); } } #if !defined(NO_GRIDUTILS) else if (ndims_x == 2 && ndims_y == 2) { double** x; double** y; double* z; x = alloc2d(ny, nx, sizeof(double)); y = alloc2d(ny, nx, sizeof(double)); z = malloc(nz * sizeof(double)); ncw_get_var_double(fname, ncid, varid_x, x[0]); ncw_get_var_double(fname, ncid, varid_y, y[0]); ncw_get_var_double(fname, ncid, varid_z, z); grid_setcoords(g, GRIDHTYPE_CURVILINEAR, NT_COR, 0, 0, nx, ny, nz, x, y, z); } #endif else enkf_quit("%s: could not determine the grid type", fname); if (prm->depthvarname != NULL) { float** depth = alloc2d(ny, nx, sizeof(float)); ncw_inq_varid(fname, ncid, prm->depthvarname, &varid_depth); ncw_get_var_float(fname, ncid, varid_depth, depth[0]); g->depth = depth; } if (prm->levelvarname != NULL) { g->numlevels = alloc2d(ny, nx, sizeof(int)); ncw_inq_varid(fname, ncid, prm->levelvarname, &varid_numlevels); ncw_get_var_int(fname, ncid, varid_numlevels, g->numlevels[0]); if (g->vtype == GRIDVTYPE_SIGMA) { int i, j; for (j = 0; j < ny; ++j) for (i = 0; i < nx; ++i) g->numlevels[j][i] *= nz; } } ncw_close(fname, ncid); if (g->numlevels == NULL && g->depth != NULL) { g->numlevels = alloc2d(ny, nx, sizeof(int)); if (g->vtype == GRIDVTYPE_SIGMA) { int i, j; for (j = 0; j < ny; ++j) for (i = 0; i < nx; ++i) if (g->depth[j][i] > 0.0) g->numlevels[j][i] = nz; } else { int i, j; for (j = 0; j < ny; ++j) { for (i = 0; i < nx; ++i) { double depth = g->depth[j][i]; double fk = NaN; if (depth > 0.0) { z2fk(g, j, i, depth, &fk); g->numlevels[j][i] = ceil(fk + 0.5); } } } } } gridprm_print(prm, " "); grid_print(g, " "); return g; }