15#define YAC_WEIGHT_FILE_VERSION_1_0_STRING "yac weight file 1.0"
21static char const *
cmd;
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" \
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" \
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" \
60 " %s -S i -T c -s src_grid.nc -t 100 -w weight_file.nc " \
63#define YAC_ASSERT(exp, msg) \
66 fprintf(stderr, "ERROR: %s\n" STR_USAGE, msg, cmd, cmd); \
71#define YAC_ASSERT_F(exp, format, ...) \
74 fprintf(stderr, "ERROR: " format "\n" STR_USAGE, __VA_ARGS__, cmd, cmd); \
81 double norm = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
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);
147int main(
int argc,
char ** argv) {
151 struct grid_config src_grid_config, tgt_grid_config;
152 char const * weight_filename, * vtk_filename;
155 &weight_filename, &vtk_filename);
168 "File %s does not exist.", weight_filename)
171 unsigned num_links, max_src_idx, max_tgt_idx;
176 &src_locations, &tgt_location, &max_src_idx, &max_tgt_idx);
180 "weight file does not match with source and target grid")
186 vtk_filename, src_grid, tgt_grid, links, num_links,
187 src_locations, tgt_location);
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) {
208 int ncid, dimid, var_id;
215 version = malloc(version_len + 1);
216 version[version_len] =
'\0';
221 "version string from weight file is not \""
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));
234 (strlen(
"TRUE") == str_link_len) &&
235 !strncmp(
"TRUE", str_link, str_link_len);
238 ((strlen(
"FALSE") == str_link_len) &&
239 !strncmp(
"FALSE", str_link, str_link_len)),
240 "invalid global attribute contains_links")
242 if (!contains_links) {
245 *src_locations = NULL;
255 num_wgts == 1,
"YAC only supports num_wgts == 1")
258 size_t num_links_in_file = 0;
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));
266 size_t num_pointsets = 0;
269 YAC_ASSERT(num_pointsets > 0,
"no point sets in file")
272 size_t max_loc_str_len;
277 "wrong max location string length in weight file")
280 *src_locations = malloc(num_pointsets *
sizeof(**src_locations));
283 for (
unsigned i = 0; i < num_pointsets; ++i) {
287 size_t str_start[2] = {i, 0};
290 YAC_HANDLE_ERROR(nc_get_vara_text(ncid, var_id, str_start, str_count, loc_str));
304 unsigned * num_links_per_pointset =
305 malloc(num_pointsets *
sizeof(*num_links_per_pointset));
311 for (
unsigned i = 0; i < num_links_per_pointset[
points_idx];
314 free(num_links_per_pointset);
317 int * address = malloc(num_links_in_file *
sizeof(*address));
321 for (
unsigned i = 0; i < num_links_in_file; ++i) {
322 int idx = address[i] + src_address_offset;
324 if ((
unsigned)idx > *max_src_idx) *max_src_idx = (unsigned)idx;
325 (*links)[i].src_idx = (unsigned)idx;
331 for (
unsigned i = 0; i < num_links_in_file; ++i) {
332 int idx = address[i] + tgt_address_offset;
334 if ((
unsigned)idx > *max_tgt_idx) *max_tgt_idx = (unsigned)idx;
335 (*links)[i].tgt_idx = (unsigned)idx;
339 double * weights = malloc(num_links_in_file *
sizeof(*weights));
342 for (
size_t i = 0; i < num_links_in_file; ++i)
343 (*links)[i].weight = weights[i];
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];
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];
390 (location ==
YAC_LOC_EDGE),
"unsupported point location")
406 struct link_data * links,
unsigned num_links,
411 for (
unsigned i = 0; i < num_links; ++i) {
417 tgt_grid, (
size_t)(links[i].
tgt_idx), tgt_location,
points[2*i+1]);
424 for (
size_t i = 0, k = 0; i < grid->
num_cells; ++i) {
426 size_t * curr_cell_corners =
430 for (
int j = 0; j < num_cell_corners; ++j)
431 cell_data[k++] = curr_cell_corners[j] + offset;
436 unsigned num_links,
unsigned * polygon_data,
unsigned offset) {
438 for (
unsigned i = 0; i < 2 * num_links; ++i)
439 polygon_data[i] = i + offset;
445 struct link_data * links,
unsigned num_links,
453 size_t num_grid_corners[2] =
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] =
459 size_t total_num_polygons =
460 num_polygons[0] + num_polygons[1] + num_polygons[2];
470 links, num_links, &src_grid, &tgt_grid, src_locations, tgt_location,
471 points + num_grid_corners[0] + num_grid_corners[1]);
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] =
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] =
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];
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));
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]);
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;
511 double * weights = NULL;
513 weights = malloc(total_num_polygons *
sizeof(*weights));
514 for (
size_t i = 0; i < num_polygons[0] + num_polygons[1]; ++i)
516 for (
size_t i = 0; i < num_polygons[2]; ++i)
517 weights[i + num_polygons[0] + num_polygons[1]] = links[i].
weight;
520 int * cell_ids = malloc(total_num_polygons *
sizeof(*cell_ids));
522 for (
size_t i = 0; i < num_polygons[0]; ++i)
523 cell_ids[i] = (
int)(src_grid.
cell_ids[i]);
525 for (
size_t i = 0; i < num_polygons[0]; ++i) cell_ids[i] = (
int)i;
528 for (
size_t i = 0; i < num_polygons[1]; ++i)
529 cell_ids[num_polygons[0] + i] = (
int)(tgt_grid.
cell_ids[i]);
531 for (
size_t i = 0; i < num_polygons[1]; ++i)
532 cell_ids[num_polygons[0] + i] = (
int)i;
534 for (
size_t i = 0; i < num_polygons[2]; ++i)
535 cell_ids[num_polygons[0] + num_polygons[1] + i] = (
int)i;
537 int * vertex_ids = malloc(total_num_points *
sizeof(*vertex_ids));
540 vertex_ids[i] = (
int)(src_grid.
vertex_ids[i]);
543 vertex_ids[i] = (
int)i;
552 for (
size_t i = 0; i < 2 * (size_t)num_links; ++i)
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");
570 file, weights, total_num_polygons,
"weights");
572 file, vertex_ids, total_num_points,
"vertex_ids");
584 free(num_points_per_polygon);
591 YAC_ASSERT_F(arg != NULL,
"-%c argument is missing", str[0])
599 "invalid %s grid type\n", str);
607 "invalid N for cubed sphere %s grid\n", str)
618 arg,
"%lf,%lf,%lf,%lf,%zu,%zu",
625 "invalid %s grid configuration (gauss grid)", str);
629 "invalid %s grid configuration "
630 "(gauss grid has invalid number of cells)", str)
633 char * arg_copy = strdup(arg);
645 char const ** weight_filename,
646 char const ** vtk_filename) {
650 *weight_filename = NULL;
651 *vtk_filename = NULL;
653 char * src_arg = NULL;
654 char * tgt_arg = NULL;
657 while ((opt = getopt(argc, argv,
"S:T:s:t:w:o:")) != -1) {
664 (opt ==
'o'),
"invalid command argument")
671 (opt ==
'S')?src_grid_config:tgt_grid_config;
674 strlen(optarg) == 1,
"invalid grid type for argument %c", (
char)opt);
707 *weight_filename = optarg;
710 *vtk_filename = optarg;
714 YAC_ASSERT_F(optind >= argc,
"non-option ARGV-element: \"%s\"", argv[optind])
716 YAC_ASSERT(*weight_filename != NULL,
"weight_filename argument is missing")
717 YAC_ASSERT(*vtk_filename != NULL,
"vtk_filename argument is missing")
725 double * vertices = malloc(count *
sizeof(*vertices));
727 double d = (end - start) / (
double)(count - 1);
729 for (
size_t i = 0; i < count; ++i)
730 vertices[i] = start + d * (
double)i;
731 vertices[count - 1] = end;
737 double * first_corner,
double * last_corner,
size_t *
num_cells) {
740 int cyclic[2] = {0, 0};
741 double * lon_vertices =
743 double * lat_vertices =
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)
struct yac_basic_grid_data yac_generate_cubed_sphere_grid(unsigned n)
void yac_nc_inq_varid(int ncid, char const *name, int *varidp)
void yac_nc_open(const char *path, int omode, int *ncidp)
void yac_nc_inq_dimid(int ncid, char const *name, int *dimidp)
int yac_file_exists(const char *filename)
#define YAC_HANDLE_ERROR(exp)
enum yac_location yac_str2loc(char const *location_str)
#define YAC_MAX_LOC_STR_LEN
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
struct grid_config::@64::@66 unstruct
struct grid_config::@64::@65 cube
struct grid_config::@64::@68 scrip
struct grid_config::@64::@66 curve
char const * mask_filename
union grid_config::@64 config
char const * grid_filename
yac_coordinate_pointer vertex_coordinates
yac_size_t_2_pointer edge_to_vertex
size_t * cell_to_vertex_offsets
int * num_vertices_per_cell
void yac_vtk_write_cell_scalars_uint(YAC_VTK_FILE *vtk_file, unsigned *scalars, unsigned num_cells, char *name)
void yac_vtk_write_cell_scalars_double(YAC_VTK_FILE *vtk_file, double *scalars, unsigned num_cells, char *name)
void yac_vtk_write_cell_scalars_int(YAC_VTK_FILE *vtk_file, int *scalars, unsigned num_cells, char *name)
void yac_vtk_write_point_data(YAC_VTK_FILE *vtk_file, double *point_data, unsigned num_points)
void yac_vtk_write_point_scalars_int(YAC_VTK_FILE *vtk_file, int *scalars, unsigned num_points, char *name)
void yac_vtk_close(YAC_VTK_FILE *vtk_file)
void yac_vtk_write_cell_data(YAC_VTK_FILE *vtk_file, unsigned *cell_corners, unsigned *num_points_per_cell, unsigned num_cells)
YAC_VTK_FILE * yac_vtk_open(const char *filename, const char *title)
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 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,...)
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
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[])
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)
static struct user_input_data_points ** points
#define YAC_ASSERT_F(exp, format,...)
#define YAC_ASSERT(exp, msg)
double(* yac_coordinate_pointer)[3]