YAC 3.12.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_read_icon_common.c
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <stdio.h>
6#include <string.h>
7#ifdef YAC_NETCDF_ENABLED
8#include <netcdf.h>
9#endif
10
11#include "tests.h"
12#include "test_common.h"
13#include "io_utils.h"
14#include "geometry.h"
16
17#ifdef YAC_NETCDF_ENABLED
18
19int vertex_of_cell[3][16] = {{1,2,6,7,10,11,13,11,8,7,3,2,3,4,4,8},
20 {2,6,7,10,11,13,14,12,11,8,7,3,4,5,8,9},
21 {6,7,10,11,13,14,15,14,12,11,8,7,8,9,9,12}};
22int edge_of_cell[3][16] = {{1,4,13,16,22,25,28,24,19,15,7,3,6,9,10,18},
23 {4,13,16,22,25,28,30,27,24,19,15,7,10,12,18,21},
24 {2,5,14,17,23,26,29,26,20,17,8,5,8,11,11,20}};
25int cells_of_vertex[6][15] = {{1, 1,11,13,14,1, 2, 9,14,3, 4, 8,5,6,7},
26 {0, 2,12,14, 0,2, 3,10,15,4, 5, 9,6,7,0},
27 {0,12,13,15, 0,3, 4,11,16,5, 6,16,7,8,0},
28 {0, 0, 0, 0, 0,0,10,13, 0,0, 8, 0,0,0,0},
29 {0, 0, 0, 0, 0,0,11,15, 0,0, 9, 0,0,0,0},
30 {0, 0, 0, 0, 0,0,12,16, 0,0,10, 0,0,0,0}};
31int vertex_of_edge[2][30] = {{1,1,2,2,2,3,3,3,4,4,4,5, 6,6,7,7,7,8,8,8,9, 10,10,11,11,11,12, 13,13,14},
32 {2,6,3,6,7,4,7,8,5,8,9,9, 7,10,8,10,11,9,11,12,12, 11,13,12,13,14,14, 14,15,15}};
33
34
36 int ncid, int var_id, enum coord_units coord_unit) {
37
38 char const * units_str = (coord_unit==DEG)?"degree":"radian";
40 nc_put_att_text(ncid, var_id, "units", strlen(units_str), units_str));
41}
42
43static void write_coord(
44 int ncid, int var_id, double * var, size_t var_size,
45 enum coord_units coord_unit) {
46
47 if (coord_unit == RAD) {
48 double * temp_var = xmalloc(var_size * sizeof(*temp_var));
49 for (size_t i = 0; i < var_size; ++i)
50 temp_var[i] = var[i] * YAC_RAD;
51 var = temp_var;
52 }
53
54 YAC_HANDLE_ERROR(nc_put_var_double(ncid, var_id, var));
55
56 if (coord_unit == RAD) free(var);
57}
58
60 char const * file_name, enum coord_units coord_unit) {
61
62 int ncid;
63
64 // create file
65 yac_nc_create(file_name, NC_CLOBBER, &ncid);
66
67 int dim_cell_id, dim_vertex_id, dim_edge_id, dim_nv_id, dim_ne_id, dim_nc_id;
68
69 // define dimensions
70 YAC_HANDLE_ERROR(nc_def_dim(ncid, "cell", 16, &dim_cell_id));
71 YAC_HANDLE_ERROR(nc_def_dim(ncid, "vertex", 15, &dim_vertex_id));
72 YAC_HANDLE_ERROR(nc_def_dim(ncid, "edge", 30, &dim_edge_id));
73 YAC_HANDLE_ERROR(nc_def_dim(ncid, "nv", 3, &dim_nv_id));
74 YAC_HANDLE_ERROR(nc_def_dim(ncid, "ne", 6, &dim_ne_id));
75 YAC_HANDLE_ERROR(nc_def_dim(ncid, "nc", 2, &dim_nc_id));
76
77
78 int var_vlon_id, var_vlat_id, var_clon_id, var_clat_id, var_mask_id,
79 var_v2c_id, var_c2v_id, var_c2e_id, var_v2e_id;
80
81 // define variables
82 YAC_HANDLE_ERROR(nc_def_var(ncid, "vlon", NC_DOUBLE, 1, &dim_vertex_id,
83 &var_vlon_id));
84 YAC_HANDLE_ERROR(nc_def_var(ncid, "vlat", NC_DOUBLE, 1, &dim_vertex_id,
85 &var_vlat_id));
86 YAC_HANDLE_ERROR(nc_def_var(ncid, "clon", NC_DOUBLE, 1, &dim_cell_id,
87 &var_clon_id));
88 YAC_HANDLE_ERROR(nc_def_var(ncid, "clat", NC_DOUBLE, 1, &dim_cell_id,
89 &var_clat_id));
90 YAC_HANDLE_ERROR(nc_def_var(ncid, "cell_sea_land_mask", NC_INT, 1, &dim_cell_id,
91 &var_mask_id));
92 def_coord_unit_att(ncid, var_vlon_id, coord_unit);
93 def_coord_unit_att(ncid, var_vlat_id, coord_unit);
94 def_coord_unit_att(ncid, var_clon_id, coord_unit);
95 def_coord_unit_att(ncid, var_clat_id, coord_unit);
97 nc_def_var(
98 ncid, "vertex_of_cell", NC_INT, 2, (int[]){dim_nv_id, dim_cell_id},
99 &var_c2v_id));
101 nc_def_var(
102 ncid, "edge_of_cell", NC_INT, 2, (int[]){dim_nv_id, dim_cell_id},
103 &var_c2e_id));
105 nc_def_var(
106 ncid, "cells_of_vertex", NC_INT, 2, (int[]){dim_ne_id, dim_vertex_id},
107 &var_v2c_id));
109 nc_def_var(
110 ncid, "edge_vertices", NC_INT, 2, (int[]){dim_nc_id, dim_edge_id},
111 &var_v2e_id));
112
113 // end definition
114 YAC_HANDLE_ERROR(nc_enddef(ncid));
115
116 // write grid data
117 write_coord(ncid, var_vlon_id, vlon, sizeof(vlon)/sizeof(vlon[0]), coord_unit);
118 write_coord(ncid, var_vlat_id, vlat, sizeof(vlat)/sizeof(vlat[0]), coord_unit);
119 write_coord(ncid, var_clon_id, clon, sizeof(clon)/sizeof(clon[0]), coord_unit);
120 write_coord(ncid, var_clat_id, clat, sizeof(clat)/sizeof(clat[0]), coord_unit);
121 YAC_HANDLE_ERROR(nc_put_var_int(ncid, var_mask_id, mask));
122 YAC_HANDLE_ERROR(nc_put_var_int(ncid, var_c2v_id, &(vertex_of_cell[0][0])));
123 YAC_HANDLE_ERROR(nc_put_var_int(ncid, var_c2e_id, &(edge_of_cell[0][0])));
124 YAC_HANDLE_ERROR(nc_put_var_int(ncid, var_v2c_id, &(cells_of_vertex[0][0])));
125 YAC_HANDLE_ERROR(nc_put_var_int(ncid, var_v2e_id, &(vertex_of_edge[0][0])));
126
127 YAC_HANDLE_ERROR(nc_close(ncid));
128}
129
130#else // YAC_NETCDF_ENABLED
131
133 char const * file_name, enum coord_units coord_unit) {
134
136 UNUSED(coord_unit);
137 die("ERROR(write_test_grid_file): YAC is built without the NetCDF support");
138}
139#endif // YAC_NETCDF_ENABLED
140
142 char * grid_name, char * grid_filename, char * mask_filename,
143 int with_corners, size_t num_lon, size_t num_lat,
144 double lon_range[2], double lat_range[2]) {
145
146#ifndef YAC_NETCDF_ENABLED
147 UNUSED(grid_name);
148 UNUSED(grid_filename);
149 UNUSED(mask_filename);
150 UNUSED(with_corners);
151 UNUSED(num_lon);
152 UNUSED(num_lat);
153 UNUSED(lon_range);
154 UNUSED(lat_range);
155 die("ERROR(write_dummy_grid_file): YAC is built without the NetCDF support");
156#else
157
158 { // grid file
159 int ncid;
160
161 // create file
162 yac_nc_create(grid_filename, NC_CLOBBER, &ncid);
163
164 char crn_dim_name[128];
165 char x_dim_name[128];
166 char y_dim_name[128];
167
168 sprintf(crn_dim_name, "crn_%s", grid_name);
169 sprintf(x_dim_name, "x_%s", grid_name);
170 sprintf(y_dim_name, "y_%s", grid_name);
171
172 int dim_crn_id = -1;
173 int dim_x_id;
174 int dim_y_id;
175
176 // define dimensions
177 if (with_corners)
178 YAC_HANDLE_ERROR(nc_def_dim(ncid, crn_dim_name, 4, &dim_crn_id));
179 YAC_HANDLE_ERROR(nc_def_dim(ncid, x_dim_name, num_lon, &dim_x_id));
180 YAC_HANDLE_ERROR(nc_def_dim(ncid, y_dim_name, num_lat, &dim_y_id));
181
182 char cla_var_name[128];
183 char clo_var_name[128];
184 char lat_var_name[128];
185 char lon_var_name[128];
186
187 sprintf(cla_var_name, "%s.cla", grid_name);
188 sprintf(clo_var_name, "%s.clo", grid_name);
189 sprintf(lat_var_name, "%s.lat", grid_name);
190 sprintf(lon_var_name, "%s.lon", grid_name);
191
192 int corner_dim_ids[3] = {dim_crn_id, dim_y_id, dim_x_id};
193 int cell_dim_ids[2] = {dim_y_id, dim_x_id};
194
195 int var_cla_id = -1;
196 int var_clo_id = -1;
197 int var_lat_id;
198 int var_lon_id;
199
200 char degree[] = "degree";
201 char title[] = "This is a reg lon-lat dummy grid";
202
203 // define variable
204 if (with_corners) {
206 nc_def_var(
207 ncid, cla_var_name, NC_DOUBLE, 3, corner_dim_ids, &var_cla_id));
209 nc_put_att_text(ncid, var_cla_id, "units", strlen(degree), degree));
211 nc_put_att_text(ncid, var_cla_id, "title", strlen(title), title));
212
214 nc_def_var(
215 ncid, clo_var_name, NC_DOUBLE, 3, corner_dim_ids, &var_clo_id));
217 nc_put_att_text(ncid, var_clo_id, "units", strlen(degree), degree));
219 nc_put_att_text(ncid, var_clo_id, "title", strlen(title), title));
220 }
221
223 nc_def_var(
224 ncid, lat_var_name, NC_DOUBLE, 2, cell_dim_ids, &var_lat_id));
226 nc_put_att_text(ncid, var_lat_id, "units", strlen(degree), degree));
228 nc_put_att_text(ncid, var_lat_id, "title", strlen(title), title));
229
231 nc_def_var(
232 ncid, lon_var_name, NC_DOUBLE, 2, cell_dim_ids, &var_lon_id));
234 nc_put_att_text(ncid, var_lon_id, "units", strlen(degree), degree));
236 nc_put_att_text(ncid, var_lon_id, "title", strlen(title), title));
237
238
239 // end definition
240 YAC_HANDLE_ERROR(nc_enddef(ncid));
241
242 // write grid data
243
244 double cla[4][num_lat][num_lon];
245 double clo[4][num_lat][num_lon];
246 double lat[num_lat][num_lon];
247 double lon[num_lat][num_lon];
248
249 for (size_t i = 0; i < num_lon; ++i) {
250 double vertex_lon[2] =
251 {((lon_range[1] - lon_range[0]) * (double)i)/(double)num_lon,
252 ((lon_range[1] - lon_range[0]) * (double)(i+1))/(double)num_lon};
253 for (size_t j = 0; j < num_lat; ++j) {
254 double vertex_lat[2] =
255 {((lat_range[1] - lat_range[0]) * (double)j)/(double)num_lat,
256 ((lat_range[1] - lat_range[0]) * (double)(j+1))/(double)num_lat};
257 cla[0][j][i] = lat_range[0] + vertex_lat[0];
258 cla[1][j][i] = lat_range[0] + vertex_lat[0];
259 cla[2][j][i] = lat_range[0] + vertex_lat[1];
260 cla[3][j][i] = lat_range[0] + vertex_lat[1];
261 clo[0][j][i] = lon_range[0] + vertex_lon[0];
262 clo[1][j][i] = lon_range[0] + vertex_lon[1];
263 clo[2][j][i] = lon_range[0] + vertex_lon[1];
264 clo[3][j][i] = lon_range[0] + vertex_lon[0];
265 lat[j][i] = lat_range[0] + (vertex_lat[0] + vertex_lat[1]) * 0.5;
266 lon[j][i] = lon_range[0] + (vertex_lon[0] + vertex_lon[1]) * 0.5;
267 }
268 }
269
270
271 if (with_corners) {
272 YAC_HANDLE_ERROR(nc_put_var_double(ncid, var_cla_id, &cla[0][0][0]));
273 YAC_HANDLE_ERROR(nc_put_var_double(ncid, var_clo_id, &clo[0][0][0]));
274 }
275 YAC_HANDLE_ERROR(nc_put_var_double(ncid, var_lat_id, &lat[0][0]));
276 YAC_HANDLE_ERROR(nc_put_var_double(ncid, var_lon_id, &lon[0][0]));
277
278 YAC_HANDLE_ERROR(nc_close(ncid));
279 }
280
281 { // mask file
282 int ncid;
283
284 // create file
285 yac_nc_create(mask_filename, NC_CLOBBER, &ncid);
286
287 char x_dim_name[128];
288 char y_dim_name[128];
289
290 sprintf(x_dim_name, "x_%s", grid_name);
291 sprintf(y_dim_name, "y_%s", grid_name);
292
293 int dim_x_id;
294 int dim_y_id;
295
296 // define dimensions
297 YAC_HANDLE_ERROR(nc_def_dim(ncid, x_dim_name, num_lon, &dim_x_id));
298 YAC_HANDLE_ERROR(nc_def_dim(ncid, y_dim_name, num_lat, &dim_y_id));
299
300 char frc_var_name[128];
301 char msk_var_name[128];
302
303 sprintf(frc_var_name, "%s.frc", grid_name);
304 sprintf(msk_var_name, "%s.msk", grid_name);
305
306 int dim_ids[2] = {dim_y_id, dim_x_id};
307
308 int var_frc_id;
309 int var_msk_id;
310
311 char adim[] = "adim";
312
313 // define variable
315 nc_def_var(
316 ncid, frc_var_name, NC_DOUBLE, 2, dim_ids, &var_frc_id));
318 nc_put_att_text(ncid, var_frc_id, "units", strlen(adim), adim));
319
321 nc_def_var(
322 ncid, msk_var_name, NC_INT, 2, dim_ids, &var_msk_id));
324 nc_put_att_text(ncid, var_msk_id, "units", strlen(adim), adim));
325
326
327 // end definition
328 YAC_HANDLE_ERROR(nc_enddef(ncid));
329
330 // write grid data
331
332 double frc[num_lat][num_lon];
333 int msk[num_lat][num_lon];
334
335 for (size_t i = 0; i < num_lon; ++i) {
336 for (size_t j = 0; j < num_lat; ++j) {
337 frc[j][i] = 1;
338 msk[j][i] = 0;
339 }
340 }
341
342 YAC_HANDLE_ERROR(nc_put_var_double(ncid, var_frc_id, &frc[0][0]));
343 YAC_HANDLE_ERROR(nc_put_var_int(ncid, var_msk_id, &msk[0][0]));
344
345 YAC_HANDLE_ERROR(nc_close(ncid));
346 }
347#endif // YAC_NETCDF_ENABLED
348}
349
350void write_test_grid_file_f2c(char const * file_name, int coord_unit) {
351
352 write_test_grid_file(file_name, (enum coord_units)coord_unit);
353}
char const * file_name
#define UNUSED(x)
Definition core.h:73
#define YAC_RAD
void yac_nc_create(const char *path, int cmode, int *ncidp)
Definition io_utils.c:367
#define xmalloc(size)
Definition ppm_xfuncs.h:66
#define RAD
int cells_of_vertex[6][15]
int edge_of_cell[3][16]
void write_test_grid_file(char const *file_name, enum coord_units coord_unit)
static void def_coord_unit_att(int ncid, int var_id, enum coord_units coord_unit)
void write_dummy_grid_file(char *grid_name, char *grid_filename, char *mask_filename, int with_corners, size_t num_lon, size_t num_lat, double lon_range[2], double lat_range[2])
int vertex_of_cell[3][16]
static void write_coord(int ncid, int var_id, double *var, size_t var_size, enum coord_units coord_unit)
void write_test_grid_file_f2c(char const *file_name, int coord_unit)
int vertex_of_edge[2][30]
static int mask[16]
static double vlon[15]
static double clon[16]
static double vlat[15]
static double clat[16]
#define YAC_HANDLE_ERROR(exp)
Definition toy_output.c:13
#define die(msg)
Definition yac_assert.h:12