YetAnotherCoupler 3.2.0_a
Loading...
Searching...
No Matches
weights2vtk.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#define YAC_WEIGHT_FILE_VERSION_1_0_STRING "yac weight file 1.0"
16
17// redefine YAC assert macros
18#undef YAC_ASSERT
19#undef YAC_ASSERT_F
20
21static char const * cmd;
22#define STR_USAGE \
23 "Usage: %s -S src_grid_type -T tgt_grid_type " \
24 "-s src_filename -t tgt_filename -w weight_filename " \
25 "-o vtk_filename\n\n" \
26 " grid_type can have the following values:\n" \
27 " 'c', 'C': cubed sphere grid (instead of a " \
28 "filename provide N, where\n" \
29 " N = sqrt(n/6), with n being the " \
30 "total number of cells\n" \
31 " 'm', 'M': curvilinear grid\n" \
32 " 'i', 'I': unstructured grid\n" \
33 " 'g', 'G': gaussian grid (instead of a filename provide the grid\n" \
34 " configuration \"x1,y1,x2,y2,nx,ny\", where:\n"\
35 " x1,y1: are the coordinates of the first grid corner\n"\
36 " x2,y2: are the coordinates of the last grid corner\n"\
37 " nx,ny: are the number of cells in each direction\n"\
38 " example: 0.0,-90.0,360.0,90.0,360,180)\n"\
39 " 's', 'S': unstructured grid in scrip file format\n" \
40 " (in addition to the grid filename also provide \n" \
41 " the mask filename and the grid name \"g,m,n\", where:\n" \
42 " g: grid filename\n" \
43 " m: mask filename\n" \
44 " n: grid name)\n" \
45 " - a lower case grid type indicates, that the global ids\n" \
46 " of the respective grid were \"0\"-based in the model\n" \
47 " component that generated the weight file\n" \
48 " - an upper case grid type indicates \"1\"-based global\n" \
49 " ids\n" \
50 "\n" \
51 "Example:\n" \
52 " Configuration:\n" \
53 " source grid type: unstructured\n" \
54 " source grid file: src_grid.nc\n" \
55 " target grid type: cubed sphere\n" \
56 " target grid file: 100 (N instead of filename)\n" \
57 " weight file name: weight_file.nc\n" \
58 " vtk file name: weights.vtk\n" \
59 " Command:\n" \
60 " %s -S i -T c -s src_grid.nc -t 100 -w weight_file.nc " \
61 "-o weights.vtk\n"
62
63#define YAC_ASSERT(exp, msg) \
64 { \
65 if(!((exp))) { \
66 fprintf(stderr, "ERROR: %s\n" STR_USAGE, msg, cmd, cmd); \
67 exit(EXIT_FAILURE); \
68 } \
69 }
70
71#define YAC_ASSERT_F(exp, format, ...) \
72 { \
73 if(!((exp))) { \
74 fprintf(stderr, "ERROR: " format "\n" STR_USAGE, __VA_ARGS__, cmd, cmd); \
75 exit(EXIT_FAILURE); \
76 } \
77 }
78
79static inline void normalise_vector(double v[]) {
80
81 double norm = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
82
83 v[0] *= norm;
84 v[1] *= norm;
85 v[2] *= norm;
86}
87
92struct link_data {
94 double weight;
95};
96
105
107 union {
108 struct {
109 unsigned n;
111 struct {
112 char const * filename;
114 struct {
115 double corners[2][2];
116 size_t num_cells[2];
118 struct {
119 char const * grid_filename;
120 char const * mask_filename;
121 char const * grid_name;
126};
127
128static void parse_arguments(int argc, char ** argv,
129 struct grid_config * src_grid_config,
130 struct grid_config * tgt_grid_config,
131 char const ** weight_filename,
132 char const ** vtk_filename);
133static void read_link_data(char const * weight_filename, int src_address_offset,
134 int tgt_address_offset, struct link_data ** links,
135 unsigned * num_links, enum yac_location ** src_locations,
136 enum yac_location * tgt_location, unsigned * max_src_idx,
137 unsigned * max_tgt_idx);
138static void write_data_to_file(char const * filename,
139 struct yac_basic_grid_data src_grid,
140 struct yac_basic_grid_data tgt_grid,
141 struct link_data * links,
142 unsigned num_links,
143 enum yac_location * src_locations,
144 enum yac_location tgt_location);
146
147int main(int argc, char ** argv) {
148
149 cmd = argv[0];
150
151 struct grid_config src_grid_config, tgt_grid_config;
152 char const * weight_filename, * vtk_filename;
153
154 parse_arguments(argc, argv, &src_grid_config, &tgt_grid_config,
155 &weight_filename, &vtk_filename);
156
157 //-------------------------------------
158 // read/generate source and target grid
159 //-------------------------------------
160 struct yac_basic_grid_data src_grid = create_grid(src_grid_config);
161 struct yac_basic_grid_data tgt_grid = create_grid(tgt_grid_config);
162
163 //-----------------
164 // read weight file
165 //-----------------
167 yac_file_exists(weight_filename),
168 "File %s does not exist.", weight_filename)
169
170 struct link_data * links;
171 unsigned num_links, max_src_idx, max_tgt_idx;
172 enum yac_location * src_locations;
173 enum yac_location tgt_location;
174 read_link_data(weight_filename, src_grid_config.address_offset,
175 tgt_grid_config.address_offset, &links, &num_links,
176 &src_locations, &tgt_location, &max_src_idx, &max_tgt_idx);
177
179 (max_src_idx < src_grid.num_cells) && (max_tgt_idx < tgt_grid.num_cells),
180 "weight file does not match with source and target grid")
181
182 //---------------
183 // write vtk file
184 //---------------
186 vtk_filename, src_grid, tgt_grid, links, num_links,
187 src_locations, tgt_location);
188
189 //---------
190 // clean up
191 //---------
192
193 free(src_locations);
194 free(links);
195 yac_basic_grid_data_free(tgt_grid);
196 yac_basic_grid_data_free(src_grid);
197
198 return EXIT_SUCCESS;
199}
200
201static void read_link_data(
202 char const * weight_filename, int src_address_offset,
203 int tgt_address_offset, struct link_data ** links,
204 unsigned * num_links, enum yac_location ** src_locations,
205 enum yac_location * tgt_location, unsigned * max_src_idx,
206 unsigned * max_tgt_idx) {
207
208 int ncid, dimid, var_id;
209 yac_nc_open(weight_filename, NC_NOWRITE, &ncid);
210
211 // global attributes
212 size_t version_len;
213 char * version;
214 YAC_HANDLE_ERROR(nc_inq_attlen(ncid, NC_GLOBAL, "version", &version_len));
215 version = malloc(version_len + 1);
216 version[version_len] = '\0';
217 YAC_HANDLE_ERROR(nc_get_att_text(ncid, NC_GLOBAL, "version", version));
219 (strlen(YAC_WEIGHT_FILE_VERSION_1_0_STRING) == version_len) &&
220 !strncmp(version, YAC_WEIGHT_FILE_VERSION_1_0_STRING, version_len),
221 "version string from weight file is not \""
223 free(version);
224
225 size_t str_link_len;
226 char * str_link;
227 var_id = NC_GLOBAL;
228 YAC_HANDLE_ERROR(nc_inq_attlen(ncid, var_id, "contains_links", &str_link_len));
229 str_link = malloc(str_link_len + 1);
230 str_link[str_link_len] = '\0';
231 YAC_HANDLE_ERROR(nc_get_att_text(ncid, var_id, "contains_links", str_link));
232
233 int contains_links =
234 (strlen("TRUE") == str_link_len) &&
235 !strncmp("TRUE", str_link, str_link_len);
237 contains_links ||
238 ((strlen("FALSE") == str_link_len) &&
239 !strncmp("FALSE", str_link, str_link_len)),
240 "invalid global attribute contains_links")
241
242 if (!contains_links) {
243 *links = NULL;
244 *num_links = 0;
245 *src_locations = NULL;
246 *max_src_idx = 0;
247 *max_tgt_idx = 0;
248 return;
249 }
250
251 size_t num_wgts = 0;
252 yac_nc_inq_dimid(ncid, "num_wgts", &dimid);
253 YAC_HANDLE_ERROR(nc_inq_dimlen(ncid, dimid, &num_wgts));
255 num_wgts == 1, "YAC only supports num_wgts == 1")
256
257 // get number of links from file
258 size_t num_links_in_file = 0;
259 yac_nc_inq_dimid(ncid, "num_links", &dimid);
260 YAC_HANDLE_ERROR(nc_inq_dimlen(ncid, dimid, &num_links_in_file));
261 YAC_ASSERT(num_links_in_file > 0, "no links defined")
262 *num_links = num_links_in_file;
263 *links = malloc(num_links_in_file * sizeof(**links));
264
265 // get number of pointsets
266 size_t num_pointsets = 0;
267 yac_nc_inq_dimid(ncid, "num_src_fields", &dimid);
268 YAC_HANDLE_ERROR(nc_inq_dimlen(ncid, dimid, &num_pointsets));
269 YAC_ASSERT(num_pointsets > 0, "no point sets in file")
270
271 // get max location string length from file
272 size_t max_loc_str_len;
273 yac_nc_inq_dimid(ncid, "max_loc_str_len", &dimid);
274 YAC_HANDLE_ERROR(nc_inq_dimlen(ncid, dimid, &max_loc_str_len));
276 max_loc_str_len == YAC_MAX_LOC_STR_LEN,
277 "wrong max location string length in weight file")
278
279 // get source locations
280 *src_locations = malloc(num_pointsets * sizeof(**src_locations));
281 yac_nc_inq_varid(ncid, "src_locations", &var_id);
282
283 for (unsigned i = 0; i < num_pointsets; ++i) {
284
285 char loc_str[YAC_MAX_LOC_STR_LEN];
286
287 size_t str_start[2] = {i, 0};
288 size_t str_count[2] = {1, YAC_MAX_LOC_STR_LEN};
289
290 YAC_HANDLE_ERROR(nc_get_vara_text(ncid, var_id, str_start, str_count, loc_str));
291
292 (*src_locations)[i] = yac_str2loc(loc_str);
293 }
294
295 // get target location
296 yac_nc_inq_varid(ncid, "dst_location", &var_id);
297 {
298 char loc_str[YAC_MAX_LOC_STR_LEN];
299 YAC_HANDLE_ERROR(nc_get_var_text(ncid, var_id, loc_str));
300 *tgt_location = yac_str2loc(loc_str);
301 }
302
303 // get number of links per pointset
304 unsigned * num_links_per_pointset =
305 malloc(num_pointsets * sizeof(*num_links_per_pointset));
306 yac_nc_inq_varid(ncid, "num_links_per_src_field", &var_id);
307 YAC_HANDLE_ERROR(nc_get_var_uint(ncid, var_id, num_links_per_pointset));
308
309 for (unsigned points_idx = 0, link_idx = 0; points_idx < num_pointsets;
310 ++points_idx)
311 for (unsigned i = 0; i < num_links_per_pointset[points_idx];
312 ++i, ++link_idx)
313 (*links)[link_idx].points_idx = points_idx;
314 free(num_links_per_pointset);
315
316 // get links
317 int * address = malloc(num_links_in_file * sizeof(*address));
318 yac_nc_inq_varid(ncid, "src_address", &var_id);
319 YAC_HANDLE_ERROR(nc_get_var_int(ncid, var_id, address));
320 *max_src_idx = 0;
321 for (unsigned i = 0; i < num_links_in_file; ++i) {
322 int idx = address[i] + src_address_offset;
323 YAC_ASSERT_F(idx >= 0, "invalid src index (%d)", idx);
324 if ((unsigned)idx > *max_src_idx) *max_src_idx = (unsigned)idx;
325 (*links)[i].src_idx = (unsigned)idx;
326 }
327
328 yac_nc_inq_varid(ncid, "dst_address", &var_id);
329 YAC_HANDLE_ERROR(nc_get_var_int(ncid, var_id, address));
330 *max_tgt_idx = 0;
331 for (unsigned i = 0; i < num_links_in_file; ++i) {
332 int idx = address[i] + tgt_address_offset;
333 YAC_ASSERT_F(idx >= 0, "invalid tgt index (%d)", idx);
334 if ((unsigned)idx > *max_tgt_idx) *max_tgt_idx = (unsigned)idx;
335 (*links)[i].tgt_idx = (unsigned)idx;
336 }
337 free(address);
338
339 double * weights = malloc(num_links_in_file * sizeof(*weights));
340 yac_nc_inq_varid(ncid, "remap_matrix", &var_id);
341 YAC_HANDLE_ERROR(nc_get_var_double(ncid, var_id, weights));
342 for (size_t i = 0; i < num_links_in_file; ++i)
343 (*links)[i].weight = weights[i];
344 free(weights);
345
346 YAC_HANDLE_ERROR(nc_close(ncid));
347}
348
350 struct yac_basic_grid_data * grid, size_t cell_index, double * point) {
351
352 int num_cell_corners = grid->num_vertices_per_cell[cell_index];
353 size_t * cell_to_vertex = grid->cell_to_vertex +
354 grid->cell_to_vertex_offsets[cell_index];
355 yac_coordinate_pointer vertex_coordinates = grid->vertex_coordinates;
356
357 point[0] = 0;
358 point[1] = 0;
359 point[2] = 0;
360
361 for (int i = 0; i < num_cell_corners; ++i)
362 for (int j = 0; j < 3; ++j)
363 point[j] += vertex_coordinates[cell_to_vertex[i]][j];
364 normalise_vector(point);
365}
366
368 struct yac_basic_grid_data * grid, size_t edge_index, double * point) {
369
370 size_t * edge_to_vertex = grid->edge_to_vertex[edge_index];
371 yac_coordinate_pointer vertex_coordinates = grid->vertex_coordinates;
372
373 point[0] = vertex_coordinates[edge_to_vertex[0]][0] +
374 vertex_coordinates[edge_to_vertex[1]][0];
375 point[1] = vertex_coordinates[edge_to_vertex[0]][1] +
376 vertex_coordinates[edge_to_vertex[1]][1];
377 point[2] = vertex_coordinates[edge_to_vertex[0]][2] +
378 vertex_coordinates[edge_to_vertex[1]][2];
379
380 normalise_vector(point);
381}
382
384 struct yac_basic_grid_data * grid, size_t point_index,
385 enum yac_location location, double * point) {
386
388 (location == YAC_LOC_CELL) ||
389 (location == YAC_LOC_CORNER) ||
390 (location == YAC_LOC_EDGE), "unsupported point location")
391 switch (location) {
392 case(YAC_LOC_CELL):
393 get_cell_middle_point(grid, point_index, point);
394 break;
395 case(YAC_LOC_CORNER):
396 memcpy(point, grid->vertex_coordinates[point_index], 3 * sizeof(*point));
397 break;
398 default:
399 case(YAC_LOC_EDGE):
400 get_edge_middle_point(grid, point_index, point);
401 break;
402 };
403}
404
406 struct link_data * links, unsigned num_links,
407 struct yac_basic_grid_data * src_grid, struct yac_basic_grid_data * tgt_grid,
408 enum yac_location * src_locations, enum yac_location tgt_location,
410
411 for (unsigned i = 0; i < num_links; ++i) {
412
414 src_grid, (size_t)(links[i].src_idx), src_locations[links[i].points_idx],
415 points[2*i+0]);
417 tgt_grid, (size_t)(links[i].tgt_idx), tgt_location, points[2*i+1]);
418 }
419}
420
422 struct yac_basic_grid_data * grid, unsigned * cell_data, unsigned offset) {
423
424 for (size_t i = 0, k = 0; i < grid->num_cells; ++i) {
425
426 size_t * curr_cell_corners =
427 grid->cell_to_vertex + grid->cell_to_vertex_offsets[i];
428 int num_cell_corners = grid->num_vertices_per_cell[i];
429
430 for (int j = 0; j < num_cell_corners; ++j)
431 cell_data[k++] = curr_cell_corners[j] + offset;
432 }
433}
434
436 unsigned num_links, unsigned * polygon_data, unsigned offset) {
437
438 for (unsigned i = 0; i < 2 * num_links; ++i)
439 polygon_data[i] = i + offset;
440}
441
442static void write_data_to_file(char const * filename,
443 struct yac_basic_grid_data src_grid,
444 struct yac_basic_grid_data tgt_grid,
445 struct link_data * links, unsigned num_links,
446 enum yac_location * src_locations,
447 enum yac_location tgt_location) {
448
449 //------------------------------------
450 // generate cell data for the vtk file
451 //------------------------------------
452
453 size_t num_grid_corners[2] =
454 {src_grid.num_vertices, tgt_grid.num_vertices};
455 size_t total_num_points =
456 num_grid_corners[0] + num_grid_corners[1] + 2 * (size_t)num_links;
457 size_t num_polygons[3] =
458 {src_grid.num_cells, tgt_grid.num_cells, num_links};
459 size_t total_num_polygons =
460 num_polygons[0] + num_polygons[1] + num_polygons[2];
461
462 yac_coordinate_pointer points = malloc(total_num_points * sizeof(*points));
463
464 // get the point data of the grids
465 memcpy(points, src_grid.vertex_coordinates,
466 src_grid.num_vertices * sizeof(*points));
467 memcpy(points + src_grid.num_vertices, tgt_grid.vertex_coordinates,
468 tgt_grid.num_vertices * sizeof(*points));
470 links, num_links, &src_grid, &tgt_grid, src_locations, tgt_location,
471 points + num_grid_corners[0] + num_grid_corners[1]);
472
473 unsigned * num_points_per_polygon =
474 malloc(total_num_polygons * sizeof(*num_points_per_polygon));
475 unsigned num_points_per_polygon_sum[3] = {0, 0, 0};
476 for (size_t i = 0; i < num_polygons[0]; ++i) {
477 num_points_per_polygon_sum[0] +=
478 (num_points_per_polygon[i] =
479 (unsigned)(src_grid.num_vertices_per_cell[i]));
480 }
481 for (size_t i = 0; i < num_polygons[1]; ++i) {
482 num_points_per_polygon_sum[1] +=
483 (num_points_per_polygon[num_polygons[0] + i] =
484 (unsigned)(tgt_grid.num_vertices_per_cell[i]));
485 }
486 for (size_t i = 0; i < num_polygons[2]; ++i)
487 num_points_per_polygon[num_polygons[0] + num_polygons[1] + i] = 2;
488 num_points_per_polygon_sum[2] = 2 * num_polygons[2];
489
490 unsigned * polygon_data =
491 malloc((num_points_per_polygon_sum[0] + num_points_per_polygon_sum[1] +
492 num_points_per_polygon_sum[2]) * sizeof(*polygon_data));
493 get_grid_cell_data(&src_grid, polygon_data, 0);
494 get_grid_cell_data(&tgt_grid, polygon_data + num_points_per_polygon_sum[0],
495 num_grid_corners[0]);
497 num_links, polygon_data + num_points_per_polygon_sum[0] +
498 num_points_per_polygon_sum[1], num_grid_corners[0] + num_grid_corners[1]);
499
500 //------------------------------------
501 // generate scalar data
502 //------------------------------------
503
504 unsigned * polygon_type = malloc(total_num_polygons * sizeof(*polygon_type));
505 for (size_t i = 0; i < num_polygons[0]; ++i) polygon_type[i] = 0;
506 for (size_t i = 0; i < num_polygons[1]; ++i)
507 polygon_type[num_polygons[0] + i] = 1;
508 for (size_t i = 0; i < num_polygons[2]; ++i)
509 polygon_type[num_polygons[0] + num_polygons[1] + i] = 2;
510
511 double * weights = NULL;
512 if (num_links > 0) {
513 weights = malloc(total_num_polygons * sizeof(*weights));
514 for (size_t i = 0; i < num_polygons[0] + num_polygons[1]; ++i)
515 weights[i] = -1;
516 for (size_t i = 0; i < num_polygons[2]; ++i)
517 weights[i + num_polygons[0] + num_polygons[1]] = links[i].weight;
518 }
519
520 int * cell_ids = malloc(total_num_polygons * sizeof(*cell_ids));
521 if (src_grid.cell_ids != NULL) {
522 for (size_t i = 0; i < num_polygons[0]; ++i)
523 cell_ids[i] = (int)(src_grid.cell_ids[i]);
524 } else {
525 for (size_t i = 0; i < num_polygons[0]; ++i) cell_ids[i] = (int)i;
526 }
527 if (tgt_grid.cell_ids != NULL) {
528 for (size_t i = 0; i < num_polygons[1]; ++i)
529 cell_ids[num_polygons[0] + i] = (int)(tgt_grid.cell_ids[i]);
530 } else {
531 for (size_t i = 0; i < num_polygons[1]; ++i)
532 cell_ids[num_polygons[0] + i] = (int)i;
533 }
534 for (size_t i = 0; i < num_polygons[2]; ++i)
535 cell_ids[num_polygons[0] + num_polygons[1] + i] = (int)i;
536
537 int * vertex_ids = malloc(total_num_points * sizeof(*vertex_ids));
538 if (src_grid.vertex_ids != NULL) {
539 for (size_t i = 0; i < src_grid.num_vertices; ++i)
540 vertex_ids[i] = (int)(src_grid.vertex_ids[i]);
541 } else {
542 for (size_t i = 0; i < src_grid.num_vertices; ++i)
543 vertex_ids[i] = (int)i;
544 }
545 if (tgt_grid.vertex_ids != NULL) {
546 for (size_t i = 0; i < tgt_grid.num_vertices; ++i)
547 vertex_ids[src_grid.num_vertices + i] = (int)(tgt_grid.vertex_ids[i]);
548 } else {
549 for (size_t i = 0; i < tgt_grid.num_vertices; ++i)
550 vertex_ids[src_grid.num_vertices + i] = (int)i;
551 }
552 for (size_t i = 0; i < 2 * (size_t)num_links; ++i)
553 vertex_ids[src_grid.num_vertices + tgt_grid.num_vertices + i] =
554 (int)(i >> 1);
555
556 //------------------------------------
557 // generate the actual vtk file
558 //------------------------------------
559
560 YAC_VTK_FILE * file = yac_vtk_open(filename, "grid data");
561 yac_vtk_write_point_data(file, &(points[0][0]), total_num_points);
563 file, polygon_data, num_points_per_polygon, total_num_polygons);
565 file, cell_ids, total_num_polygons, "cell_ids");
567 file, polygon_type, total_num_polygons, "polygon_type");
568 if (num_links > 0)
570 file, weights, total_num_polygons, "weights");
572 file, vertex_ids, total_num_points, "vertex_ids");
573 yac_vtk_close(file);
574
575 //------------------------------------
576 // some final cleanup
577 //------------------------------------
578
579 free(weights);
580 free(polygon_type);
581 free(cell_ids);
582 free(vertex_ids);
583 free(polygon_data);
584 free(num_points_per_polygon);
585 free(points);
586}
587
589 struct grid_config * grid_config, char * arg, char * str) {
590
591 YAC_ASSERT_F(arg != NULL, "-%c argument is missing", str[0])
592
594 (grid_config->type == CUBE) ||
595 (grid_config->type == CURVE) ||
596 (grid_config->type == UNSTRUCT) ||
597 (grid_config->type == GAUSS) ||
598 (grid_config->type == SCRIP),
599 "invalid %s grid type\n", str);
600
601 switch (grid_config->type) {
602 default:
603 case CUBE:
604 grid_config->config.cube.n = atoi(arg);
607 "invalid N for cubed sphere %s grid\n", str)
608 break;
609 case CURVE:
611 break;
612 case UNSTRUCT:
614 break;
615 case GAUSS:
617 sscanf(
618 arg, "%lf,%lf,%lf,%lf,%zu,%zu",
625 "invalid %s grid configuration (gauss grid)", str);
627 (grid_config->config.gauss.num_cells[0] > 0) &&
629 "invalid %s grid configuration "
630 "(gauss grid has invalid number of cells)", str)
631 break;
632 case SCRIP: {
633 char * arg_copy = strdup(arg);
634 grid_config->config.scrip.grid_filename = strtok(arg_copy, ",");
635 grid_config->config.scrip.mask_filename = strtok(NULL, ",");
636 grid_config->config.scrip.grid_name = strtok(NULL, ",");
637 break;
638 }
639 }
640}
641
642void parse_arguments(int argc, char ** argv,
643 struct grid_config * src_grid_config,
644 struct grid_config * tgt_grid_config,
645 char const ** weight_filename,
646 char const ** vtk_filename) {
647
648 src_grid_config->type = NONE;
649 tgt_grid_config->type = NONE;
650 *weight_filename = NULL;
651 *vtk_filename = NULL;
652
653 char * src_arg = NULL;
654 char * tgt_arg = NULL;
655
656 int opt;
657 while ((opt = getopt(argc, argv, "S:T:s:t:w:o:")) != -1) {
659 (opt == 'S') ||
660 (opt == 'T') ||
661 (opt == 's') ||
662 (opt == 't') ||
663 (opt == 'w') ||
664 (opt == 'o'), "invalid command argument")
665 switch (opt) {
666 default:
667 case 'S':
668 case 'T':
669 {
670 struct grid_config * grid_config =
671 (opt == 'S')?src_grid_config:tgt_grid_config;
672
674 strlen(optarg) == 1, "invalid grid type for argument %c", (char)opt);
675
676 switch (optarg[0]) {
677 case 'c':
678 case 'C':
680 break;
681 case 'm':
682 case 'M':
684 break;
685 case 'i':
686 case 'I':
688 break;
689 case 'g':
690 case 'G':
692 break;
693 case 's':
694 case 'S':
696 };
697 grid_config->address_offset = (optarg[0] < 'a')?-2:-1;
698 break;
699 }
700 case 's':
701 src_arg = optarg;
702 break;
703 case 't':
704 tgt_arg = optarg;
705 break;
706 case 'w':
707 *weight_filename = optarg;
708 break;
709 case 'o':
710 *vtk_filename = optarg;
711 break;
712 }
713 }
714 YAC_ASSERT_F(optind >= argc, "non-option ARGV-element: \"%s\"", argv[optind])
715 YAC_ASSERT(argc != 1, "too few arguments")
716 YAC_ASSERT(*weight_filename != NULL, "weight_filename argument is missing")
717 YAC_ASSERT(*vtk_filename != NULL, "vtk_filename argument is missing")
718
719 interpret_grid_arg(src_grid_config, src_arg, "source");
720 interpret_grid_arg(tgt_grid_config, tgt_arg, "target");
721}
722
723static double * generate_vertices(double start, double end, size_t count) {
724
725 double * vertices = malloc(count * sizeof(*vertices));
726
727 double d = (end - start) / (double)(count - 1);
728
729 for (size_t i = 0; i < count; ++i)
730 vertices[i] = start + d * (double)i;
731 vertices[count - 1] = end;
732
733 return vertices;
734}
735
737 double * first_corner, double * last_corner, size_t * num_cells) {
738
739 size_t num_vertices[2] = {num_cells[0] + 1, num_cells[1] + 1};
740 int cyclic[2] = {0, 0};
741 double * lon_vertices =
742 generate_vertices(first_corner[0], last_corner[0], num_vertices[0]);
743 double * lat_vertices =
744 generate_vertices(first_corner[1], last_corner[1], num_vertices[1]);
745
746 struct yac_basic_grid_data grid_data =
748 num_vertices, cyclic, lon_vertices, lat_vertices);
749
750 free(lon_vertices);
751 free(lat_vertices);
752
753 return grid_data;
754}
755
757
759 (grid_config.type == CUBE) ||
760 (grid_config.type == CURVE) ||
762 (grid_config.type == GAUSS) ||
763 (grid_config.type == SCRIP), "invalid grid configuration")
764 switch(grid_config.type) {
765 default:
766 case CUBE:
768 case CURVE:
771 "File %s does not exist.", grid_config.config.curve.filename);
772 return
775 case UNSTRUCT:
778 "File %s does not exist.", grid_config.config.unstruct.filename);
779 return
782 case GAUSS:
783 return
788 case SCRIP:
791 "File %s does not exist.", grid_config.config.scrip.grid_filename);
794 "File %s does not exist.", grid_config.config.scrip.mask_filename);
795 return
799 (char*)(grid_config.config.scrip.grid_name), 0, 0);
800 }
801}
802
void yac_basic_grid_data_free(struct yac_basic_grid_data grid)
struct yac_basic_grid_data yac_generate_basic_grid_data_reg_2d_deg(size_t nbr_vertices[2], int cyclic[2], double *lon_vertices, double *lat_vertices)
Definition grid_reg2d.c:74
struct yac_basic_grid_data yac_generate_cubed_sphere_grid(unsigned n)
void yac_nc_inq_varid(int ncid, char const *name, int *varidp)
Definition io_utils.c:403
void yac_nc_open(const char *path, int omode, int *ncidp)
Definition io_utils.c:344
void yac_nc_inq_dimid(int ncid, char const *name, int *dimidp)
Definition io_utils.c:379
int yac_file_exists(const char *filename)
Definition utils_core.c:12
#define YAC_HANDLE_ERROR(exp)
Definition io_utils.h:30
enum yac_location yac_str2loc(char const *location_str)
Definition location.c:21
yac_location
Definition location.h:12
@ YAC_LOC_CORNER
Definition location.h:15
@ YAC_LOC_EDGE
Definition location.h:16
@ YAC_LOC_CELL
Definition location.h:14
#define YAC_MAX_LOC_STR_LEN
Definition location.h:10
struct yac_basic_grid_data yac_read_icon_basic_grid_data(char const *filename)
struct yac_basic_grid_data yac_read_mpiom_basic_grid_data(char const *filename)
struct yac_basic_grid_data yac_read_scrip_basic_grid_data(char const *grid_filename, char const *mask_filename, char const *grid_name, int valid_mask_value, int use_ll_edges)
struct grid_config::@64::@67 gauss
unsigned n
struct grid_config::@64::@66 unstruct
char const * grid_name
char const * filename
struct grid_config::@64::@65 cube
double corners[2][2]
struct grid_config::@64::@68 scrip
struct grid_config::@64::@66 curve
enum grid_type type
char const * mask_filename
union grid_config::@64 config
char const * grid_filename
size_t num_cells[2]
yac_coordinate_pointer vertex_coordinates
yac_size_t_2_pointer edge_to_vertex
size_t * cell_to_vertex_offsets
void yac_vtk_write_cell_scalars_uint(YAC_VTK_FILE *vtk_file, unsigned *scalars, unsigned num_cells, char *name)
Definition vtk_output.c:243
void yac_vtk_write_cell_scalars_double(YAC_VTK_FILE *vtk_file, double *scalars, unsigned num_cells, char *name)
Definition vtk_output.c:264
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_write_point_scalars_int(YAC_VTK_FILE *vtk_file, int *scalars, unsigned num_points, char *name)
Definition vtk_output.c:278
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 void parse_arguments(int argc, char **argv, struct grid_config *src_grid_config, struct grid_config *tgt_grid_config, char const **weight_filename, char const **vtk_filename)
static void get_grid_cell_data(struct yac_basic_grid_data *grid, unsigned *cell_data, unsigned offset)
static void get_link_address_data(unsigned num_links, unsigned *polygon_data, unsigned offset)
static char const * cmd
Definition weights2vtk.c:21
static void interpret_grid_arg(struct grid_config *grid_config, char *arg, char *str)
int main(int argc, char **argv)
static struct yac_basic_grid_data create_grid(struct grid_config grid_config)
static void get_cell_middle_point(struct yac_basic_grid_data *grid, size_t cell_index, double *point)
#define YAC_ASSERT_F(exp, format,...)
Definition weights2vtk.c:71
grid_type
Definition weights2vtk.c:97
@ UNSTRUCT
@ GAUSS
@ CURVE
@ SCRIP
@ NONE
Definition weights2vtk.c:98
@ CUBE
Definition weights2vtk.c:99
static struct yac_basic_grid_data generate_gauss_grid(double *first_corner, double *last_corner, size_t *num_cells)
static void get_link_xyz_coordinates(struct link_data *links, unsigned num_links, struct yac_basic_grid_data *src_grid, struct yac_basic_grid_data *tgt_grid, enum yac_location *src_locations, enum yac_location tgt_location, yac_coordinate_pointer points)
#define YAC_WEIGHT_FILE_VERSION_1_0_STRING
Definition weights2vtk.c:15
static void read_link_data(char const *weight_filename, int src_address_offset, int tgt_address_offset, struct link_data **links, unsigned *num_links, enum yac_location **src_locations, enum yac_location *tgt_location, unsigned *max_src_idx, unsigned *max_tgt_idx)
static void get_point_coordinates(struct yac_basic_grid_data *grid, size_t point_index, enum yac_location location, double *point)
static double * generate_vertices(double start, double end, size_t count)
static void normalise_vector(double v[])
Definition weights2vtk.c:79
static void write_data_to_file(char const *filename, struct yac_basic_grid_data src_grid, struct yac_basic_grid_data tgt_grid, struct link_data *links, unsigned num_links, enum yac_location *src_locations, enum yac_location tgt_location)
static void get_edge_middle_point(struct yac_basic_grid_data *grid, size_t edge_index, double *point)
#define YAC_ASSERT(exp, msg)
Definition weights2vtk.c:63
static struct user_input_data_points ** points
Definition yac.c:120
#define YAC_ASSERT_F(exp, format,...)
Definition yac_assert.h:18
#define YAC_ASSERT(exp, msg)
Definition yac_assert.h:15
double(* yac_coordinate_pointer)[3]
Definition yac_types.h:19