23#ifdef YAC_NETCDF_ENABLED
50 double ** vertex_lon,
double ** vertex_lat,
51 size_t * nbr_vertices,
int * old_to_new_id);
53 double ** vertex_lon,
double ** vertex_lat,
54 size_t * nbr_vertices,
int * old_to_new_id,
55 yac_int ** vertex_ids, MPI_Comm comm);
58 size_t nbr_cells,
size_t ** duplicated_cell_idx,
59 size_t ** orig_cell_idx,
size_t * nbr_duplicated_cells);
63 MPI_Comm comm,
size_t ** duplicated_cell_idx,
64 yac_int ** orig_cell_ids,
size_t * num_duplicated_cells_);
67 const void * a,
const void * b) {
68 return *(
int const *)a - *(
int const*)b;
72 const void * a,
const void * b) {
78 const void * a_,
const void * b_) {
87 int ret = (num_vertices_a > num_vertices_b) -
88 (num_vertices_a < num_vertices_b);
90 for (
size_t i = 0; (
i < num_vertices_a) && !ret; ++
i)
98 const void * a_,
const void * b_) {
112 const void * a_,
const void * b_) {
121 return (a->
id > b->
id) - (a->
id < b->
id);
125 const void * a_,
const void * b_) {
136 const void * a_,
const void * b_) {
145 const void * a_,
const void * b_) {
150 return (a->
i > b->
i) - (a->
i < b->
i);
154 const char * filename,
const char * grid_name,
156 size_t * num_vertices_,
size_t * num_cells_,
int ** num_vertices_per_cell_,
157 int ** cell_to_vertex_,
double ** x_vertices,
double ** y_vertices,
158 double ** x_cells,
double ** y_cells,
159 size_t ** duplicated_cell_idx_,
size_t ** orig_cell_idx_,
160 size_t * nbr_duplicated_cells_,
int with_vertices) {
162 size_t grid_name_len = strlen(grid_name) + 1;
163 char cla_var_name[4 + grid_name_len];
164 char clo_var_name[4 + grid_name_len];
165 char lat_var_name[4 + grid_name_len];
166 char lon_var_name[4 + grid_name_len];
168 snprintf(cla_var_name, 4 + grid_name_len,
"%s.cla", grid_name);
169 snprintf(clo_var_name, 4 + grid_name_len,
"%s.clo", grid_name);
170 snprintf(lat_var_name, 4 + grid_name_len,
"%s.lat", grid_name);
171 snprintf(lon_var_name, 4 + grid_name_len,
"%s.lon", grid_name);
189 int dim_ids[NC_MAX_VAR_DIMS];
193 nc_inq_var(ncid, cla_var_id, NULL, NULL, &ndims, dim_ids, NULL));
196 "invalid number of dimensions for variable \"%s\" (has to be 3 not %d)",
197 cla_var_name, ndims);
201 nc_inq_var(ncid, lat_var_id, NULL, NULL, &ndims, dim_ids, NULL));
204 "invalid number of dimensions for variable \"%s\" (has to be 2 not %d)",
205 lat_var_name, ndims);
206 dim_ids[2] = dim_ids[1];
207 dim_ids[1] = dim_ids[0];
210 int crn_dim_id = dim_ids[0];
211 int x_dim_id = dim_ids[2];
212 int y_dim_id = dim_ids[1];
215 size_t crn_dim_len, x_dim_len, y_dim_len;
223 size_t num_cells = x_dim_len * y_dim_len;
224 size_t num_vertices =
num_cells * crn_dim_len;
228 "cell mask size is inconsistent with number of grid cells")
230 if ((x_cells != NULL) && (y_cells != NULL)) {
240 double * cla =
xmalloc(num_vertices *
sizeof(*cla));
241 double * clo =
xmalloc(num_vertices *
sizeof(*clo));
252 (x_cells != NULL) && (y_cells != NULL),
253 "no pointers for cell coordinates were provided")
255 memcpy(cla, *y_cells,
num_cells *
sizeof(*cla));
256 memcpy(clo, *x_cells,
num_cells *
sizeof(*clo));
261 size_t * reorder_idx =
xmalloc(num_vertices *
sizeof(*reorder_idx));
262 for (
size_t y = 0, l = 0; y < y_dim_len; ++y)
263 for (
size_t x = 0; x < x_dim_len; ++x)
264 for (
size_t n = 0; n < crn_dim_len; ++n, ++l)
265 reorder_idx[x + y * x_dim_len + n * x_dim_len * y_dim_len] = l;
277 int * num_vertices_per_cell =
279 size_t total_num_cell_vertices = 0;
282 if (crn_dim_len > 1) {
284 size_t curr_num_vertices = 0;
286 if (crn_dim_len > 1) {
287 int prev_vertex = from_vertices[crn_dim_len-1];
288 for (
size_t j = 0; j < crn_dim_len; ++j, ++from_vertices) {
289 int curr_vertex = *from_vertices;
290 if (prev_vertex != curr_vertex) {
291 prev_vertex = curr_vertex;
292 if (to_vertices != from_vertices) *to_vertices = curr_vertex;
299 from_vertices += crn_dim_len;
301 num_vertices_per_cell[
i] = (int)curr_num_vertices;
302 total_num_cell_vertices += curr_num_vertices;
307 if (to_vertices != from_vertices) *to_vertices = *from_vertices;
309 ++total_num_cell_vertices;
310 num_vertices_per_cell[
i] = 1;
312 num_vertices_per_cell[
i] = 0;
318 if (total_num_cell_vertices !=
num_cells * crn_dim_len)
325 int * cell_to_vertex_copy =
326 xmalloc(total_num_cell_vertices *
sizeof(*cell_to_vertex_copy));
329 total_num_cell_vertices *
sizeof(*cell_to_vertex_copy));
332 cell_to_vertex_copy + offset, (
size_t)(num_vertices_per_cell[
i]),
334 offset += num_vertices_per_cell[
i];
338 size_t * duplicated_cell_idx;
339 size_t * orig_cell_idx;
340 size_t nbr_duplicated_cells;
343 &duplicated_cell_idx, &orig_cell_idx, &nbr_duplicated_cells);
344 free(cell_to_vertex_copy);
347 for (
size_t i = 0;
i < nbr_duplicated_cells; ++
i)
350 if ((duplicated_cell_idx_ != NULL) && (orig_cell_idx_ != NULL) &&
351 (nbr_duplicated_cells_ != NULL)) {
352 *duplicated_cell_idx_ = duplicated_cell_idx;
353 *orig_cell_idx_ = orig_cell_idx;
354 *nbr_duplicated_cells_ = nbr_duplicated_cells;
356 free(duplicated_cell_idx);
362 *num_vertices_ = num_vertices;
363 *num_vertices_per_cell_ = num_vertices_per_cell;
370 free(num_vertices_per_cell);
380 const char * filename,
const char * grid_name,
382 size_t * num_vertices_,
size_t * num_cells_,
int ** num_vertices_per_cell_,
383 int ** cell_to_vertex_,
384 double ** x_vertices_,
double ** y_vertices_,
yac_int ** vertex_ids_,
385 double ** x_cells_,
double ** y_cells_,
yac_int ** cell_ids_,
386 size_t ** duplicated_cell_idx_,
yac_int ** orig_cell_ids_,
387 size_t * nbr_duplicated_cells_,
388 int io_rank_idx,
int num_io_ranks, MPI_Comm comm,
int with_vertices) {
391 size_t num_vertices = 0;
392 size_t * reorder_idx = NULL;
393 size_t max_num_vertices_per_cell = 0;
395 double * x_vertices = NULL;
396 double * y_vertices = NULL;
398 double * x_cells = NULL;
399 double * y_cells = NULL;
402 if ((io_rank_idx >= 0) && (io_rank_idx < num_io_ranks)) {
404 size_t grid_name_len = strlen(grid_name) + 1;
405 char cla_var_name[4 + grid_name_len];
406 char clo_var_name[4 + grid_name_len];
407 char lat_var_name[4 + grid_name_len];
408 char lon_var_name[4 + grid_name_len];
410 snprintf(cla_var_name, 4 + grid_name_len,
"%s.cla", grid_name);
411 snprintf(clo_var_name, 4 + grid_name_len,
"%s.clo", grid_name);
412 snprintf(lat_var_name, 4 + grid_name_len,
"%s.lat", grid_name);
413 snprintf(lon_var_name, 4 + grid_name_len,
"%s.lon", grid_name);
419 int cla_var_id, clo_var_id, lat_var_id, lon_var_id;
428 int dim_ids[NC_MAX_VAR_DIMS];
432 nc_inq_var(ncid, cla_var_id, NULL, NULL, &ndims, dim_ids, NULL));
435 "invalid number of dimensions for variable \"%s\" (has to be 3 not %d)",
436 cla_var_name, ndims);
440 nc_inq_var(ncid, lat_var_id, NULL, NULL, &ndims, dim_ids, NULL));
443 "invalid number of dimensions for variable \"%s\" (has to be 2 not %d)",
444 lat_var_name, ndims);
445 dim_ids[2] = dim_ids[1];
446 dim_ids[1] = dim_ids[0];
449 int crn_dim_id = dim_ids[0];
450 int x_dim_id = dim_ids[2];
451 int y_dim_id = dim_ids[1];
454 size_t crn_dim_len, x_dim_len, y_dim_len;
463 size_t x_start_local =
465 (((
unsigned long)x_dim_len * (
unsigned long)io_rank_idx) /
466 (
unsigned long)num_io_ranks);
467 size_t x_count_local =
469 (((
unsigned long)x_dim_len * (io_rank_idx + 1)) /
470 (
unsigned long)num_io_ranks) - x_start_local;
477 max_num_vertices_per_cell = crn_dim_len;
482 max_num_vertices_per_cell = 1;
487 "cell mask size is inconsistent with number of grid cells")
489 if ((x_cells_ != NULL) && (y_cells_ != NULL)) {
492 size_t start[2] = {0, x_start_local};
493 size_t count[2] = {y_dim_len, x_count_local};
495 nc_get_vara_double(ncid, lon_var_id, start, count, x_cells));
497 nc_get_vara_double(ncid, lat_var_id, start, count, y_cells));
503 x_vertices =
xmalloc(num_vertices *
sizeof(*x_vertices));
504 y_vertices =
xmalloc(num_vertices *
sizeof(*y_vertices));
507 size_t start[3] = {0, 0, x_start_local};
508 size_t count[3] = {crn_dim_len, y_dim_len, x_count_local};
510 nc_get_vara_double(ncid, clo_var_id, start, count, x_vertices));
512 nc_get_vara_double(ncid, cla_var_id, start, count, y_vertices));
520 (x_cells_ != NULL) && (y_cells_ != NULL),
521 "no pointers for cell coordinates were provided")
523 memcpy(x_vertices, x_cells,
num_cells *
sizeof(*x_vertices));
524 memcpy(y_vertices, y_cells,
num_cells *
sizeof(*y_vertices));
529 reorder_idx =
xmalloc(num_vertices *
sizeof(*reorder_idx));
530 for (
size_t y = 0, l = 0; y < y_dim_len; ++y)
531 for (
size_t x = 0; x < x_count_local; ++x)
532 for (
size_t n = 0; n < crn_dim_len; ++n, ++l)
534 x + y * x_count_local + n * x_count_local * y_dim_len] = l;
538 for (
size_t y = 0, k = 0; y < y_dim_len; ++y)
539 for (
size_t x = 0; x < x_count_local; ++x, ++k)
540 cell_ids[k] = y * x_dim_len + x + x_start_local;
544 (y_dim_len * x_dim_len * crn_dim_len) <= YAC_INT_MAX,
545 "number of vertices exceed maximum global id (%zu)",
546 (
size_t)YAC_INT_MAX);
550 for (
size_t n = 0, l = 0; n < crn_dim_len; ++n)
552 vertex_ids[l] = cell_ids[
i] * crn_dim_len + n;
558 &x_vertices, &y_vertices, &num_vertices,
567 int * num_vertices_per_cell =
569 size_t total_num_cell_vertices = 0;
572 if (max_num_vertices_per_cell > 1) {
574 size_t curr_num_vertices = 0;
576 if (max_num_vertices_per_cell > 1) {
577 int prev_vertex = from_vertices[max_num_vertices_per_cell-1];
578 for (
size_t j = 0; j < max_num_vertices_per_cell; ++j, ++from_vertices) {
579 int curr_vertex = *from_vertices;
580 if (prev_vertex != curr_vertex) {
581 prev_vertex = curr_vertex;
582 if (to_vertices != from_vertices) *to_vertices = curr_vertex;
589 from_vertices += max_num_vertices_per_cell;
591 num_vertices_per_cell[
i] = (int)curr_num_vertices;
592 total_num_cell_vertices += curr_num_vertices;
597 if (to_vertices != from_vertices) *to_vertices = *from_vertices;
599 ++total_num_cell_vertices;
600 num_vertices_per_cell[
i] = 1;
602 num_vertices_per_cell[
i] = 0;
608 if (total_num_cell_vertices !=
num_cells * max_num_vertices_per_cell)
614 size_t * duplicated_cell_idx;
616 size_t nbr_duplicated_cells;
619 vertex_ids, comm, &duplicated_cell_idx, &orig_cell_ids,
620 &nbr_duplicated_cells);
623 for (
size_t i = 0;
i < nbr_duplicated_cells; ++
i)
626 if ((duplicated_cell_idx_ != NULL) && (orig_cell_ids_ != NULL) &&
627 (nbr_duplicated_cells_ != NULL)) {
628 *duplicated_cell_idx_ = duplicated_cell_idx;
629 *orig_cell_ids_ = orig_cell_ids;
630 *nbr_duplicated_cells_ = nbr_duplicated_cells;
632 free(duplicated_cell_idx);
638 *num_vertices_ = num_vertices;
639 *num_vertices_per_cell_ = num_vertices_per_cell;
640 *x_vertices_ = x_vertices;
641 *y_vertices_ = y_vertices;
643 *vertex_ids_ = vertex_ids;
647 free(num_vertices_per_cell);
654 if ((x_cells_ != NULL) && (y_cells_ != NULL)) {
658 *cell_ids_ = cell_ids;
662 const char * filename,
const char * grid_name,
size_t * num_cells_,
665 size_t grid_name_len = strlen(grid_name) + 1;
666 char msk_var_name[4 + grid_name_len];
668 snprintf(msk_var_name, 4 + grid_name_len,
"%s.msk", grid_name);
679 int dim_ids[NC_MAX_VAR_DIMS];
681 nc_inq_var(ncid, msk_var_id, NULL, NULL, &ndims, dim_ids, NULL));
684 "invalid number of dimensions for variable \"%s\" (has to be 2 not %d)",
685 msk_var_name, ndims);
686 int x_dim_id = dim_ids[1];
687 int y_dim_id = dim_ids[0];
695 size_t num_cells = x_dim_len * y_dim_len;
709 const char * filename,
const char * grid_name,
size_t * num_cells_,
710 int **
cell_mask,
int io_rank_idx,
int num_io_ranks) {
712 if ((io_rank_idx >= 0) && (io_rank_idx < num_io_ranks)) {
714 size_t grid_name_len = strlen(grid_name) + 1;
715 char msk_var_name[4 + grid_name_len];
717 snprintf(msk_var_name, 4 + grid_name_len,
"%s.msk", grid_name);
728 int dim_ids[NC_MAX_VAR_DIMS];
730 nc_inq_var(ncid, msk_var_id, NULL, NULL, &ndims, dim_ids, NULL));
733 "invalid number of dimensions for variable \"%s\" (has to be 2 not %d)",
734 msk_var_name, ndims);
735 int x_dim_id = dim_ids[1];
736 int y_dim_id = dim_ids[0];
745 size_t x_start_local =
747 (((
unsigned long)x_dim_len * (
unsigned long)io_rank_idx) /
748 (
unsigned long)num_io_ranks);
749 size_t x_count_local =
751 (((
unsigned long)x_dim_len * (io_rank_idx+1)) /
752 (
unsigned long)num_io_ranks) - x_start_local;
754 size_t num_cells = x_count_local * y_dim_len;
760 size_t start[2] = {0, x_start_local};
761 size_t count[2] = {y_dim_len, x_count_local};
763 nc_get_vara_int(ncid, msk_var_id, start, count, *
cell_mask));
776 char const * grid_filename,
char const * mask_filename,
777 char const * grid_name,
int valid_mask_value,
778 size_t * num_vertices,
size_t *
num_cells,
int ** num_vertices_per_cell,
779 double ** x_vertices,
double ** y_vertices,
780 double ** x_cells,
double ** y_cells,
782 size_t ** orig_cell_idx,
size_t * nbr_duplicated_cells,
int with_vertices) {
784 size_t cell_mask_size;
787 mask_filename, grid_name, &cell_mask_size, &
cell_mask);
789 for (
size_t i = 0;
i < cell_mask_size; ++
i)
793 grid_filename, grid_name, cell_mask_size,
cell_mask,
795 x_vertices, y_vertices, x_cells, y_cells, duplicated_cell_idx,
796 orig_cell_idx, nbr_duplicated_cells, with_vertices);
799 for (
size_t i = 0;
i < *num_vertices; ++
i) {
804 if ((x_cells != NULL) && (y_cells != NULL)) {
812 !with_vertices || (*num_vertices <= INT_MAX),
"too man vertices in grid")
819 char const * grid_filename,
char const * mask_filename,
820 char const * grid_name,
int valid_mask_value,
821 size_t * num_vertices,
size_t *
num_cells,
int ** num_vertices_per_cell,
822 double ** x_vertices,
double ** y_vertices,
823 double ** x_cells,
double ** y_cells,
825 size_t ** orig_cell_idx,
size_t * nbr_duplicated_cells) {
828 grid_filename, mask_filename, grid_name, valid_mask_value,
829 num_vertices,
num_cells, num_vertices_per_cell, x_vertices, y_vertices,
831 duplicated_cell_idx, orig_cell_idx, nbr_duplicated_cells, 1);
835 MPI_Comm comm,
int * io_rank_idx,
int * num_io_ranks) {
837 int local_is_io, * io_ranks;
844 while ((*io_rank_idx < *num_io_ranks) &&
845 (comm_rank != io_ranks[*io_rank_idx]))
848 !local_is_io || (*io_rank_idx < *num_io_ranks),
849 "unable to determine io_rank_idx");
856 char const * grid_filename,
char const * mask_filename,
857 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
858 size_t * num_vertices,
size_t *
num_cells,
int ** num_vertices_per_cell,
859 double ** x_vertices,
double ** y_vertices,
yac_int ** vertex_ids,
860 double ** x_cells,
double ** y_cells,
yac_int ** cell_ids,
862 yac_int ** orig_cell_ids,
size_t * nbr_duplicated_cells,
int with_vertices) {
865 if (comm == MPI_COMM_NULL) {
867 size_t * orig_cell_idx = NULL;
870 grid_filename, mask_filename, grid_name, valid_mask_value,
871 num_vertices,
num_cells, num_vertices_per_cell,
874 (orig_cell_ids != NULL)?&orig_cell_idx:NULL,
875 nbr_duplicated_cells, with_vertices);
878 *vertex_ids =
xmalloc(*num_vertices *
sizeof(**vertex_ids));
879 for (
size_t i = 0;
i < *num_vertices; ++
i) (*vertex_ids)[
i] =
i;
885 if (orig_cell_ids != NULL) {
887 xmalloc(*nbr_duplicated_cells *
sizeof(**orig_cell_ids));
888 for (
size_t i = 0;
i < *nbr_duplicated_cells; ++
i)
889 (*orig_cell_ids)[
i] = (*cell_ids)[orig_cell_idx[
i]];
895 int io_rank_idx, num_io_ranks;
899 size_t cell_mask_size;
901 mask_filename, grid_name, &cell_mask_size, &
cell_mask,
902 io_rank_idx, num_io_ranks);
904 for (
size_t i = 0;
i < cell_mask_size; ++
i)
908 grid_filename, grid_name, cell_mask_size,
cell_mask,
910 x_vertices, y_vertices, vertex_ids,
911 x_cells, y_cells, cell_ids, duplicated_cell_idx,
912 orig_cell_ids, nbr_duplicated_cells,
913 io_rank_idx, num_io_ranks, comm, with_vertices);
916 for (
size_t i = 0;
i < *num_vertices; ++
i) {
921 if ((x_cells != NULL) && (y_cells != NULL)) {
929 !with_vertices || (*num_vertices <= INT_MAX),
"too man vertices in grid")
931 *
num_cells <= INT_MAX,
"too man cells in grid")
934 "mask and grid size do not match "
935 "(mask_file: \"%s\" grid_file: \"%s\" grid_name: \"%s\"",
936 mask_filename, grid_filename, grid_name)
943 char const * grid_filename,
char const * mask_filename,
944 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
int use_ll,
945 double ** x_cells,
double ** y_cells,
size_t ** duplicated_cell_idx,
946 yac_int ** orig_cell_global_ids,
size_t * nbr_duplicated_cells) {
960 grid_filename, mask_filename, comm, grid_name, valid_mask_value,
964 orig_cell_global_ids, nbr_duplicated_cells, 1);
969 for (
size_t i = 0; (i <
num_cells) && use_ll; ++i)
972 if (comm != MPI_COMM_NULL) {
975 MPI_IN_PLACE, &use_ll, 1, MPI_INT, MPI_MIN, comm), comm);
978 if (!use_ll && (comm_rank == 0))
980 stderr,
"WARNING(yac_read_scrip_basic_grid_data_): "
981 "grid \"%s\" from \"%s\": required LL but stored as GC "
982 "(>4 vertices per cell)\n",
983 grid_name, grid_filename);
987 (*generate_basic_grid_data_unstruct_ptr)(
988 size_t,
size_t,
int *,
double *,
double *,
int *) =
994 generate_basic_grid_data_unstruct_ptr(
1015 char const * grid_filename,
char const * mask_filename,
1016 char const * grid_name,
int valid_mask_value,
int use_ll_edges) {
1020 grid_filename, mask_filename, MPI_COMM_NULL,
1021 grid_name, valid_mask_value, use_ll_edges,
1022 NULL, NULL, NULL, NULL, NULL);
1026 char const * grid_filename,
char const * mask_filename,
1027 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
1028 char const *
name,
int use_ll_edges,
size_t * cell_coord_idx,
1029 size_t ** duplicated_cell_idx,
yac_int ** orig_cell_global_ids,
1030 size_t * nbr_duplicated_cells) {
1033 double * x_cells, * y_cells;
1038 grid_filename, mask_filename, comm, grid_name, valid_mask_value,
1039 use_ll_edges, (cell_coord_idx != NULL)?&x_cells:NULL,
1040 (cell_coord_idx != NULL)?&y_cells:NULL, duplicated_cell_idx,
1041 orig_cell_global_ids, nbr_duplicated_cells));
1043 if (cell_coord_idx != NULL) {
1065 char const * grid_filename,
char const * mask_filename,
1066 MPI_Fint comm,
char const * grid_name,
int valid_mask_value,
1067 char const *
name,
int use_ll_edges,
size_t * cell_coord_idx,
1068 size_t ** duplicated_cell_idx,
yac_int ** orig_cell_global_ids,
1069 size_t * nbr_duplicated_cells) {
1073 grid_filename, mask_filename, MPI_Comm_f2c(comm), grid_name,
1074 valid_mask_value,
name, use_ll_edges, cell_coord_idx,
1075 duplicated_cell_idx, orig_cell_global_ids, nbr_duplicated_cells);
1079 char const * grid_filename,
char const * mask_filename,
1080 char const * grid_name,
int valid_mask_value,
char const *
name,
1081 int use_ll_edges,
size_t * cell_coord_idx,
1082 size_t ** duplicated_cell_idx,
yac_int ** orig_cell_global_ids,
1083 size_t * nbr_duplicated_cells) {
1087 grid_filename, mask_filename, MPI_COMM_NULL, grid_name, valid_mask_value,
1088 name, use_ll_edges, cell_coord_idx, duplicated_cell_idx,
1089 orig_cell_global_ids, nbr_duplicated_cells);
1093 char const * grid_filename,
char const * mask_filename, MPI_Comm comm,
1094 char const * grid_name,
int valid_mask_value,
size_t ** duplicated_vertex_idx,
1095 yac_int ** orig_vertex_global_ids,
size_t * nbr_duplicated_vertices) {
1097 size_t file_num_cells;
1099 double * file_x_cells;
1100 double * file_y_cells;
1102 int * file_cell_core_mask;
1105 grid_filename, mask_filename, comm, grid_name, valid_mask_value,
1106 NULL, &file_num_cells, NULL, NULL, NULL, NULL,
1107 &file_x_cells, &file_y_cells, &file_cell_ids,
1108 NULL, &file_cell_core_mask, duplicated_vertex_idx,
1109 orig_vertex_global_ids, nbr_duplicated_vertices, 0);
1113 file_num_cells, file_x_cells, file_y_cells);
1119 grid_data.core_vertex_mask = file_cell_core_mask;
1128 char const * grid_filename,
char const * mask_filename,
1129 char const * grid_name,
int valid_mask_value) {
1133 grid_filename, mask_filename, MPI_COMM_NULL,
1134 grid_name, valid_mask_value, NULL, NULL, NULL);
1138 char const * grid_filename,
char const * mask_filename,
1139 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
1140 char const *
name,
size_t * vertex_coord_idx,
1141 size_t ** duplicated_vertex_idx,
yac_int ** orig_vertex_global_ids,
1142 size_t * nbr_duplicated_vertices) {
1147 grid_filename, mask_filename, comm, grid_name, valid_mask_value,
1148 duplicated_vertex_idx, orig_vertex_global_ids, nbr_duplicated_vertices);
1152 if (vertex_coord_idx != NULL) {
1156 xmalloc(num_vertices *
sizeof(*vertex_coords));
1159 num_vertices *
sizeof(*vertex_coords));
1169 char const * grid_filename,
char const * mask_filename,
1170 MPI_Fint comm,
char const * grid_name,
int valid_mask_value,
1171 char const *
name,
size_t * vertex_coord_idx,
1172 size_t ** duplicated_vertex_idx,
yac_int ** orig_vertex_global_ids,
1173 size_t * nbr_duplicated_vertices) {
1177 grid_filename, mask_filename, MPI_Comm_f2c(comm), grid_name,
1178 valid_mask_value,
name, vertex_coord_idx, duplicated_vertex_idx,
1179 orig_vertex_global_ids, nbr_duplicated_vertices);
1183 char const * grid_filename,
char const * mask_filename,
1184 char const * grid_name,
int valid_mask_value,
char const *
name,
1185 size_t * vertex_coord_idx,
size_t ** duplicated_vertex_idx,
1186 yac_int ** orig_vertex_global_ids,
size_t * nbr_duplicated_vertices) {
1190 grid_filename, mask_filename, MPI_COMM_NULL, grid_name, valid_mask_value,
1191 name, vertex_coord_idx, duplicated_vertex_idx, orig_vertex_global_ids,
1192 nbr_duplicated_vertices);
1196 char const * grid_filename, MPI_Comm comm,
char const * grid_name) {
1198 int local_is_io, * io_ranks, num_io_ranks;
1200 int root_rank = io_ranks[0];
1205 int contains_corner_information = 0;
1207 if (local_is_io && (comm_rank == root_rank)) {
1209 size_t grid_name_len = strlen(grid_name) + 1;
1210 char cla_var_name[4 + grid_name_len];
1211 char clo_var_name[4 + grid_name_len];
1213 snprintf(cla_var_name, 4 + grid_name_len,
"%s.cla", grid_name);
1214 snprintf(clo_var_name, 4 + grid_name_len,
"%s.clo", grid_name);
1220 int cla_var_id, clo_var_id;
1222 contains_corner_information =
1223 (NC_NOERR == nc_inq_varid(ncid, cla_var_name, &cla_var_id)) &&
1224 (NC_NOERR == nc_inq_varid(ncid, clo_var_name, &clo_var_id));
1231 &contains_corner_information, 1, MPI_INT, root_rank, comm), comm);
1233 return contains_corner_information;
1237 char const * grid_filename,
char const * mask_filename,
1238 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
1239 char const *
name,
int use_ll_edges,
size_t * point_coord_idx,
1240 size_t ** duplicated_point_idx,
yac_int ** orig_point_global_ids,
1241 size_t * nbr_duplicated_points,
int * point_location) {
1243 int contains_corner_information =
1246 if (contains_corner_information) {
1250 grid_filename, mask_filename, comm, grid_name,
1251 valid_mask_value,
name, use_ll_edges, point_coord_idx,
1252 duplicated_point_idx, orig_point_global_ids, nbr_duplicated_points);
1257 grid_filename, mask_filename, comm, grid_name,
1258 valid_mask_value,
name, point_coord_idx, duplicated_point_idx,
1259 orig_point_global_ids, nbr_duplicated_points);
1264 char const * grid_filename,
char const * mask_filename,
1265 MPI_Fint comm,
char const * grid_name,
int valid_mask_value,
1266 char const *
name,
int use_ll_edges,
size_t * point_coord_idx,
1267 size_t ** duplicated_point_idx,
yac_int ** orig_point_global_ids,
1268 size_t * nbr_duplicated_points,
int * point_location) {
1272 grid_filename, mask_filename, MPI_Comm_f2c(comm), grid_name,
1273 valid_mask_value,
name, use_ll_edges, point_coord_idx,
1274 duplicated_point_idx, orig_point_global_ids, nbr_duplicated_points,
1281 const void * a,
const void * b) {
1285 if (ret)
return ret;
1287 for (
int i = 0; (
i < count) && !ret; ++
i)
1294 double ** vertex_lon,
double ** vertex_lat,
yac_int ** vertex_ids,
1295 size_t * nbr_vertices,
int * old_to_new_id) {
1298 xmalloc(*nbr_vertices *
sizeof(*sort_array));
1300 double const scale = (double)(2 << 20);
1301 int32_t
const periode = (int32_t)(360.0 * scale);
1303 for (
size_t i = 0;
i < *nbr_vertices; ++
i) {
1305 int32_t curr_lon = (int32_t)round((*vertex_lon)[
i] * scale);
1306 int32_t curr_lat = (int32_t)round((*vertex_lat)[
i] * scale);
1308 if ((curr_lat == (int32_t)(90.0 * scale)) ||
1309 (curr_lat == (int32_t)(-90.0 * scale))) {
1315 curr_lon = curr_lon - (((curr_lon - periode) / periode) * periode);
1316 else if (curr_lon > periode)
1317 curr_lon = curr_lon - ((curr_lon / periode) * periode);
1320 sort_array[
i].
lon = curr_lon;
1321 sort_array[
i].
lat = curr_lat;
1322 sort_array[
i].
dlon = (*vertex_lon)[
i];
1323 sort_array[
i].
dlat = (*vertex_lat)[
i];
1324 sort_array[
i].
id = (vertex_ids != NULL)?(*vertex_ids)[
i]:YAC_INT_MAX;
1326 sort_array[
i].
i =
i;
1329 yac_mergesort(sort_array, *nbr_vertices,
sizeof(*sort_array),
1333 {.
lon = INT32_MAX, .lat = INT32_MAX, .i = SIZE_MAX};
1335 size_t new_nbr_vertices = 0;
1336 for (
size_t i = 0;
i < *nbr_vertices; ++
i, ++curr) {
1340 (*vertex_lon)[new_nbr_vertices] = curr->
dlon;
1341 (*vertex_lat)[new_nbr_vertices] = curr->dlat;
1342 if (vertex_ids != NULL)
1343 (*vertex_ids)[new_nbr_vertices] = curr->id;
1344 sort_array[new_nbr_vertices] = *curr;
1348 old_to_new_id[curr->i] = (int)(new_nbr_vertices - 1);
1351 (*vertex_lon) =
xrealloc(*vertex_lon, new_nbr_vertices *
sizeof(**vertex_lon));
1352 (*vertex_lat) =
xrealloc(*vertex_lat, new_nbr_vertices *
sizeof(**vertex_lat));
1353 if (vertex_ids != NULL)
1354 (*vertex_ids) =
xrealloc(*vertex_ids, new_nbr_vertices *
sizeof(**vertex_ids));
1355 *nbr_vertices = new_nbr_vertices;
1361 double ** vertex_lon,
double ** vertex_lat,
1362 size_t * nbr_vertices,
int * old_to_new_id) {
1366 vertex_lon, vertex_lat, NULL, nbr_vertices, old_to_new_id));
1370unsigned long djb2_hash(
unsigned char * values,
size_t count) {
1372 unsigned long hash = 5381;
1374 for (
size_t i = 0;
i < count; ++
i) {
1375 unsigned int value = values[
i];
1376 hash = ((hash << 5) + hash) +
value;
1383 void *
data,
size_t data_size,
int comm_size) {
1386 djb2_hash((
unsigned char*)
data, data_size) % (
unsigned long)comm_size;
1392 MPI_Datatype point_with_index_dt;
1393 enum {NUM_MEMBERS = 5};
1394 int array_of_blocklengths[NUM_MEMBERS] = {1, 1, 1, 1, 1};
1395 MPI_Aint array_of_displacements[NUM_MEMBERS];
1398 yac_mpi_call(MPI_Get_address(&dummy, &base_addr), comm);
1401 &(dummy.
lon), &array_of_displacements[0]), comm);
1402 array_of_displacements[0] -= base_addr;
1405 &(dummy.
lat), &array_of_displacements[1]), comm);
1406 array_of_displacements[1] -= base_addr;
1409 &(dummy.
id), &array_of_displacements[2]), comm);
1410 array_of_displacements[2] -= base_addr;
1413 &(dummy.
dlon), &array_of_displacements[3]), comm);
1414 array_of_displacements[3] -= base_addr;
1417 &(dummy.
dlat), &array_of_displacements[4]), comm);
1418 array_of_displacements[4] -= base_addr;
1420 const MPI_Datatype array_of_types[NUM_MEMBERS] =
1421 {MPI_INT32_T, MPI_INT32_T,
yac_int_dt, MPI_DOUBLE, MPI_DOUBLE};
1423 MPI_Type_create_struct(
1424 NUM_MEMBERS, array_of_blocklengths, array_of_displacements,
1425 array_of_types, &point_with_index_dt), comm);
1430 double ** vertex_lon,
double ** vertex_lat,
1431 size_t * nbr_vertices_,
int * old_to_new_id,
yac_int ** vertex_ids,
1434 char const * routine =
"remove_duplicated_vertices_parallel";
1439 vertex_lon, vertex_lat, vertex_ids, nbr_vertices_, old_to_new_id);
1441 sort_array =
xrealloc(sort_array, *nbr_vertices_ *
sizeof(*sort_array));
1443 size_t nbr_vertices = *nbr_vertices_;
1445 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
1447 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
1449 int comm_rank, comm_size;
1454 for (
size_t i = 0;
i < nbr_vertices; ++
i) {
1457 &(sort_array[
i].
lon), 2 *
sizeof(sort_array[
i].
lon), comm_size);
1460 sort_array[
i].
i =
i;
1464 yac_mergesort(sort_array, nbr_vertices,
sizeof(*sort_array),
1468 1, sendcounts, recvcounts, sdispls, rdispls, comm);
1470 size_t recv_count = recvcounts[comm_size - 1] + rdispls[comm_size - 1];
1472 xmalloc(recv_count *
sizeof(*dist_sort_array));
1475 MPI_Datatype point_with_index_dt =
1477 yac_mpi_call(MPI_Type_commit(&point_with_index_dt), comm);
1479 sort_array, sendcounts, sdispls+1,
1480 dist_sort_array, recvcounts, rdispls,
1481 sizeof(*sort_array), point_with_index_dt, comm, routine, __LINE__);
1483 for (
size_t i = 0;
i < recv_count; ++
i) dist_sort_array[
i].
i =
i;
1486 yac_mergesort(dist_sort_array, recv_count,
sizeof(*dist_sort_array),
1490 {.
lon = INT32_MAX, .lat = INT32_MAX};
1492 for (
size_t i = 0;
i < recv_count; ++
i, ++curr) {
1499 curr->
id = prev->
id;
1500 curr->dlon = prev->
dlon;
1501 curr->dlat = prev->
dlat;
1506 yac_mergesort(dist_sort_array, recv_count,
sizeof(*dist_sort_array),
1511 dist_sort_array, recvcounts, rdispls,
1512 sort_array, sendcounts, sdispls+1,
1513 sizeof(*sort_array), point_with_index_dt, comm, routine, __LINE__);
1514 free(dist_sort_array);
1516 yac_mpi_call(MPI_Type_free(&point_with_index_dt), comm);
1519 for (
size_t i = 0;
i < nbr_vertices; ++
i) {
1521 (*vertex_lon)[sort_array[
i].
i] = sort_array[
i].dlon;
1522 (*vertex_lat)[sort_array[
i].i] = sort_array[
i].dlat;
1523 (*vertex_ids)[sort_array[
i].i] = sort_array[
i].id;
1531 size_t nbr_cells,
size_t ** duplicated_cell_idx,
1532 size_t ** orig_cell_idx,
size_t * nbr_duplicated_cells) {
1535 size_t nbr_unmasked_cells = 0;
1536 for (
size_t i = 0;
i < nbr_cells; ++
i)
1540 xmalloc(nbr_unmasked_cells *
sizeof(*sort_array));
1543 for (
size_t i = 0, offset = 0, j = 0;
i < nbr_cells; ++
i) {
1549 sort_array[j].
i =
i;
1553 offset += (size_t)(num_vertices_per_cell[
i]);
1557 yac_mergesort(sort_array, nbr_unmasked_cells,
sizeof(*sort_array),
1561 *nbr_duplicated_cells = 0;
1562 for (
size_t i = 1;
i < nbr_unmasked_cells; ++
i)
1564 ++*nbr_duplicated_cells;
1567 *duplicated_cell_idx =
1568 xmalloc(*nbr_duplicated_cells *
sizeof(**duplicated_cell_idx));
1570 xmalloc(*nbr_duplicated_cells *
sizeof(**orig_cell_idx));
1572 for (
size_t i = 1, j = 0;
i < nbr_unmasked_cells; ++
i, ++curr) {
1576 (*duplicated_cell_idx)[j] = (size_t)(curr->i);
1577 (*orig_cell_idx)[j] = (size_t)(prev->
i);
1586 MPI_Comm comm,
size_t count) {
1588 MPI_Datatype cell_to_vertex_ids_dt;
1590 MPI_Type_contiguous(
1591 (
int)count,
yac_int_dt, &cell_to_vertex_ids_dt), comm);
1592 return cell_to_vertex_ids_dt;
1598 MPI_Comm comm,
size_t ** duplicated_cell_idx_,
1599 yac_int ** orig_cell_ids_,
size_t * num_duplicated_cells_) {
1601 char const * routine =
"detect_duplicated_cells_parallel";
1608 size_t max_num_vertices_per_cell = 0;
1609 size_t local_num_cells = 0;
1612 if ((
size_t)(num_vertices_per_cell[
i]) > max_num_vertices_per_cell)
1613 max_num_vertices_per_cell = (size_t)(num_vertices_per_cell[
i]);
1621 MPI_IN_PLACE, &max_num_vertices_per_cell, 1,
YAC_MPI_SIZE_T, MPI_MAX,
1626 xmalloc(local_num_cells * (1 + max_num_vertices_per_cell) *
1627 sizeof(*local_cell_ids));
1628 yac_int * local_cell_to_vertex_ids = local_cell_ids + local_num_cells;
1631 yac_int * curr_local_cell_ids = local_cell_ids;
1632 yac_int * curr_local_cell_to_vertex_ids = local_cell_to_vertex_ids;
1636 size_t curr_num_vertices_per_cell = (size_t)(num_vertices_per_cell[
i]);
1639 *curr_local_cell_ids = cell_ids[
i];
1643 for (; j < curr_num_vertices_per_cell; ++j)
1644 curr_local_cell_to_vertex_ids[j] =
1645 vertex_ids[curr_cell_to_vertex[j]];
1648 qsort(curr_local_cell_to_vertex_ids, curr_num_vertices_per_cell,
1652 for (; j < max_num_vertices_per_cell; ++j)
1653 curr_local_cell_to_vertex_ids[j] = YAC_INT_MAX;
1655 curr_local_cell_ids++;
1656 curr_local_cell_to_vertex_ids += max_num_vertices_per_cell;
1658 curr_cell_to_vertex += curr_num_vertices_per_cell;
1661 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
1663 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
1666 int * dist_cell_ranks =
xmalloc(local_num_cells *
sizeof(*dist_cell_ranks));
1667 for (
size_t i = 0;
i < local_num_cells; ++
i) {
1670 local_cell_to_vertex_ids +
i * max_num_vertices_per_cell,
1671 max_num_vertices_per_cell *
sizeof(*local_cell_to_vertex_ids),
1674 dist_cell_ranks[
i] = rank;
1678 1, sendcounts, recvcounts, sdispls, rdispls, comm);
1680 size_t dist_num_cells = recvcounts[comm_size-1] + rdispls[comm_size-1];
1682 xmalloc((local_num_cells + dist_num_cells) *
1683 (1 + max_num_vertices_per_cell) *
sizeof(*yac_int_buffer));
1684 yac_int * dist_cell_ids = yac_int_buffer;
1685 yac_int * dist_cell_vertex_ids = yac_int_buffer + dist_num_cells;
1686 yac_int * send_local_cell_ids =
1687 yac_int_buffer + dist_num_cells * (1 + max_num_vertices_per_cell);
1688 yac_int * send_local_cell_to_vertex_ids =
1689 yac_int_buffer + local_num_cells +
1690 dist_num_cells * (1 + max_num_vertices_per_cell);
1693 for (
size_t i = 0;
i < local_num_cells; ++
i) {
1694 size_t pos = sdispls[dist_cell_ranks[
i] + 1]++;
1695 send_local_cell_ids[pos] = local_cell_ids[
i];
1697 send_local_cell_to_vertex_ids + pos * max_num_vertices_per_cell,
1698 local_cell_to_vertex_ids +
i * max_num_vertices_per_cell,
1699 max_num_vertices_per_cell *
sizeof(*send_local_cell_to_vertex_ids));
1702 xrealloc(local_cell_ids, local_num_cells *
sizeof(*local_cell_ids));
1705 MPI_Datatype cell_to_vertex_ids_dt =
1707 yac_mpi_call(MPI_Type_commit(&cell_to_vertex_ids_dt), comm);
1708 yac_alltoallv_yac_int_p2p(
1709 send_local_cell_ids, sendcounts, sdispls,
1710 dist_cell_ids, recvcounts, rdispls, comm, routine, __LINE__);
1712 send_local_cell_to_vertex_ids, sendcounts, sdispls,
1713 dist_cell_vertex_ids, recvcounts, rdispls,
1714 max_num_vertices_per_cell *
sizeof(*dist_cell_vertex_ids),
1715 cell_to_vertex_ids_dt, comm, routine, __LINE__);
1716 yac_mpi_call(MPI_Type_free(&cell_to_vertex_ids_dt), comm);
1722 dist_num_cells * (1 + max_num_vertices_per_cell) *
1723 sizeof(*yac_int_buffer));
1724 dist_cell_ids = yac_int_buffer;
1725 dist_cell_vertex_ids = yac_int_buffer + dist_num_cells;
1729 xmalloc(dist_num_cells *
sizeof(*sort_array));
1730 for (
size_t i = 0;
i < dist_num_cells; ++
i) {
1731 sort_array[
i].
cell_id = dist_cell_ids[
i];
1733 dist_cell_vertex_ids +
i * max_num_vertices_per_cell;
1735 sort_array[
i].
i =
i;
1740 sort_array, dist_num_cells,
sizeof(*sort_array),
1746 for (
size_t i = 1;
i < dist_num_cells; ++
i, ++curr) {
1759 (local_num_cells + dist_num_cells) *
sizeof(*yac_int_buffer));
1760 yac_int * recv_local_cell_ids = yac_int_buffer;
1761 dist_cell_ids = yac_int_buffer + local_num_cells;
1762 for (
size_t i = 0;
i < dist_num_cells; ++
i)
1763 dist_cell_ids[sort_array[
i].
i] = sort_array[
i].
cell_id;
1767 yac_alltoallv_yac_int_p2p(
1768 dist_cell_ids, recvcounts, rdispls,
1769 recv_local_cell_ids, sendcounts, sdispls, comm, routine, __LINE__);
1774 size_t num_duplicated_cells = 0;
1775 for (
size_t i = 0;
i < local_num_cells; ++
i) {
1777 size_t pos = sdispls[dist_cell_ranks[
i]]++;
1779 if (local_cell_ids[
i] != recv_local_cell_ids[pos]) {
1780 num_duplicated_cells++;
1781 local_cell_ids[
i] = recv_local_cell_ids[pos];
1783 local_cell_ids[
i] = YAC_INT_MAX;
1786 free(yac_int_buffer);
1787 free(dist_cell_ranks);
1789 size_t * duplicated_cell_idx =
1790 xmalloc(num_duplicated_cells *
sizeof(*duplicated_cell_idx));
1792 xmalloc(num_duplicated_cells *
sizeof(*orig_cell_ids));
1799 if (local_cell_ids[j] != YAC_INT_MAX) {
1800 duplicated_cell_idx[k] =
i;
1801 orig_cell_ids[k] = local_cell_ids[j];
1807 free(local_cell_ids);
1809 *duplicated_cell_idx_ = duplicated_cell_idx;
1810 *orig_cell_ids_ = orig_cell_ids;
1811 *num_duplicated_cells_ = num_duplicated_cells;
1817 char const * grid_filename,
char const * mask_filename,
1818 char const * grid_name,
int valid_mask_value,
int use_ll_edges) {
1823 UNUSED(valid_mask_value);
1826 "ERROR(yac_read_scrip_basic_grid_data): "
1827 "YAC is built without the NetCDF support");
1831 (
size_t[]){0,0}, (
int[]){0,0}, NULL, NULL);
1835 char const * grid_filename,
char const * mask_filename,
1836 char const * grid_name,
int valid_mask_value,
char const *
name,
1837 int use_ll_edges,
size_t * cell_coord_idx,
1838 size_t ** duplicated_cell_idx,
yac_int ** orig_cell_global_ids,
1839 size_t * nbr_duplicated_cells) {
1844 UNUSED(valid_mask_value);
1848 UNUSED(duplicated_cell_idx);
1849 UNUSED(orig_cell_global_ids);
1850 UNUSED(nbr_duplicated_cells);
1852 "ERROR(yac_read_scrip_basic_grid): "
1853 "YAC is built without the NetCDF support");
1859 char const * grid_filename,
char const * mask_filename,
1860 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
1861 char const *
name,
int use_ll_edges,
size_t * cell_coord_idx,
1862 size_t ** duplicated_cell_idx,
yac_int ** orig_cell_global_ids,
1863 size_t * nbr_duplicated_cells) {
1869 UNUSED(valid_mask_value);
1873 UNUSED(duplicated_cell_idx);
1874 UNUSED(orig_cell_global_ids);
1875 UNUSED(nbr_duplicated_cells);
1877 "ERROR(yac_read_scrip_basic_grid_parallel): "
1878 "YAC is built without the NetCDF support");
1884 char const * grid_filename,
char const * mask_filename,
1885 char const * grid_name,
int valid_mask_value) {
1890 UNUSED(valid_mask_value);
1892 "ERROR(yac_read_scrip_cloud_basic_grid_data): "
1893 "YAC is built without the NetCDF support");
1897 (
size_t[]){0,0}, (
int[]){0,0}, NULL, NULL);
1901 char const * grid_filename,
char const * mask_filename,
1902 char const * grid_name,
int valid_mask_value,
char const *
name,
1903 size_t * vertex_coord_idx,
size_t ** duplicated_vertex_idx,
1904 yac_int ** orig_vertex_global_ids,
size_t * nbr_duplicated_vertices) {
1909 UNUSED(valid_mask_value);
1911 UNUSED(vertex_coord_idx);
1912 UNUSED(duplicated_vertex_idx);
1913 UNUSED(orig_vertex_global_ids);
1914 UNUSED(nbr_duplicated_vertices);
1916 "ERROR(yac_read_scrip_cloud_basic_grid): "
1917 "YAC is built without the NetCDF support");
1923 char const * grid_filename,
char const * mask_filename,
1924 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
1925 char const *
name,
size_t * vertex_coord_idx,
1926 size_t ** duplicated_vertex_idx,
yac_int ** orig_vertex_global_ids,
1927 size_t * nbr_duplicated_vertices) {
1933 UNUSED(valid_mask_value);
1935 UNUSED(vertex_coord_idx);
1936 UNUSED(duplicated_vertex_idx);
1937 UNUSED(orig_vertex_global_ids);
1938 UNUSED(nbr_duplicated_vertices);
1940 "ERROR(yac_read_scrip_cloud_basic_grid_parallel): "
1941 "YAC is built without the NetCDF support");
1947 char const * grid_filename,
char const * mask_filename,
1948 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
1949 char const *
name,
int use_ll_edges,
size_t * point_coord_idx,
1950 size_t ** duplicated_point_idx,
yac_int ** orig_point_global_ids,
1951 size_t * nbr_duplicated_points,
int * point_location) {
1957 UNUSED(valid_mask_value);
1961 UNUSED(duplicated_point_idx);
1962 UNUSED(orig_point_global_ids);
1963 UNUSED(nbr_duplicated_points);
1966 "ERROR(yac_read_scrip_generic_basic_grid_parallel): "
1967 "YAC is built without the NetCDF support");
1973 char const * grid_filename,
char const * mask_filename,
1974 char const * grid_name,
int valid_mask_value,
1975 size_t * num_vertices,
size_t *
num_cells,
int ** num_vertices_per_cell,
1976 double ** x_vertices,
double ** y_vertices,
1977 double ** x_cells,
double ** y_cells,
1979 size_t ** orig_cell_idx,
size_t * nbr_duplicated_cells) {
1984 UNUSED(valid_mask_value);
1987 UNUSED(num_vertices_per_cell);
1994 UNUSED(duplicated_cell_idx);
1996 UNUSED(nbr_duplicated_cells);
1998 "ERROR(yac_read_scrip_grid_information): "
1999 "YAC is built without the NetCDF support");
2003 char const * grid_filename,
char const * mask_filename,
2004 MPI_Fint comm,
char const * grid_name,
int valid_mask_value,
2005 char const *
name,
int use_ll_edges,
size_t * cell_coord_idx,
2006 size_t ** duplicated_cell_idx,
yac_int ** orig_cell_global_ids,
2007 size_t * nbr_duplicated_cells) {
2013 UNUSED(valid_mask_value);
2017 UNUSED(duplicated_cell_idx);
2018 UNUSED(orig_cell_global_ids);
2019 UNUSED(nbr_duplicated_cells);
2021 "ERROR(yac_read_scrip_basic_grid_parallel_f2c): "
2022 "YAC is built without the NetCDF support");
2027 char const * grid_filename,
char const * mask_filename,
2028 MPI_Fint comm,
char const * grid_name,
int valid_mask_value,
2029 char const *
name,
size_t * vertex_coord_idx,
2030 size_t ** duplicated_vertex_idx,
yac_int ** orig_vertex_global_ids,
2031 size_t * nbr_duplicated_vertices) {
2037 UNUSED(valid_mask_value);
2039 UNUSED(vertex_coord_idx);
2040 UNUSED(duplicated_vertex_idx);
2041 UNUSED(orig_vertex_global_ids);
2042 UNUSED(nbr_duplicated_vertices);
2044 "ERROR(yac_read_scrip_cloud_basic_grid_parallel_f2c): "
2045 "YAC is built without the NetCDF support");
2050 char const * grid_filename,
char const * mask_filename,
2051 MPI_Fint comm,
char const * grid_name,
int valid_mask_value,
2052 char const *
name,
int use_ll_edges,
size_t * point_coord_idx,
2053 size_t ** duplicated_point_idx,
yac_int ** orig_point_global_ids,
2054 size_t * nbr_duplicated_points,
int * point_location) {
2060 UNUSED(valid_mask_value);
2064 UNUSED(duplicated_point_idx);
2065 UNUSED(orig_point_global_ids);
2066 UNUSED(nbr_duplicated_points);
2069 "ERROR(yac_read_scrip_generic_basic_grid_parallel_f2c): "
2070 "YAC is built without the NetCDF support");
#define YAC_ASSERT(exp, msg)
struct yac_basic_grid * yac_basic_grid_new(char const *name, struct yac_basic_grid_data grid_data)
size_t yac_basic_grid_add_coordinates_nocpy(struct yac_basic_grid *grid, enum yac_location location, yac_coordinate_pointer coordinates)
size_t yac_basic_grid_get_data_size(struct yac_basic_grid *grid, enum yac_location location)
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)
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_cloud(size_t nbr_points, double *x_points, double *y_points)
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)
void yac_get_io_ranks(MPI_Comm comm, int *local_is_io_, int **io_ranks_, int *num_io_ranks_)
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_mergesort(void *base, size_t num, size_t size, int(*compar)(const void *, const void *))
#define xrealloc(ptr, size)
struct yac_basic_grid * yac_read_scrip_cloud_basic_grid_parallel_f2c(char const *grid_filename, char const *mask_filename, MPI_Fint comm, char const *grid_name, int valid_mask_value, char const *name, size_t *vertex_coord_idx, size_t **duplicated_vertex_idx, yac_int **orig_vertex_global_ids, size_t *nbr_duplicated_vertices)
struct yac_basic_grid * yac_read_scrip_basic_grid_parallel(char const *grid_filename, char const *mask_filename, MPI_Comm comm, char const *grid_name, int valid_mask_value, char const *name, int use_ll_edges, size_t *cell_coord_idx, size_t **duplicated_cell_idx, yac_int **orig_cell_global_ids, size_t *nbr_duplicated_cells)
unsigned long djb2_hash(unsigned char *values, size_t count)
static void yac_read_part_scrip_grid_information(char const *grid_filename, char const *mask_filename, MPI_Comm comm, char const *grid_name, int valid_mask_value, size_t *num_vertices, size_t *num_cells, int **num_vertices_per_cell, double **x_vertices, double **y_vertices, yac_int **vertex_ids, double **x_cells, double **y_cells, yac_int **cell_ids, int **cell_to_vertex, int **cell_core_mask, size_t **duplicated_cell_idx, yac_int **orig_cell_ids, size_t *nbr_duplicated_cells, int with_vertices)
static void yac_read_part_scrip_basic_grid_information(const char *filename, const char *grid_name, size_t cell_mask_size, int *cell_mask, size_t *num_vertices_, size_t *num_cells_, int **num_vertices_per_cell_, int **cell_to_vertex_, double **x_vertices_, double **y_vertices_, yac_int **vertex_ids_, double **x_cells_, double **y_cells_, yac_int **cell_ids_, size_t **duplicated_cell_idx_, yac_int **orig_cell_ids_, size_t *nbr_duplicated_cells_, int io_rank_idx, int num_io_ranks, MPI_Comm comm, int with_vertices)
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)
static void yac_read_scrip_basic_grid_information(const char *filename, const char *grid_name, size_t cell_mask_size, int *cell_mask, size_t *num_vertices_, size_t *num_cells_, int **num_vertices_per_cell_, int **cell_to_vertex_, double **x_vertices, double **y_vertices, double **x_cells, double **y_cells, size_t **duplicated_cell_idx_, size_t **orig_cell_idx_, size_t *nbr_duplicated_cells_, int with_vertices)
static int compare_point_with_index_coord_id(const void *a_, const void *b_)
static void yac_read_part_scrip_mask_information(const char *filename, const char *grid_name, size_t *num_cells_, int **cell_mask, int io_rank_idx, int num_io_ranks)
void yac_read_scrip_grid_information(char const *grid_filename, char const *mask_filename, char const *grid_name, int valid_mask_value, size_t *num_vertices, size_t *num_cells, int **num_vertices_per_cell, double **x_vertices, double **y_vertices, double **x_cells, double **y_cells, int **cell_to_vertex, int **cell_core_mask, size_t **duplicated_cell_idx, size_t **orig_cell_idx, size_t *nbr_duplicated_cells)
static void yac_read_scrip_mask_information(const char *filename, const char *grid_name, size_t *num_cells_, int **cell_mask)
static int compare_cell_vertices_with_index(const void *a, const void *b)
static void detect_duplicated_cells_parallel(int *cell_to_vertex, int *num_vertices_per_cell, int *cell_mask, yac_int *cell_ids, size_t num_cells, yac_int *vertex_ids, MPI_Comm comm, size_t **duplicated_cell_idx, yac_int **orig_cell_ids, size_t *num_duplicated_cells_)
static MPI_Datatype get_point_with_index_mpi_datatype(MPI_Comm comm)
struct yac_basic_grid * yac_read_scrip_generic_basic_grid_parallel_f2c(char const *grid_filename, char const *mask_filename, MPI_Fint comm, char const *grid_name, int valid_mask_value, char const *name, int use_ll_edges, size_t *point_coord_idx, size_t **duplicated_point_idx, yac_int **orig_point_global_ids, size_t *nbr_duplicated_points, int *point_location)
static void remove_duplicated_vertices_parallel(double **vertex_lon, double **vertex_lat, size_t *nbr_vertices, int *old_to_new_id, yac_int **vertex_ids, MPI_Comm comm)
struct yac_basic_grid_data yac_read_scrip_cloud_basic_grid_data(char const *grid_filename, char const *mask_filename, char const *grid_name, int valid_mask_value)
static struct point_with_index * remove_duplicated_vertices_(double **vertex_lon, double **vertex_lat, yac_int **vertex_ids, size_t *nbr_vertices, int *old_to_new_id)
struct yac_basic_grid * yac_read_scrip_cloud_basic_grid_parallel(char const *grid_filename, char const *mask_filename, MPI_Comm comm, char const *grid_name, int valid_mask_value, char const *name, size_t *vertex_coord_idx, size_t **duplicated_vertex_idx, yac_int **orig_vertex_global_ids, size_t *nbr_duplicated_vertices)
struct yac_basic_grid * yac_read_scrip_cloud_basic_grid(char const *grid_filename, char const *mask_filename, char const *grid_name, int valid_mask_value, char const *name, size_t *vertex_coord_idx, size_t **duplicated_vertex_idx, yac_int **orig_vertex_global_ids, size_t *nbr_duplicated_vertices)
struct yac_basic_grid * yac_read_scrip_generic_basic_grid_parallel(char const *grid_filename, char const *mask_filename, MPI_Comm comm, char const *grid_name, int valid_mask_value, char const *name, int use_ll_edges, size_t *point_coord_idx, size_t **duplicated_point_idx, yac_int **orig_point_global_ids, size_t *nbr_duplicated_points, int *point_location)
static int check_corner_information(char const *grid_filename, MPI_Comm comm, char const *grid_name)
static int compare_cell_vertex_ids_with_index_ids_id(const void *a_, const void *b_)
static int compute_bucket(void *data, size_t data_size, int comm_size)
struct yac_basic_grid * yac_read_scrip_basic_grid_parallel_f2c(char const *grid_filename, char const *mask_filename, MPI_Fint comm, char const *grid_name, int valid_mask_value, char const *name, int use_ll_edges, size_t *cell_coord_idx, size_t **duplicated_cell_idx, yac_int **orig_cell_global_ids, size_t *nbr_duplicated_cells)
static struct yac_basic_grid_data yac_read_scrip_basic_grid_data_(char const *grid_filename, char const *mask_filename, MPI_Comm comm, char const *grid_name, int valid_mask_value, int use_ll, double **x_cells, double **y_cells, size_t **duplicated_cell_idx, yac_int **orig_cell_global_ids, size_t *nbr_duplicated_cells)
static int compare_yac_int(const void *a, const void *b)
static int compare_point_with_index_rank(const void *a_, const void *b_)
static void detect_duplicated_cells(int *cell_to_vertex, int *num_vertices_per_cell, int *cell_mask, size_t nbr_cells, size_t **duplicated_cell_idx, size_t **orig_cell_idx, size_t *nbr_duplicated_cells)
static MPI_Datatype get_cell_to_vertex_ids_mpi_datatype(MPI_Comm comm, size_t count)
static int compare_cell_vertex_ids_with_index_ids(const void *a_, const void *b_)
static int get_io_configuration(MPI_Comm comm, int *io_rank_idx, int *num_io_ranks)
static int compare_point_with_index_i(const void *a_, const void *b_)
static struct yac_basic_grid_data yac_read_scrip_cloud_basic_grid_data_(char const *grid_filename, char const *mask_filename, MPI_Comm comm, char const *grid_name, int valid_mask_value, size_t **duplicated_vertex_idx, yac_int **orig_vertex_global_ids, size_t *nbr_duplicated_vertices)
static int compare_int(const void *a, const void *b)
static void yac_read_scrip_grid_information_(char const *grid_filename, char const *mask_filename, char const *grid_name, int valid_mask_value, size_t *num_vertices, size_t *num_cells, int **num_vertices_per_cell, double **x_vertices, double **y_vertices, double **x_cells, double **y_cells, int **cell_to_vertex, int **cell_core_mask, size_t **duplicated_cell_idx, size_t **orig_cell_idx, size_t *nbr_duplicated_cells, int with_vertices)
static void remove_duplicated_vertices(double **vertex_lon, double **vertex_lat, size_t *nbr_vertices, int *old_to_new_id)
struct yac_basic_grid * yac_read_scrip_basic_grid(char const *grid_filename, char const *mask_filename, char const *grid_name, int valid_mask_value, char const *name, int use_ll_edges, size_t *cell_coord_idx, size_t **duplicated_cell_idx, yac_int **orig_cell_global_ids, size_t *nbr_duplicated_cells)
static int compare_point_with_index_coord(const void *a_, const void *b_)
yac_coordinate_pointer vertex_coordinates
int * num_vertices_per_cell
double cell_coords[36][3]
#define YAC_HANDLE_ERROR(exp)
static void LLtoXYZ(double lon, double lat, double p_out[])
void yac_quicksort_index_size_t_int(size_t *a, size_t n, int *idx)
#define YAC_ASSERT_F(exp, format,...)
void yac_generate_alltoallv_args(int count, size_t const *sendcounts, size_t *recvcounts, size_t *sdispls, size_t *rdispls, MPI_Comm comm)
void yac_free_comm_buffers(size_t *sendcounts, size_t *recvcounts, size_t *sdispls, size_t *rdispls)
void yac_get_comm_buffers(int count, size_t **sendcounts, size_t **recvcounts, size_t **sdispls, size_t **rdispls, MPI_Comm comm)
MPI_Datatype yac_create_resized(MPI_Datatype dt, size_t new_size, MPI_Comm comm)
void yac_alltoallv_p2p(void const *send_buffer, size_t const *sendcounts, size_t const *sdispls, void *recv_buffer, size_t const *recvcounts, size_t const *rdispls, size_t dt_size, MPI_Datatype dt, MPI_Comm comm, char const *caller, int line)
#define yac_mpi_call(call, comm)
double(* yac_coordinate_pointer)[3]