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