20#define RAD (0.01745329251994329576923690768489)
21#define FRAC_MASK_TOL (1e-12)
22#define RESULT_TOL (1e-2)
44 double *** src_field_buffer,
double *** src_frac_mask_buffer,
47 size_t num_tgt_points,
int use_csr_format);
53 double const tgt_coords[3],
int src_cell_id,
size_t src_cell_idx,
54 int const ** global_results_points,
double ** result_weights,
62 double *** src_field_buffer,
double *** src_frac_mask_buffer,
84 MPI_Comm_rank ( MPI_COMM_WORLD, &rank );
85 MPI_Comm_size ( MPI_COMM_WORLD, &size );
88 PUT_ERR(
"ERROR: wrong number of processes");
93 int is_src =
rank <= 1;
94 int is_tgt = (
rank >= 1) && (rank < 3);
95 int is_dummy = !is_src && !is_tgt;
97 int tgt_rank =
rank - 1;
100 int comp_ids[2], src_comp_id, tgt_comp_id, dummy_comp_id;
102 char const * src_comp_name =
"source_component";
103 char const * tgt_comp_name =
"target_component";
104 char const * dummy_comp_name =
"dummy_component";
105 char const * comp_names[2];
106 if (is_src) comp_names[num_comps++] = src_comp_name;
107 if (is_tgt) comp_names[num_comps++] = tgt_comp_name;
108 if (is_dummy) comp_names[num_comps++] = dummy_comp_name;
110 dummy_comp_id = is_dummy?
comp_ids[--num_comps]:-1;
111 tgt_comp_id = is_tgt?
comp_ids[--num_comps]:-1;
112 src_comp_id = is_src?
comp_ids[--num_comps]:-1;
115 int src_grid_id, tgt_grid_id, dummy_grid_id;
117 int src_cell_mask_id_quarter;
119 int src_cell_mask_id_half_a;
120 int src_cell_mask_id_half_b;
122 int tgt_cell_mask_id_half_a;
123 int tgt_cell_mask_id_half_b;
126 char const * dummy_grid_name =
"dummy_grid";
127 int src_cell_global_ids[2][2] = {{0,2}, {1,3}};
128 int tgt_cell_global_ids[2][6] = {{0,1,2, 3,4,5}, {3,4,5, 6,7,8}};
129 int tgt_vertex_global_ids[2][12] = {{0,1,2,3, 4,5,6,7, 8,9,10,11},
130 {4,5,6,7, 8,9,10,11, 12,13,14,15}};
132 int nbr_vertices[2] = {2,3};
134 double x_vertices[2][2] = {{-1.0,0.0}, {0.0,1.0}};
135 double y_vertices[3] = {-1.0,0.0,1.0};
136 int src_cell_is_valid[3][2][2] =
137 {{{0,1},{1,1}},{{1,1},{0,0}},{{0,0},{1,1}}};
138 for (
int i = 0;
i < nbr_vertices[0]; ++
i) x_vertices[src_rank][i] *=
RAD;
139 for (
int i = 0;
i < nbr_vertices[1]; ++
i) y_vertices[i] *=
RAD;
142 x_vertices[src_rank], y_vertices, &src_grid_id);
146 src_grid_id, (nbr_vertices[0] - 1) * (nbr_vertices[1] - 1),
148 &src_cell_mask_id_quarter);
150 src_grid_id, (nbr_vertices[0] - 1) * (nbr_vertices[1] - 1),
152 &src_cell_mask_id_half_a);
154 src_grid_id, (nbr_vertices[0] - 1) * (nbr_vertices[1] - 1),
156 &src_cell_mask_id_half_b);
159 src_cell_mask_id_quarter = -1;
160 src_cell_mask_id_half_a = -1;
161 src_cell_mask_id_half_b = -1;
164 int nbr_vertices[2] = {4,3};
166 double x_vertices[4] = {-1.5,-0.5,0.5,1.5};
167 double y_vertices[2][3] = {{-1.5,-0.5,0.5}, {-0.5,0.5,1.5}};
168 int tgt_cell_is_valid_a[2][6] = {{0,0,0, 0,0,0},{0,0,0, 1,1,1}};
169 int tgt_cell_is_valid_b[2][6] = {{1,1,1, 0,0,0},{0,0,0, 0,0,0}};
170 for (
int i = 0;
i < nbr_vertices[0]; ++
i) x_vertices[i] *=
RAD;
171 for (
int i = 0;
i < nbr_vertices[1]; ++
i) y_vertices[tgt_rank][i] *=
RAD;
174 x_vertices, y_vertices[tgt_rank], &tgt_grid_id);
180 tgt_grid_id, (nbr_vertices[0] - 1) * (nbr_vertices[1] - 1),
182 &tgt_cell_mask_id_half_a);
184 tgt_grid_id, (nbr_vertices[0] - 1) * (nbr_vertices[1] - 1),
186 &tgt_cell_mask_id_half_b);
189 tgt_cell_mask_id_half_a = -1;
190 tgt_cell_mask_id_half_b = -1;
193 dummy_grid_name, (
int[]){2,2}, (
int[]){0,0},
194 (
double[]){-1,1}, (
double[]){-1,1}, &dummy_grid_id);
197 int src_cell_point_id, tgt_cell_point_id, tgt_vertex_point_id,
201 double x_cells[2][2] = {{-0.5}, {0.5}};
202 double y_cells[2] = {-0.5,0.5};
203 for (
int i = 0;
i <
num_cells[0]; ++
i) x_cells[src_rank][i] *=
RAD;
207 x_cells[src_rank], y_cells, &src_cell_point_id);
209 src_cell_point_id = -1;
213 int num_vertices[2] = {4,3};
214 double x_cells[3] = {-1.0,0.0,1.0};
215 double y_cells[2][2] = {{-1.0,0.0}, {0.0,1.0}};
216 double x_vertices[4] = {-1.5,-0.5,0.5,1.5};
217 double y_vertices[2][3] = {{-1.5,-0.5,0.5}, {-0.5,0.5,1.5}};
219 for (
int i = 0;
i <
num_cells[1]; ++
i) y_cells[tgt_rank][i] *=
RAD;
220 for (
int i = 0;
i < num_vertices[0]; ++
i) x_vertices[i] *=
RAD;
221 for (
int i = 0;
i < num_vertices[1]; ++
i) y_vertices[tgt_rank][i] *=
RAD;
224 x_cells, y_cells[tgt_rank], &tgt_cell_point_id);
227 x_vertices, y_vertices[tgt_rank], &tgt_vertex_point_id);
229 tgt_cell_point_id = -1;
230 tgt_vertex_point_id = -1;
234 (
double[]){0}, (
double[]){0}, &dummy_cell_point_id);
241 double fixed_value = -2.0;
243 int interp_stack_conserv, interp_stack_callback;
250 interp_stack_callback,
"multi_compute_weights");
252 int ext_couple_config;
267 char const * coupling_period;
268 int interp_stack_config;
272 double *** src_field_buffer;
273 double *** src_frac_mask_buffer;
278 {{.name =
"source_field",
279 .point_ids = (
int[]){src_cell_point_id},
280 .mask_ids = (
int[]){src_cell_mask_id_quarter},
281 .global_ids = (
int*[]){is_src?src_cell_global_ids[src_rank]:NULL},
283 {.name =
"target_field",
284 .point_ids = (
int[]){tgt_cell_point_id},
285 .global_ids = (
int*[]){is_tgt?tgt_cell_global_ids[tgt_rank]:NULL},
286 .mask_ids = (
int[]){-1},
288 .coupling_period =
"1",
289 .interp_stack_config = interp_stack_conserv,
295 {{.name =
"source_field_frac",
296 .point_ids = (
int[]){src_cell_point_id},
297 .mask_ids = (
int[]){src_cell_mask_id_quarter},
298 .global_ids = (
int*[]){is_src?src_cell_global_ids[src_rank]:NULL},
300 {.name =
"target_field_frac",
301 .point_ids = (
int[]){tgt_cell_point_id},
302 .global_ids = (
int*[]){is_tgt?tgt_cell_global_ids[tgt_rank]:NULL},
303 .mask_ids = (
int[]){-1},
305 .coupling_period =
"1",
306 .interp_stack_config = interp_stack_conserv,
315 {{.name =
"source_field_full_a",
316 .point_ids = (
int[]){src_cell_point_id},
317 .mask_ids = (
int[]){-1},
318 .global_ids = (
int*[]){is_src?src_cell_global_ids[src_rank]:NULL},
320 {.name =
"target_field_half_a",
321 .point_ids = (
int[]){tgt_cell_point_id},
322 .global_ids = (
int*[]){is_tgt?tgt_cell_global_ids[tgt_rank]:NULL},
323 .mask_ids = (
int[]){tgt_cell_mask_id_half_a},
325 .coupling_period =
"2",
326 .interp_stack_config = interp_stack_conserv,
335 {{.name =
"source_field_full_b",
336 .point_ids = (
int[]){src_cell_point_id},
337 .mask_ids = (
int[]){-1},
338 .global_ids = (
int*[]){is_src?src_cell_global_ids[src_rank]:NULL},
340 {.name =
"target_field_half_b",
341 .point_ids = (
int[]){tgt_cell_point_id},
342 .global_ids = (
int*[]){is_tgt?tgt_cell_global_ids[tgt_rank]:NULL},
343 .mask_ids = (
int[]){tgt_cell_mask_id_half_b},
345 .coupling_period =
"2",
346 .interp_stack_config = interp_stack_conserv,
355 {{.name =
"source_field_half_a",
356 .point_ids = (
int[]){src_cell_point_id},
357 .mask_ids = (
int[]){src_cell_mask_id_half_a},
358 .global_ids = (
int*[]){is_src?src_cell_global_ids[src_rank]:NULL},
360 {.name =
"target_field_full_a",
361 .point_ids = (
int[]){tgt_cell_point_id},
362 .global_ids = (
int*[]){is_tgt?tgt_cell_global_ids[tgt_rank]:NULL},
363 .mask_ids = (
int[]){-1},
365 .coupling_period =
"2",
366 .interp_stack_config = interp_stack_conserv,
375 {{.name =
"source_field_half_b",
376 .point_ids = (
int[]){src_cell_point_id},
377 .mask_ids = (
int[]){src_cell_mask_id_half_b},
378 .global_ids = (
int*[]){is_src?src_cell_global_ids[src_rank]:NULL},
380 {.name =
"target_field_full_b",
381 .point_ids = (
int[]){tgt_cell_point_id},
382 .global_ids = (
int*[]){is_tgt?tgt_cell_global_ids[tgt_rank]:NULL},
383 .mask_ids = (
int[]){-1},
385 .coupling_period =
"2",
386 .interp_stack_config = interp_stack_conserv,
395 {{.name =
"source_field_frac_full_a",
396 .point_ids = (
int[]){src_cell_point_id},
397 .mask_ids = (
int[]){-1},
398 .global_ids = (
int*[]){is_src?src_cell_global_ids[src_rank]:NULL},
400 {.name =
"target_field_frac_half_a",
401 .point_ids = (
int[]){tgt_cell_point_id},
402 .global_ids = (
int*[]){is_tgt?tgt_cell_global_ids[tgt_rank]:NULL},
403 .mask_ids = (
int[]){tgt_cell_mask_id_half_a},
405 .coupling_period =
"2",
406 .interp_stack_config = interp_stack_conserv,
415 {{.name =
"source_field_frac_full_b",
416 .point_ids = (
int[]){src_cell_point_id},
417 .mask_ids = (
int[]){-1},
418 .global_ids = (
int*[]){is_src?src_cell_global_ids[src_rank]:NULL},
420 {.name =
"target_field_frac_half_b",
421 .point_ids = (
int[]){tgt_cell_point_id},
422 .global_ids = (
int*[]){is_tgt?tgt_cell_global_ids[tgt_rank]:NULL},
423 .mask_ids = (
int[]){tgt_cell_mask_id_half_b},
425 .coupling_period =
"2",
426 .interp_stack_config = interp_stack_conserv,
435 {{.name =
"source_field_frac_half_a",
436 .point_ids = (
int[]){src_cell_point_id},
437 .mask_ids = (
int[]){src_cell_mask_id_half_a},
438 .global_ids = (
int*[]){is_src?src_cell_global_ids[src_rank]:NULL},
440 {.name =
"target_field_frac_full_a",
441 .point_ids = (
int[]){tgt_cell_point_id},
442 .global_ids = (
int*[]){is_tgt?tgt_cell_global_ids[tgt_rank]:NULL},
443 .mask_ids = (
int[]){-1},
445 .coupling_period =
"2",
446 .interp_stack_config = interp_stack_conserv,
455 {{.name =
"source_field_frac_half_b",
456 .point_ids = (
int[]){src_cell_point_id},
457 .mask_ids = (
int[]){src_cell_mask_id_half_b},
458 .global_ids = (
int*[]){is_src?src_cell_global_ids[src_rank]:NULL},
460 {.name =
"target_field_frac_full_b",
461 .point_ids = (
int[]){tgt_cell_point_id},
462 .global_ids = (
int*[]){is_tgt?tgt_cell_global_ids[tgt_rank]:NULL},
463 .mask_ids = (
int[]){-1},
465 .coupling_period =
"2",
466 .interp_stack_config = interp_stack_conserv,
474 {{.name =
"source_field_multi",
475 .point_ids = (
int[]){src_cell_point_id, src_cell_point_id},
476 .mask_ids = (
int[]){-1,-1},
477 .global_ids = (
int*[]){is_src?src_cell_global_ids[src_rank]:NULL},
479 {.name =
"target_field_multi",
480 .point_ids = (
int[]){tgt_vertex_point_id},
481 .global_ids = (
int*[]){is_tgt?tgt_vertex_global_ids[tgt_rank]:NULL},
482 .mask_ids = (
int[]){-1},
484 .coupling_period =
"1",
485 .interp_stack_config = interp_stack_callback,
493 {{.name =
"source_field_comp",
494 .point_ids = (
int[]){src_cell_point_id},
495 .mask_ids = (
int[]){src_cell_mask_id_quarter},
496 .global_ids = (
int*[]){is_src?src_cell_global_ids[src_rank]:NULL},
498 {.name =
"target_field_comp_raw",
499 .point_ids = (
int[]){tgt_cell_point_id},
500 .global_ids = (
int*[]){is_tgt?tgt_cell_global_ids[tgt_rank]:NULL},
501 .mask_ids = (
int[]){-1},
503 .coupling_period =
"1",
504 .interp_stack_config = interp_stack_conserv,
510 {{.name =
"source_field_csr",
511 .point_ids = (
int[]){src_cell_point_id},
512 .mask_ids = (
int[]){src_cell_mask_id_quarter},
513 .global_ids = (
int*[]){is_src?src_cell_global_ids[src_rank]:NULL},
515 {.name =
"target_field_csr",
516 .point_ids = (
int[]){tgt_cell_point_id},
517 .global_ids = (
int*[]){is_tgt?tgt_cell_global_ids[tgt_rank]:NULL},
518 .mask_ids = (
int[]){-1},
520 .coupling_period =
"1",
521 .interp_stack_config = interp_stack_conserv,
528 for (
size_t i = 0;
i <
sizeof(test_configs) /
sizeof(test_configs[0]); ++
i) {
531 for (
int j = 0; j < 2; ++j) {
532 if (test_configs[i].field[j].point_ids[0] != -1) {
533 int comp_id = (j ==
SRC)?src_comp_id:tgt_comp_id;
534 if (test_configs[i].field[j].mask_ids[0] != -1)
537 test_configs[i].field[j].point_ids,
538 test_configs[i].field[j].mask_ids,
541 &test_configs[i].field[j].
id);
545 test_configs[i].field[j].point_ids,
548 &test_configs[i].field[j].
id);
550 test_configs[
i].field[j].id = -1;
565 test_configs[i].coupling_period,
567 test_configs[i].interp_stack_config, 0, 0, ext_couple_config);
570 int tgt_field_non_raw_id;
576 "target_field_comb_non_raw", tgt_comp_id, &tgt_cell_point_id,
582 interp_stack_conserv, 0, 0);
584 tgt_field_non_raw_id = -1;
588 int src_dummy_field_id = -1, tgt_dummy_field_id = -1;
589 switch (1 * is_src + 2 * is_tgt) {
592 "target_field_dummy", dummy_comp_id, &dummy_cell_point_id,
595 "source_field_dummy", dummy_comp_id, &dummy_cell_point_id,
601 "target_field_dummy", src_comp_id, &dummy_cell_point_id,
607 "source_field_dummy", tgt_comp_id, &dummy_cell_point_id,
615 PUT_ERR(
"ERROR: invalid process type");
625 for (
size_t i = 0;
i <
sizeof(test_configs) /
sizeof(test_configs[0]); ++
i) {
626 test_configs[
i].interp_weights_data =
628 test_configs[i].field[
TGT].
id, test_configs[i].use_csr_format);
629 size_t num_src_fields = test_configs[
i].interp_weights_data.num_src_fields;
631 test_configs[
i].interp_weights_data.src_field_buffer_sizes;
632 size_t sum_src_field_buffer_sizes = 0;
635 double * src_field_buffer_1d =
636 (sum_src_field_buffer_sizes > 0)?
639 sizeof(*src_field_buffer_1d)):NULL;
640 double *** src_field_buffer =
643 src_field_buffer[
i] = malloc(
num_src_fields *
sizeof(**src_field_buffer));
645 src_field_buffer[
i][j] = src_field_buffer_1d + offset;
649 test_configs[
i].src_field_buffer = src_field_buffer;
651 double * src_frac_mask_buffer_1d =
652 (sum_src_field_buffer_sizes > 0)?
655 sizeof(*src_frac_mask_buffer_1d)):NULL;
656 double *** src_frac_mask_buffer =
659 src_frac_mask_buffer[
i] =
662 src_frac_mask_buffer[
i][j] = src_frac_mask_buffer_1d + offset;
666 test_configs[
i].src_frac_mask_buffer = src_frac_mask_buffer;
668 test_configs[
i].src_frac_mask_buffer = NULL;
679 GLOBAL_NUM_SRC_CELLS = 4,
680 GLOBAL_NUM_TGT_CELLS = 9,
681 GLOBAL_NUM_TGT_VERTICES = 16,
684 NUM_TGT_VERTICES = 12,
687 {{1,2,3,4}, {-1,-2,-3,-4}};
694 for (
size_t k = 0; k < NUM_SRC_CELLS; ++k)
695 src_field_data[i][j][k] =
696 global_src_field_data[j][src_cell_global_ids[src_rank][k]];
697 src_field_[
i][j] = src_field_data[
i][j];
708 int src_field_id = test_configs[TEST_IDX].field[
SRC].id;
709 int tgt_field_id = test_configs[TEST_IDX].field[
TGT].id;
710 double *** src_field_buffer = test_configs[TEST_IDX].src_field_buffer;
712 {{fixed_value,0.25*(2),0.25*(2),
713 0.25*(3),0.25*(2+3+4),0.25*(2+4),
714 0.25*(3),0.25*(3+4),0.25*(4)}};
716 for (
size_t t = 0;
t < NUM_TESTS_BASIC; ++
t) {
718 switch (1 * is_src + 2 * is_tgt) {
759 src_field, src_field_buffer, &send_info, &recv_info, &
ierror);
764 PUT_ERR(
"ERROR: invalid process type");
773 test_configs[TEST_IDX].field[
TGT].global_ids[0],
780 enum {TEST_IDX = 1, NUM_FRAC_MASKS = 3,
782 int src_field_id = test_configs[TEST_IDX].field[
SRC].id;
783 int tgt_field_id = test_configs[TEST_IDX].field[
TGT].id;
784 double *** src_field_buffer = test_configs[TEST_IDX].src_field_buffer;
785 double *** src_frac_mask_buffer =
786 test_configs[TEST_IDX].src_frac_mask_buffer;
788 {{fixed_value,0.25*(2),0.25*(2),
789 0.25*(3),0.25*(2+3+4),0.25*(2+4),
790 0.25*(3),0.25*(3+4),0.25*(4)},
792 (0.25*(1.0*3))/((0.25*1.0)/(0.25)),
793 (0.25*(0.0*2+0.5*3+1.0*4))/((0.25*(0.0+0.5+1.0))/(0.25+0.25+0.25)),
794 (0.25*(0.0*2+1.0*4))/((0.25*(0.0+1.0))/(0.25+0.25)),
795 (0.25*(0.5*3))/((0.25*0.5)/(0.25)),
796 (0.25*(0.5*3+1.0*4))/((0.25*(0.5+1.0))/(0.25+0.25)),
797 (0.25*(1.0*4))/((0.25*1.0)/(0.25))}};
799 double global_src_frac_mask_data
801 {{{1,1,1,1}},{{0.5,0.0,0.5,1.0}}};
802 double src_frac_mask_data
804 double * src_frac_mask_
808 for (
size_t t = 0;
t < NUM_FRAC_MASKS; ++
t) {
811 for (
size_t k = 0; k < NUM_SRC_CELLS; ++k)
812 src_frac_mask_data[t][i][j][k] =
813 global_src_frac_mask_data
814 [t][j][src_cell_global_ids[src_rank][k]];
815 src_frac_mask_[
t][
i][j] = src_frac_mask_data[
t][
i][j];
817 src_frac_mask[
t][
i] = src_frac_mask_[
t][
i];
822 for (
size_t t = 0;
t < NUM_FRAC_TESTS; ++
t) {
824 switch (1 * is_src + 2 * is_tgt) {
833 src_field, src_frac_mask[t&1], &info, &
ierror);
845 src_frac_mask_buffer, &info, &
ierror);
851 src_frac_mask_buffer, &info, &
ierror);
856 src_frac_mask_buffer[0][0], &info, &
ierror);
862 src_frac_mask_buffer[0][0], &info, &
ierror);
872 src_field, src_frac_mask[t&1],
873 src_field_buffer, src_frac_mask_buffer,
874 &send_info, &recv_info, &
ierror);
879 PUT_ERR(
"ERROR: invalid process type");
887 src_field_buffer, src_frac_mask_buffer,
889 test_configs[TEST_IDX].field[
TGT].global_ids[0],
897 enum {MIN_TEST_IDX = 2, MAX_TEST_IDX = 9,
902 0.25*(3),0.25*(3+4),0.25*(4)}},
903 {{0.25*(1),0.25*(1+2),0.25*(2),
906 {{0.25*(1),0.25*(1),fixed_value,
907 0.25*(1+3),0.25*(1+3),fixed_value,
908 0.25*(3),0.25*(3),fixed_value}},
909 {{fixed_value,0.25*(2),0.25*(2),
910 fixed_value,0.25*(2+4),0.25*(2+4),
911 fixed_value,0.25*(4),0.25*(4)}},
914 0.25*(3),0.25*(3+4),0.25*(4)}},
915 {{0.25*(1),0.25*(1+2),0.25*(2),
918 {{0.25*(1),0.25*(1),fixed_value,
919 0.25*(1+3),0.25*(1+3),fixed_value,
920 0.25*(3),0.25*(3),fixed_value}},
921 {{fixed_value,0.25*(2),0.25*(2),
922 fixed_value,0.25*(2+4),0.25*(2+4),
923 fixed_value,0.25*(4),0.25*(4)}}};
924 double global_src_frac_mask_data
926 double src_frac_mask_data
933 for (
size_t k = 0; k < NUM_SRC_CELLS; ++k)
934 src_frac_mask_data[i][j][k] =
935 global_src_frac_mask_data[j][src_cell_global_ids[src_rank][k]];
936 src_frac_mask_[
i][j] = src_frac_mask_data[
i][j];
938 src_frac_mask[
i] = src_frac_mask_[
i];
942 for (
int use_only_exchange = 0; use_only_exchange <= 1;
943 ++use_only_exchange) {
944 for (
size_t test_idx = MIN_TEST_IDX; test_idx < MAX_TEST_IDX; ++test_idx) {
947 is_src?test_configs[test_idx].field[
SRC].id:src_dummy_field_id;
949 is_tgt?test_configs[test_idx].field[
TGT].id:tgt_dummy_field_id;
950 double *** src_field_buffer = test_configs[test_idx].src_field_buffer;
951 double *** src_frac_mask_buffer =
952 test_configs[test_idx].src_frac_mask_buffer;
954 test_configs[test_idx].frac_mask_fallback_value !=
957 for (
size_t t = 0;
t < NUM_TIMESTEPS; ++
t) {
961 switch (1 * is_src + 2 * is_tgt) {
964 if (use_only_exchange) {
968 NULL, NULL, NULL, NULL,
969 &send_info, &recv_info, &
ierror);
973 NULL, NULL, &send_info, &recv_info, &
ierror);
981 if (use_only_exchange) {
985 src_field, src_frac_mask, NULL, NULL,
986 &send_info, &recv_info, &
ierror);
990 src_field, NULL, &send_info, &recv_info, &
ierror);
1008 if (use_only_exchange) {
1012 NULL, NULL, src_field_buffer, src_frac_mask_buffer,
1013 &send_info, &recv_info, &
ierror);
1017 NULL, src_field_buffer, &send_info, &recv_info, &
ierror);
1022 src_field_buffer, src_frac_mask_buffer, &info, &
ierror);
1034 src_field, src_frac_mask,
1035 src_field_buffer, src_frac_mask_buffer,
1036 &send_info, &recv_info, &
ierror);
1040 src_field, src_field_buffer, &send_info, &recv_info, &
ierror);
1045 PUT_ERR(
"ERROR: invalid process type");
1053 src_field_buffer, with_frac_mask?src_frac_mask_buffer:NULL,
1055 test_configs[test_idx].field[
TGT].global_ids[0],
1057 test_configs[test_idx].use_csr_format);
1066 int src_field_id = test_configs[TEST_IDX].field[
SRC].id;
1067 int tgt_field_id = test_configs[TEST_IDX].field[
TGT].id;
1068 double *** src_field_buffer = test_configs[TEST_IDX].src_field_buffer;
1070 {{fixed_value, fixed_value, fixed_value, fixed_value,
1071 fixed_value, 1, 2, fixed_value,
1072 fixed_value, -3, -4, fixed_value,
1073 fixed_value, fixed_value, fixed_value, fixed_value}};
1075 switch (1 * is_src + 2 * is_tgt) {
1099 src_field, src_field_buffer, &send_info, &recv_info, &
ierror);
1104 PUT_ERR(
"ERROR: invalid process type");
1112 src_field_buffer, NULL,
1114 test_configs[TEST_IDX].field[
TGT].global_ids[0],
1121 int src_field_id = test_configs[TEST_IDX].field[
SRC].id;
1122 int tgt_field_id = test_configs[TEST_IDX].field[
TGT].id;
1123 double *** src_field_buffer = test_configs[TEST_IDX].src_field_buffer;
1125 {{fixed_value,0.25*(2),0.25*(2),
1126 0.25*(3),0.25*(2+3+4),0.25*(2+4),
1127 0.25*(3),0.25*(3+4),0.25*(4)}};
1129 switch (1 * is_src + 2 * is_tgt) {
1160 PUT_ERR(
"ERROR: invalid process type");
1168 src_field_buffer, NULL,
1170 test_configs[TEST_IDX].field[
TGT].global_ids[0],
1182 for (
size_t j = 0; j < NUM_TGT_CELLS; ++j)
1183 tgt_field[i][j] = -1.0;
1193 int * tgt_global_ids =
1194 test_configs[TEST_IDX].field[
TGT].global_ids[0];
1196 for (
size_t j = 0; j < NUM_TGT_CELLS; ++j)
1209 int src_field_id = test_configs[TEST_IDX].field[
SRC].id;
1210 int tgt_field_id = test_configs[TEST_IDX].field[
TGT].id;
1211 double *** src_field_buffer = test_configs[TEST_IDX].src_field_buffer;
1213 {{fixed_value,0.25*(2),0.25*(2),
1214 0.25*(3),0.25*(2+3+4),0.25*(2+4),
1215 0.25*(3),0.25*(3+4),0.25*(4)}};
1217 for (
size_t t = 0;
t < NUM_TESTS_BASIC; ++
t) {
1219 switch (1 * is_src + 2 * is_tgt) {
1260 src_field, src_field_buffer, &send_info, &recv_info, &
ierror);
1265 PUT_ERR(
"ERROR: invalid process type");
1274 test_configs[TEST_IDX].field[
TGT].global_ids[0],
1282 for (
size_t i = 0;
i <
sizeof(test_configs) /
sizeof(test_configs[0]); ++
i) {
1284 free(test_configs[i].src_field_buffer[0][0]);
1286 free(test_configs[i].src_field_buffer[j]);
1287 free(test_configs[i].src_field_buffer);
1290 free(test_configs[i].src_frac_mask_buffer[0][0]);
1292 free(test_configs[i].src_frac_mask_buffer[j]);
1293 free(test_configs[i].src_frac_mask_buffer);
1303 double *** src_field_buffer,
double *** src_frac_mask_buffer,
1306 size_t num_tgt_points,
int use_csr_format) {
1309 double const wgt_tol = 1e-6;
1315 int with_frac_mask =
1328 for (
size_t j = 0; j < num_fixed_tgt; ++j, ++k)
1336 if (with_frac_mask) {
1341 double tgt_value = 0.0;
1342 double frac_weight_sum = 0.0;
1343 double weight_sum = 0.0;
1352 if (num_src == 0)
continue;
1354 for (
size_t j = 0; j < num_src; ++j, ++k) {
1364 src_frac_mask_buffer
1371 tgt_field[collection_idx][tgt_idx] =
1374 (tgt_value / frac_weight_sum) * weight_sum +
1384 double tgt_value = 0.0;
1393 if (num_src == 0)
continue;
1395 for (
size_t j = 0; j < num_src; ++j, ++k) {
1405 tgt_field[collection_idx][tgt_idx] =
1429 double const tgt_coords[3],
int src_cell_id,
size_t src_cell_idx,
1430 int const ** global_results_points,
double ** result_weights,
1431 size_t * result_count,
void *
user_data) {
1435 (void)(src_cell_idx);
1440 int use_second_src_field = src_cell_id >= 2;
1442 static int results_point;
1443 static double result_weight;
1445 results_point = src_cell_id;
1446 result_weight = 1.0;
1448 global_results_points[use_second_src_field] = &results_point;
1449 global_results_points[use_second_src_field^1] = NULL;
1450 result_weights[use_second_src_field] = &result_weight;
1451 result_weights[use_second_src_field^1] = NULL;
1452 result_count[use_second_src_field] = 1;
1453 result_count[use_second_src_field^1] = 0;
1457 int
field_id, int use_csr_format) {
1463 if (use_csr_format) {
1466 &
data.frac_mask_fallback_value,
1467 &
data.scaling_factor, &
data.scaling_summand,
1468 &
data.num_fixed_values, &
data.fixed_values,
1469 &
data.num_tgt_per_fixed_value, &
data.tgt_idx_fixed,
1471 &
data.num_src_fields, &
data.src_field_buffer_sizes);
1472 data.num_wgt_tgt = 0;
1473 data.wgt_tgt_idx = NULL;
1474 data.num_src_per_tgt = NULL;
1478 &
data.frac_mask_fallback_value,
1479 &
data.scaling_factor, &
data.scaling_summand,
1480 &
data.num_fixed_values, &
data.fixed_values,
1481 &
data.num_tgt_per_fixed_value, &
data.tgt_idx_fixed,
1482 &
data.num_wgt_tgt, &
data.wgt_tgt_idx, &
data.num_src_per_tgt,
1484 &
data.num_src_fields, &
data.src_field_buffer_sizes);
1485 data.src_indptr = NULL;
1488 data.num_src_fields = 0;
1496 double *** src_field_buffer,
double *** src_frac_mask_buffer,
1512 for (
size_t j = 0; j < num_tgt_points; ++j)
1513 tgt_field[i][j] = -1.0;
1517 src_field_buffer, src_frac_mask_buffer,
1519 num_tgt_points, use_csr_format);
1523 for (
size_t j = 0; j < num_tgt_points; ++j)
double const YAC_FRAC_MASK_NO_VALUE
size_t * num_tgt_per_fixed_value
double frac_mask_fallback_value
size_t * src_field_buffer_sizes
static void multi_compute_weights(double const tgt_coords[3], int src_cell_id, size_t src_cell_idx, int const **global_results_points, double **result_weights, size_t *result_count, void *user_data)
static struct interp_weights_data get_interp_weights_data(int field_id, int use_csr_format)
static void compute_tgt_field(double ***src_field_buffer, double ***src_frac_mask_buffer, double **tgt_field, size_t collection_size, struct interp_weights_data interp_weights_data, size_t num_tgt_points, int use_csr_format)
static void interp_weights_data_free(struct interp_weights_data *interp_weights_data)
static void check_results(int is_tgt, int info, size_t collection_size, size_t num_tgt_points, double ***src_field_buffer, double ***src_frac_mask_buffer, struct interp_weights_data interp_weights_data, int *tgt_global_ids, double *ref_tgt_field_data, int use_csr_format)
char const src_grid_name[]
char const tgt_grid_name[]
static double tgt_field_data[MAX_COLLECTION_SIZE][NUM_TGT_POINTS]
static double ref_tgt_field_data[MAX_COLLECTION_SIZE][NUM_TGT_POINTS]
#define MAX_COLLECTION_SIZE
void yac_cget_raw_frac_async(int const field_id, int collection_size, double ***src_field_buffer, double ***src_frac_mask_buffer, int *info, int *ierr)
int const YAC_REDUCTION_TIME_AVERAGE
void yac_cget_raw_async(int const field_id, int collection_size, double ***src_field_buffer, int *info, int *ierr)
void yac_cput_frac(int const field_id, int const collection_size, double ***const send_field, double ***const send_frac_mask, int *info, int *ierr)
void yac_cenable_field_frac_mask(const char *comp_name, const char *grid_name, const char *field_name, double frac_mask_fallback_value)
void yac_cdef_field_mask(char const *name, int const comp_id, int const *point_ids, int const *mask_ids, int const num_pointsets, int collection_size, const char *timestep, int time_unit, int *field_id)
void yac_cset_global_index(int const *global_index, int location, int grid_id)
void yac_cget_raw_interp_weights_data_csr(int const field_id, double *frac_mask_fallback_value, double *scaling_factor, double *scaling_summand, size_t *num_fixed_values, double **fixed_values, size_t **num_tgt_per_fixed_value, size_t **tgt_idx_fixed, size_t **src_indptr_, double **weights, size_t **src_field_idx, size_t **src_idx, size_t *num_src_fields, size_t **src_field_buffer_sizes)
void yac_cfree_ext_couple_config(int ext_couple_config_id)
void yac_cdef_datetime(const char *start_datetime, const char *end_datetime)
int const YAC_LOCATION_CELL
void yac_cadd_compute_weights_callback(yac_func_compute_weights compute_weights_callback, void *user_data, char const *key)
void yac_cget_raw(int const field_id, int collection_size, double ***src_field_buffer, int *info, int *ierr)
void yac_cget_raw_frac(int const field_id, int collection_size, double ***src_field_buffer, double ***src_frac_mask_buffer, int *info, int *ierr)
void yac_cfinalize()
Finalises YAC.
void yac_cget_raw_async_(int const field_id, int const collection_size, double *src_field_buffer, int *info, int *ierr)
void yac_cget_raw_interp_weights_data(int const field_id, double *frac_mask_fallback_value, double *scaling_factor, double *scaling_summand, size_t *num_fixed_values, double **fixed_values, size_t **num_tgt_per_fixed_value, size_t **tgt_idx_fixed, size_t *num_wgt_tgt, size_t **wgt_tgt_idx, size_t **num_src_per_tgt, double **weights, size_t **src_field_idx, size_t **src_idx, size_t *num_src_fields, size_t **src_field_buffer_size)
void yac_cget_ext_couple_config(int *ext_couple_config_id)
int const YAC_LOCATION_CORNER
void yac_cdef_couple_custom(char const *src_comp_name, char const *src_grid_name, char const *src_field_name, char const *tgt_comp_name, char const *tgt_grid_name, char const *tgt_field_name, char const *coupling_timestep, int time_unit, int time_reduction, int interp_stack_config_id, int src_lag, int tgt_lag, int ext_couple_config_id)
int const YAC_CONSERV_DESTAREA
void yac_cget(int const field_id, int collection_size, double **recv_field, int *info, int *ierr)
void yac_cdef_grid_reg2d(const char *grid_name, int nbr_vertices[2], int cyclic[2], double *x_vertices, double *y_vertices, int *grid_id)
void yac_cset_ext_couple_config_use_raw_exchange(int ext_couple_config_id, int use_raw_exchange)
void yac_cdef_points_reg2d(int const grid_id, int const *nbr_points, int const located, double const *x_points, double const *y_points, int *point_id)
void yac_cexchange_raw_frac(int const send_field_id, int const recv_field_id, int const collection_size, double ***const send_field, double ***const send_frac_mask, double ***src_field_buffer, double ***src_frac_mask_buffer, int *send_info, int *recv_info, int *ierr)
int const YAC_TIME_UNIT_SECOND
void yac_cadd_interp_stack_config_conservative(int interp_stack_config_id, int order, int enforced_conserv, int partial_coverage, int normalisation)
void yac_cput(int const field_id, int const collection_size, double ***const send_field, int *info, int *ierr)
int const YAC_ACTION_NONE
no data exchanges
void yac_cdef_calendar(int calendar)
void yac_cget_raw_frac_async_(int const field_id, int const collection_size, double *src_field_buffer, double *src_frac_mask_buffer, int *info, int *ierr)
void yac_cwait(int field_id)
void yac_cget_raw_frac_(int const field_id, int const collection_size, double *src_field_buffer, double *src_frac_mask_buffer, int *info, int *ierr)
void yac_cdef_comps(char const **comp_names, int num_comps, int *comp_ids)
int const YAC_ACTION_GET_FOR_RESTART
last valid get
int const YAC_PROLEPTIC_GREGORIAN
void yac_cadd_interp_stack_config_fixed(int interp_stack_config_id, double value)
int const YAC_ACTION_COUPLING
data exchange
void yac_cexchange_raw(int const send_field_id, int const recv_field_id, int const collection_size, double ***const send_field, double ***src_field_buffer, int *send_info, int *recv_info, int *ierr)
void yac_cdef_mask(int const grid_id, int const nbr_points, int const located, int const *is_valid, int *mask_id)
void yac_cadd_interp_stack_config_user_callback(int interp_stack_config_id, char const *func_compute_weights_key)
void yac_cfree_interp_stack_config(int interp_stack_config_id)
void yac_cget_interp_stack_config(int *interp_stack_config_id)
void yac_cdef_field(char const *name, int const comp_id, int const *point_ids, int const num_pointsets, int collection_size, const char *timestep, int time_unit, int *field_id)
void yac_cdef_couple(char const *src_comp_name, char const *src_grid_name, char const *src_field_name, char const *tgt_comp_name, char const *tgt_grid_name, char const *tgt_field_name, char const *coupling_timestep, int time_unit, int time_reduction, int interp_stack_config_id, int src_lag, int tgt_lag)