15static int utest_compare_cell_coords(
double * a,
double * b,
int count) {
17 for (
int order = -1; order <= 1; order += 2) {
18 for (
int start = 0; start < count; ++start) {
22 for (
int i = 0;
i < count; ++
i) {
24 int j = (count + start + order *
i) % count;
26 if (fabs(a[i] - b[j]) > 1e-6) ++differences;
29 if (!differences)
return 0;
35static int utest_compare_ints(
int * a,
int * b,
int count) {
37 for (
int order = -1; order <= 1; order += 2) {
38 for (
int start = 0; start < count; ++start) {
42 for (
int i = 0;
i < count; ++
i) {
44 int j = (count + start + order *
i) % count;
46 if (a[i] != b[j]) ++differences;
49 if (!differences)
return 0;
55void utest_check_grid_file(
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)
274 if (!utest_compare_cell_coords(
275 curr_cla, ref_cla + j * ref_num_corners_per_cell,
276 ref_num_corners_per_cell) &&
277 !utest_compare_cell_coords(
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;
292 if (utest_compare_cell_coords(
293 curr_cla, ref_cla + match_idx * ref_num_corners_per_cell,
294 ref_num_corners_per_cell))
296 if (utest_compare_cell_coords(
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)
310 if (utest_compare_ints(
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)
316 if (utest_compare_ints(
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)
322 if (utest_compare_ints(
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)
328 if (utest_compare_ints(
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");
357void utest_write_dummy_exodus_grid_file(
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];
446void utest_write_dummy_scrip_grid_file(
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]) {
452 grid_name, grid_filename, mask_filename, with_corners?4:0,
453 num_lon, num_lat, lon_range, lat_range, 0);
457 char * grid_name,
char * grid_filename,
char * mask_filename,
458 size_t num_corners,
size_t num_lon,
size_t num_lat,
459 double lon_range[2],
double lat_range[2],
size_t invalid_cell_stride) {
461 int with_corners = num_corners > 0;
469 char crn_dim_name[128];
470 char x_dim_name[128];
471 char y_dim_name[128];
473 sprintf(crn_dim_name,
"crn_%s", grid_name);
474 sprintf(x_dim_name,
"x_%s", grid_name);
475 sprintf(y_dim_name,
"y_%s", grid_name);
487 char cla_var_name[128];
488 char clo_var_name[128];
489 char lat_var_name[128];
490 char lon_var_name[128];
492 sprintf(cla_var_name,
"%s.cla", grid_name);
493 sprintf(clo_var_name,
"%s.clo", grid_name);
494 sprintf(lat_var_name,
"%s.lat", grid_name);
495 sprintf(lon_var_name,
"%s.lon", grid_name);
497 int corner_dim_ids[3] = {dim_crn_id, dim_y_id, dim_x_id};
498 int cell_dim_ids[2] = {dim_y_id, dim_x_id};
505 char degree[] =
"degree";
506 char title[] =
"This is a reg lon-lat dummy grid";
512 ncid, cla_var_name, NC_DOUBLE, 3, corner_dim_ids, &var_cla_id));
514 nc_put_att_text(ncid, var_cla_id,
"units", strlen(degree), degree));
516 nc_put_att_text(ncid, var_cla_id,
"title", strlen(title), title));
520 ncid, clo_var_name, NC_DOUBLE, 3, corner_dim_ids, &var_clo_id));
522 nc_put_att_text(ncid, var_clo_id,
"units", strlen(degree), degree));
524 nc_put_att_text(ncid, var_clo_id,
"title", strlen(title), title));
529 ncid, lat_var_name, NC_DOUBLE, 2, cell_dim_ids, &var_lat_id));
531 nc_put_att_text(ncid, var_lat_id,
"units", strlen(degree), degree));
533 nc_put_att_text(ncid, var_lat_id,
"title", strlen(title), title));
537 ncid, lon_var_name, NC_DOUBLE, 2, cell_dim_ids, &var_lon_id));
539 nc_put_att_text(ncid, var_lon_id,
"units", strlen(degree), degree));
541 nc_put_att_text(ncid, var_lon_id,
"title", strlen(title), title));
549 double cla[num_corners?num_corners:1][num_lat][num_lon];
550 double clo[num_corners?num_corners:1][num_lat][num_lon];
551 double lat[num_lat][num_lon];
552 double lon[num_lat][num_lon];
554 for (
size_t i = 0; i < num_lon; ++i) {
555 double vertex_lon[2] =
556 {((lon_range[1] - lon_range[0]) * (
double)i)/(
double)num_lon,
557 ((lon_range[1] - lon_range[0]) * (
double)(i+1))/(double)num_lon};
558 for (
size_t j = 0; j < num_lat; ++j) {
559 double vertex_lat[2] =
560 {((lat_range[1] - lat_range[0]) * (
double)j)/(
double)num_lat,
561 ((lat_range[1] - lat_range[0]) * (
double)(j+1))/(double)num_lat};
563 cla[0][j][i] = lat_range[0] + vertex_lat[0];
564 cla[1][j][i] = lat_range[0] + vertex_lat[0];
565 cla[2][j][i] = lat_range[0] + vertex_lat[1];
566 cla[3][j][i] = lat_range[0] + vertex_lat[1];
567 clo[0][j][i] = lon_range[0] + vertex_lon[0];
568 clo[1][j][i] = lon_range[0] + vertex_lon[1];
569 clo[2][j][i] = lon_range[0] + vertex_lon[1];
570 clo[3][j][i] = lon_range[0] + vertex_lon[0];
573 for (
size_t n = 4; n < num_corners; ++n) {
575 lat_range[0] + vertex_lat[1] +
576 ((vertex_lat[0] - vertex_lat[1]) * (
double)(n - 3)) /
577 (double)(num_corners - 3);
578 clo[n][j][i] = lon_range[0] + vertex_lon[0];
581 lat[j][i] = lat_range[0] + (vertex_lat[0] + vertex_lat[1]) * 0.5;
582 lon[j][i] = lon_range[0] + (vertex_lon[0] + vertex_lon[1]) * 0.5;
603 char x_dim_name[128];
604 char y_dim_name[128];
606 sprintf(x_dim_name,
"x_%s", grid_name);
607 sprintf(y_dim_name,
"y_%s", grid_name);
616 char frc_var_name[128];
617 char msk_var_name[128];
619 sprintf(frc_var_name,
"%s.frc", grid_name);
620 sprintf(msk_var_name,
"%s.msk", grid_name);
622 int dim_ids[2] = {dim_y_id, dim_x_id};
627 char adim[] =
"adim";
632 ncid, frc_var_name, NC_DOUBLE, 2, dim_ids, &var_frc_id));
634 nc_put_att_text(ncid, var_frc_id,
"units", strlen(adim), adim));
638 ncid, msk_var_name, NC_INT, 2, dim_ids, &var_msk_id));
640 nc_put_att_text(ncid, var_msk_id,
"units", strlen(adim), adim));
648 double frc[num_lat][num_lon];
649 int msk[num_lat][num_lon];
651 for (
size_t i = 0; i < num_lon; ++i) {
652 for (
size_t j = 0; j < num_lat; ++j) {
656 (invalid_cell_stride > 0) &&
657 (((i + j * num_lon) % invalid_cell_stride) == 0);
669 char * grid_filename,
size_t num_x,
size_t num_y,
670 double lon_range[2],
double lat_range[2],
int mask_ndims) {
677 int dim_x_id, dim_y_id, dim_nv_id, dim_time_id, dim_depth_id;
684 int cell_dim_ids[2] = {dim_y_id, dim_x_id};
685 int bounds_dim_ids[3] = {dim_y_id, dim_x_id, dim_nv_id};
686 int mask_dim_ids[4] =
688 (mask_ndims == 4)?dim_depth_id:dim_y_id,
689 (mask_ndims == 4)?dim_y_id:dim_x_id,
693 int var_lon_id, var_lat_id, var_lon_bounds_id, var_lat_bounds_id, var_msk_id;
695 nc_def_var(ncid,
"lon", NC_DOUBLE, 2, cell_dim_ids, &var_lon_id));
697 nc_def_var(ncid,
"lat", NC_DOUBLE, 2, cell_dim_ids, &var_lat_id));
700 ncid,
"lon_bounds", NC_DOUBLE, 3, bounds_dim_ids, &var_lon_bounds_id));
703 ncid,
"lat_bounds", NC_DOUBLE, 3, bounds_dim_ids, &var_lat_bounds_id));
705 nc_def_var(ncid,
"var1", NC_INT, mask_ndims, mask_dim_ids, &var_msk_id));
710 double lon[num_y][num_x];
711 double lat[num_y][num_x];
712 double lon_bounds[num_y][num_x][4];
713 double lat_bounds[num_y][num_x][4];
714 int msk[num_y][num_x];
716 for (
size_t j = 0; j < num_y; ++j) {
717 double vertex_lat[2] =
719 ((lat_range[1] - lat_range[0]) * (
double)j) / (
double)num_y,
721 ((lat_range[1] - lat_range[0]) * (
double)(j+1)) / (double)num_y};
722 for (
size_t i = 0; i < num_x; ++i) {
723 double vertex_lon[2] =
725 ((lon_range[1] - lon_range[0]) * (
double)i) / (
double)num_x,
727 ((lon_range[1] - lon_range[0]) * (
double)(i+1)) / (double)num_x};
728 lon_bounds[j][i][0] = vertex_lon[0];
729 lon_bounds[j][i][1] = vertex_lon[1];
730 lon_bounds[j][i][2] = vertex_lon[1];
731 lon_bounds[j][i][3] = vertex_lon[0];
732 lat_bounds[j][i][0] = vertex_lat[0];
733 lat_bounds[j][i][1] = vertex_lat[0];
734 lat_bounds[j][i][2] = vertex_lat[1];
735 lat_bounds[j][i][3] = vertex_lat[1];
736 lon[j][i] = (vertex_lon[0] + vertex_lon[1]) * 0.5;
737 lat[j][i] = (vertex_lat[0] + vertex_lat[1]) * 0.5;
740 msk[j][i] = (int)((i + j) & 1);
747 nc_put_var_double(ncid, var_lon_bounds_id, &lon_bounds[0][0][0]));
749 nc_put_var_double(ncid, var_lat_bounds_id, &lat_bounds[0][0][0]));
static void LLtoXYZ_deg(double lon, double lat, double p_out[])
void write_dummy_mpiom_grid_file(char *grid_filename, size_t num_x, size_t num_y, double lon_range[2], double lat_range[2], int mask_ndims)
void write_dummy_scrip_grid_file_ext(char *grid_name, char *grid_filename, char *mask_filename, size_t num_corners, size_t num_lon, size_t num_lat, double lon_range[2], double lat_range[2], size_t invalid_cell_stride)
void yac_nc_create(const char *path, int cmode, int *ncidp)
void yac_nc_inq_varid(int ncid, char const *name, int *varidp)
int yac_file_exists(const char *filename)
Check whether a file exists.
void yac_nc_open(const char *path, int omode, int *ncidp)
void yac_nc_inq_dimid(int ncid, char const *name, int *dimidp)
#define YAC_HANDLE_ERROR(exp)