56 char const * filename,
char const * grid_name,
57 size_t ref_num_cells,
size_t ref_num_corners_per_cell,
58 double * ref_cla,
double * ref_clo,
double * ref_lat,
double * ref_lon,
59 int * ref_cell_global_ids,
int * ref_core_cell_mask,
60 int * ref_vertex_global_ids,
int * ref_core_vertex_mask,
61 int * ref_edge_global_ids,
int * ref_core_edge_mask) {
64 PUT_ERR(
"error file does not exist");
68 size_t grid_name_len = strlen(grid_name) + 1;
70 char nv_dim_name[3 + grid_name_len];
71 char nc_dim_name[3 + grid_name_len];
73 char cla_var_name[4 + grid_name_len];
74 char clo_var_name[4 + grid_name_len];
75 char lat_var_name[4 + grid_name_len];
76 char lon_var_name[4 + grid_name_len];
77 char gid_var_name[4 + grid_name_len];
78 char cmk_var_name[4 + grid_name_len];
79 char vgid_var_name[5 + grid_name_len];
80 char vcmk_var_name[5 + grid_name_len];
81 char egid_var_name[5 + grid_name_len];
82 char ecmk_var_name[5 + grid_name_len];
84 snprintf(nv_dim_name, 3 + grid_name_len,
"nv_%s", grid_name);
85 snprintf(nc_dim_name, 3 + grid_name_len,
"nc_%s", grid_name);
87 snprintf(cla_var_name, 4 + grid_name_len,
"%s.cla", grid_name);
88 snprintf(clo_var_name, 4 + grid_name_len,
"%s.clo", grid_name);
89 snprintf(lat_var_name, 4 + grid_name_len,
"%s.lat", grid_name);
90 snprintf(lon_var_name, 4 + grid_name_len,
"%s.lon", grid_name);
91 snprintf(gid_var_name, 4 + grid_name_len,
"%s.gid", grid_name);
92 snprintf(cmk_var_name, 4 + grid_name_len,
"%s.cmk", grid_name);
93 snprintf(vgid_var_name, 5 + grid_name_len,
"%s.vgid", grid_name);
94 snprintf(vcmk_var_name, 5 + grid_name_len,
"%s.vcmk", grid_name);
95 snprintf(egid_var_name, 5 + grid_name_len,
"%s.egid", grid_name);
96 snprintf(ecmk_var_name, 5 + grid_name_len,
"%s.ecmk", grid_name);
101 int nv_dim_id, nc_dim_id;
105 int cla_var_id, clo_var_id, lat_var_id, lon_var_id,
106 gid_var_id, cmk_var_id, vgid_var_id, vcmk_var_id,
107 egid_var_id, ecmk_var_id;
114 if (ref_cell_global_ids)
116 if (ref_core_cell_mask)
118 if (ref_vertex_global_ids)
120 if (ref_core_vertex_mask)
122 if (ref_edge_global_ids)
124 if (ref_core_edge_mask)
127 size_t nv_dim_len, nc_dim_len;
131 if (nv_dim_len != ref_num_corners_per_cell)
133 if (nc_dim_len < ref_num_cells)
PUT_ERR(
"wrong nc dim size");
137 int dimids[NC_MAX_VAR_DIMS];
140 nc_inq_var(ncid, cla_var_id, NULL, &
type, &ndims, dimids, NULL));
141 if (
type != NC_DOUBLE)
PUT_ERR(
"wrong type for cla");
142 if (ndims != 2)
PUT_ERR(
"wrong ndims for cla");
143 if ((dimids[0] != nc_dim_id) ||
144 (dimids[1] != nv_dim_id))
PUT_ERR(
"wrong dimensions for cla");
147 nc_inq_var(ncid, clo_var_id, NULL, &
type, &ndims, dimids, NULL));
148 if (
type != NC_DOUBLE)
PUT_ERR(
"wrong type for clo");
149 if (ndims != 2)
PUT_ERR(
"wrong ndims for clo");
150 if ((dimids[0] != nc_dim_id) ||
151 (dimids[1] != nv_dim_id))
PUT_ERR(
"wrong dimensions for clo");
155 nc_inq_var(ncid, lat_var_id, NULL, &
type, &ndims, dimids, NULL));
156 if (
type != NC_DOUBLE)
PUT_ERR(
"wrong type for lat");
157 if (ndims != 1)
PUT_ERR(
"wrong ndims for lat");
158 if (dimids[0] != nc_dim_id)
PUT_ERR(
"wrong dimensions for lat");
163 nc_inq_var(ncid, lon_var_id, NULL, &
type, &ndims, dimids, NULL));
164 if (
type != NC_DOUBLE)
PUT_ERR(
"wrong type for lon");
165 if (ndims != 1)
PUT_ERR(
"wrong ndims for lon");
166 if (dimids[0] != nc_dim_id)
PUT_ERR(
"wrong dimensions for lon");
169 if (ref_cell_global_ids) {
171 nc_inq_var(ncid, gid_var_id, NULL, &
type, &ndims, dimids, NULL));
173 if (ndims != 1)
PUT_ERR(
"wrong ndims for gid");
174 if (dimids[0] != nc_dim_id)
PUT_ERR(
"wrong dimensions for gid");
177 if (ref_core_cell_mask) {
179 nc_inq_var(ncid, cmk_var_id, NULL, &
type, &ndims, dimids, NULL));
181 if (ndims != 1)
PUT_ERR(
"wrong ndims for cmk");
182 if (dimids[0] != nc_dim_id)
PUT_ERR(
"wrong dimensions for cmk");
185 if (ref_vertex_global_ids) {
187 nc_inq_var(ncid, vgid_var_id, NULL, &
type, &ndims, dimids, NULL));
188 if (
type != NC_INT)
PUT_ERR(
"wrong type for vgid");
189 if (ndims != 2)
PUT_ERR(
"wrong ndims for vgid");
190 if ((dimids[0] != nc_dim_id) ||
191 (dimids[1] != nv_dim_id))
PUT_ERR(
"wrong dimensions for vgid");
194 if (ref_core_vertex_mask) {
196 nc_inq_var(ncid, vcmk_var_id, NULL, &
type, &ndims, dimids, NULL));
197 if (
type != NC_INT)
PUT_ERR(
"wrong type for vcmk");
198 if (ndims != 2)
PUT_ERR(
"wrong ndims for vcmk");
199 if ((dimids[0] != nc_dim_id) ||
200 (dimids[1] != nv_dim_id))
PUT_ERR(
"wrong dimensions for vcmk");
203 if (ref_edge_global_ids) {
205 nc_inq_var(ncid, egid_var_id, NULL, &
type, &ndims, dimids, NULL));
206 if (
type != NC_INT)
PUT_ERR(
"wrong type for egid");
207 if (ndims != 2)
PUT_ERR(
"wrong ndims for egid");
208 if ((dimids[0] != nc_dim_id) ||
209 (dimids[1] != nv_dim_id))
PUT_ERR(
"wrong dimensions for egid");
212 if (ref_core_edge_mask) {
214 nc_inq_var(ncid, ecmk_var_id, NULL, &
type, &ndims, dimids, NULL));
215 if (
type != NC_INT)
PUT_ERR(
"wrong type for ecmk");
216 if (ndims != 2)
PUT_ERR(
"wrong ndims for ecmk");
217 if ((dimids[0] != nc_dim_id) ||
218 (dimids[1] != nv_dim_id))
PUT_ERR(
"wrong dimensions for ecmk");
221 double * clo = malloc(nc_dim_len * nv_dim_len *
sizeof(*clo));
222 double * cla = malloc(nc_dim_len * nv_dim_len *
sizeof(*cla));
223 double * lon = ref_lon?malloc(nc_dim_len *
sizeof(*lon)):NULL;
224 double * lat = ref_lat?malloc(nc_dim_len *
sizeof(*lat)):NULL;
225 int * gid = ref_cell_global_ids?malloc(nc_dim_len *
sizeof(*gid)):NULL;
226 int * cmk = ref_core_cell_mask?malloc(nc_dim_len *
sizeof(*cmk)):NULL;
227 int * vgid = ref_vertex_global_ids?malloc(nc_dim_len * nv_dim_len *
sizeof(*vgid)):NULL;
228 int * vcmk = ref_core_vertex_mask?malloc(nc_dim_len * nv_dim_len *
sizeof(*vcmk)):NULL;
229 int * egid = ref_edge_global_ids?malloc(nc_dim_len * nv_dim_len *
sizeof(*egid)):NULL;
230 int * ecmk = ref_core_edge_mask?malloc(nc_dim_len * nv_dim_len *
sizeof(*ecmk)):NULL;
238 if (ref_cell_global_ids)
240 if (ref_core_cell_mask)
242 if (ref_vertex_global_ids)
244 if (ref_core_vertex_mask)
246 if (ref_edge_global_ids)
248 if (ref_core_edge_mask)
251 int * ref_cell_flag = calloc(ref_num_cells,
sizeof(*ref_cell_flag));
254 for (
size_t i = 0; i < nc_dim_len; ++i) {
257 double * curr_cla = cla + i * nv_dim_len;
258 double * curr_clo = clo + i * nv_dim_len;
261 size_t match_idx = SIZE_MAX;
263 if (ref_cell_global_ids) {
264 for (
size_t j = 0; (j < ref_num_cells) && (match_idx == SIZE_MAX); ++j)
265 if (gid[i] == ref_cell_global_ids[j])
267 }
else if (ref_lat && ref_lon) {
268 for (
size_t j = 0; (j < ref_num_cells) && (match_idx == SIZE_MAX); ++j)
269 if ((fabs(lat[i] - ref_lat[j]) < 1e-3) &&
270 (fabs(lon[i] - ref_lon[j]) < 1e-3))
273 for (
size_t j = 0; (j < ref_num_cells) && (match_idx == SIZE_MAX); ++j)
275 curr_cla, ref_cla + j * ref_num_corners_per_cell,
276 ref_num_corners_per_cell) &&
278 curr_clo, ref_clo + j * ref_num_corners_per_cell,
279 ref_num_corners_per_cell))
284 if (match_idx == SIZE_MAX) {
286 PUT_ERR(
"error no matching cell");
290 ref_cell_flag[match_idx] = 1;
293 curr_cla, ref_cla + match_idx * ref_num_corners_per_cell,
294 ref_num_corners_per_cell))
297 curr_clo, ref_clo + match_idx * ref_num_corners_per_cell,
298 ref_num_corners_per_cell))
301 if (fabs(lat[i] - ref_lat[match_idx]) > 1e-3)
PUT_ERR(
"wrong lat");
303 if (fabs(lon[i] - ref_lon[match_idx]) > 1e-3)
PUT_ERR(
"wrong lon");
304 if (ref_cell_global_ids)
305 if (gid[i] != (
int)(ref_cell_global_ids[match_idx]))
PUT_ERR(
"wrong gid");
306 if (ref_core_cell_mask)
307 if (cmk[i] != (ref_core_cell_mask[match_idx]))
309 if (ref_vertex_global_ids)
311 vgid + i * nv_dim_len,
312 ref_vertex_global_ids + match_idx * ref_num_corners_per_cell,
313 ref_num_corners_per_cell))
315 if (ref_core_vertex_mask)
317 vcmk + i * nv_dim_len,
318 ref_core_vertex_mask + match_idx * ref_num_corners_per_cell,
319 ref_num_corners_per_cell))
321 if (ref_edge_global_ids)
323 egid + i * nv_dim_len,
324 ref_edge_global_ids + match_idx * ref_num_corners_per_cell,
325 ref_num_corners_per_cell))
327 if (ref_core_edge_mask)
329 ecmk + i * nv_dim_len,
330 ref_core_edge_mask + match_idx * ref_num_corners_per_cell,
331 ref_num_corners_per_cell))
336 size_t match_count = 0;
337 for (
size_t i = 0; i < ref_num_cells; ++i)
338 if (ref_cell_flag[i]) match_count++;
340 if (match_count != ref_num_cells)
PUT_ERR(
"missing cells");
358 char const * grid_filename,
size_t num_lon,
size_t num_lat,
359 double lon_range[2],
double lat_range[2]) {
361 size_t num_nodes = num_lon * num_lat;
362 size_t num_elem = (num_lon - 1) * (num_lat - 1);
374 int num_el_blk_dim_id;
375 int elem_blk1_dim_id;
376 int node_per_el1_dim_id;
380 nc_def_dim(ncid,
"num_dim", 3, &coord_dim_id));
382 nc_def_dim(ncid,
"num_nodes", num_nodes, &node_dim_id));
384 nc_def_dim(ncid,
"num_elem", num_elem, &elem_dim_id));
386 nc_def_dim(ncid,
"num_el_blk", 1, &num_el_blk_dim_id));
388 nc_def_dim(ncid,
"num_el_in_blk1", num_elem, &elem_blk1_dim_id));
390 nc_def_dim(ncid,
"num_nod_per_el1", 4, &node_per_el1_dim_id));
392 int elem_dim_ids[2] = {elem_blk1_dim_id, node_per_el1_dim_id};
393 int coord_dim_ids[2] = {coord_dim_id, node_dim_id};
400 nc_def_var(ncid,
"connect1", NC_INT, 2, elem_dim_ids, &var_elem_id));
402 nc_def_var(ncid,
"coord", NC_DOUBLE, 2, coord_dim_ids, &var_coord_id));
409 int elem[num_elem][4];
411 for (
size_t i = 0, k = 0; i < (num_lat - 1); ++i) {
412 for (
size_t j = 0; j < (num_lon - 1); ++j, ++k) {
413 elem[k][0] = (int)((i + 0) * num_lon + (j + 0) + 1);
414 elem[k][1] = (int)((i + 0) * num_lon + (j + 1) + 1);
415 elem[k][2] = (int)((i + 1) * num_lon + (j + 1) + 1);
416 elem[k][3] = (int)((i + 1) * num_lon + (j + 0) + 1);
422 double coords[3][num_nodes];
424 for (
size_t i = 0, k = 0; i < num_lat; ++i) {
426 ((double)i * (lat_range[1] - lat_range[0])) / (
double)(num_lat - 1) +
428 for (
size_t j = 0; j < num_lon; ++j, ++k) {
430 ((double)j * (lon_range[1] - lon_range[0])) / (
double)(num_lon - 1) +
432 double temp_coord[3];
434 coords[0][k] = temp_coord[0];
435 coords[1][k] = temp_coord[1];
436 coords[2][k] = temp_coord[2];
447 char * grid_name,
char * grid_filename,
char * mask_filename,
448 int with_corners,
size_t num_lon,
size_t num_lat,
449 double lon_range[2],
double lat_range[2]) {
457 char crn_dim_name[128];
458 char x_dim_name[128];
459 char y_dim_name[128];
461 sprintf(crn_dim_name,
"crn_%s", grid_name);
462 sprintf(x_dim_name,
"x_%s", grid_name);
463 sprintf(y_dim_name,
"y_%s", grid_name);
475 char cla_var_name[128];
476 char clo_var_name[128];
477 char lat_var_name[128];
478 char lon_var_name[128];
480 sprintf(cla_var_name,
"%s.cla", grid_name);
481 sprintf(clo_var_name,
"%s.clo", grid_name);
482 sprintf(lat_var_name,
"%s.lat", grid_name);
483 sprintf(lon_var_name,
"%s.lon", grid_name);
485 int corner_dim_ids[3] = {dim_crn_id, dim_y_id, dim_x_id};
486 int cell_dim_ids[2] = {dim_y_id, dim_x_id};
493 char degree[] =
"degree";
494 char title[] =
"This is a reg lon-lat dummy grid";
500 ncid, cla_var_name, NC_DOUBLE, 3, corner_dim_ids, &var_cla_id));
502 nc_put_att_text(ncid, var_cla_id,
"units", strlen(degree), degree));
504 nc_put_att_text(ncid, var_cla_id,
"title", strlen(title), title));
508 ncid, clo_var_name, NC_DOUBLE, 3, corner_dim_ids, &var_clo_id));
510 nc_put_att_text(ncid, var_clo_id,
"units", strlen(degree), degree));
512 nc_put_att_text(ncid, var_clo_id,
"title", strlen(title), title));
517 ncid, lat_var_name, NC_DOUBLE, 2, cell_dim_ids, &var_lat_id));
519 nc_put_att_text(ncid, var_lat_id,
"units", strlen(degree), degree));
521 nc_put_att_text(ncid, var_lat_id,
"title", strlen(title), title));
525 ncid, lon_var_name, NC_DOUBLE, 2, cell_dim_ids, &var_lon_id));
527 nc_put_att_text(ncid, var_lon_id,
"units", strlen(degree), degree));
529 nc_put_att_text(ncid, var_lon_id,
"title", strlen(title), title));
537 double cla[4][num_lat][num_lon];
538 double clo[4][num_lat][num_lon];
539 double lat[num_lat][num_lon];
540 double lon[num_lat][num_lon];
542 for (
size_t i = 0; i < num_lon; ++i) {
543 double vertex_lon[2] =
544 {((lon_range[1] - lon_range[0]) * (
double)i)/(
double)num_lon,
545 ((lon_range[1] - lon_range[0]) * (
double)(i+1))/(double)num_lon};
546 for (
size_t j = 0; j < num_lat; ++j) {
547 double vertex_lat[2] =
548 {((lat_range[1] - lat_range[0]) * (
double)j)/(
double)num_lat,
549 ((lat_range[1] - lat_range[0]) * (
double)(j+1))/(double)num_lat};
550 cla[0][j][i] = lat_range[0] + vertex_lat[0];
551 cla[1][j][i] = lat_range[0] + vertex_lat[0];
552 cla[2][j][i] = lat_range[0] + vertex_lat[1];
553 cla[3][j][i] = lat_range[0] + vertex_lat[1];
554 clo[0][j][i] = lon_range[0] + vertex_lon[0];
555 clo[1][j][i] = lon_range[0] + vertex_lon[1];
556 clo[2][j][i] = lon_range[0] + vertex_lon[1];
557 clo[3][j][i] = lon_range[0] + vertex_lon[0];
558 lat[j][i] = lat_range[0] + (vertex_lat[0] + vertex_lat[1]) * 0.5;
559 lon[j][i] = lon_range[0] + (vertex_lon[0] + vertex_lon[1]) * 0.5;
580 char x_dim_name[128];
581 char y_dim_name[128];
583 sprintf(x_dim_name,
"x_%s", grid_name);
584 sprintf(y_dim_name,
"y_%s", grid_name);
593 char frc_var_name[128];
594 char msk_var_name[128];
596 sprintf(frc_var_name,
"%s.frc", grid_name);
597 sprintf(msk_var_name,
"%s.msk", grid_name);
599 int dim_ids[2] = {dim_y_id, dim_x_id};
604 char adim[] =
"adim";
609 ncid, frc_var_name, NC_DOUBLE, 2, dim_ids, &var_frc_id));
611 nc_put_att_text(ncid, var_frc_id,
"units", strlen(adim), adim));
615 ncid, msk_var_name, NC_INT, 2, dim_ids, &var_msk_id));
617 nc_put_att_text(ncid, var_msk_id,
"units", strlen(adim), adim));
625 double frc[num_lat][num_lon];
626 int msk[num_lat][num_lon];
628 for (
size_t i = 0; i < num_lon; ++i) {
629 for (
size_t j = 0; j < num_lat; ++j) {