22#ifdef YAC_NETCDF_ENABLED
49 double ** vertex_lon,
double ** vertex_lat,
50 size_t * nbr_vertices,
int * old_to_new_id);
52 double ** vertex_lon,
double ** vertex_lat,
53 size_t * nbr_vertices,
int * old_to_new_id,
54 yac_int ** vertex_ids, MPI_Comm comm);
57 size_t nbr_cells,
size_t ** duplicated_cell_idx,
58 size_t ** orig_cell_idx,
size_t * nbr_duplicated_cells);
62 MPI_Comm comm,
size_t ** duplicated_cell_idx,
63 yac_int ** orig_cell_ids,
size_t * num_duplicated_cells_);
66 const void * a,
const void * b) {
67 return *(
int const *)a - *(
int const*)b;
71 const void * a,
const void * b) {
77 const void * a_,
const void * b_) {
86 int ret = (num_vertices_a > num_vertices_b) -
87 (num_vertices_a < num_vertices_b);
89 for (
size_t i = 0; (
i < num_vertices_a) && !ret; ++
i)
97 const void * a_,
const void * b_) {
111 const void * a_,
const void * b_) {
120 return (a->
id > b->
id) - (a->
id < b->
id);
124 const void * a_,
const void * b_) {
135 const void * a_,
const void * b_) {
144 const void * a_,
const void * b_) {
149 return (a->
i > b->
i) - (a->
i < b->
i);
153 const char * filename,
const char * grid_name,
155 size_t * num_vertices_,
size_t * num_cells_,
int ** num_vertices_per_cell_,
156 int ** cell_to_vertex_,
double ** x_vertices,
double ** y_vertices,
157 double ** x_cells,
double ** y_cells,
158 size_t ** duplicated_cell_idx_,
size_t ** orig_cell_idx_,
159 size_t * nbr_duplicated_cells_,
int with_vertices) {
161 size_t grid_name_len = strlen(grid_name) + 1;
162 char cla_var_name[4 + grid_name_len];
163 char clo_var_name[4 + grid_name_len];
164 char lat_var_name[4 + grid_name_len];
165 char lon_var_name[4 + grid_name_len];
167 snprintf(cla_var_name, 4 + grid_name_len,
"%s.cla", grid_name);
168 snprintf(clo_var_name, 4 + grid_name_len,
"%s.clo", grid_name);
169 snprintf(lat_var_name, 4 + grid_name_len,
"%s.lat", grid_name);
170 snprintf(lon_var_name, 4 + grid_name_len,
"%s.lon", grid_name);
188 int dim_ids[NC_MAX_VAR_DIMS];
192 nc_inq_var(ncid, cla_var_id, NULL, NULL, &ndims, dim_ids, NULL));
195 "ERROR(yac_read_scrip_basic_grid_information): "
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 "ERROR(yac_read_scrip_basic_grid_information): "
205 "invalid number of dimensions for variable \"%s\" (has to be 2 not %d)",
206 lat_var_name, ndims);
207 dim_ids[2] = dim_ids[1];
208 dim_ids[1] = dim_ids[0];
211 int crn_dim_id = dim_ids[0];
212 int x_dim_id = dim_ids[2];
213 int y_dim_id = dim_ids[1];
216 size_t crn_dim_len, x_dim_len, y_dim_len;
224 size_t num_cells = x_dim_len * y_dim_len;
225 size_t num_vertices =
num_cells * crn_dim_len;
229 "ERROR(yac_read_scrip_basic_grid_information): "
230 "cell mask size is inconsistent with number of grid cells")
232 if ((x_cells != NULL) && (y_cells != NULL)) {
242 double * cla =
xmalloc(num_vertices *
sizeof(*cla));
243 double * clo =
xmalloc(num_vertices *
sizeof(*clo));
254 (x_cells != NULL) && (y_cells != NULL),
255 "ERROR(yac_read_scrip_basic_grid_information): "
256 "no pointers for cell coordinates were provided")
258 memcpy(cla, *y_cells,
num_cells *
sizeof(*cla));
259 memcpy(clo, *x_cells,
num_cells *
sizeof(*clo));
264 size_t * reorder_idx =
xmalloc(num_vertices *
sizeof(*reorder_idx));
265 for (
size_t y = 0, l = 0; y < y_dim_len; ++y)
266 for (
size_t x = 0; x < x_dim_len; ++x)
267 for (
size_t n = 0; n < crn_dim_len; ++n, ++l)
268 reorder_idx[x + y * x_dim_len + n * x_dim_len * y_dim_len] = l;
280 int * num_vertices_per_cell =
282 size_t total_num_cell_vertices = 0;
285 if (crn_dim_len > 1) {
287 size_t curr_num_vertices = 0;
289 if (crn_dim_len > 1) {
290 int prev_vertex = from_vertices[crn_dim_len-1];
291 for (
size_t j = 0; j < crn_dim_len; ++j, ++from_vertices) {
292 int curr_vertex = *from_vertices;
293 if (prev_vertex != curr_vertex) {
294 prev_vertex = curr_vertex;
295 if (to_vertices != from_vertices) *to_vertices = curr_vertex;
302 from_vertices += crn_dim_len;
304 num_vertices_per_cell[
i] = (int)curr_num_vertices;
305 total_num_cell_vertices += curr_num_vertices;
310 if (to_vertices != from_vertices) *to_vertices = *from_vertices;
312 ++total_num_cell_vertices;
313 num_vertices_per_cell[
i] = 1;
315 num_vertices_per_cell[
i] = 0;
321 if (total_num_cell_vertices !=
num_cells * crn_dim_len)
328 int * cell_to_vertex_copy =
329 xmalloc(total_num_cell_vertices *
sizeof(*cell_to_vertex_copy));
332 total_num_cell_vertices *
sizeof(*cell_to_vertex_copy));
335 cell_to_vertex_copy + offset, (
size_t)(num_vertices_per_cell[
i]),
337 offset += num_vertices_per_cell[
i];
341 size_t * duplicated_cell_idx;
342 size_t * orig_cell_idx;
343 size_t nbr_duplicated_cells;
346 &duplicated_cell_idx, &orig_cell_idx, &nbr_duplicated_cells);
347 free(cell_to_vertex_copy);
350 for (
size_t i = 0;
i < nbr_duplicated_cells; ++
i)
353 if ((duplicated_cell_idx_ != NULL) && (orig_cell_idx_ != NULL) &&
354 (nbr_duplicated_cells_ != NULL)) {
355 *duplicated_cell_idx_ = duplicated_cell_idx;
356 *orig_cell_idx_ = orig_cell_idx;
357 *nbr_duplicated_cells_ = nbr_duplicated_cells;
359 free(duplicated_cell_idx);
365 *num_vertices_ = num_vertices;
366 *num_vertices_per_cell_ = num_vertices_per_cell;
373 free(num_vertices_per_cell);
383 const char * filename,
const char * grid_name,
385 size_t * num_vertices_,
size_t * num_cells_,
int ** num_vertices_per_cell_,
386 int ** cell_to_vertex_,
387 double ** x_vertices_,
double ** y_vertices_,
yac_int ** vertex_ids_,
388 double ** x_cells_,
double ** y_cells_,
yac_int ** cell_ids_,
389 size_t ** duplicated_cell_idx_,
yac_int ** orig_cell_ids_,
390 size_t * nbr_duplicated_cells_,
391 int io_rank_idx,
int num_io_ranks, MPI_Comm comm,
int with_vertices) {
394 size_t num_vertices = 0;
395 size_t * reorder_idx = NULL;
396 size_t max_num_vertices_per_cell = 0;
398 double * x_vertices = NULL;
399 double * y_vertices = NULL;
401 double * x_cells = NULL;
402 double * y_cells = NULL;
405 if ((io_rank_idx >= 0) && (io_rank_idx < num_io_ranks)) {
407 size_t grid_name_len = strlen(grid_name) + 1;
408 char cla_var_name[4 + grid_name_len];
409 char clo_var_name[4 + grid_name_len];
410 char lat_var_name[4 + grid_name_len];
411 char lon_var_name[4 + grid_name_len];
413 snprintf(cla_var_name, 4 + grid_name_len,
"%s.cla", grid_name);
414 snprintf(clo_var_name, 4 + grid_name_len,
"%s.clo", grid_name);
415 snprintf(lat_var_name, 4 + grid_name_len,
"%s.lat", grid_name);
416 snprintf(lon_var_name, 4 + grid_name_len,
"%s.lon", grid_name);
422 int cla_var_id, clo_var_id, lat_var_id, lon_var_id;
431 int dim_ids[NC_MAX_VAR_DIMS];
435 nc_inq_var(ncid, cla_var_id, NULL, NULL, &ndims, dim_ids, NULL));
438 "ERROR(yac_read_part_scrip_basic_grid_information): "
439 "invalid number of dimensions for variable \"%s\" (has to be 3 not %d)",
440 cla_var_name, ndims);
444 nc_inq_var(ncid, lat_var_id, NULL, NULL, &ndims, dim_ids, NULL));
447 "ERROR(yac_read_part_scrip_basic_grid_information): "
448 "invalid number of dimensions for variable \"%s\" (has to be 2 not %d)",
449 lat_var_name, ndims);
450 dim_ids[2] = dim_ids[1];
451 dim_ids[1] = dim_ids[0];
454 int crn_dim_id = dim_ids[0];
455 int x_dim_id = dim_ids[2];
456 int y_dim_id = dim_ids[1];
459 size_t crn_dim_len, x_dim_len, y_dim_len;
468 size_t x_start_local =
470 (((
unsigned long)x_dim_len * (
unsigned long)io_rank_idx) /
471 (
unsigned long)num_io_ranks);
472 size_t x_count_local =
474 (((
unsigned long)x_dim_len * (io_rank_idx + 1)) /
475 (
unsigned long)num_io_ranks) - x_start_local;
482 max_num_vertices_per_cell = crn_dim_len;
487 max_num_vertices_per_cell = 1;
492 "ERROR(yac_read_part_scrip_basic_grid_information): "
493 "cell mask size is inconsistent with number of grid cells")
495 if ((x_cells_ != NULL) && (y_cells_ != NULL)) {
498 size_t start[2] = {0, x_start_local};
499 size_t count[2] = {y_dim_len, x_count_local};
501 nc_get_vara_double(ncid, lon_var_id, start, count, x_cells));
503 nc_get_vara_double(ncid, lat_var_id, start, count, y_cells));
509 x_vertices =
xmalloc(num_vertices *
sizeof(*x_vertices));
510 y_vertices =
xmalloc(num_vertices *
sizeof(*y_vertices));
513 size_t start[3] = {0, 0, x_start_local};
514 size_t count[3] = {crn_dim_len, y_dim_len, x_count_local};
516 nc_get_vara_double(ncid, clo_var_id, start, count, x_vertices));
518 nc_get_vara_double(ncid, cla_var_id, start, count, y_vertices));
526 (x_cells_ != NULL) && (y_cells_ != NULL),
527 "ERROR(yac_read_part_scrip_basic_grid_information): "
528 "no pointers for cell coordinates were provided")
530 memcpy(x_vertices, x_cells,
num_cells *
sizeof(*x_vertices));
531 memcpy(y_vertices, y_cells,
num_cells *
sizeof(*y_vertices));
536 reorder_idx =
xmalloc(num_vertices *
sizeof(*reorder_idx));
537 for (
size_t y = 0, l = 0; y < y_dim_len; ++y)
538 for (
size_t x = 0; x < x_count_local; ++x)
539 for (
size_t n = 0; n < crn_dim_len; ++n, ++l)
541 x + y * x_count_local + n * x_count_local * y_dim_len] = l;
545 for (
size_t y = 0, k = 0; y < y_dim_len; ++y)
546 for (
size_t x = 0; x < x_count_local; ++x, ++k)
547 cell_ids[k] = y * x_dim_len + x + x_start_local;
551 (y_dim_len * x_dim_len * crn_dim_len) <= XT_INT_MAX,
552 "ERROR(yac_read_part_scrip_basic_grid_information): "
553 "number of vertices exceed maximum global id (%zu)",
558 for (
size_t n = 0, l = 0; n < crn_dim_len; ++n)
560 vertex_ids[l] = cell_ids[
i] * crn_dim_len + n;
566 &x_vertices, &y_vertices, &num_vertices,
575 int * num_vertices_per_cell =
577 size_t total_num_cell_vertices = 0;
580 if (max_num_vertices_per_cell > 1) {
582 size_t curr_num_vertices = 0;
584 if (max_num_vertices_per_cell > 1) {
585 int prev_vertex = from_vertices[max_num_vertices_per_cell-1];
586 for (
size_t j = 0; j < max_num_vertices_per_cell; ++j, ++from_vertices) {
587 int curr_vertex = *from_vertices;
588 if (prev_vertex != curr_vertex) {
589 prev_vertex = curr_vertex;
590 if (to_vertices != from_vertices) *to_vertices = curr_vertex;
597 from_vertices += max_num_vertices_per_cell;
599 num_vertices_per_cell[
i] = (int)curr_num_vertices;
600 total_num_cell_vertices += curr_num_vertices;
605 if (to_vertices != from_vertices) *to_vertices = *from_vertices;
607 ++total_num_cell_vertices;
608 num_vertices_per_cell[
i] = 1;
610 num_vertices_per_cell[
i] = 0;
616 if (total_num_cell_vertices !=
num_cells * max_num_vertices_per_cell)
622 size_t * duplicated_cell_idx;
624 size_t nbr_duplicated_cells;
627 vertex_ids, comm, &duplicated_cell_idx, &orig_cell_ids,
628 &nbr_duplicated_cells);
631 for (
size_t i = 0;
i < nbr_duplicated_cells; ++
i)
634 if ((duplicated_cell_idx_ != NULL) && (orig_cell_ids_ != NULL) &&
635 (nbr_duplicated_cells_ != NULL)) {
636 *duplicated_cell_idx_ = duplicated_cell_idx;
637 *orig_cell_ids_ = orig_cell_ids;
638 *nbr_duplicated_cells_ = nbr_duplicated_cells;
640 free(duplicated_cell_idx);
646 *num_vertices_ = num_vertices;
647 *num_vertices_per_cell_ = num_vertices_per_cell;
648 *x_vertices_ = x_vertices;
649 *y_vertices_ = y_vertices;
651 *vertex_ids_ = vertex_ids;
655 free(num_vertices_per_cell);
662 if ((x_cells_ != NULL) && (y_cells_ != NULL)) {
666 *cell_ids_ = cell_ids;
670 const char * filename,
const char * grid_name,
size_t * num_cells_,
673 size_t grid_name_len = strlen(grid_name) + 1;
674 char msk_var_name[4 + grid_name_len];
676 snprintf(msk_var_name, 4 + grid_name_len,
"%s.msk", grid_name);
687 int dim_ids[NC_MAX_VAR_DIMS];
689 nc_inq_var(ncid, msk_var_id, NULL, NULL, &ndims, dim_ids, NULL));
692 "ERROR(yac_read_scrip_mask_information): "
693 "invalid number of dimensions for variable \"%s\" (has to be 2 not %d)",
694 msk_var_name, ndims);
695 int x_dim_id = dim_ids[1];
696 int y_dim_id = dim_ids[0];
704 size_t num_cells = x_dim_len * y_dim_len;
718 const char * filename,
const char * grid_name,
size_t * num_cells_,
719 int **
cell_mask,
int io_rank_idx,
int num_io_ranks) {
721 if ((io_rank_idx >= 0) && (io_rank_idx < num_io_ranks)) {
723 size_t grid_name_len = strlen(grid_name) + 1;
724 char msk_var_name[4 + grid_name_len];
726 snprintf(msk_var_name, 4 + grid_name_len,
"%s.msk", grid_name);
737 int dim_ids[NC_MAX_VAR_DIMS];
739 nc_inq_var(ncid, msk_var_id, NULL, NULL, &ndims, dim_ids, NULL));
742 "ERROR(yac_read_part_scrip_mask_information): "
743 "invalid number of dimensions for variable \"%s\" (has to be 2 not %d)",
744 msk_var_name, ndims);
745 int x_dim_id = dim_ids[1];
746 int y_dim_id = dim_ids[0];
755 size_t x_start_local =
757 (((
unsigned long)x_dim_len * (
unsigned long)io_rank_idx) /
758 (
unsigned long)num_io_ranks);
759 size_t x_count_local =
761 (((
unsigned long)x_dim_len * (io_rank_idx+1)) /
762 (
unsigned long)num_io_ranks) - x_start_local;
764 size_t num_cells = x_count_local * y_dim_len;
770 size_t start[2] = {0, x_start_local};
771 size_t count[2] = {y_dim_len, x_count_local};
773 nc_get_vara_int(ncid, msk_var_id, start, count, *
cell_mask));
786 char const * grid_filename,
char const * mask_filename,
787 char const * grid_name,
int valid_mask_value,
788 size_t * num_vertices,
size_t *
num_cells,
int ** num_vertices_per_cell,
789 double ** x_vertices,
double ** y_vertices,
790 double ** x_cells,
double ** y_cells,
792 size_t ** orig_cell_idx,
size_t * nbr_duplicated_cells,
int with_vertices) {
794 size_t cell_mask_size;
797 mask_filename, grid_name, &cell_mask_size, &
cell_mask);
799 for (
size_t i = 0;
i < cell_mask_size; ++
i)
803 grid_filename, grid_name, cell_mask_size,
cell_mask,
805 x_vertices, y_vertices, x_cells, y_cells, duplicated_cell_idx,
806 orig_cell_idx, nbr_duplicated_cells, with_vertices);
809 for (
size_t i = 0;
i < *num_vertices; ++
i) {
814 if ((x_cells != NULL) && (y_cells != NULL)) {
822 !with_vertices || (*num_vertices <= INT_MAX),
823 "ERROR(yac_read_scrip_grid_information): "
824 "too man vertices in grid")
827 "ERROR(yac_read_scrip_grid_information): "
828 "too man cells in grid")
834 char const * grid_filename,
char const * mask_filename,
835 char const * grid_name,
int valid_mask_value,
836 size_t * num_vertices,
size_t *
num_cells,
int ** num_vertices_per_cell,
837 double ** x_vertices,
double ** y_vertices,
838 double ** x_cells,
double ** y_cells,
840 size_t ** orig_cell_idx,
size_t * nbr_duplicated_cells) {
843 grid_filename, mask_filename, grid_name, valid_mask_value,
844 num_vertices,
num_cells, num_vertices_per_cell, x_vertices, y_vertices,
846 duplicated_cell_idx, orig_cell_idx, nbr_duplicated_cells, 1);
850 MPI_Comm comm,
int * io_rank_idx,
int * num_io_ranks) {
852 int local_is_io, * io_ranks;
859 while ((*io_rank_idx < *num_io_ranks) &&
860 (comm_rank != io_ranks[*io_rank_idx]))
863 !local_is_io || (*io_rank_idx < *num_io_ranks),
864 "ERROR(get_io_configuration): unable to determine io_rank_idx");
871 char const * grid_filename,
char const * mask_filename,
872 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
873 size_t * num_vertices,
size_t *
num_cells,
int ** num_vertices_per_cell,
874 double ** x_vertices,
double ** y_vertices,
yac_int ** vertex_ids,
875 double ** x_cells,
double ** y_cells,
yac_int ** cell_ids,
877 yac_int ** orig_cell_ids,
size_t * nbr_duplicated_cells,
int with_vertices) {
880 if (comm == MPI_COMM_NULL) {
882 size_t * orig_cell_idx = NULL;
885 grid_filename, mask_filename, grid_name, valid_mask_value,
886 num_vertices,
num_cells, num_vertices_per_cell,
889 (orig_cell_ids != NULL)?&orig_cell_idx:NULL,
890 nbr_duplicated_cells, with_vertices);
893 *vertex_ids =
xmalloc(*num_vertices *
sizeof(**vertex_ids));
894 for (
size_t i = 0;
i < *num_vertices; ++
i) (*vertex_ids)[
i] =
i;
900 if (orig_cell_ids != NULL) {
902 xmalloc(*nbr_duplicated_cells *
sizeof(**orig_cell_ids));
903 for (
size_t i = 0;
i < *nbr_duplicated_cells; ++
i)
904 (*orig_cell_ids)[
i] = (*cell_ids)[orig_cell_idx[
i]];
910 int io_rank_idx, num_io_ranks;
914 size_t cell_mask_size;
916 mask_filename, grid_name, &cell_mask_size, &
cell_mask,
917 io_rank_idx, num_io_ranks);
919 for (
size_t i = 0;
i < cell_mask_size; ++
i)
923 grid_filename, grid_name, cell_mask_size,
cell_mask,
925 x_vertices, y_vertices, vertex_ids,
926 x_cells, y_cells, cell_ids, duplicated_cell_idx,
927 orig_cell_ids, nbr_duplicated_cells,
928 io_rank_idx, num_io_ranks, comm, with_vertices);
931 for (
size_t i = 0;
i < *num_vertices; ++
i) {
936 if ((x_cells != NULL) && (y_cells != NULL)) {
944 !with_vertices || (*num_vertices <= INT_MAX),
945 "ERROR(yac_read_part_scrip_grid_information): "
946 "too man vertices in grid")
949 "ERROR(yac_read_part_scrip_grid_information): "
950 "too man cells in grid")
953 "ERROR(yac_read_part_scrip_grid_information): "
954 "mask and grid size do not match "
955 "(mask_file: \"%s\" grid_file: \"%s\" grid_name: \"%s\"",
956 mask_filename, grid_filename, grid_name)
963 char const * grid_filename,
char const * mask_filename,
964 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
int use_ll,
965 double ** x_cells,
double ** y_cells,
size_t ** duplicated_cell_idx,
966 yac_int ** orig_cell_global_ids,
size_t * nbr_duplicated_cells) {
980 grid_filename, mask_filename, comm, grid_name, valid_mask_value,
984 orig_cell_global_ids, nbr_duplicated_cells, 1);
989 for (
size_t i = 0; (i <
num_cells) && use_ll; ++i)
992 if (comm != MPI_COMM_NULL) {
995 MPI_IN_PLACE, &use_ll, 1, MPI_INT, MPI_MIN, comm), comm);
998 if (!use_ll && (comm_rank == 0))
1000 stderr,
"WARNING(yac_read_scrip_basic_grid_data_): "
1001 "grid \"%s\" from \"%s\": required LL but stored as GC "
1002 "(>4 vertices per cell)\n",
1003 grid_name, grid_filename);
1007 (*generate_basic_grid_data_unstruct_ptr)(
1008 size_t,
size_t,
int *,
double *,
double *,
int *) =
1014 generate_basic_grid_data_unstruct_ptr(
1035 char const * grid_filename,
char const * mask_filename,
1036 char const * grid_name,
int valid_mask_value,
int use_ll_edges) {
1040 grid_filename, mask_filename, MPI_COMM_NULL,
1041 grid_name, valid_mask_value, use_ll_edges,
1042 NULL, NULL, NULL, NULL, NULL);
1046 char const * grid_filename,
char const * mask_filename,
1047 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
1048 char const *
name,
int use_ll_edges,
size_t * cell_coord_idx,
1049 size_t ** duplicated_cell_idx,
yac_int ** orig_cell_global_ids,
1050 size_t * nbr_duplicated_cells) {
1053 double * x_cells, * y_cells;
1058 grid_filename, mask_filename, comm, grid_name, valid_mask_value,
1059 use_ll_edges, (cell_coord_idx != NULL)?&x_cells:NULL,
1060 (cell_coord_idx != NULL)?&y_cells:NULL, duplicated_cell_idx,
1061 orig_cell_global_ids, nbr_duplicated_cells));
1063 if (cell_coord_idx != NULL) {
1085 char const * grid_filename,
char const * mask_filename,
1086 MPI_Fint comm,
char const * grid_name,
int valid_mask_value,
1087 char const *
name,
int use_ll_edges,
size_t * cell_coord_idx,
1088 size_t ** duplicated_cell_idx,
yac_int ** orig_cell_global_ids,
1089 size_t * nbr_duplicated_cells) {
1093 grid_filename, mask_filename, MPI_Comm_f2c(comm), grid_name,
1094 valid_mask_value,
name, use_ll_edges, cell_coord_idx,
1095 duplicated_cell_idx, orig_cell_global_ids, nbr_duplicated_cells);
1099 char const * grid_filename,
char const * mask_filename,
1100 char const * grid_name,
int valid_mask_value,
char const *
name,
1101 int use_ll_edges,
size_t * cell_coord_idx,
1102 size_t ** duplicated_cell_idx,
yac_int ** orig_cell_global_ids,
1103 size_t * nbr_duplicated_cells) {
1107 grid_filename, mask_filename, MPI_COMM_NULL, grid_name, valid_mask_value,
1108 name, use_ll_edges, cell_coord_idx, duplicated_cell_idx,
1109 orig_cell_global_ids, nbr_duplicated_cells);
1113 char const * grid_filename,
char const * mask_filename, MPI_Comm comm,
1114 char const * grid_name,
int valid_mask_value,
size_t ** duplicated_vertex_idx,
1115 yac_int ** orig_vertex_global_ids,
size_t * nbr_duplicated_vertices) {
1117 size_t file_num_cells;
1119 double * file_x_cells;
1120 double * file_y_cells;
1122 int * file_cell_core_mask;
1125 grid_filename, mask_filename, comm, grid_name, valid_mask_value,
1126 NULL, &file_num_cells, NULL, NULL, NULL, NULL,
1127 &file_x_cells, &file_y_cells, &file_cell_ids,
1128 NULL, &file_cell_core_mask, duplicated_vertex_idx,
1129 orig_vertex_global_ids, nbr_duplicated_vertices, 0);
1133 file_num_cells, file_x_cells, file_y_cells);
1139 grid_data.core_vertex_mask = file_cell_core_mask;
1148 char const * grid_filename,
char const * mask_filename,
1149 char const * grid_name,
int valid_mask_value) {
1153 grid_filename, mask_filename, MPI_COMM_NULL,
1154 grid_name, valid_mask_value, NULL, NULL, NULL);
1158 char const * grid_filename,
char const * mask_filename,
1159 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
1160 char const *
name,
size_t * vertex_coord_idx,
1161 size_t ** duplicated_vertex_idx,
yac_int ** orig_vertex_global_ids,
1162 size_t * nbr_duplicated_vertices) {
1167 grid_filename, mask_filename, comm, grid_name, valid_mask_value,
1168 duplicated_vertex_idx, orig_vertex_global_ids, nbr_duplicated_vertices);
1172 if (vertex_coord_idx != NULL) {
1176 xmalloc(num_vertices *
sizeof(*vertex_coords));
1179 num_vertices *
sizeof(*vertex_coords));
1189 char const * grid_filename,
char const * mask_filename,
1190 MPI_Fint comm,
char const * grid_name,
int valid_mask_value,
1191 char const *
name,
size_t * vertex_coord_idx,
1192 size_t ** duplicated_vertex_idx,
yac_int ** orig_vertex_global_ids,
1193 size_t * nbr_duplicated_vertices) {
1197 grid_filename, mask_filename, MPI_Comm_f2c(comm), grid_name,
1198 valid_mask_value,
name, vertex_coord_idx, duplicated_vertex_idx,
1199 orig_vertex_global_ids, nbr_duplicated_vertices);
1203 char const * grid_filename,
char const * mask_filename,
1204 char const * grid_name,
int valid_mask_value,
char const *
name,
1205 size_t * vertex_coord_idx,
size_t ** duplicated_vertex_idx,
1206 yac_int ** orig_vertex_global_ids,
size_t * nbr_duplicated_vertices) {
1210 grid_filename, mask_filename, MPI_COMM_NULL, grid_name, valid_mask_value,
1211 name, vertex_coord_idx, duplicated_vertex_idx, orig_vertex_global_ids,
1212 nbr_duplicated_vertices);
1216 char const * grid_filename, MPI_Comm comm,
char const * grid_name) {
1218 int local_is_io, * io_ranks, num_io_ranks;
1220 int root_rank = io_ranks[0];
1225 int contains_corner_information = 0;
1227 if (local_is_io && (comm_rank == root_rank)) {
1229 size_t grid_name_len = strlen(grid_name) + 1;
1230 char cla_var_name[4 + grid_name_len];
1231 char clo_var_name[4 + grid_name_len];
1233 snprintf(cla_var_name, 4 + grid_name_len,
"%s.cla", grid_name);
1234 snprintf(clo_var_name, 4 + grid_name_len,
"%s.clo", grid_name);
1240 int cla_var_id, clo_var_id;
1242 contains_corner_information =
1243 (NC_NOERR == nc_inq_varid(ncid, cla_var_name, &cla_var_id)) &&
1244 (NC_NOERR == nc_inq_varid(ncid, clo_var_name, &clo_var_id));
1251 &contains_corner_information, 1, MPI_INT, root_rank, comm), comm);
1253 return contains_corner_information;
1257 char const * grid_filename,
char const * mask_filename,
1258 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
1259 char const *
name,
int use_ll_edges,
size_t * point_coord_idx,
1260 size_t ** duplicated_point_idx,
yac_int ** orig_point_global_ids,
1261 size_t * nbr_duplicated_points,
int * point_location) {
1263 int contains_corner_information =
1266 if (contains_corner_information) {
1270 grid_filename, mask_filename, comm, grid_name,
1271 valid_mask_value,
name, use_ll_edges, point_coord_idx,
1272 duplicated_point_idx, orig_point_global_ids, nbr_duplicated_points);
1277 grid_filename, mask_filename, comm, grid_name,
1278 valid_mask_value,
name, point_coord_idx, duplicated_point_idx,
1279 orig_point_global_ids, nbr_duplicated_points);
1284 char const * grid_filename,
char const * mask_filename,
1285 MPI_Fint comm,
char const * grid_name,
int valid_mask_value,
1286 char const *
name,
int use_ll_edges,
size_t * point_coord_idx,
1287 size_t ** duplicated_point_idx,
yac_int ** orig_point_global_ids,
1288 size_t * nbr_duplicated_points,
int * point_location) {
1292 grid_filename, mask_filename, MPI_Comm_f2c(comm), grid_name,
1293 valid_mask_value,
name, use_ll_edges, point_coord_idx,
1294 duplicated_point_idx, orig_point_global_ids, nbr_duplicated_points,
1301 const void * a,
const void * b) {
1305 if (ret)
return ret;
1307 for (
int i = 0; (
i < count) && !ret; ++
i)
1314 double ** vertex_lon,
double ** vertex_lat,
yac_int ** vertex_ids,
1315 size_t * nbr_vertices,
int * old_to_new_id) {
1318 xmalloc(*nbr_vertices *
sizeof(*sort_array));
1320 double const scale = (double)(2 << 20);
1321 int32_t
const periode = (int32_t)(360.0 * scale);
1323 for (
size_t i = 0;
i < *nbr_vertices; ++
i) {
1325 int32_t curr_lon = (int32_t)round((*vertex_lon)[
i] * scale);
1326 int32_t curr_lat = (int32_t)round((*vertex_lat)[
i] * scale);
1328 if ((curr_lat == (int32_t)(90.0 * scale)) ||
1329 (curr_lat == (int32_t)(-90.0 * scale))) {
1335 curr_lon = curr_lon - (((curr_lon - periode) / periode) * periode);
1336 else if (curr_lon > periode)
1337 curr_lon = curr_lon - ((curr_lon / periode) * periode);
1340 sort_array[
i].
lon = curr_lon;
1341 sort_array[
i].
lat = curr_lat;
1342 sort_array[
i].
dlon = (*vertex_lon)[
i];
1343 sort_array[
i].
dlat = (*vertex_lat)[
i];
1344 sort_array[
i].
id = (vertex_ids != NULL)?(*vertex_ids)[
i]:XT_INT_MAX;
1346 sort_array[
i].
i =
i;
1349 yac_mergesort(sort_array, *nbr_vertices,
sizeof(*sort_array),
1353 {.
lon = INT32_MAX, .lat = INT32_MAX, .i = SIZE_MAX};
1355 size_t new_nbr_vertices = 0;
1356 for (
size_t i = 0;
i < *nbr_vertices; ++
i, ++curr) {
1360 (*vertex_lon)[new_nbr_vertices] = curr->
dlon;
1361 (*vertex_lat)[new_nbr_vertices] = curr->dlat;
1362 if (vertex_ids != NULL)
1363 (*vertex_ids)[new_nbr_vertices] = curr->id;
1364 sort_array[new_nbr_vertices] = *curr;
1368 old_to_new_id[curr->i] = (int)(new_nbr_vertices - 1);
1371 (*vertex_lon) =
xrealloc(*vertex_lon, new_nbr_vertices *
sizeof(**vertex_lon));
1372 (*vertex_lat) =
xrealloc(*vertex_lat, new_nbr_vertices *
sizeof(**vertex_lat));
1373 if (vertex_ids != NULL)
1374 (*vertex_ids) =
xrealloc(*vertex_ids, new_nbr_vertices *
sizeof(**vertex_ids));
1375 *nbr_vertices = new_nbr_vertices;
1381 double ** vertex_lon,
double ** vertex_lat,
1382 size_t * nbr_vertices,
int * old_to_new_id) {
1386 vertex_lon, vertex_lat, NULL, nbr_vertices, old_to_new_id));
1390unsigned long djb2_hash(
unsigned char * values,
size_t count) {
1392 unsigned long hash = 5381;
1394 for (
size_t i = 0;
i < count; ++
i) {
1395 unsigned int value = values[
i];
1396 hash = ((hash << 5) + hash) +
value;
1403 void *
data,
size_t data_size,
int comm_size) {
1406 djb2_hash((
unsigned char*)
data, data_size) % (
unsigned long)comm_size;
1412 MPI_Datatype point_with_index_dt;
1413 int array_of_blocklengths[] = {1, 1, 1, 1, 1};
1414 const MPI_Aint array_of_displacements[] =
1415 {(MPI_Aint)(intptr_t)(
const void *)&(dummy.
lon) -
1416 (MPI_Aint)(intptr_t)(
const void *)&dummy,
1417 (MPI_Aint)(intptr_t)(
const void *)&(dummy.
lat) -
1418 (MPI_Aint)(intptr_t)(
const void *)&dummy,
1419 (MPI_Aint)(intptr_t)(
const void *)&(dummy.
id) -
1420 (MPI_Aint)(intptr_t)(
const void *)&dummy,
1421 (MPI_Aint)(intptr_t)(
const void *)&(dummy.
dlon) -
1422 (MPI_Aint)(intptr_t)(
const void *)&dummy,
1423 (MPI_Aint)(intptr_t)(
const void *)&(dummy.
dlat) -
1424 (MPI_Aint)(intptr_t)(
const void *)&dummy};
1425 const MPI_Datatype array_of_types[] =
1426 {MPI_INT32_T, MPI_INT32_T,
yac_int_dt, MPI_DOUBLE, MPI_DOUBLE};
1428 MPI_Type_create_struct(5, array_of_blocklengths, array_of_displacements,
1429 array_of_types, &point_with_index_dt), comm);
1434 double ** vertex_lon,
double ** vertex_lat,
1435 size_t * nbr_vertices_,
int * old_to_new_id,
yac_int ** vertex_ids,
1438 char const * routine =
"remove_duplicated_vertices_parallel";
1443 vertex_lon, vertex_lat, vertex_ids, nbr_vertices_, old_to_new_id);
1445 sort_array =
xrealloc(sort_array, *nbr_vertices_ *
sizeof(*sort_array));
1447 size_t nbr_vertices = *nbr_vertices_;
1449 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
1451 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
1453 int comm_rank, comm_size;
1458 for (
size_t i = 0;
i < nbr_vertices; ++
i) {
1461 &(sort_array[
i].
lon), 2 *
sizeof(sort_array[
i].
lon), comm_size);
1464 sort_array[
i].
i =
i;
1468 yac_mergesort(sort_array, nbr_vertices,
sizeof(*sort_array),
1472 1, sendcounts, recvcounts, sdispls, rdispls, comm);
1474 size_t recv_count = recvcounts[comm_size - 1] + rdispls[comm_size - 1];
1476 xmalloc(recv_count *
sizeof(*dist_sort_array));
1479 MPI_Datatype point_with_index_dt =
1481 yac_mpi_call(MPI_Type_commit(&point_with_index_dt), comm);
1483 sort_array, sendcounts, sdispls+1,
1484 dist_sort_array, recvcounts, rdispls,
1485 sizeof(*sort_array), point_with_index_dt, comm, routine, __LINE__);
1487 for (
size_t i = 0;
i < recv_count; ++
i) dist_sort_array[
i].
i =
i;
1490 yac_mergesort(dist_sort_array, recv_count,
sizeof(*dist_sort_array),
1494 {.
lon = INT32_MAX, .lat = INT32_MAX};
1496 for (
size_t i = 0;
i < recv_count; ++
i, ++curr) {
1503 curr->
id = prev->
id;
1504 curr->dlon = prev->
dlon;
1505 curr->dlat = prev->
dlat;
1510 yac_mergesort(dist_sort_array, recv_count,
sizeof(*dist_sort_array),
1515 dist_sort_array, recvcounts, rdispls,
1516 sort_array, sendcounts, sdispls+1,
1517 sizeof(*sort_array), point_with_index_dt, comm, routine, __LINE__);
1518 free(dist_sort_array);
1520 yac_mpi_call(MPI_Type_free(&point_with_index_dt), comm);
1523 for (
size_t i = 0;
i < nbr_vertices; ++
i) {
1525 (*vertex_lon)[sort_array[
i].
i] = sort_array[
i].dlon;
1526 (*vertex_lat)[sort_array[
i].i] = sort_array[
i].dlat;
1527 (*vertex_ids)[sort_array[
i].i] = sort_array[
i].id;
1535 size_t nbr_cells,
size_t ** duplicated_cell_idx,
1536 size_t ** orig_cell_idx,
size_t * nbr_duplicated_cells) {
1539 size_t nbr_unmasked_cells = 0;
1540 for (
size_t i = 0;
i < nbr_cells; ++
i)
1544 xmalloc(nbr_unmasked_cells *
sizeof(*sort_array));
1547 for (
size_t i = 0, offset = 0, j = 0;
i < nbr_cells; ++
i) {
1553 sort_array[j].
i =
i;
1557 offset += (size_t)(num_vertices_per_cell[
i]);
1561 yac_mergesort(sort_array, nbr_unmasked_cells,
sizeof(*sort_array),
1565 *nbr_duplicated_cells = 0;
1566 for (
size_t i = 1;
i < nbr_unmasked_cells; ++
i)
1568 ++*nbr_duplicated_cells;
1571 *duplicated_cell_idx =
1572 xmalloc(*nbr_duplicated_cells *
sizeof(**duplicated_cell_idx));
1574 xmalloc(*nbr_duplicated_cells *
sizeof(**orig_cell_idx));
1576 for (
size_t i = 1, j = 0;
i < nbr_unmasked_cells; ++
i, ++curr) {
1580 (*duplicated_cell_idx)[j] = (size_t)(curr->i);
1581 (*orig_cell_idx)[j] = (size_t)(prev->
i);
1590 MPI_Comm comm,
size_t count) {
1592 MPI_Datatype cell_to_vertex_ids_dt;
1594 MPI_Type_contiguous(
1595 (
int)count,
yac_int_dt, &cell_to_vertex_ids_dt), comm);
1596 return cell_to_vertex_ids_dt;
1602 MPI_Comm comm,
size_t ** duplicated_cell_idx_,
1603 yac_int ** orig_cell_ids_,
size_t * num_duplicated_cells_) {
1605 char const * routine =
"detect_duplicated_cells_parallel";
1612 size_t max_num_vertices_per_cell = 0;
1613 size_t local_num_cells = 0;
1616 if ((
size_t)(num_vertices_per_cell[
i]) > max_num_vertices_per_cell)
1617 max_num_vertices_per_cell = (size_t)(num_vertices_per_cell[
i]);
1625 MPI_IN_PLACE, &max_num_vertices_per_cell, 1,
YAC_MPI_SIZE_T, MPI_MAX,
1630 xmalloc(local_num_cells * (1 + max_num_vertices_per_cell) *
1631 sizeof(*local_cell_ids));
1632 yac_int * local_cell_to_vertex_ids = local_cell_ids + local_num_cells;
1635 yac_int * curr_local_cell_ids = local_cell_ids;
1636 yac_int * curr_local_cell_to_vertex_ids = local_cell_to_vertex_ids;
1640 size_t curr_num_vertices_per_cell = (size_t)(num_vertices_per_cell[
i]);
1643 *curr_local_cell_ids = cell_ids[
i];
1647 for (; j < curr_num_vertices_per_cell; ++j)
1648 curr_local_cell_to_vertex_ids[j] =
1649 vertex_ids[curr_cell_to_vertex[j]];
1652 qsort(curr_local_cell_to_vertex_ids, curr_num_vertices_per_cell,
1656 for (; j < max_num_vertices_per_cell; ++j)
1657 curr_local_cell_to_vertex_ids[j] = XT_INT_MAX;
1659 curr_local_cell_ids++;
1660 curr_local_cell_to_vertex_ids += max_num_vertices_per_cell;
1662 curr_cell_to_vertex += curr_num_vertices_per_cell;
1665 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
1667 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
1670 int * dist_cell_ranks =
xmalloc(local_num_cells *
sizeof(*dist_cell_ranks));
1671 for (
size_t i = 0;
i < local_num_cells; ++
i) {
1674 local_cell_to_vertex_ids +
i * max_num_vertices_per_cell,
1675 max_num_vertices_per_cell *
sizeof(*local_cell_to_vertex_ids),
1678 dist_cell_ranks[
i] = rank;
1682 1, sendcounts, recvcounts, sdispls, rdispls, comm);
1684 size_t dist_num_cells = recvcounts[comm_size-1] + rdispls[comm_size-1];
1686 xmalloc((local_num_cells + dist_num_cells) *
1687 (1 + max_num_vertices_per_cell) *
sizeof(*yac_int_buffer));
1688 yac_int * dist_cell_ids = yac_int_buffer;
1689 yac_int * dist_cell_vertex_ids = yac_int_buffer + dist_num_cells;
1690 yac_int * send_local_cell_ids =
1691 yac_int_buffer + dist_num_cells * (1 + max_num_vertices_per_cell);
1692 yac_int * send_local_cell_to_vertex_ids =
1693 yac_int_buffer + local_num_cells +
1694 dist_num_cells * (1 + max_num_vertices_per_cell);
1697 for (
size_t i = 0;
i < local_num_cells; ++
i) {
1698 size_t pos = sdispls[dist_cell_ranks[
i] + 1]++;
1699 send_local_cell_ids[pos] = local_cell_ids[
i];
1701 send_local_cell_to_vertex_ids + pos * max_num_vertices_per_cell,
1702 local_cell_to_vertex_ids +
i * max_num_vertices_per_cell,
1703 max_num_vertices_per_cell *
sizeof(*send_local_cell_to_vertex_ids));
1706 xrealloc(local_cell_ids, local_num_cells *
sizeof(*local_cell_ids));
1709 MPI_Datatype cell_to_vertex_ids_dt =
1711 yac_mpi_call(MPI_Type_commit(&cell_to_vertex_ids_dt), comm);
1712 yac_alltoallv_yac_int_p2p(
1713 send_local_cell_ids, sendcounts, sdispls,
1714 dist_cell_ids, recvcounts, rdispls, comm, routine, __LINE__);
1716 send_local_cell_to_vertex_ids, sendcounts, sdispls,
1717 dist_cell_vertex_ids, recvcounts, rdispls,
1718 max_num_vertices_per_cell *
sizeof(*dist_cell_vertex_ids),
1719 cell_to_vertex_ids_dt, comm, routine, __LINE__);
1720 yac_mpi_call(MPI_Type_free(&cell_to_vertex_ids_dt), comm);
1726 dist_num_cells * (1 + max_num_vertices_per_cell) *
1727 sizeof(*yac_int_buffer));
1728 dist_cell_ids = yac_int_buffer;
1729 dist_cell_vertex_ids = yac_int_buffer + dist_num_cells;
1733 xmalloc(dist_num_cells *
sizeof(*sort_array));
1734 for (
size_t i = 0;
i < dist_num_cells; ++
i) {
1735 sort_array[
i].
cell_id = dist_cell_ids[
i];
1737 dist_cell_vertex_ids +
i * max_num_vertices_per_cell;
1739 sort_array[
i].
i =
i;
1744 sort_array, dist_num_cells,
sizeof(*sort_array),
1750 for (
size_t i = 1;
i < dist_num_cells; ++
i, ++curr) {
1763 (local_num_cells + dist_num_cells) *
sizeof(*yac_int_buffer));
1764 yac_int * recv_local_cell_ids = yac_int_buffer;
1765 dist_cell_ids = yac_int_buffer + local_num_cells;
1766 for (
size_t i = 0;
i < dist_num_cells; ++
i)
1767 dist_cell_ids[sort_array[
i].
i] = sort_array[
i].
cell_id;
1771 yac_alltoallv_yac_int_p2p(
1772 dist_cell_ids, recvcounts, rdispls,
1773 recv_local_cell_ids, sendcounts, sdispls, comm, routine, __LINE__);
1778 size_t num_duplicated_cells = 0;
1779 for (
size_t i = 0;
i < local_num_cells; ++
i) {
1781 size_t pos = sdispls[dist_cell_ranks[
i]]++;
1783 if (local_cell_ids[
i] != recv_local_cell_ids[pos]) {
1784 num_duplicated_cells++;
1785 local_cell_ids[
i] = recv_local_cell_ids[pos];
1787 local_cell_ids[
i] = XT_INT_MAX;
1790 free(yac_int_buffer);
1791 free(dist_cell_ranks);
1793 size_t * duplicated_cell_idx =
1794 xmalloc(num_duplicated_cells *
sizeof(*duplicated_cell_idx));
1796 xmalloc(num_duplicated_cells *
sizeof(*orig_cell_ids));
1803 if (local_cell_ids[j] != XT_INT_MAX) {
1804 duplicated_cell_idx[k] =
i;
1805 orig_cell_ids[k] = local_cell_ids[j];
1811 free(local_cell_ids);
1813 *duplicated_cell_idx_ = duplicated_cell_idx;
1814 *orig_cell_ids_ = orig_cell_ids;
1815 *num_duplicated_cells_ = num_duplicated_cells;
1821 char
const * grid_filename,
char const * mask_filename,
1822 char const * grid_name,
int valid_mask_value,
int use_ll_edges) {
1827 UNUSED(valid_mask_value);
1830 "ERROR(yac_read_scrip_basic_grid_data): "
1831 "YAC is built without the NetCDF support");
1835 (
size_t[]){0,0}, (
int[]){0,0}, NULL, NULL);
1839 char const * grid_filename,
char const * mask_filename,
1840 char const * grid_name,
int valid_mask_value,
char const *
name,
1841 int use_ll_edges,
size_t * cell_coord_idx,
1842 size_t ** duplicated_cell_idx,
yac_int ** orig_cell_global_ids,
1843 size_t * nbr_duplicated_cells) {
1848 UNUSED(valid_mask_value);
1852 UNUSED(duplicated_cell_idx);
1853 UNUSED(orig_cell_global_ids);
1854 UNUSED(nbr_duplicated_cells);
1856 "ERROR(yac_read_scrip_basic_grid): "
1857 "YAC is built without the NetCDF support");
1863 char const * grid_filename,
char const * mask_filename,
1864 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
1865 char const *
name,
int use_ll_edges,
size_t * cell_coord_idx,
1866 size_t ** duplicated_cell_idx,
yac_int ** orig_cell_global_ids,
1867 size_t * nbr_duplicated_cells) {
1873 UNUSED(valid_mask_value);
1877 UNUSED(duplicated_cell_idx);
1878 UNUSED(orig_cell_global_ids);
1879 UNUSED(nbr_duplicated_cells);
1881 "ERROR(yac_read_scrip_basic_grid_parallel): "
1882 "YAC is built without the NetCDF support");
1888 char
const * grid_filename,
char const * mask_filename,
1889 char const * grid_name,
int valid_mask_value) {
1894 UNUSED(valid_mask_value);
1896 "ERROR(yac_read_scrip_cloud_basic_grid_data): "
1897 "YAC is built without the NetCDF support");
1901 (
size_t[]){0,0}, (
int[]){0,0}, NULL, NULL);
1905 char const * grid_filename,
char const * mask_filename,
1906 char const * grid_name,
int valid_mask_value,
char const *
name,
1907 size_t * vertex_coord_idx,
size_t ** duplicated_vertex_idx,
1908 yac_int ** orig_vertex_global_ids,
size_t * nbr_duplicated_vertices) {
1913 UNUSED(valid_mask_value);
1915 UNUSED(vertex_coord_idx);
1916 UNUSED(duplicated_vertex_idx);
1917 UNUSED(orig_vertex_global_ids);
1918 UNUSED(nbr_duplicated_vertices);
1920 "ERROR(yac_read_scrip_cloud_basic_grid): "
1921 "YAC is built without the NetCDF support");
1927 char const * grid_filename,
char const * mask_filename,
1928 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
1929 char const *
name,
size_t * vertex_coord_idx,
1930 size_t ** duplicated_vertex_idx,
yac_int ** orig_vertex_global_ids,
1931 size_t * nbr_duplicated_vertices) {
1937 UNUSED(valid_mask_value);
1939 UNUSED(vertex_coord_idx);
1940 UNUSED(duplicated_vertex_idx);
1941 UNUSED(orig_vertex_global_ids);
1942 UNUSED(nbr_duplicated_vertices);
1944 "ERROR(yac_read_scrip_cloud_basic_grid_parallel): "
1945 "YAC is built without the NetCDF support");
1951 char const * grid_filename,
char const * mask_filename,
1952 MPI_Comm comm,
char const * grid_name,
int valid_mask_value,
1953 char const *
name,
int use_ll_edges,
size_t * point_coord_idx,
1954 size_t ** duplicated_point_idx,
yac_int ** orig_point_global_ids,
1955 size_t * nbr_duplicated_points,
int * point_location) {
1961 UNUSED(valid_mask_value);
1965 UNUSED(duplicated_point_idx);
1966 UNUSED(orig_point_global_ids);
1967 UNUSED(nbr_duplicated_points);
1970 "ERROR(yac_read_scrip_generic_basic_grid_parallel): "
1971 "YAC is built without the NetCDF support");
1977 char const * grid_filename,
char const * mask_filename,
1978 char const * grid_name,
int valid_mask_value,
1979 size_t * num_vertices,
size_t *
num_cells,
int ** num_vertices_per_cell,
1980 double ** x_vertices,
double ** y_vertices,
1981 double ** x_cells,
double ** y_cells,
1983 size_t ** orig_cell_idx,
size_t * nbr_duplicated_cells) {
1988 UNUSED(valid_mask_value);
1991 UNUSED(num_vertices_per_cell);
1998 UNUSED(duplicated_cell_idx);
2000 UNUSED(nbr_duplicated_cells);
2002 "ERROR(yac_read_scrip_grid_information): "
2003 "YAC is built without the NetCDF support");
2007 char const * grid_filename,
char const * mask_filename,
2008 MPI_Fint comm,
char const * grid_name,
int valid_mask_value,
2009 char const *
name,
int use_ll_edges,
size_t * cell_coord_idx,
2010 size_t ** duplicated_cell_idx,
yac_int ** orig_cell_global_ids,
2011 size_t * nbr_duplicated_cells) {
2017 UNUSED(valid_mask_value);
2021 UNUSED(duplicated_cell_idx);
2022 UNUSED(orig_cell_global_ids);
2023 UNUSED(nbr_duplicated_cells);
2025 "ERROR(yac_read_scrip_basic_grid_parallel_f2c): "
2026 "YAC is built without the NetCDF support");
2031 char const * grid_filename,
char const * mask_filename,
2032 MPI_Fint comm,
char const * grid_name,
int valid_mask_value,
2033 char const *
name,
size_t * vertex_coord_idx,
2034 size_t ** duplicated_vertex_idx,
yac_int ** orig_vertex_global_ids,
2035 size_t * nbr_duplicated_vertices) {
2041 UNUSED(valid_mask_value);
2043 UNUSED(vertex_coord_idx);
2044 UNUSED(duplicated_vertex_idx);
2045 UNUSED(orig_vertex_global_ids);
2046 UNUSED(nbr_duplicated_vertices);
2048 "ERROR(yac_read_scrip_cloud_basic_grid_parallel_f2c): "
2049 "YAC is built without the NetCDF support");
2054 char const * grid_filename,
char const * mask_filename,
2055 MPI_Fint comm,
char const * grid_name,
int valid_mask_value,
2056 char const *
name,
int use_ll_edges,
size_t * point_coord_idx,
2057 size_t ** duplicated_point_idx,
yac_int ** orig_point_global_ids,
2058 size_t * nbr_duplicated_points,
int * point_location) {
2064 UNUSED(valid_mask_value);
2068 UNUSED(duplicated_point_idx);
2069 UNUSED(orig_point_global_ids);
2070 UNUSED(nbr_duplicated_points);
2073 "ERROR(yac_read_scrip_generic_basic_grid_parallel_f2c): "
2074 "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]