26static int utest_check_global_ids(
27 yac_int * global_ids,
int count,
int ref_global_count, MPI_Comm comm);
28static int utest_compare_global_ids(
31int main(
int argc,
char** argv) {
35 xt_initialize(MPI_COMM_WORLD);
37 int comm_rank, comm_size;
38 MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
39 MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
46 PUT_ERR(
"ERROR: missing grid file directory");
53 char * grid_filenames[] =
54 {
"icon_grid_0030_R02B03_G.nc",
"icon_grid_0043_R02B04_G.nc"};
55 for (
int i = 0;
i < 2; ++
i)
59 malloc(strlen(argv[1]) + strlen(grid_filenames[i]) + 2), argv[1]),
63 char const *
grid_names[2] = {
"R02B02",
"R02B03"};
65 for (
int i = 0;
i < 2; ++
i)
68 filenames[i], MPI_COMM_WORLD);
79 size_t num_src_fields =
sizeof(src_fields) /
sizeof(src_fields[0]);
81 {.location =
YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
89 PUT_ERR(
"error in yac_interp_grid_get_src_grid_name");
93 PUT_ERR(
"error in yac_interp_grid_get_tgt_grid_name");
96 PUT_ERR(
"error in yac_interp_grid_get_num_src_fields");
100 PUT_ERR(
"error in yac_interp_grid_get_src_field_location");
105 for (
int i = 0;
i < 2; ++
i) {
111 if (comm_size >= 4) {
114 int do_test = comm_rank < 4;
116 MPI_Comm_split(MPI_COMM_WORLD, do_test, 0, &comm);
117 int comm_rank, comm_size;
118 MPI_Comm_rank(comm, &comm_rank);
119 MPI_Comm_size(comm, &comm_size);
125 int is_tgt = comm_rank >= 2;
127 double coordinates_x[2][5] = {{0.0,1.0,2.0,3.0,4.0}, {0.5,1.5,2.5,3.5,-1.0}};
128 double coordinates_y[2][4] = {{0.0,1.0,2.0,3.0}, {0.5,1.5,2.5,-1.0}};
130 size_t local_start[4][2] = {{0,0},{2,0},{0,0},{2,0}};
131 size_t local_count[4][2] = {{2,3},{2,3},{2,2},{1,2}};
133 for (
int i = 0;
i < 2; ++
i){
141 local_start[comm_rank], local_count[comm_rank],
with_halo);
143 char const *
grid_names[2] = {
"src_grid",
"tgt_grid"};
153 {.location =
YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
154 {.location =
YAC_LOC_EDGE, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
155 size_t num_src_fields =
sizeof(src_fields) /
sizeof(src_fields[0]);
157 {.location =
YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
165 size_t * tgt_indices, tgt_count;
170 interp_grid, tgt_indices, tgt_count, tgt_global_ids);
172 double tgt_coordinates[12][3];
174 interp_grid, tgt_indices, tgt_count, tgt_coordinates);
177 int count_ = (int)tgt_count, counts[4], displs[4];
178 MPI_Allgather(&count_, 1, MPI_INT, counts, 1, MPI_INT, comm);
179 for (
int i = 0, accu = 0;
i < comm_size; accu += counts[
i++])
182 int global_count = 0;
183 for (
int i = 0;
i < comm_size; ++
i) global_count += counts[i];
184 if (global_count != 12)
185 PUT_ERR(
"error in yac_interp_grid_get_tgt_points");
187 yac_int all_tgt_global_ids[12];
189 tgt_global_ids, count_,
yac_int_dt, all_tgt_global_ids,
191 double all_tgt_coordinates[12][3];
192 for (
int i = 0;
i < comm_size; ++
i) counts[i] *= 3;
193 for (
int i = 0;
i < comm_size; ++
i) displs[i] *= 3;
195 tgt_coordinates, 3*count_, MPI_DOUBLE, all_tgt_coordinates,
196 counts, displs, MPI_DOUBLE, 0, comm);
198 if (comm_rank == 0) {
199 double ref_tgt_coords[12][3];
200 for (
size_t i = 0, k = 0;
i <
num_cells[1][1]+1; ++
i)
201 for (
size_t j = 0; j <
num_cells[1][0]+1; ++j, ++k)
204 &(ref_tgt_coords[k][0]));
206 if ((all_tgt_global_ids[i] >= 12) || (all_tgt_global_ids[i] < 0))
207 PUT_ERR(
"error in yac_interp_grid_get_tgt_points");
210 PUT_ERR(
"error in yac_interp_grid_get_tgt_points");
215 size_t ref_global_count[3] = {12, 20, 31};
216 for (
size_t src_field_idx = 0; src_field_idx < 3; ++src_field_idx) {
220 PUT_ERR(
"error in yac_interp_grid_get_src_field_location");
222 size_t * src_indices, src_count;
224 interp_grid, src_field_idx, &src_indices, &src_count);
228 interp_grid, src_indices, src_count, src_field_idx, src_global_ids);
230 if (utest_check_global_ids(
231 src_global_ids, src_count, ref_global_count[src_field_idx], comm))
232 PUT_ERR(
"error in yac_interp_grid_get_src_points or "
233 "yac_interp_grid_get_src_global_ids");
238 double search_coords[15][3];
239 for (
size_t i = 0, k = 0;
i <
num_cells[1][1]+1; ++
i)
240 for (
size_t j = 0; j <
num_cells[1][0]+1; ++j, ++k)
248 size_t src_cells[15];
250 interp_grid, search_coords, 15, src_cells);
259 for (
size_t i = 0;
i < 15; ++
i) {
261 size_t curr_src_cell = src_cells[
i];
262 if (curr_src_cell != SIZE_MAX) {
264 src_grid_data, curr_src_cell, &cell);
266 PUT_ERR(
"error in yac_interp_grid_do_points_search");
276 size_t count =
sizeof(bnd_circles) /
sizeof(bnd_circles[0]);
282 bnd_circles[0].sq_crd = DBL_MAX;
288 bnd_circles[1].sq_crd = DBL_MAX;
294 bnd_circles[2].sq_crd = DBL_MAX;
300 bnd_circles[3].sq_crd = DBL_MAX;
306 bnd_circles[4].sq_crd = DBL_MAX;
308 size_t ref_num_src_per_bnd_circle[] = {1, 3, 0, 12, 2};
309 yac_int ref_src_cell_global_ids[] =
310 {0, 0,1,4, 0,1,2,3,4,5,6,7,8,9,10,11, 5,6};
312 size_t * cells, num_cells_per_bnd_circle[count];
315 interp_grid, bnd_circles, count, 0,
316 &cells, num_cells_per_bnd_circle);
318 for (
size_t i = 0, displ = 0;
i < count; ++
i) {
319 if (num_cells_per_bnd_circle[i] != ref_num_src_per_bnd_circle[i]) {
320 PUT_ERR(
"error in yac_interp_grid_do_bnd_circle_search_src");
322 yac_int src_cell_global_ids[20];
324 interp_grid, cells + displ, num_cells_per_bnd_circle[i], 0,
325 src_cell_global_ids);
326 if (utest_compare_global_ids(
327 src_cell_global_ids, ref_src_cell_global_ids + displ,
328 num_cells_per_bnd_circle[i]))
329 PUT_ERR(
"error in yac_interp_grid_do_bnd_circle_search_src");
331 displ += num_cells_per_bnd_circle[
i];
337 size_t * tgt_cells, num_tgt_cells_per_corner[12];
339 interp_grid, tgt_indices, tgt_count,
340 &tgt_cells, num_tgt_cells_per_corner);
342 yac_int const * tgt_global_corner_ids =
345 yac_int const * tgt_global_cell_ids =
349 yac_int ref_tgt_corner_cells[12][4] =
350 {{0}, {0,1}, {1,2}, {2},
351 {0,3}, {0,1,3,4}, {1,2,4,5}, {2,5},
352 {3}, {3,4}, {4,5}, {5}};
353 size_t ref_num_tgt_cells_per_corner[12] =
354 {1,2,2,1, 2,4,4,2, 1,2,2,1};
356 for (
size_t i = 0, k = 0;
i < tgt_count; ++
i) {
357 if (ref_num_tgt_cells_per_corner[
358 tgt_global_corner_ids[tgt_indices[i]]] !=
359 num_tgt_cells_per_corner[i])
360 PUT_ERR(
"ERROR in yac_interp_grid_get_tgt_corner_cells");
362 for (
size_t j = 0; j < num_tgt_cells_per_corner[
i]; ++j, ++k)
363 if (ref_tgt_corner_cells[
364 tgt_global_corner_ids[tgt_indices[i]]][j] !=
365 tgt_global_cell_ids[tgt_cells[k]])
366 PUT_ERR(
"ERROR in yac_interp_grid_get_tgt_corner_cells");
373 for (
size_t src_field_idx = 0; src_field_idx < 3; ++src_field_idx) {
378 size_t * src_indices, src_count;
380 interp_grid, src_field_idx, &src_indices, &src_count);
384 interp_grid, src_indices, src_count, src_field_idx, src_global_ids);
386 size_t * src_cells, num_src_cells_per_corner[12];
388 interp_grid, src_indices, src_count,
389 &src_cells, num_src_cells_per_corner);
391 yac_int const * src_global_corner_ids =
394 yac_int const * src_global_cell_ids =
398 yac_int ref_src_corner_cells[20][4] =
399 {{0}, {0,1}, {1,2}, {2,3}, {3},
400 {0,4}, {0,1,4,5}, {1,2,5,6}, {2,3,6,7}, {3,7},
401 {4,8}, {4,5,8,9}, {5,6,9,10}, {6,7,10,11}, {7,11},
402 {8}, {8,9}, {9,10}, {10,11}, {11}};
403 size_t ref_num_src_cells_per_corner[20] =
404 {1,2,2,2,1, 2,4,4,4,2, 2,4,4,4,2, 1,2,2,2,1};
406 for (
size_t i = 0, k = 0;
i < src_count; ++
i) {
407 if (ref_num_src_cells_per_corner[
408 src_global_corner_ids[src_indices[i]]] !=
409 num_src_cells_per_corner[i])
410 PUT_ERR(
"ERROR in yac_interp_grid_get_src_corner_cells");
412 for (
size_t j = 0; j < num_src_cells_per_corner[
i]; ++j, ++k)
413 if (ref_src_corner_cells[
414 src_global_corner_ids[src_indices[i]]][j] !=
415 src_global_cell_ids[src_cells[k]])
416 PUT_ERR(
"ERROR in yac_interp_grid_get_src_corner_cells");
433 for (
int to_tgt_owner = 0; to_tgt_owner <= 1; ++to_tgt_owner) {
435 int is_tgt = comm_rank >= 2;
438 {0.5,1.5,2.5,3.5,-1.0}};
442 size_t local_start[4][2] = {{0,0},{2,0},{0,0},{2,0}};
443 size_t local_count[4][2] = {{2,3},{2,3},{2,2},{1,2}};
445 for (
int i = 0;
i < 2; ++
i){
453 local_start[comm_rank], local_count[comm_rank],
with_halo);
455 char const *
grid_names[2] = {
"src_grid",
"tgt_grid"};
463 malloc(
grid_data.num_cells *
sizeof(*src_cell_coordinates));
465 for (
int j = 0; j < 3; ++j) src_cell_coordinates[i][j] = 0.0;
466 size_t * cell_vertices =
469 for (
int k = 0; k < 3; ++k)
470 src_cell_coordinates[i][k] +=
471 grid_data.vertex_coordinates[cell_vertices[j]][k];
477 free(src_cell_coordinates);
485 size_t num_src_fields =
sizeof(src_fields) /
sizeof(src_fields[0]);
488 .masks_idx = SIZE_MAX};
495 size_t * tgt_points, tgt_count;
501 interp_grid, tgt_points, tgt_count, tgt_global_ids);
505 malloc(tgt_count *
sizeof(*tgt_coordinates));
507 interp_grid, tgt_points, tgt_count, tgt_coordinates);
510 size_t * src_points = malloc(tgt_count *
sizeof(*src_points));
512 interp_grid, tgt_coordinates, tgt_count, 1, src_points, M_PI);
513 free(tgt_coordinates);
516 double *
weights = malloc(tgt_count *
sizeof(*weights));
517 for (
size_t i = 0;
i < tgt_count; ++
i)
518 weights[i] = (
double)tgt_global_ids[
i];
523 &tgt_points, &weights, &tgt_count);
528 interp_grid, src_points, tgt_count, 0, src_global_ids);
530 interp_grid, tgt_points, tgt_count, tgt_global_ids);
532 tgt_global_ids, tgt_count, src_global_ids, weights);
535 size_t ref_num_points[2][4] = {{6,6,0,0},{0,0,9,3}};
536 yac_int ref_global_ids[2][4][9] =
537 {{{0,1,4,5,8,9},{2,3,6,7,10,11},{-1},{-1}},
538 {{-1},{-1},{0,1,2,4,5,6,8,9,10},{3,7,11}}};
539 if (tgt_count != ref_num_points[to_tgt_owner][comm_rank])
541 "error in yac_interp_grid_relocate_src_tgt_pairs_orig");
542 for (
size_t i = 0;
i < tgt_count; ++
i) {
543 if (src_global_ids[i] != ref_global_ids[to_tgt_owner][comm_rank][i])
545 "error in yac_interp_grid_relocate_src_tgt_pairs_orig");
546 if (tgt_global_ids[i] != ref_global_ids[to_tgt_owner][comm_rank][i])
548 "error in yac_interp_grid_relocate_src_tgt_pairs_orig");
549 if (weights[i] != (
double)ref_global_ids[to_tgt_owner][comm_rank][i])
551 "error in yac_interp_grid_relocate_src_tgt_pairs_orig");
565 MPI_Comm_free(&comm);
568 PUT_ERR(
"insufficient number of processes");
578static int utest_check_global_ids(
579 yac_int * global_ids,
int count,
int ref_global_count, MPI_Comm comm) {
583 int comm_rank, comm_size;
584 MPI_Comm_rank(comm, &comm_rank);
585 MPI_Comm_size(comm, &comm_size);
587 int * counts =
xmalloc((
size_t)comm_size *
sizeof(*counts));
588 int * displs =
xmalloc((
size_t)comm_size *
sizeof(*displs));
589 MPI_Allgather(&count, 1, MPI_INT, counts, 1, MPI_INT, comm);
590 for (
int i = 0, accu = 0;
i < comm_size; accu += counts[
i++])
593 int global_count = 0;
594 for (
int i = 0;
i < comm_size; ++
i) global_count += counts[i];
598 xmalloc((
size_t)global_count *
sizeof(*all_global_ids)):
601 global_ids, count,
yac_int_dt, all_global_ids,
604 if (comm_rank == 0) {
607 for (
int i = 0;
i < global_count; ++
i) {
608 if ((all_global_ids[i] >= ref_global_count) ||
609 (all_global_ids[i] < 0)) {
612 if (!
flag[all_global_ids[i]]) ++flag_count;
613 flag[all_global_ids[
i]] = 1;
616 if (flag_count != ref_global_count) ++error_count;
620 free(all_global_ids);
627static int utest_compare_global_ids(
630 size_t match_count = 0;
631 for (
size_t i = 0;
i < count; ++
i)
632 for (
size_t j = 0; j < count; ++j)
633 if (global_ids[i] == ref_global_ids[j]) ++match_count;
634 return match_count != count;
char const * grid_names[]
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(struct yac_basic_grid *grid, enum yac_location location, yac_coordinate_pointer coordinates, size_t count)
struct yac_basic_grid * yac_basic_grid_empty_new(char const *name)
void yac_basic_grid_delete(struct yac_basic_grid *grid)
int yac_point_in_cell(double point_coords[3], struct yac_grid_cell cell)
void yac_dist_grid_pair_delete(struct yac_dist_grid_pair *grid_pair)
struct yac_dist_grid_pair * yac_dist_grid_pair_new(struct yac_basic_grid *grid_a, struct yac_basic_grid *grid_b, MPI_Comm comm)
void yac_const_basic_grid_data_get_grid_cell(struct yac_const_basic_grid_data *grid_data, size_t cell_idx, struct yac_grid_cell *buffer_cell)
struct yac_basic_grid_data yac_generate_basic_grid_data_reg2d(double const *global_coords_x, double const *global_coords_y, size_t const num_global_cells_[2], size_t const local_start[2], size_t const local_count[2], int with_halo)
static struct sin_cos_angle get_vector_angle_2(double const a[3], double const b[3])
static void LLtoXYZ_deg(double lon, double lat, double p_out[])
static void normalise_vector(double v[])
static double get_vector_angle(double const a[3], double const b[3])
void yac_init_grid_cell(struct yac_grid_cell *cell)
void yac_free_grid_cell(struct yac_grid_cell *cell)
void yac_interp_grid_do_points_search(struct yac_interp_grid *interp_grid, yac_coordinate_pointer search_coords, size_t count, size_t *src_cells)
size_t yac_interp_grid_get_num_src_fields(struct yac_interp_grid *interp_grid)
char const * yac_interp_grid_get_src_grid_name(struct yac_interp_grid *interp_grid)
void yac_interp_grid_delete(struct yac_interp_grid *interp_grid)
void yac_interp_grid_get_tgt_points(struct yac_interp_grid *interp_grid, size_t **tgt_indices, size_t *count)
char const * yac_interp_grid_get_tgt_grid_name(struct yac_interp_grid *interp_grid)
void yac_interp_grid_get_tgt_global_ids(struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count, yac_int *tgt_global_ids)
struct yac_interp_grid * yac_interp_grid_new(struct yac_dist_grid_pair *grid_pair, char const *src_grid_name, char const *tgt_grid_name, size_t num_src_fields, struct yac_interp_field const *src_fields, struct yac_interp_field const tgt_field)
void yac_interp_grid_do_bnd_circle_search_src(struct yac_interp_grid *interp_grid, const_bounding_circle_pointer bnd_circles, size_t count, size_t src_field_idx, size_t **src_cells, size_t *num_src_per_bnd_circle)
void yac_interp_grid_get_tgt_corner_cells(struct yac_interp_grid *interp_grid, size_t *tgt_corners, size_t count, size_t **tgt_cells, size_t *num_cells_per_corner)
void yac_interp_grid_get_src_points(struct yac_interp_grid *interp_grid, size_t src_field_idx, size_t **src_indices, size_t *count)
enum yac_location yac_interp_grid_get_src_field_location(struct yac_interp_grid *interp_grid, size_t src_field_idx)
void yac_interp_grid_do_nnn_search_src(struct yac_interp_grid *interp_grid, yac_coordinate_pointer search_coords, size_t count, size_t n, size_t *src_points, double max_search_distance)
void yac_interp_grid_get_src_corner_cells(struct yac_interp_grid *interp_grid, size_t *src_corners, size_t count, size_t **src_cells, size_t *num_cells_per_corner)
void yac_interp_grid_get_tgt_coordinates(struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count, yac_coordinate_pointer tgt_coordinates)
struct yac_const_basic_grid_data * yac_interp_grid_get_basic_grid_data_tgt(struct yac_interp_grid *interp_grid)
void yac_interp_grid_get_src_global_ids(struct yac_interp_grid *interp_grid, size_t *src_points, size_t count, size_t src_field_idx, yac_int *src_global_ids)
void yac_interp_grid_relocate_src_tgt_pairs_orig(struct yac_interp_grid *interp_grid, int to_tgt_owner, enum yac_location src_location, size_t **src_points, size_t **tgt_points, double **weights, size_t *count)
struct yac_const_basic_grid_data * yac_interp_grid_get_basic_grid_data_src(struct yac_interp_grid *interp_grid)
#define xcalloc(nmemb, size)
struct yac_basic_grid_data yac_read_icon_basic_grid_data_parallel(const char *filename, MPI_Comm comm)
int * num_vertices_per_cell
const const_yac_int_pointer ids[3]
enum yac_location location
struct yac_interp_field tgt_field
struct yac_dist_grid_pair * grid_pair
struct yac_interp_field src_fields[]
void set_even_io_rank_list(MPI_Comm comm)
static void LLtoXYZ(double lon, double lat, double p_out[])
void yac_quicksort_index_yac_int_yac_int_double(yac_int *a, size_t n, yac_int *b, double *c)
struct yac_basic_grid ** grids
double(* yac_coordinate_pointer)[3]