YetAnotherCoupler 3.5.2
Loading...
Searching...
No Matches
basic_grid.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
8#include "basic_grid.h"
9#include "grid_cell.h"
10#include "field_data_set.h"
11#include "io_utils.h"
12#include "yac_mpi_internal.h"
13#include "time.h"
14#include "yac_config.h"
15#include "geometry.h"
16
23
25 .vertex_coordinates = NULL,
26 .cell_ids = NULL,
27 .vertex_ids = NULL,
28 .edge_ids = NULL,
29 .num_cells = 0,
30 .num_vertices = 0,
31 .num_edges = 0,
32 .core_cell_mask = NULL,
33 .core_vertex_mask = NULL,
34 .core_edge_mask = NULL,
35 .num_vertices_per_cell = NULL,
36 .num_cells_per_vertex = NULL,
37 .cell_to_vertex = NULL,
38 .cell_to_vertex_offsets = NULL,
39 .cell_to_edge = NULL,
40 .cell_to_edge_offsets = NULL,
41 .vertex_to_cell = NULL,
42 .vertex_to_cell_offsets = NULL,
43 .edge_to_vertex = NULL,
44 .edge_type = NULL,
45 .num_total_cells = 0,
46 .num_total_vertices = 0,
47 .num_total_edges = 0
48};
49
51 char const * name, struct yac_basic_grid_data grid_data) {
52
53 struct yac_basic_grid * grid = xmalloc(1 * sizeof(*grid));
54
55 grid->name = strdup(name);
56 grid->is_empty = 0;
58 grid->data = grid_data;
59
60 return grid;
61}
62
64 struct yac_basic_grid * grid =
66 grid->is_empty = 1;
67 return grid;
68}
69
71
73 grid, "ERROR(yac_basic_grid_delete): "
74 "NULL is not a valid value for argument grid")
75 free(grid->name);
78 free(grid);
79}
80
82 struct yac_basic_grid * grid, struct yac_interp_field field) {
83
85 grid, "ERROR(yac_basic_grid_get_field_coordinates): "
86 "NULL is not a valid value for argument grid")
87
89 (field.coordinates_idx != SIZE_MAX)?
92 field.coordinates_idx):NULL;
93
94 // if no field coordinates are defined, but the location is at the corners of
95 // of the grid cells, return coordinates of them
96 return
97 ((coords != NULL) || (field.location != YAC_LOC_CORNER))?
99}
100
102 struct yac_basic_grid * grid, enum yac_location location) {
103
105 (location == YAC_LOC_CELL) ||
106 (location == YAC_LOC_CORNER) ||
107 (location == YAC_LOC_EDGE),
108 "ERROR(yac_basic_grid_get_core_mask): invalid location")
109
110 switch (location) {
111 default:
112 case(YAC_LOC_CELL): return grid->data.core_cell_mask;
113 case(YAC_LOC_CORNER): return grid->data.core_vertex_mask;
114 case(YAC_LOC_EDGE): return grid->data.core_edge_mask;
115 };
116}
117
119 struct yac_basic_grid * grid, struct yac_interp_field field) {
120
121 if (field.masks_idx == SIZE_MAX) return NULL;
122
123 return
126}
127
128char const * yac_basic_grid_get_name(struct yac_basic_grid * grid) {
129
131 grid, "ERROR(yac_basic_grid_get_name): "
132 "NULL is not a valid value for argument grid")
133
134 return grid->name;
135}
136
138 struct yac_basic_grid * grid) {
139
141 grid, "ERROR(yac_basic_grid_get_data): "
142 "NULL is not a valid value for argument grid")
143
144 return &(grid->data);
145}
146
148 struct yac_basic_grid * grid, enum yac_location location) {
149
151 grid, "ERROR(yac_basic_grid_get_data_size): "
152 "NULL is not a valid value for argument grid")
154 (location == YAC_LOC_CELL) ||
155 (location == YAC_LOC_CORNER) ||
156 (location == YAC_LOC_EDGE),
157 "ERROR(yac_basic_grid_get_data_size): invalid location")
158
159 switch (location) {
160 default:
161 case (YAC_LOC_CELL):
162 return grid->data.num_cells;
163 case (YAC_LOC_CORNER):
164 return grid->data.num_vertices;
165 case (YAC_LOC_EDGE):
166 return grid->data.num_edges;
167 };
168}
169
171 struct yac_basic_grid * grid, int location) {
172
173 return
175}
176
178 struct yac_basic_grid * grid, enum yac_location location,
179 char const * mask_name) {
180
181 if (mask_name == NULL) return SIZE_MAX;
182
183 struct yac_field_data * data =
184 yac_basic_grid_get_field_data(grid, location);
185
186 if (data == NULL) return SIZE_MAX;
187
188 size_t mask_idx = SIZE_MAX;
190
191 for (size_t i = 0; (i < masks_count) && (mask_idx == SIZE_MAX); ++i) {
192 char const * curr_mask_name =
194 if ((curr_mask_name != NULL) &&
195 (!strcmp(mask_name, curr_mask_name)))
196 mask_idx = i;
197 }
198
200 mask_idx != SIZE_MAX,
201 "ERROR(yac_basic_grid_get_named_mask_idx): grid \"%s\" does not contain "
202 "%s-mask with the name \"%s\"",
203 grid->name, yac_loc2str(location), mask_name)
204
205 return mask_idx;
206}
207
209 struct yac_basic_grid * grid,
211
213 grid, "ERROR(yac_basic_grid_add_coordinates_nocpy): "
214 "NULL is not a valid value for argument grid")
216 !grid->is_empty, "ERROR(yac_basic_grid_add_coordinates_nocpy): "
217 "grid \"%s\" is an empty grid", grid->name)
218
219 return
221 grid->field_data_set, location, coordinates);
222}
223
225 struct yac_basic_grid * grid, int location, double * coordinates) {
226
227 return
230}
231
233 struct yac_basic_grid * grid, enum yac_location location,
234 yac_coordinate_pointer coordinates, size_t count) {
235
237 grid, "ERROR(yac_basic_grid_add_coordinates): "
238 "NULL is not a valid value for argument grid")
240 !grid->is_empty, "ERROR(yac_basic_grid_add_coordinates): "
241 "grid \"%s\" is an empty grid", grid->name)
242
243 return
245 grid->field_data_set, location, coordinates, count);
246}
247
249 struct yac_basic_grid * grid, int location,
250 double * coordinates, size_t count) {
251
252 return
254 grid, yac_get_location(location),
256}
257
259 struct yac_basic_grid * grid,
260 enum yac_location location, int const * mask,
261 char const * mask_name) {
262
264 grid, "ERROR(yac_basic_grid_add_mask_nocpy): "
265 "NULL is not a valid value for argument grid")
267 !grid->is_empty, "ERROR(yac_basic_grid_add_mask_nocpy): "
268 "grid \"%s\" is an empty grid", grid->name)
269
270 return
272 grid->field_data_set, location, mask, mask_name);
273}
274
276 struct yac_basic_grid * grid, int location,
277 int const * mask, char const * mask_name) {
278
279 return
281 grid, yac_get_location(location), mask, mask_name);
282}
283
285 struct yac_basic_grid * grid, enum yac_location location,
286 int const * mask, size_t count, char const * mask_name) {
287
289 grid, "ERROR(yac_basic_grid_add_mask): "
290 "NULL is not a valid value for argument grid")
292 !grid->is_empty, "ERROR(yac_basic_grid_add_mask): "
293 "grid \"%s\" is an empty grid", grid->name)
294
295 return
297 grid->field_data_set, location, mask, count, mask_name);
298}
299
301 struct yac_basic_grid * grid, int location,
302 int const * mask, size_t count, char const * mask_name) {
303
304 return
306 grid, yac_get_location(location), mask, count, mask_name);
307}
308
310 struct yac_basic_grid * grid, enum yac_location location) {
311
313 grid, "ERROR(yac_basic_grid_get_field_data): "
314 "NULL is not a valid value for argument grid")
315
316 if (grid->is_empty)
317 return NULL;
318 else
319 return
321 grid->field_data_set, location);
322}
323
325 char const * name, size_t nbr_vertices[2], int cyclic[2],
326 double *lon_vertices, double *lat_vertices) {
327
328 return
330 name,
332 nbr_vertices, cyclic, lon_vertices, lat_vertices));
333}
334
336 char const * name, size_t nbr_vertices[2], int cyclic[2],
337 double *lon_vertices, double *lat_vertices) {
338
339 return
341 name,
343 nbr_vertices, cyclic, lon_vertices, lat_vertices));
344}
345
347 char const * name, size_t nbr_vertices[2], int cyclic[2],
348 double *lon_vertices, double *lat_vertices) {
349
350 return
352 name,
354 nbr_vertices, cyclic, lon_vertices, lat_vertices));
355}
356
358 char const * name, size_t nbr_vertices[2], int cyclic[2],
359 double *lon_vertices, double *lat_vertices) {
360
361 return
363 name,
365 nbr_vertices, cyclic, lon_vertices, lat_vertices));
366}
367
369 char const * name, size_t nbr_vertices, size_t nbr_cells,
370 int *num_vertices_per_cell, double *x_vertices, double *y_vertices,
371 int *cell_to_vertex) {
372
373 return
375 name,
377 nbr_vertices, nbr_cells, num_vertices_per_cell,
378 x_vertices, y_vertices, cell_to_vertex));
379}
380
382 char const * name, size_t nbr_vertices, size_t nbr_cells,
383 int *num_vertices_per_cell, double *x_vertices, double *y_vertices,
384 int *cell_to_vertex) {
385
386 return
388 name,
390 nbr_vertices, nbr_cells, num_vertices_per_cell,
391 x_vertices, y_vertices, cell_to_vertex));
392}
393
395 char const * name, size_t nbr_vertices, size_t nbr_cells,
396 int *num_vertices_per_cell, double *x_vertices, double *y_vertices,
397 int *cell_to_vertex) {
398
399 return
401 name,
403 nbr_vertices, nbr_cells, num_vertices_per_cell,
404 x_vertices, y_vertices, cell_to_vertex));
405}
406
408 char const * name, size_t nbr_vertices, size_t nbr_cells,
409 int *num_vertices_per_cell, double *x_vertices, double *y_vertices,
410 int *cell_to_vertex) {
411
412 return
414 name,
416 nbr_vertices, nbr_cells, num_vertices_per_cell,
417 x_vertices, y_vertices, cell_to_vertex));
418}
419
421 char const * name, size_t nbr_vertices, size_t nbr_cells, size_t nbr_edges,
422 int *num_edges_per_cell, double *x_vertices, double *y_vertices,
423 int *cell_to_edge, int *edge_to_vertex) {
424
425 return
427 name,
429 nbr_vertices, nbr_cells, nbr_edges, num_edges_per_cell,
430 x_vertices, y_vertices, cell_to_edge, edge_to_vertex));
431}
432
434 char const * name, size_t nbr_vertices, size_t nbr_cells, size_t nbr_edges,
435 int *num_edges_per_cell, double *x_vertices, double *y_vertices,
436 int *cell_to_edge, int *edge_to_vertex) {
437
438 return
440 name,
442 nbr_vertices, nbr_cells, nbr_edges, num_edges_per_cell,
443 x_vertices, y_vertices, cell_to_edge, edge_to_vertex));
444}
445
447 char const * name, size_t nbr_vertices, size_t nbr_cells, size_t nbr_edges,
448 int *num_edges_per_cell, double *x_vertices, double *y_vertices,
449 int *cell_to_edge, int *edge_to_vertex) {
450
451 return
453 name,
455 nbr_vertices, nbr_cells, nbr_edges, num_edges_per_cell,
456 x_vertices, y_vertices, cell_to_edge, edge_to_vertex));
457}
458
460 char const * name, size_t nbr_vertices, size_t nbr_cells, size_t nbr_edges,
461 int *num_edges_per_cell, double *x_vertices, double *y_vertices,
462 int *cell_to_edge, int *edge_to_vertex) {
463
464 return
466 name,
468 nbr_vertices, nbr_cells, nbr_edges, num_edges_per_cell,
469 x_vertices, y_vertices, cell_to_edge, edge_to_vertex));
470}
471
473 char const * name, size_t nbr_points, double *x_points, double *y_points) {
474
475 return
477 name,
478 yac_generate_basic_grid_data_cloud(nbr_points, x_points, y_points));
479}
480
482 char const * name, size_t nbr_points, double *x_points, double *y_points) {
483
484 return
486 name,
487 yac_generate_basic_grid_data_cloud_deg(nbr_points, x_points, y_points));
488}
489
490#ifdef YAC_NETCDF_ENABLED
491
492static int def_dim(
493 char const * filename, int ncid, char const * name, size_t dim_len,
494 int file_is_new) {
495
496 int create_dim = file_is_new;
497 int dim_id;
498
499 // if the netcdf file already exists
500 if (!file_is_new) {
501
502 // check whether the dimension already exists in the file
503 int status = nc_inq_dimid(ncid, name, &dim_id);
504
505 // if the dimension already exists, check for a consistent dimension size
506 if (!((create_dim = (status == NC_EBADDIM)))) {
507
508 YAC_HANDLE_ERROR(status);
509
510 size_t temp_dim_len;
511 YAC_HANDLE_ERROR(nc_inq_dimlen(ncid, dim_id, &temp_dim_len));
512
514 dim_len == temp_dim_len,
515 "ERROR(def_dim): file \"%s\" already contains dimension \"%s\", "
516 "but it has a different size %zu != %zu",
517 filename, name, dim_len, temp_dim_len);
518 }
519 }
520
521 if (create_dim) YAC_HANDLE_ERROR(nc_def_dim(ncid, name, dim_len, &dim_id));
522
523 return dim_id;
524}
525
526static void def_var(
527 char const * filename, int ncid, char const * name, nc_type type,
528 int ndims, const int * dimids, char const * att_name, char const * att_value,
529 int file_is_new) {
530
531 int create_var = file_is_new;
532 int var_id;
533
534 // if the netcdf file already exists
535 if (!file_is_new) {
536
537 // check whether the variable already exists in the file
538 int status = nc_inq_varid(ncid, name, &var_id);
539
540 // if the variable already exists
541 if (!((create_var = (status == NC_ENOTVAR)))) {
542
543 YAC_HANDLE_ERROR(status);
544
545 // check the consistency of the variable definition
546 nc_type temp_type;
547 int temp_ndims;
548 int temp_dimids[NC_MAX_VAR_DIMS];
550 nc_inq_var(
551 ncid, var_id, NULL, &temp_type, &temp_ndims, temp_dimids, NULL));
553 type == temp_type,
554 "ERROR(def_var): file \"%s\" already contains variable \"%s\", "
555 "but it has a different data type %d != %d",
556 filename, name, type, temp_type);
558 ndims == temp_ndims,
559 "ERROR(def_var): file \"%s\" already contains variable \"%s\", "
560 "but it has a different number of dimensions %d != %d",
561 filename, name, ndims, temp_ndims);
562 for (int i = 0; i < ndims; ++i) {
564 dimids[i] == temp_dimids[i],
565 "ERROR(def_var): file \"%s\" already contains variable \"%s\", "
566 "but it has a different dimensions dimid[%d] %d != %d",
567 filename, name, i, dimids[i], temp_dimids[i])
568 }
569
570 if (att_name != NULL) {
571
572 size_t att_len;
573 YAC_HANDLE_ERROR(nc_inq_attlen(ncid, var_id, att_name, &att_len));
574
575 char * temp_att_value = xcalloc((att_len + 1), sizeof(temp_att_value));
576 YAC_HANDLE_ERROR(nc_get_att_text(ncid, var_id, att_name, temp_att_value));
577
579 !strcmp(att_value, temp_att_value),
580 "ERROR(def_var): file \"%s\" already contains variable \"%s\", "
581 "but it has a different attribute value (name: \"%s\") "
582 "\"%s\" != \"%s\"",
583 filename, name, att_name, att_value, temp_att_value);
584 free(temp_att_value);
585 }
586 }
587 }
588
589 if (create_var) {
590 YAC_HANDLE_ERROR(nc_def_var(ncid, name, type, ndims, dimids, &var_id));
591 if (att_name != NULL)
593 nc_put_att_text(ncid, var_id, att_name, strlen(att_value), att_value));
594 }
595}
596
598 char const * filename, char const * grid_name, size_t num_cells,
599 int num_vertices_per_cell, int cell_center_coords_avaiable,
600 int cell_global_ids_available, int core_cell_mask_available,
601 int vertex_global_ids_available, int core_vertex_mask_available,
602 int edge_global_ids_available, int core_edge_mask_available) {
603
604 size_t grid_name_len = strlen(grid_name) + 1;
605
606 char nv_dim_name[3 + grid_name_len];
607 char nc_dim_name[3 + grid_name_len];
608
609 char cla_var_name[4 + grid_name_len];
610 char clo_var_name[4 + grid_name_len];
611 char lat_var_name[4 + grid_name_len];
612 char lon_var_name[4 + grid_name_len];
613 char rnk_var_name[4 + grid_name_len];
614 char cmk_var_name[4 + grid_name_len];
615 char gid_var_name[4 + grid_name_len];
616 char vcmk_var_name[5 + grid_name_len];
617 char vgid_var_name[5 + grid_name_len];
618 char ecmk_var_name[5 + grid_name_len];
619 char egid_var_name[5 + grid_name_len];
620 char const * unit_att = "units";
621 char const * coord_unit = "degree";
622
623 snprintf(nv_dim_name, 3 + grid_name_len, "nv_%s", grid_name);
624 snprintf(nc_dim_name, 3 + grid_name_len, "nc_%s", grid_name);
625
626 snprintf(cla_var_name, 4 + grid_name_len, "%s.cla", grid_name);
627 snprintf(clo_var_name, 4 + grid_name_len, "%s.clo", grid_name);
628 snprintf(lat_var_name, 4 + grid_name_len, "%s.lat", grid_name);
629 snprintf(lon_var_name, 4 + grid_name_len, "%s.lon", grid_name);
630 snprintf(rnk_var_name, 4 + grid_name_len, "%s.rnk", grid_name);
631 snprintf(cmk_var_name, 4 + grid_name_len, "%s.cmk", grid_name);
632 snprintf(gid_var_name, 4 + grid_name_len, "%s.gid", grid_name);
633 snprintf(vcmk_var_name, 5 + grid_name_len, "%s.vcmk", grid_name);
634 snprintf(vgid_var_name, 5 + grid_name_len, "%s.vgid", grid_name);
635 snprintf(ecmk_var_name, 5 + grid_name_len, "%s.ecmk", grid_name);
636 snprintf(egid_var_name, 5 + grid_name_len, "%s.egid", grid_name);
637
638 int ncid;
639
640 // create/open file
641 int file_is_new = !yac_file_exists(filename);
642 if (file_is_new) {
643 yac_nc_create(filename, NC_CLOBBER | NC_64BIT_OFFSET, &ncid);
644 } else {
645 yac_nc_open(filename, NC_WRITE | NC_SHARE, &ncid);
646 nc_redef(ncid);
647 }
648
649 // define dimensions
650 int nv_dim_id =
651 def_dim(filename, ncid, nv_dim_name, (size_t)num_vertices_per_cell, file_is_new);
652 int nc_dim_id =
653 def_dim(filename, ncid, nc_dim_name, (size_t)num_cells, file_is_new);
654
655 // define variables
656 int corner_dims[2] = {nc_dim_id, nv_dim_id};
657 int cell_dims[1] = {nc_dim_id};
658 def_var(
659 filename, ncid, cla_var_name, NC_DOUBLE, 2, corner_dims,
660 unit_att, coord_unit, file_is_new);
661 def_var(
662 filename, ncid, clo_var_name, NC_DOUBLE, 2, corner_dims,
663 unit_att, coord_unit, file_is_new);
664 if (cell_center_coords_avaiable) {
665 def_var(
666 filename, ncid, lat_var_name, NC_DOUBLE, 1, cell_dims,
667 unit_att, coord_unit, file_is_new);
668 def_var(
669 filename, ncid, lon_var_name, NC_DOUBLE, 1, cell_dims,
670 unit_att, coord_unit, file_is_new);
671 }
672 if (cell_global_ids_available)
673 def_var(
674 filename, ncid, gid_var_name, NC_INT, 1, cell_dims, NULL, NULL, file_is_new);
675 if (core_cell_mask_available)
676 def_var(
677 filename, ncid, cmk_var_name, NC_INT, 1, cell_dims, NULL, NULL, file_is_new);
678 if (vertex_global_ids_available)
679 def_var(
680 filename, ncid, vgid_var_name, NC_INT, 2, corner_dims, NULL, NULL, file_is_new);
681 if (core_vertex_mask_available)
682 def_var(
683 filename, ncid, vcmk_var_name, NC_INT, 2, corner_dims, NULL, NULL, file_is_new);
684 if (edge_global_ids_available)
685 def_var(
686 filename, ncid, egid_var_name, NC_INT, 2, corner_dims, NULL, NULL, file_is_new);
687 if (core_edge_mask_available)
688 def_var(
689 filename, ncid, ecmk_var_name, NC_INT, 2, corner_dims, NULL, NULL, file_is_new);
690 def_var(
691 filename, ncid, rnk_var_name, NC_INT, 1, cell_dims, NULL, NULL, file_is_new);
692
693 time_t now = time(NULL);
694 char str_now_UTC[32];
695 strftime(
696 str_now_UTC, sizeof(str_now_UTC), "%Y-%m-%dT%H:%M:%SZ",
697 gmtime(&now));
698 char const * yac_version = YAC_VERSION;
699 char const * created_by = "Created by YAC";
700 char const * grid_type = "curvilinear";
702 nc_put_att_text(ncid, NC_GLOBAL, "YAC", strlen(yac_version), yac_version));
704 nc_put_att_text(ncid, NC_GLOBAL, "title", strlen(created_by), created_by));
706 nc_put_att_text(ncid, NC_GLOBAL, "description", strlen(created_by), created_by));
708 nc_put_att_text(ncid, NC_GLOBAL, "grid", strlen(grid_type), grid_type));
710 nc_put_att_text(ncid, NC_GLOBAL, "timeStamp", strlen(str_now_UTC), str_now_UTC));
711
712 // end definition
713 YAC_HANDLE_ERROR(nc_enddef(ncid));
714
715 // close file
716 YAC_HANDLE_ERROR(nc_close(ncid));
717}
718
719static void put_vara(
720 int ncid, char const * grid_name, char const * var_ext,
721 size_t * start, size_t * count, void const * buffer) {
722
723 if (count[0] == 0) return;
724
725 char * var_name =
726 xmalloc((strlen(grid_name) + strlen(var_ext) + 2) * sizeof(*var_name));
727
728 sprintf(var_name, "%s.%s", grid_name, var_ext);
729
730 int var_id;
731
732 yac_nc_inq_varid(ncid, var_name, &var_id);
733
734 free(var_name);
735
737 nc_put_vara(ncid, var_id, start, count, buffer));
738}
739
740#endif // YAC_NETCDF_ENABLED
741
743 struct yac_basic_grid * grid, char const * filename, MPI_Comm comm) {
744
745#ifndef YAC_NETCDF_ENABLED
746
747 UNUSED(grid);
748 UNUSED(filename);
749 UNUSED(comm);
750
751 die(
752 "ERROR(yac_basic_grid_to_file_parallel): "
753 "YAC is built without the NetCDF support");
754#else
755
756 int comm_rank, comm_size;
757 yac_mpi_call(MPI_Comm_rank(comm, &comm_rank), comm);
758 yac_mpi_call(MPI_Comm_size(comm, &comm_size), comm);
759
760 { // consistency check
761 int filename_len = (int)strlen(filename) + 1;
762 yac_mpi_call(MPI_Bcast(&filename_len, 1, MPI_INT, 0, comm), comm);
763 char * filename_buffer =
764 xmalloc((size_t)filename_len * sizeof(*filename_buffer));
765 if (comm_rank == 0) strcpy(filename_buffer, filename);
767 MPI_Bcast(filename_buffer, filename_len, MPI_CHAR, 0, comm), comm);
768
770 !strcmp(filename, filename_buffer),
771 "ERROR(yac_basic_grid_to_file_parallel): "
772 "inconsistent filename (\"%s\" on rank 0 != \"%s\" on rank %d)",
773 filename_buffer, filename, comm_rank);
774 free(filename_buffer);
775 }
776
777 struct yac_field_data * cell_field =
779 yac_const_coordinate_pointer cell_center_coords =
780 ((cell_field != NULL) &&
781 (yac_field_data_get_coordinates_count(cell_field) > 0))?
782 yac_field_data_get_coordinates_data(cell_field, 0):NULL;
783 struct yac_basic_grid_data * grid_data = yac_basic_grid_get_data(grid);
784
785 uint64_t local_cell_count = (uint64_t)grid->data.num_cells;
786 uint64_t * global_cell_counts =
787 xmalloc((size_t)comm_size * sizeof(*global_cell_counts));
788 int max_num_vertices_per_cell = 0;
789 int cell_center_coords_avaiable =
790 (grid_data->num_cells == 0) || (cell_center_coords != NULL);
791 int cell_global_ids_available =
792 (grid_data->num_cells == 0) || (grid_data->cell_ids != NULL);
793 int core_cell_mask_available =
794 (grid_data->num_cells == 0) || (grid_data->core_cell_mask != NULL);
795 int vertex_global_ids_available =
796 (grid_data->num_vertices == 0) || (grid_data->vertex_ids != NULL);
797 int core_vertex_mask_available =
798 (grid_data->num_vertices == 0) || (grid_data->core_vertex_mask != NULL);
799 int edge_global_ids_available =
800 (grid_data->num_edges == 0) || (grid_data->edge_ids != NULL);
801 int core_edge_mask_available =
802 (grid_data->num_edges == 0) || (grid_data->core_edge_mask != NULL);
803
804 for (size_t i = 0; i < grid->data.num_cells; ++i)
805 if (grid->data.num_vertices_per_cell[i] > max_num_vertices_per_cell)
806 max_num_vertices_per_cell = grid->data.num_vertices_per_cell[i];
807
809 MPI_Allgather(
810 &local_cell_count, 1, MPI_UINT64_T,
811 global_cell_counts, 1, MPI_UINT64_T, comm), comm);
813 MPI_Allreduce(
814 MPI_IN_PLACE, &max_num_vertices_per_cell, 1, MPI_INT, MPI_MAX, comm),
815 comm);
816 int ints[7] = {cell_center_coords_avaiable,
817 cell_global_ids_available,
818 core_cell_mask_available,
819 vertex_global_ids_available,
820 core_vertex_mask_available,
821 edge_global_ids_available,
822 core_edge_mask_available};
824 MPI_Allreduce(
825 MPI_IN_PLACE, ints, sizeof(ints)/sizeof(ints[0]),
826 MPI_INT, MPI_MIN, comm), comm);
827 cell_center_coords_avaiable = ints[0];
828 cell_global_ids_available = ints[1];
829 core_cell_mask_available = ints[2];
830 vertex_global_ids_available = ints[3];
831 core_vertex_mask_available = ints[4];
832 edge_global_ids_available = ints[5];
833 core_edge_mask_available = ints[6];
834
835 size_t global_cell_count = 0;
836 for (int i = 0; i < comm_size; ++i)
837 global_cell_count += (size_t)(global_cell_counts[i]);
838
840 global_cell_count > 0,
841 "ERROR(yac_basic_grid_to_file_parallel): grid \"%s\" has no cells",
842 grid->name);
843
844 // create the grid file
845 if (comm_rank == 0)
847 filename, grid->name, global_cell_count, max_num_vertices_per_cell,
848 cell_center_coords_avaiable,
849 cell_global_ids_available, core_cell_mask_available,
850 vertex_global_ids_available, core_vertex_mask_available,
851 edge_global_ids_available, core_edge_mask_available);
852 yac_mpi_call(MPI_Barrier(comm), comm);
853
854 // determine processes that will do output
855 int io_flag;
856 int * io_ranks;
857 int num_io_ranks;
858 yac_get_io_ranks(comm, &io_flag, &io_ranks, &num_io_ranks);
859
860 size_t recv_count = 0;
861 size_t io_start_idx = SIZE_MAX;
862
863 if (io_flag) {
864
865 int io_rank_idx;
866 for (io_rank_idx = 0; io_rank_idx < num_io_ranks; ++io_rank_idx)
867 if (io_ranks[io_rank_idx] == comm_rank) break;
868
869 io_start_idx =
870 (size_t)(
871 ((long long)(io_rank_idx) * (long long)global_cell_count)/
872 (long long)num_io_ranks);
873 recv_count =
874 (size_t)(
875 ((long long)(io_rank_idx + 1) * (long long)global_cell_count)/
876 (long long)num_io_ranks - (long long)io_start_idx);
877 }
878
879 // generate transfer positions
880 struct Xt_com_pos * com_pos_buffer =
881 xmalloc(5 * (size_t)comm_size * sizeof(*com_pos_buffer));
882 struct Xt_com_pos * cell_src_com = com_pos_buffer;
883 struct Xt_com_pos * cell_dst_com = com_pos_buffer + (size_t)comm_size;
884 struct Xt_com_pos * vertex_src_com = com_pos_buffer + 2 * (size_t)comm_size;
885 struct Xt_com_pos * vertex_dst_com = com_pos_buffer + 3 * (size_t)comm_size;
886 struct Xt_com_pos * edge_src_com = com_pos_buffer + 4 * (size_t)comm_size;
887 struct Xt_com_pos * edge_dst_com = vertex_dst_com;
888 int num_src_msg = 0, num_dst_msg = 0;
889 int * transfer_pos_buffer =
890 xmalloc(
891 (size_t)(2 * max_num_vertices_per_cell + 1) *
892 (grid->data.num_cells + recv_count) * sizeof(*transfer_pos_buffer));
893 int * cell_send_pos = transfer_pos_buffer;
894 int * cell_recv_pos = transfer_pos_buffer + grid->data.num_cells;
895 int * vertex_send_pos =
896 transfer_pos_buffer + grid->data.num_cells + recv_count;
897 int * vertex_recv_pos =
898 transfer_pos_buffer + grid->data.num_cells + recv_count +
899 (size_t)max_num_vertices_per_cell * grid->data.num_cells;
900 int * edge_send_pos =
901 transfer_pos_buffer + grid->data.num_cells + recv_count +
902 (size_t)max_num_vertices_per_cell * grid->data.num_cells +
903 (size_t)max_num_vertices_per_cell * recv_count;
904
905 for (size_t i = 0; i < grid->data.num_cells; ++i) {
906
907 size_t * cell_to_vertex =
909 size_t * cell_to_edge =
911 int num_vertices = grid->data.num_vertices_per_cell[i];
912
913 cell_send_pos[i] = (int)i;
914 for (int j = 0; j < num_vertices; ++j)
915 vertex_send_pos[i * (size_t)max_num_vertices_per_cell + (size_t)j] =
916 cell_to_vertex[j];
917 for (int j = num_vertices; j < max_num_vertices_per_cell; ++j)
918 vertex_send_pos[i * (size_t)max_num_vertices_per_cell + (size_t)j] = 0;
919 for (int j = 0; j < num_vertices; ++j)
920 edge_send_pos[i * (size_t)max_num_vertices_per_cell + (size_t)j] =
921 cell_to_edge[j];
922 for (int j = num_vertices; j < max_num_vertices_per_cell; ++j)
923 edge_send_pos[i * (size_t)max_num_vertices_per_cell + (size_t)j] = 0;
924 }
925
926 for (size_t i = 0, k = 0; i < recv_count; ++i) {
927 cell_recv_pos[i] = (int)i;
928 for (int j = 0; j < max_num_vertices_per_cell; ++j, ++k)
929 vertex_recv_pos[k] = k;
930 }
931
932 size_t io_end_idx = 0;
933 size_t global_count_accu = 0;
934 for (int io_rank_idx = 0, curr_rank = 0; io_rank_idx < num_io_ranks;
935 ++io_rank_idx) {
936
937 int curr_io_rank = io_ranks[io_rank_idx];
938 size_t io_start_idx = io_end_idx;
939 io_end_idx =
940 (size_t)(
941 ((long long)(io_rank_idx + 1) * (long long)global_cell_count)/
942 (long long)num_io_ranks);
943 size_t io_size = io_end_idx - io_start_idx;
944 size_t curr_recv_size = 0;
945
946 while(global_count_accu < io_end_idx) {
947
948 size_t count =
949 MIN(
950 (global_count_accu + global_cell_counts[curr_rank]) -
951 (io_start_idx + curr_recv_size), io_size - curr_recv_size);
952
953 if (curr_rank == comm_rank) {
954 cell_src_com[num_src_msg].transfer_pos = cell_send_pos;
955 cell_src_com[num_src_msg].num_transfer_pos = (int)count;
956 cell_src_com[num_src_msg].rank = curr_io_rank;
957 cell_send_pos += count;
958
959 vertex_src_com[num_src_msg].transfer_pos = vertex_send_pos;
960 vertex_src_com[num_src_msg].num_transfer_pos =
961 (int)count * max_num_vertices_per_cell;
962 vertex_src_com[num_src_msg].rank = curr_io_rank;
963 vertex_send_pos +=
964 count * (size_t)max_num_vertices_per_cell;
965
966 edge_src_com[num_src_msg].transfer_pos = edge_send_pos;
967 edge_src_com[num_src_msg].num_transfer_pos =
968 (int)count * max_num_vertices_per_cell;
969 edge_src_com[num_src_msg].rank = curr_io_rank;
970 edge_send_pos +=
971 count * (size_t)max_num_vertices_per_cell;
972
973 num_src_msg++;
974 }
975
976 if (curr_io_rank == comm_rank) {
977 cell_dst_com[num_dst_msg].transfer_pos = cell_recv_pos;
978 cell_dst_com[num_dst_msg].num_transfer_pos = (int)count;
979 cell_dst_com[num_dst_msg].rank = curr_rank;
980 cell_recv_pos += count;
981
982 vertex_dst_com[num_dst_msg].transfer_pos = vertex_recv_pos;
983 vertex_dst_com[num_dst_msg].num_transfer_pos =
984 (int)count * max_num_vertices_per_cell;
985 vertex_dst_com[num_dst_msg].rank = curr_rank;
986 vertex_recv_pos += count * (size_t)max_num_vertices_per_cell;
987
988 num_dst_msg++;
989 }
990
991 if ((global_count_accu + global_cell_counts[curr_rank]) <=
992 io_end_idx) {
993 global_count_accu += global_cell_counts[curr_rank];
994 curr_rank++;
995 }
996
997 curr_recv_size += count;
998
999 if (curr_recv_size >= io_size) break;
1000 }
1001 }
1002
1003 free(global_cell_counts);
1004
1005 // open grid file
1006 int ncid;
1007 size_t start[2], count[2];
1008 if (io_flag) {
1009
1010 int io_rank_idx;
1011 for (io_rank_idx = 0; io_rank_idx < num_io_ranks; ++io_rank_idx)
1012 if (io_ranks[io_rank_idx] == comm_rank) break;
1013
1014 start[0] = io_start_idx;
1015 start[1] = 0;
1016 count[0] = recv_count;
1017 count[1] = max_num_vertices_per_cell;
1018
1019 yac_nc_open(filename, NC_WRITE | NC_SHARE, &ncid);
1020 } else {
1021 count[0] = 0;
1022 count[1] = 0;
1023 }
1024
1025 void * recv_buffer =
1026 xmalloc(
1027 (size_t)max_num_vertices_per_cell * recv_count *
1028 MAX(MAX(sizeof(double), sizeof(int)), sizeof(yac_int)));
1029
1030 //----------------------------------------------------------------------------
1031 // redistribute cell based data
1032 //----------------------------------------------------------------------------
1033
1034 Xt_xmap cell_xmap =
1035 xt_xmap_intersection_pos_new(
1036 num_src_msg, cell_src_com, num_dst_msg, cell_dst_com, comm);
1037
1038 Xt_redist cell_redist_int = xt_redist_p2p_new(cell_xmap, MPI_INT);
1039
1040 // number of vertices per cell
1041 int * num_vertices_per_cell =
1042 xmalloc(recv_count * sizeof(*num_vertices_per_cell));
1043 xt_redist_s_exchange1(
1044 cell_redist_int, grid->data.num_vertices_per_cell, num_vertices_per_cell);
1045
1046 // cell center coordinates (if available)
1047 if (cell_center_coords_avaiable) {
1048
1049 // generate cell center lon/lat data
1050 double * send_buffer_dble =
1051 xmalloc(2 * grid->data.num_cells * sizeof(*send_buffer_dble));;
1052 double * send_buffer_lon = send_buffer_dble;
1053 double * send_buffer_lat = send_buffer_dble + grid->data.num_cells;
1054 for (size_t i = 0; i < grid->data.num_cells; ++i) {
1055 XYZtoLL(
1056 cell_center_coords[i], send_buffer_lon + i, send_buffer_lat + i);
1057 send_buffer_lon[i] /= YAC_RAD;
1058 send_buffer_lat[i] /= YAC_RAD;
1059 }
1060
1061 // exchange cell center lon/lat data and write it to file
1062 Xt_redist cell_redist_dble = xt_redist_p2p_new(cell_xmap, MPI_DOUBLE);
1063 xt_redist_s_exchange1(cell_redist_dble, send_buffer_lon, recv_buffer);
1064 put_vara(ncid, grid->name, "lon", start, count, recv_buffer);
1065 xt_redist_s_exchange1(cell_redist_dble, send_buffer_lat, recv_buffer);
1066 put_vara(ncid, grid->name, "lat", start, count, recv_buffer);
1067 xt_redist_delete(cell_redist_dble);
1068 free(send_buffer_dble);
1069 }
1070
1071 int * cell_send_buffer_int =
1072 xmalloc(grid->data.num_cells * sizeof(*cell_send_buffer_int));
1073
1074 // cell ranks
1075 {
1076 // generate cell owner rank data
1077 for (size_t i = 0; i < grid->data.num_cells; ++i)
1078 cell_send_buffer_int[i] = comm_rank;
1079
1080 // exchange cell owner ranks and write it to file
1081 xt_redist_s_exchange1(cell_redist_int, cell_send_buffer_int, recv_buffer);
1082 put_vara(ncid, grid->name, "rnk", start, count, recv_buffer);
1083 }
1084
1085 // cell core mask (if available)
1086 if (core_cell_mask_available) {
1087
1088 // exchange core cell mask and write to file
1089 xt_redist_s_exchange1(
1090 cell_redist_int, grid->data.core_cell_mask, recv_buffer);
1091 put_vara(ncid, grid->name, "cmk", start, count, recv_buffer);
1092 }
1093
1094 // cell global ids (if available)
1095 if (cell_global_ids_available) {
1096
1097 // convert global ids to int
1098 for (size_t i = 0; i < grid->data.num_cells; ++i)
1099 cell_send_buffer_int[i] = (int)(grid->data.cell_ids[i]);
1100
1101 // exchange cell global ids and write to file
1102 xt_redist_s_exchange1(
1103 cell_redist_int, cell_send_buffer_int, recv_buffer);
1104 put_vara(ncid, grid->name, "gid", start, count, recv_buffer);
1105 }
1106
1107 xt_redist_delete(cell_redist_int);
1108 free(cell_send_buffer_int);
1109
1110 xt_xmap_delete(cell_xmap);
1111
1112 //----------------------------------------------------------------------------
1113 // redistribute vertex based data
1114 //----------------------------------------------------------------------------
1115
1116 Xt_xmap vertex_xmap =
1117 xt_xmap_intersection_pos_new(
1118 num_src_msg, vertex_src_com, num_dst_msg, vertex_dst_com, comm);
1119
1120 // vertex coordinates
1121 {
1122 // generate vertex lon/lat data
1123 double * send_buffer_dble =
1124 xmalloc(2 * grid->data.num_vertices * sizeof(*send_buffer_dble));
1125 double * send_buffer_lon = send_buffer_dble;
1126 double * send_buffer_lat = send_buffer_dble + grid->data.num_vertices;
1127 for (size_t i = 0; i < grid->data.num_vertices; ++i) {
1128 XYZtoLL(
1129 grid->data.vertex_coordinates[i],
1130 send_buffer_lon + i, send_buffer_lat + i);
1131 send_buffer_lon[i] /= YAC_RAD;
1132 send_buffer_lat[i] /= YAC_RAD;
1133 }
1134
1135 // exchange vertex lon/lat data and write it to file
1136 Xt_redist vertex_redist_dble = xt_redist_p2p_new(vertex_xmap, MPI_DOUBLE);
1137 xt_redist_s_exchange1(vertex_redist_dble, send_buffer_lon, recv_buffer);
1138 for (size_t i = 0, k = 0; i < recv_count;
1139 ++i, k += (size_t)max_num_vertices_per_cell)
1140 for (size_t j = (size_t)num_vertices_per_cell[i];
1141 j < (size_t)max_num_vertices_per_cell; ++j)
1142 ((double*)recv_buffer)[k+j] = DBL_MAX;
1143 put_vara(ncid, grid->name, "clo", start, count, recv_buffer);
1144 xt_redist_s_exchange1(vertex_redist_dble, send_buffer_lat, recv_buffer);
1145 free(send_buffer_dble);
1146 for (size_t i = 0, k = 0; i < recv_count;
1147 ++i, k += (size_t)max_num_vertices_per_cell)
1148 for (size_t j = (size_t)num_vertices_per_cell[i];
1149 j < (size_t)max_num_vertices_per_cell; ++j)
1150 ((double*)recv_buffer)[k+j] = DBL_MAX;
1151 put_vara(ncid, grid->name, "cla", start, count, recv_buffer);
1152 xt_redist_delete(vertex_redist_dble);
1153 }
1154
1155 Xt_redist vertex_redist_int = xt_redist_p2p_new(vertex_xmap, MPI_INT);
1156 int * vertex_send_buffer_int =
1157 xmalloc(grid->data.num_vertices * sizeof(*vertex_send_buffer_int));
1158
1159 // core vertex mask (if available)
1160 if (core_vertex_mask_available) {
1161
1162 // exchange core vertex mask and write to file
1163 xt_redist_s_exchange1(
1164 vertex_redist_int, grid->data.core_vertex_mask, recv_buffer);
1165 for (size_t i = 0, k = 0; i < recv_count;
1166 ++i, k += (size_t)max_num_vertices_per_cell)
1167 for (size_t j = (size_t)num_vertices_per_cell[i];
1168 j < (size_t)max_num_vertices_per_cell; ++j)
1169 ((int*)recv_buffer)[k+j] = INT_MAX;
1170 put_vara(ncid, grid->name, "vcmk", start, count, recv_buffer);
1171 }
1172
1173 // vertex global ids (if available)
1174 if (vertex_global_ids_available) {
1175
1176 // convert global ids to int
1177 for (size_t i = 0; i < grid->data.num_vertices; ++i)
1178 vertex_send_buffer_int[i] = (int)(grid->data.vertex_ids[i]);
1179
1180 // exchange vertex global ids and write to file
1181 xt_redist_s_exchange1(
1182 vertex_redist_int, vertex_send_buffer_int, recv_buffer);
1183 for (size_t i = 0, k = 0; i < recv_count;
1184 ++i, k += (size_t)max_num_vertices_per_cell)
1185 for (size_t j = (size_t)num_vertices_per_cell[i];
1186 j < (size_t)max_num_vertices_per_cell; ++j)
1187 ((int*)recv_buffer)[k+j] = INT_MAX;
1188 put_vara(ncid, grid->name, "vgid", start, count, recv_buffer);
1189 }
1190
1191 free(vertex_send_buffer_int);
1192 xt_redist_delete(vertex_redist_int);
1193
1194 xt_xmap_delete(vertex_xmap);
1195
1196 //----------------------------------------------------------------------------
1197 // redistribute edge based data
1198 //----------------------------------------------------------------------------
1199
1200 if (core_edge_mask_available || edge_global_ids_available) {
1201
1202 Xt_xmap edge_xmap =
1203 xt_xmap_intersection_pos_new(
1204 num_src_msg, edge_src_com, num_dst_msg, edge_dst_com, comm);
1205
1206 Xt_redist edge_redist_int = xt_redist_p2p_new(edge_xmap, MPI_INT);
1207 int * edge_send_buffer_int =
1208 xmalloc(grid->data.num_edges * sizeof(*edge_send_buffer_int));
1209
1210 // core edge mask (if available)
1211 if (core_edge_mask_available) {
1212
1213 // exchange core edge mask and write to file
1214 xt_redist_s_exchange1(
1215 edge_redist_int, grid->data.core_edge_mask, recv_buffer);
1216 for (size_t i = 0, k = 0; i < recv_count;
1217 ++i, k += (size_t)max_num_vertices_per_cell)
1218 for (size_t j = (size_t)num_vertices_per_cell[i];
1219 j < (size_t)max_num_vertices_per_cell; ++j)
1220 ((int*)recv_buffer)[k+j] = INT_MAX;
1221 put_vara(ncid, grid->name, "ecmk", start, count, recv_buffer);
1222 }
1223
1224 // edge global ids (if available)
1225 if (edge_global_ids_available) {
1226
1227 // convert global ids to int
1228 for (size_t i = 0; i < grid->data.num_edges; ++i)
1229 edge_send_buffer_int[i] = (int)(grid->data.edge_ids[i]);
1230
1231 // exchange edge global ids and write to file
1232 xt_redist_s_exchange1(
1233 edge_redist_int, edge_send_buffer_int, recv_buffer);
1234 for (size_t i = 0, k = 0; i < recv_count;
1235 ++i, k += (size_t)max_num_vertices_per_cell)
1236 for (size_t j = (size_t)num_vertices_per_cell[i];
1237 j < (size_t)max_num_vertices_per_cell; ++j)
1238 ((int*)recv_buffer)[k+j] = INT_MAX;
1239 put_vara(ncid, grid->name, "egid", start, count, recv_buffer);
1240 }
1241
1242 free(edge_send_buffer_int);
1243 xt_redist_delete(edge_redist_int);
1244
1245 xt_xmap_delete(edge_xmap);
1246 }
1247
1248 // close file
1249 if (io_flag) YAC_HANDLE_ERROR(nc_close(ncid));
1250
1251 free(num_vertices_per_cell);
1252 free(recv_buffer);
1253 free(com_pos_buffer);
1254 free(transfer_pos_buffer);
1255 free(io_ranks);
1256
1257 // ensure that the writing of the weight file is complete
1258 yac_mpi_call(MPI_Barrier(comm), comm);
1259
1260#endif // YAC_NETCDF_ENABLED
1261}
1262
1264 struct yac_basic_grid * grid, double * cell_areas) {
1265
1267 grid->data, cell_areas);
1268}
struct yac_basic_grid * yac_basic_grid_unstruct_edge_new(char const *name, size_t nbr_vertices, size_t nbr_cells, size_t nbr_edges, int *num_edges_per_cell, double *x_vertices, double *y_vertices, int *cell_to_edge, int *edge_to_vertex)
Definition basic_grid.c:420
struct yac_basic_grid * yac_basic_grid_unstruct_edge_ll_new(char const *name, size_t nbr_vertices, size_t nbr_cells, size_t nbr_edges, int *num_edges_per_cell, double *x_vertices, double *y_vertices, int *cell_to_edge, int *edge_to_vertex)
Definition basic_grid.c:446
static struct yac_basic_grid_data yac_basic_grid_data_empty
Definition basic_grid.c:24
struct yac_field_data * yac_basic_grid_get_field_data(struct yac_basic_grid *grid, enum yac_location location)
Definition basic_grid.c:309
size_t yac_basic_grid_get_named_mask_idx(struct yac_basic_grid *grid, enum yac_location location, char const *mask_name)
Definition basic_grid.c:177
int const * yac_basic_grid_get_field_mask(struct yac_basic_grid *grid, struct yac_interp_field field)
Definition basic_grid.c:118
struct yac_basic_grid * yac_basic_grid_new(char const *name, struct yac_basic_grid_data grid_data)
Definition basic_grid.c:50
struct yac_basic_grid * yac_basic_grid_reg_2d_deg_new(char const *name, size_t nbr_vertices[2], int cyclic[2], double *lon_vertices, double *lat_vertices)
Definition basic_grid.c:335
void yac_basic_grid_to_file_parallel(struct yac_basic_grid *grid, char const *filename, MPI_Comm comm)
Definition basic_grid.c:742
static void create_grid_file(char const *filename, char const *grid_name, size_t num_cells, int num_vertices_per_cell, int cell_center_coords_avaiable, int cell_global_ids_available, int core_cell_mask_available, int vertex_global_ids_available, int core_vertex_mask_available, int edge_global_ids_available, int core_edge_mask_available)
Definition basic_grid.c:597
struct yac_basic_grid * yac_basic_grid_cloud_new(char const *name, size_t nbr_points, double *x_points, double *y_points)
Definition basic_grid.c:472
struct yac_basic_grid * yac_basic_grid_unstruct_deg_new(char const *name, size_t nbr_vertices, size_t nbr_cells, int *num_vertices_per_cell, double *x_vertices, double *y_vertices, int *cell_to_vertex)
Definition basic_grid.c:381
struct yac_basic_grid * yac_basic_grid_unstruct_new(char const *name, size_t nbr_vertices, size_t nbr_cells, int *num_vertices_per_cell, double *x_vertices, double *y_vertices, int *cell_to_vertex)
Definition basic_grid.c:368
yac_const_coordinate_pointer yac_basic_grid_get_field_coordinates(struct yac_basic_grid *grid, struct yac_interp_field field)
Definition basic_grid.c:81
struct yac_basic_grid_data * yac_basic_grid_get_data(struct yac_basic_grid *grid)
Definition basic_grid.c:137
static void def_var(char const *filename, int ncid, char const *name, nc_type type, int ndims, const int *dimids, char const *att_name, char const *att_value, int file_is_new)
Definition basic_grid.c:526
struct yac_basic_grid * yac_basic_grid_cloud_deg_new(char const *name, size_t nbr_points, double *x_points, double *y_points)
Definition basic_grid.c:481
struct yac_basic_grid * yac_basic_grid_unstruct_edge_deg_new(char const *name, size_t nbr_vertices, size_t nbr_cells, size_t nbr_edges, int *num_edges_per_cell, double *x_vertices, double *y_vertices, int *cell_to_edge, int *edge_to_vertex)
Definition basic_grid.c:433
size_t yac_basic_grid_add_mask(struct yac_basic_grid *grid, enum yac_location location, int const *mask, size_t count, char const *mask_name)
Definition basic_grid.c:284
struct yac_basic_grid * yac_basic_grid_reg_2d_new(char const *name, size_t nbr_vertices[2], int cyclic[2], double *lon_vertices, double *lat_vertices)
Definition basic_grid.c:324
struct yac_basic_grid * yac_basic_grid_unstruct_ll_new(char const *name, size_t nbr_vertices, size_t nbr_cells, int *num_vertices_per_cell, double *x_vertices, double *y_vertices, int *cell_to_vertex)
Definition basic_grid.c:394
size_t yac_basic_grid_get_data_size_f2c(struct yac_basic_grid *grid, int location)
Definition basic_grid.c:170
size_t yac_basic_grid_add_coordinates_nocpy(struct yac_basic_grid *grid, enum yac_location location, yac_coordinate_pointer coordinates)
Definition basic_grid.c:208
char const * yac_basic_grid_get_name(struct yac_basic_grid *grid)
Definition basic_grid.c:128
void yac_basic_grid_compute_cell_areas(struct yac_basic_grid *grid, double *cell_areas)
size_t yac_basic_grid_add_mask_nocpy_f2c(struct yac_basic_grid *grid, int location, int const *mask, char const *mask_name)
Definition basic_grid.c:275
size_t yac_basic_grid_add_coordinates_f2c(struct yac_basic_grid *grid, int location, double *coordinates, size_t count)
Definition basic_grid.c:248
size_t yac_basic_grid_add_coordinates(struct yac_basic_grid *grid, enum yac_location location, yac_coordinate_pointer coordinates, size_t count)
Definition basic_grid.c:232
size_t yac_basic_grid_get_data_size(struct yac_basic_grid *grid, enum yac_location location)
Definition basic_grid.c:147
struct yac_basic_grid * yac_basic_grid_unstruct_ll_deg_new(char const *name, size_t nbr_vertices, size_t nbr_cells, int *num_vertices_per_cell, double *x_vertices, double *y_vertices, int *cell_to_vertex)
Definition basic_grid.c:407
static void put_vara(int ncid, char const *grid_name, char const *var_ext, size_t *start, size_t *count, void const *buffer)
Definition basic_grid.c:719
int const * yac_basic_grid_get_core_mask(struct yac_basic_grid *grid, enum yac_location location)
Definition basic_grid.c:101
size_t yac_basic_grid_add_coordinates_nocpy_f2c(struct yac_basic_grid *grid, int location, double *coordinates)
Definition basic_grid.c:224
static int def_dim(char const *filename, int ncid, char const *name, size_t dim_len, int file_is_new)
Definition basic_grid.c:492
struct yac_basic_grid * yac_basic_grid_empty_new(char const *name)
Definition basic_grid.c:63
void yac_basic_grid_delete(struct yac_basic_grid *grid)
Definition basic_grid.c:70
size_t yac_basic_grid_add_mask_f2c(struct yac_basic_grid *grid, int location, int const *mask, size_t count, char const *mask_name)
Definition basic_grid.c:300
struct yac_basic_grid * yac_basic_grid_curve_2d_new(char const *name, size_t nbr_vertices[2], int cyclic[2], double *lon_vertices, double *lat_vertices)
Definition basic_grid.c:346
struct yac_basic_grid * yac_basic_grid_curve_2d_deg_new(char const *name, size_t nbr_vertices[2], int cyclic[2], double *lon_vertices, double *lat_vertices)
Definition basic_grid.c:357
struct yac_basic_grid * yac_basic_grid_unstruct_edge_ll_deg_new(char const *name, size_t nbr_vertices, size_t nbr_cells, size_t nbr_edges, int *num_edges_per_cell, double *x_vertices, double *y_vertices, int *cell_to_edge, int *edge_to_vertex)
Definition basic_grid.c:459
size_t yac_basic_grid_add_mask_nocpy(struct yac_basic_grid *grid, enum yac_location location, int const *mask, char const *mask_name)
Definition basic_grid.c:258
void yac_basic_grid_data_compute_cell_areas(struct yac_basic_grid_data grid, double *cell_areas)
void yac_basic_grid_data_free(struct yac_basic_grid_data grid)
struct yac_basic_grid_data yac_generate_basic_grid_data_unstruct_deg(size_t nbr_vertices, size_t nbr_cells, int *num_vertices_per_cell, double *x_vertices, double *y_vertices, int *cell_to_vertex)
struct yac_basic_grid_data yac_generate_basic_grid_data_reg_2d(size_t nbr_vertices[2], int cyclic[2], double *lon_vertices, double *lat_vertices)
Definition grid_reg2d.c:65
struct yac_basic_grid_data yac_generate_basic_grid_data_unstruct_ll(size_t nbr_vertices, size_t nbr_cells, int *num_vertices_per_cell, double *x_vertices, double *y_vertices, int *cell_to_vertex)
struct yac_basic_grid_data yac_generate_basic_grid_data_unstruct_edge(size_t nbr_vertices, size_t nbr_cells, size_t nbr_edges, int *num_edges_per_cell, double *x_vertices, double *y_vertices, int *cell_to_edge, int *edge_to_vertex)
struct yac_basic_grid_data yac_generate_basic_grid_data_cloud(size_t nbr_points, double *x_points, double *y_points)
Definition grid_cloud.c:50
struct yac_basic_grid_data yac_generate_basic_grid_data_unstruct_edge_deg(size_t nbr_vertices, size_t nbr_cells, size_t nbr_edges, int *num_edges_per_cell, double *x_vertices, double *y_vertices, int *cell_to_edge, int *edge_to_vertex)
struct yac_basic_grid_data yac_generate_basic_grid_data_unstruct_edge_ll(size_t nbr_vertices, size_t nbr_cells, size_t nbr_edges, int *num_edges_per_cell, double *x_vertices, double *y_vertices, int *cell_to_edge, int *edge_to_vertex)
struct yac_basic_grid_data yac_generate_basic_grid_data_unstruct_edge_ll_deg(size_t nbr_vertices, size_t nbr_cells, size_t nbr_edges, int *num_edges_per_cell, double *x_vertices, double *y_vertices, int *cell_to_edge, int *edge_to_vertex)
struct yac_basic_grid_data yac_generate_basic_grid_data_cloud_deg(size_t nbr_points, double *x_points, double *y_points)
Definition grid_cloud.c:58
struct yac_basic_grid_data yac_generate_basic_grid_data_curve_2d_deg(size_t nbr_vertices[2], int cyclic[2], double *lon_vertices, double *lat_vertices)
struct yac_basic_grid_data yac_generate_basic_grid_data_curve_2d(size_t nbr_vertices[2], int cyclic[2], double *lon_vertices, double *lat_vertices)
struct yac_basic_grid_data yac_generate_basic_grid_data_unstruct(size_t nbr_vertices, size_t nbr_cells, int *num_vertices_per_cell, double *x_vertices, double *y_vertices, int *cell_to_vertex)
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_basic_grid_data_unstruct_ll_deg(size_t nbr_vertices, size_t nbr_cells, int *num_vertices_per_cell, double *x_vertices, double *y_vertices, int *cell_to_vertex)
#define UNUSED(x)
Definition core.h:73
size_t yac_field_data_get_masks_count(struct yac_field_data *field_data)
Definition field_data.c:57
size_t yac_field_data_get_coordinates_count(struct yac_field_data *field_data)
Definition field_data.c:92
yac_const_coordinate_pointer yac_field_data_get_coordinates_data(struct yac_field_data *field_data, size_t coordinates_idx)
Definition field_data.c:97
int const * yac_field_data_get_mask_data(struct yac_field_data *field_data, size_t mask_idx)
Definition field_data.c:62
char const * yac_field_data_get_mask_name(struct yac_field_data *field_data, size_t mask_idx)
Definition field_data.c:82
void yac_field_data_set_delete(struct yac_field_data_set *field_data_set)
size_t yac_field_data_set_add_mask_nocpy(struct yac_field_data_set *field_data_set, enum yac_location location, int const *mask, char const *mask_name)
struct yac_field_data * yac_field_data_set_get_field_data(struct yac_field_data_set *field_data_set, enum yac_location location)
size_t yac_field_data_set_add_mask(struct yac_field_data_set *field_data_set, enum yac_location location, int const *mask, size_t count, char const *mask_name)
struct yac_field_data_set * yac_field_data_set_empty_new()
size_t yac_field_data_set_add_coordinates(struct yac_field_data_set *field_data_set, enum yac_location location, yac_coordinate_pointer coordinates, size_t count)
size_t yac_field_data_set_add_coordinates_nocpy(struct yac_field_data_set *field_data_set, enum yac_location location, yac_coordinate_pointer coordinates)
#define YAC_RAD
Definition geometry.h:30
static void XYZtoLL(double const p_in[], double *lon, double *lat)
Definition geometry.h:318
enum callback_type type
void yac_get_io_ranks(MPI_Comm comm, int *local_is_io_, int **io_ranks_, int *num_io_ranks_)
Definition io_utils.c:309
void yac_nc_create(const char *path, int cmode, int *ncidp)
Definition io_utils.c:367
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
int yac_file_exists(const char *filename)
Definition utils_core.c:12
#define YAC_HANDLE_ERROR(exp)
Definition io_utils.h:30
char const * yac_loc2str(enum yac_location location)
Definition location.c:32
enum yac_location yac_get_location(int const location)
Definition location.c:44
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 xcalloc(nmemb, size)
Definition ppm_xfuncs.h:64
#define xmalloc(size)
Definition ppm_xfuncs.h:66
yac_coordinate_pointer vertex_coordinates
size_t * cell_to_vertex_offsets
struct yac_basic_grid_data data
Definition basic_grid.c:21
struct yac_field_data_set * field_data_set
Definition basic_grid.c:20
size_t masks_count
Definition field_data.c:15
yac_coordinate_pointer * coordinates
Definition field_data.c:16
enum yac_location location
Definition basic_grid.h:18
size_t coordinates_idx
Definition basic_grid.h:19
#define MIN(a, b)
#define MAX(a, b)
static char * yac_version
Definition version.h:7
grid_type
#define YAC_ASSERT_F(exp, format,...)
Definition yac_assert.h:19
#define die(msg)
Definition yac_assert.h:12
#define YAC_ASSERT(exp, msg)
Definition yac_assert.h:16
#define yac_mpi_call(call, comm)
Xt_int yac_int
Definition yac_types.h:15
double const (* yac_const_coordinate_pointer)[3]
Definition yac_types.h:20
double(* yac_coordinate_pointer)[3]
Definition yac_types.h:19