YAC 3.7.0
Yet Another Coupler
Loading...
Searching...
No Matches
debug_grid2vtk.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 <stdlib.h>
6#include <stdio.h>
7#include <unistd.h>
8#include <string.h>
9#include <math.h>
10
11#include <netcdf.h>
12
13#include "yac_utils.h"
14
15// redefine YAC assert macros
16#undef YAC_ASSERT
17#undef YAC_ASSERT_F
18
19#define YAC_RAD (0.01745329251994329576923690768489) // M_PI / 180
20
21static char const * cmd;
22#define STR_USAGE "Usage: %s -n grid_name -f grid_filename -o vtk_filename\n"
23
24#define YAC_ASSERT(exp, msg) \
25 { \
26 if(!((exp))) { \
27 fprintf(stderr, "ERROR: %s\n" STR_USAGE, msg, cmd); \
28 exit(EXIT_FAILURE); \
29 } \
30 }
31
32#define YAC_ASSERT_F(exp, format, ...) \
33 { \
34 if(!((exp))) { \
35 fprintf(stderr, "ERROR: " format "\n" STR_USAGE, __VA_ARGS__, cmd); \
36 exit(EXIT_FAILURE); \
37 } \
38 }
39
44static void parse_arguments(int argc, char ** argv,
45 char const ** grid_filename,
46 char const ** grid_name,
47 char const ** vtk_filename);
48static void read_grid_file(
49 char const * grid_filename, char const * grid_name,
50 size_t * nv, size_t * nc,
51 double ** clon, double ** clat, double ** vlon, double ** vlat,
52 int ** gid, int ** cmk, int ** rnk);
53static void write_vtk_file(
54 char const * vtk_filename, char const * grid_name,
55 size_t nv, size_t nc,
56 double * clon, double * clat, double * vlon, double * vlat,
57 int * gid, int * cmk, int * rnk);
58
59int main(int argc, char ** argv) {
60
61 cmd = argv[0];
62
63 char const * grid_name, * grid_filename, * vtk_filename;
64 parse_arguments(argc, argv, &grid_filename, &grid_name, &vtk_filename);
65
66 size_t nv, nc;
67 double * clon, * clat, * lon, * lat;
68 int * gid, * cmk, * rnk;
69
71 grid_filename, grid_name,
72 &nv, &nc, &clon, &clat, &lon, &lat, &gid, &cmk, &rnk);
73
75 vtk_filename, grid_name,
76 nv, nc, clon, clat, lon, lat, gid, cmk, rnk);
77
78 free(clon);
79 free(clat);
80 free(lon);
81 free(lat);
82 free(gid);
83 free(cmk);
84 free(rnk);
85}
86
87static double * read_coords(int ncid, int varid, size_t varlen) {
88
89 int is_degree = yac_check_coord_units(ncid, varid);
90
91 double * coord = malloc(varlen * sizeof(*coord));
92 YAC_HANDLE_ERROR(nc_get_var_double (ncid, varid, coord));
93
94 // convert to radiant if necessary
95 if (is_degree) for (size_t i = 0; i < varlen; ++i) coord[i] *= YAC_RAD;
96
97 return coord;
98}
99
100static int * read_int(int ncid, int varid, size_t varlen) {
101
102 int * array = malloc(varlen * sizeof(*array));
103 YAC_HANDLE_ERROR(nc_get_var_int(ncid, varid, array));
104 return array;
105}
106
107static void read_grid_file(
108 char const * grid_filename, char const * grid_name,
109 size_t * nv, size_t * nc,
110 double ** clon, double ** clat, double ** lon, double ** lat,
111 int ** gid, int ** cmk, int ** rnk) {
112
113 int status;
114
115 size_t grid_name_len = strlen(grid_name) + 1;
116 char nv_dim_name[3 + grid_name_len];
117 char nc_dim_name[3 + grid_name_len];
118 char cla_var_name[4 + grid_name_len];
119 char clo_var_name[4 + grid_name_len];
120 char lat_var_name[4 + grid_name_len];
121 char lon_var_name[4 + grid_name_len];
122 char gid_var_name[4 + grid_name_len];
123 char cmk_var_name[4 + grid_name_len];
124 char rnk_var_name[4 + grid_name_len];
125
126 snprintf(nv_dim_name, 3 + grid_name_len, "nv_%s", grid_name);
127 snprintf(nc_dim_name, 3 + grid_name_len, "nc_%s", grid_name);
128 snprintf(cla_var_name, 4 + grid_name_len, "%s.cla", grid_name);
129 snprintf(clo_var_name, 4 + grid_name_len, "%s.clo", grid_name);
130 snprintf(lat_var_name, 4 + grid_name_len, "%s.lat", grid_name);
131 snprintf(lon_var_name, 4 + grid_name_len, "%s.lon", grid_name);
132 snprintf(gid_var_name, 4 + grid_name_len, "%s.gid", grid_name);
133 snprintf(cmk_var_name, 4 + grid_name_len, "%s.cmk", grid_name);
134 snprintf(rnk_var_name, 4 + grid_name_len, "%s.rnk", grid_name);
135
137 yac_file_exists(grid_filename), "File %s does not exist.", grid_filename)
138
139 int ncid, dimid, var_id;
140 yac_nc_open(grid_filename, NC_NOWRITE, &ncid);
141
142 yac_nc_inq_dimid(ncid, nv_dim_name, &dimid);
143 YAC_HANDLE_ERROR(nc_inq_dimlen(ncid, dimid, nv));
144 yac_nc_inq_dimid(ncid, nc_dim_name, &dimid);
145 YAC_HANDLE_ERROR(nc_inq_dimlen(ncid, dimid, nc));
146
147 yac_nc_inq_varid(ncid, cla_var_name, &var_id);
148 *clat = read_coords(ncid, var_id, *nv * *nc);
149 yac_nc_inq_varid(ncid, clo_var_name, &var_id);
150 *clon = read_coords(ncid, var_id, *nv * *nc);
151
152 status = nc_inq_varid(ncid, lat_var_name, &var_id);
153 if (status == NC_NOERR) {
154 *lat = read_coords(ncid, var_id, *nc);
155 } else if (status == NC_ENOTVAR) {
156 *lat = NULL;
157 status = NC_NOERR;
158 }
159 YAC_HANDLE_ERROR(status);
160 status = nc_inq_varid(ncid, lon_var_name, &var_id);
161 if (status == NC_NOERR) {
162 *lon = read_coords(ncid, var_id, *nc);
163 } else if (status == NC_ENOTVAR) {
164 *lon = NULL;
165 status = NC_NOERR;
166 }
167 YAC_HANDLE_ERROR(status);
168
169 status = nc_inq_varid(ncid, gid_var_name, &var_id);
170 if (status == NC_NOERR) {
171 *gid = read_int(ncid, var_id, *nc);
172 } else if (status == NC_ENOTVAR) {
173 *gid = NULL;
174 status = NC_NOERR;
175 }
176 YAC_HANDLE_ERROR(status);
177
178 status = nc_inq_varid(ncid, cmk_var_name, &var_id);
179 if (status == NC_NOERR) {
180 *cmk = read_int(ncid, var_id, *nc);
181 } else if (status == NC_ENOTVAR) {
182 *cmk = NULL;
183 status = NC_NOERR;
184 }
185 YAC_HANDLE_ERROR(status);
186
187 YAC_HANDLE_ERROR(nc_inq_varid(ncid, rnk_var_name, &var_id));
188 *rnk = read_int(ncid, var_id, *nc);
189
190 YAC_HANDLE_ERROR(nc_close(ncid));
191}
192
193static void LLtoXYZ(double lon, double lat, double p_out[]) {
194
195 if ((fabs(lon) > 8.0 * M_PI) || (fabs(lat) > 2.0 * M_PI)) {
196 p_out[0] = 0.0;
197 p_out[1] = 0.0;
198 p_out[2] = 0.0;
199 return;
200 }
201
202 while (lon < -M_PI) lon += 2.0 * M_PI;
203 while (lon >= M_PI) lon -= 2.0 * M_PI;
204
205 double cos_lat = cos(lat);
206 p_out[0] = cos_lat * cos(lon);
207 p_out[1] = cos_lat * sin(lon);
208 p_out[2] = sin(lat);
209}
210
211static void write_vtk_file(
212 char const * vtk_filename, char const * grid_name,
213 size_t nv, size_t nc,
214 double * clon, double * clat, double * lon, double * lat,
215 int * gid, int * cmk, int * rnk) {
216
218 malloc((nv * nc + ((lon && lat)?nc:0)) * sizeof(*points));
219
220 for (size_t i = 0; i < nv * nc; ++i) LLtoXYZ(clon[i], clat[i], points[i]);
221 if (lon && lat)
222 for (size_t i = 0; i < nc; ++i)
223 LLtoXYZ(lon[i], lat[i], points[nv * nc + i]);
224
225 unsigned * num_points_per_polygon =
226 malloc(nc * sizeof(*num_points_per_polygon));
227 for (size_t i = 0; i < nc; ++i) num_points_per_polygon[i] = (unsigned)nv;
228
229 unsigned * polygon_data = malloc(nc * nv * sizeof(*polygon_data));
230 for (size_t i = 0; i < nv * nc; ++i) polygon_data[i] = (unsigned)i;
231
232 YAC_VTK_FILE * file = yac_vtk_open(vtk_filename, grid_name);
233 yac_vtk_write_point_data(file, &(points[0][0]), nv * nc + ((lon && lat)?nc:0));
235 file, polygon_data, num_points_per_polygon, nc);
236 if (gid) yac_vtk_write_cell_scalars_int(file, gid, nc, "gid");
237 if (cmk) yac_vtk_write_cell_scalars_int(file, cmk, nc, "cmk");
238 if (rnk) yac_vtk_write_cell_scalars_int(file, rnk, nc, "rnk");
239 yac_vtk_close(file);
240
241 free(polygon_data);
242 free(num_points_per_polygon);
243 free(points);
244}
245
246static void parse_arguments(int argc, char ** argv,
247 char const ** grid_filename,
248 char const ** grid_name,
249 char const ** vtk_filename) {
250
251 *grid_name = NULL;
252 *grid_filename = NULL;
253 *vtk_filename = NULL;;
254
255 int opt;
256 while ((opt = getopt(argc, argv, "n:f:o:")) != -1) {
258 (opt == 'n') ||
259 (opt == 'f') ||
260 (opt == 'o'), "invalid command argument")
261 switch (opt) {
262 default:
263 case 'n':
264 *grid_name = optarg;
265 break;
266 case 'f':
267 *grid_filename = optarg;
268 break;
269 case 'o':
270 *vtk_filename = optarg;
271 break;
272 }
273 }
274 YAC_ASSERT_F(optind >= argc, "non-option ARGV-element: \"%s\"", argv[optind])
275 YAC_ASSERT(argc != 1, "too few arguments")
276 YAC_ASSERT(*grid_name != NULL, "grid_name argument is missing")
277 YAC_ASSERT(*grid_filename != NULL, "grid_filename argument is missing")
278 YAC_ASSERT(*vtk_filename != NULL, "vtk_filename argument is missing")
279}
static void parse_arguments(int argc, char **argv, char const **grid_filename, char const **grid_name, char const **vtk_filename)
static char const * cmd
int main(int argc, char **argv)
static void write_vtk_file(char const *vtk_filename, char const *grid_name, size_t nv, size_t nc, double *clon, double *clat, double *vlon, double *vlat, int *gid, int *cmk, int *rnk)
#define YAC_ASSERT_F(exp, format,...)
static double * read_coords(int ncid, int varid, size_t varlen)
static int * read_int(int ncid, int varid, size_t varlen)
#define YAC_RAD
static void LLtoXYZ(double lon, double lat, double p_out[])
static void read_grid_file(char const *grid_filename, char const *grid_name, size_t *nv, size_t *nc, double **clon, double **clat, double **vlon, double **vlat, int **gid, int **cmk, int **rnk)
#define YAC_ASSERT(exp, msg)
void yac_nc_inq_varid(int ncid, char const *name, int *varidp)
Definition io_utils.c:411
void yac_nc_open(const char *path, int omode, int *ncidp)
Definition io_utils.c:350
void yac_nc_inq_dimid(int ncid, char const *name, int *dimidp)
Definition io_utils.c:385
int yac_file_exists(const char *filename)
Definition utils_core.c:12
#define YAC_HANDLE_ERROR(exp)
Definition io_utils.h:35
int yac_check_coord_units(int ncid, int varid)
Definition read_grid.c:45
void yac_vtk_write_cell_scalars_int(YAC_VTK_FILE *vtk_file, int *scalars, unsigned num_cells, char *name)
Definition vtk_output.c:250
void yac_vtk_write_point_data(YAC_VTK_FILE *vtk_file, double *point_data, unsigned num_points)
Definition vtk_output.c:69
void yac_vtk_close(YAC_VTK_FILE *vtk_file)
Definition vtk_output.c:403
void yac_vtk_write_cell_data(YAC_VTK_FILE *vtk_file, unsigned *cell_corners, unsigned *num_points_per_cell, unsigned num_cells)
Definition vtk_output.c:88
YAC_VTK_FILE * yac_vtk_open(const char *filename, const char *title)
Definition vtk_output.c:45
static struct user_input_data_points ** points
Definition yac.c:150
double(* yac_coordinate_pointer)[3]
Definition yac_types.h:19