YAC 3.12.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_interp_method_file_parallel.c
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <stdlib.h>
6#include <unistd.h>
7#include <string.h>
8
9#include "tests.h"
10#include "test_common.h"
11#include "geometry.h"
15#include "dist_grid_utils.h"
17#include "yac_mpi.h"
18#include "yac_mpi_common.h"
19#include "weight_file_common.h"
20
21#include <mpi.h>
22#include <yaxt.h>
23#include <netcdf.h>
24
30double const tol = 1e-7;
31double const err_tol = 1e-14;
32
33char const src_grid_name[] = "src_grid";
34char const tgt_grid_name[] = "tgt_grid";
35char const file_name[] = "test_interp_method_file_parallel_weights.nc";
36char const file_name_2[] = "test_interp_method_file_parallel_weights_2.nc";
37
38static void utest_target_main(MPI_Comm target_comm);
39static void utest_source_main(MPI_Comm source_comm);
40static void utest_target_main_abort(MPI_Comm target_comm);
41static void utest_source_main_abort(MPI_Comm source_comm);
42
45enum {
49enum {
52
53static void on_missing_abort_handler(
54 MPI_Comm comm, char const * msg, char const * source, int line);
55
56static MPI_Comm split_comm;
57
58int main (void) {
59
60 MPI_Init(NULL, NULL);
61
62 xt_initialize(MPI_COMM_WORLD);
63
64 int comm_rank, comm_size;
65 MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
66 MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
67 MPI_Barrier(MPI_COMM_WORLD);
68
69 if (comm_size != 3) {
70 PUT_ERR("ERROR: wrong number of processes");
71 xt_finalize();
72 MPI_Finalize();
73 return TEST_EXIT_CODE;
74 }
75
76 int tgt_flag = comm_rank < 1;
77 MPI_Comm_split(MPI_COMM_WORLD, tgt_flag, 0, &split_comm);
78
79 char const * io_ranks[3] = {"0", "1,2", "0,1,2"};
80
81 for (int i = 0; i < 3; ++i) {
83 setenv("YAC_IO_RANK_LIST", io_ranks[i], 1);
84 setenv("YAC_IO_MAX_NUM_RANKS_PER_NODE", "3", 1);
85 if (tgt_flag) utest_target_main(split_comm);
86 else utest_source_main(split_comm);
87 }
88
89 // the following test will not return, because it checks an error case
90 if (tgt_flag) utest_target_main_abort(split_comm);
91 else utest_source_main_abort(split_comm);
92
93 MPI_Comm_free(&split_comm);
94 xt_finalize();
95 MPI_Finalize();
96
97 return TEST_EXIT_CODE;
98}
99
100static void utest_source_main(MPI_Comm source_comm) {
101
102 int my_source_rank;
103 MPI_Comm_rank(source_comm, &my_source_rank);
104
105 { // simple weight file interpolation (one link per target point) with two
106 // source processes and a single target process the source fields have two
107 // struct points per grid (the test check how the interpolation
108 // methods handle NULL target coordinates )
109
110 // the global source grid has 3x2 cells:
111 // 08--14--09--15--10--16--11
112 // | | | |
113 // 08 03 10 04 12 05 13
114 // | | | |
115 // 04--07--05--09--06--11--07
116 // | | | |
117 // 01 00 03 01 05 02 06
118 // | | | |
119 // 00--00--01--02--02--04--03
120 //
121 //---------------
122 // setup
123 //---------------
124
125 // create weight file
126 if (my_source_rank == 0) {
127
128 int src_indices[] = {0,1,2,3,4,5,6,7,8,9,10,11};
129 int tgt_indices[] = {0,1,2,3,4,5,6,7,8,9,10,11};
130 double weights[] = {0,1,2,3,4,5,6,7,8,9,10,11};
131 size_t num_links = 12;
132 enum yac_location src_locations[2] = {YAC_LOC_CORNER, YAC_LOC_CELL};
133 enum yac_location tgt_location = YAC_LOC_CORNER;
134 unsigned num_src_fields = 2;
135 int num_links_per_field[2] = {num_links, 0};
136 int * tgt_id_fixed = NULL;
137 size_t num_fixed_tgt = 0;
138 double * fixed_values = NULL;
139 int * num_tgt_per_fixed_value = NULL;
140 size_t num_fixed_values = 0;
141
143 file_name, src_indices, tgt_indices, weights, num_links,
144 src_locations, num_src_fields, num_links_per_field, tgt_id_fixed,
145 num_fixed_tgt, fixed_values, num_tgt_per_fixed_value,
146 num_fixed_values, tgt_location, src_grid_name, tgt_grid_name);
147 }
148
149 double coordinates_x[] = {0.0, 1.0, 2.0, 3.0};
150 double coordinates_y[] = {0.0, 1.0, 2.0};
151 size_t const num_global_cells[2] = {3,2};
152 size_t local_start[2][2] = {{0,0},{2,0}};
153 size_t local_count[2][2] = {{2,2},{1,2}};
154 int with_halo = 1;
155 int global_corner_mask[3][4] = {
156 {1,1,1,1}, {1,1,0,0}, {0,0,0,0}};
157 for (size_t i = 0; i <= num_global_cells[0]; ++i)
159 for (size_t i = 0; i <= num_global_cells[1]; ++i)
161
164 coordinates_x, coordinates_y, num_global_cells,
165 local_start[my_source_rank], local_count[my_source_rank], with_halo);
166
167 int * src_corner_mask =
168 xmalloc(grid_data.num_vertices * sizeof(*src_corner_mask));
169 for (size_t i = 0; i < grid_data.num_vertices; ++i)
170 src_corner_mask[i] =
171 ((int*)(&(global_corner_mask[0][0])))[grid_data.vertex_ids[i]];
172
173 struct yac_basic_grid * src_grid =
176 src_grid, YAC_LOC_CORNER, src_corner_mask, NULL);
177 struct yac_basic_grid * tgt_grid =
179
180 struct yac_dist_grid_pair * grid_pair =
181 yac_dist_grid_pair_new(src_grid, tgt_grid, MPI_COMM_WORLD);
182
183 struct yac_interp_field src_fields[] =
184 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = 0},
185 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
186 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
188 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
189
190 struct yac_interp_grid * interp_grid =
193
194 //----------------------------------------
195 // test generation of interpolation method
196 //----------------------------------------
197
198 struct interp_method * method_stack[2] = {
202
203 //-----------------
204 // generate weights
205 //-----------------
206
207 struct yac_interp_weights * weights =
208 yac_interp_method_do_search(method_stack, interp_grid);
209
210 yac_interp_method_delete(method_stack);
211
212 enum yac_interp_weights_reorder_type reorder_type[2] =
214
215 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
216 ++i) {
217 for (size_t collection_size = 1; collection_size < 4;
218 collection_size += 2) {
219
220 struct yac_interpolation * interpolation =
222 weights, reorder_type[i], collection_size,
223 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
224
225 //------------------------------
226 // check generated interpolation
227 //------------------------------
228 {
229 double *** src_data = xmalloc(collection_size * sizeof(*src_data));
230
231 for (size_t collection_idx = 0; collection_idx < collection_size;
232 ++collection_idx) {
233 src_data[collection_idx] = xmalloc(1 * sizeof(**src_data));
234 src_data[collection_idx][0] =
235 xmalloc(grid_data.num_vertices * sizeof(***src_data));
236 for (size_t i = 0; i < grid_data.num_vertices; ++i)
237 src_data[collection_idx][0][i] =
238 (double)(grid_data.vertex_ids[i]) +
239 (double)(collection_idx * 12);
240 }
241
242 yac_interpolation_execute_put(interpolation, src_data);
243
244 for (size_t collection_idx = 0; collection_idx < collection_size;
245 ++collection_idx) {
246 free(src_data[collection_idx][0]);
247 free(src_data[collection_idx]);
248 }
249 free(src_data);
250 }
251
252 //---------------
253 // cleanup
254 //---------------
255
256 yac_interpolation_delete(interpolation);
257 }
258 }
259
260 //---------------
261 // cleanup
262 //---------------
263
265 yac_interp_grid_delete(interp_grid);
266 yac_dist_grid_pair_delete(grid_pair);
267 yac_basic_grid_delete(tgt_grid);
268 yac_basic_grid_delete(src_grid);
269
270 if (my_source_rank == 0) unlink(file_name);
271 }
272
273 { // simple weight file interpolation (multiple links per target point)
274 // with two source processes and a single target process
275 // there are two source fields
276
277 // the global grid has 4x2 cells:
278 // 08--14--09--15--10--16--11
279 // | | | |
280 // 08 03 10 04 12 05 13
281 // | | | |
282 // 04--07--05--09--06--11--07
283 // | | | |
284 // 01 00 03 01 05 02 06
285 // | | | |
286 // 00--00--01--02--02--04--03
287 //
288 //---------------
289 // setup
290 //---------------
291
292 // create weight file
293 if (my_source_rank == 0) {
294
295 int tgt_indices[] = { 0, 0, 0, 0,
296 1, 1, 1, 1,
297 2, 2, 2, 2,
298 3, 3, 3, 3,
299 4, 4, 4, 4,
300 5, 5, 5, 5};
301 int src_indices[] = { 0, 1, 4, 5,
302 1, 2, 5, 6,
303 2, 3, 6, 7,
304 4, 5, 8, 9,
305 5, 6, 9,10,
306 6, 7,10,11};
307 double weights[] = {0.1,0.2,0.3,0.4,
308 0.5,0.6,0.7,0.8,
309 0.9,1.0,1.1,1.2,
310 1.3,1.4,1.5,1.6,
311 1.7,1.8,1.9,2.0,
312 2.1,2.2,2.3,2.4};
313 size_t num_links = 24;
314 enum yac_location src_locations[2] = {YAC_LOC_CORNER, YAC_LOC_CELL};
315 enum yac_location tgt_location = YAC_LOC_CORNER;
316 unsigned num_src_fields = 2;
317 int num_links_per_field[2] = {num_links, 0};
318 int * tgt_id_fixed = NULL;
319 size_t num_fixed_tgt = 0;
320 double * fixed_values = NULL;
321 int * num_tgt_per_fixed_value = NULL;
322 size_t num_fixed_values = 0;
323
325 file_name, src_indices, tgt_indices, weights, num_links,
326 src_locations, num_src_fields, num_links_per_field, tgt_id_fixed,
327 num_fixed_tgt, fixed_values, num_tgt_per_fixed_value,
328 num_fixed_values, tgt_location, src_grid_name, tgt_grid_name);
329 }
330
331 double coordinates_x[] = {0.0, 1.0, 2.0, 3.0};
332 double coordinates_y[] = {0.0, 1.0, 2.0};
333 size_t const num_global_cells[2] = {3,2};
334 size_t local_start[2][2] = {{0,0},{2,0}};
335 size_t local_count[2][2] = {{2,2},{1,2}};
336 int with_halo = 1;
337 for (size_t i = 0; i <= num_global_cells[0]; ++i)
339 for (size_t i = 0; i <= num_global_cells[1]; ++i)
341
344 coordinates_x, coordinates_y, num_global_cells,
345 local_start[my_source_rank], local_count[my_source_rank], with_halo);
346
347 struct yac_basic_grid * src_grid =
349 struct yac_basic_grid * tgt_grid =
351
352 struct yac_dist_grid_pair * grid_pair =
353 yac_dist_grid_pair_new(src_grid, tgt_grid, MPI_COMM_WORLD);
354
355 struct yac_interp_field src_fields[] =
356 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
357 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
358 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
360 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
361
362 struct yac_interp_grid * interp_grid =
365
366 //----------------------------------------
367 // test generation of interpolation method
368 //----------------------------------------
369
370 struct interp_method * method_stack[2] = {
374
375 //-----------------
376 // generate weights
377 //-----------------
378
379 struct yac_interp_weights * weights =
380 yac_interp_method_do_search(method_stack, interp_grid);
381
382 yac_interp_method_delete(method_stack);
383
384 enum yac_interp_weights_reorder_type reorder_type[2] =
386
387 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
388 ++i) {
389
390 struct yac_interpolation * interpolation =
392 weights, reorder_type[i], 1,
393 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
394
395 //------------------------------
396 // check generated interpolation
397 //------------------------------
398 {
399 double ** src_fields = xmalloc(1 * sizeof(*src_fields));
400 double *** src_data = &src_fields;
401
402 double * src_field =
403 xmalloc(grid_data.num_vertices * sizeof(*src_field));
404 for (size_t i = 0; i < grid_data.num_vertices; ++i)
405 src_field[i] = (double)(grid_data.vertex_ids[i]);
406 src_fields[0] = src_field;
407
408 yac_interpolation_execute_put(interpolation, src_data);
409
410 free(src_fields[0]);
411 free(src_fields);
412 }
413
414 //---------------
415 // cleanup
416 //---------------
417
418 yac_interpolation_delete(interpolation);
419 }
420
421 //---------------
422 // cleanup
423 //---------------
424
426 yac_interp_grid_delete(interp_grid);
427 yac_dist_grid_pair_delete(grid_pair);
428 yac_basic_grid_delete(tgt_grid);
429 yac_basic_grid_delete(src_grid);
430
431 if (my_source_rank == 0) unlink(file_name);
432 }
433
434 { // simple weight file interpolation (multiple links per target point)
435 // with two source processes and a single target process
436 // there are two source fields and a source mask
437
438 // the global grid has 4x2 cells:
439 // 08--14--09--15--10--16--11
440 // | | | |
441 // 08 03 10 04 12 05 13
442 // | | | |
443 // 04--07--05--09--06--11--07
444 // | | | |
445 // 01 00 03 01 05 02 06
446 // | | | |
447 // 00--00--01--02--02--04--03
448 //
449 // source mask:
450 //
451 // 0-------1-------1-------1
452 // | | | |
453 // | 0 | 1 | 1 |
454 // | | | |
455 // 1-------1-------1-------1
456 // | | | |
457 // | 1 | 1 | 0 |
458 // | | | |
459 // 1-------1-------1-------0
460 //
461 //---------------
462 // setup
463 //---------------
464
465 // create weight file
466 if (my_source_rank == 0) {
467
468 int tgt_indices[] = { 0, 0, 0, 0,
469 1, 1, 1, 1,
470 2, 2, 2, 2,
471 3, 3, 3, 3,
472 4, 4, 4, 4,
473 5, 5, 5, 5};
474 int src_indices[] = { 0, 1, 4, 5,
475 1, 2, 5, 6,
476 2, 3, 6, 7,
477 4, 5, 8, 9,
478 5, 6, 9,10,
479 6, 7,10,11};
480 double weights[] = {0.1,0.2,0.3,0.4,
481 0.5,0.6,0.7,0.8,
482 0.9,1.0,1.1,1.2,
483 1.3,1.4,1.5,1.6,
484 1.7,1.8,1.9,2.0,
485 2.1,2.2,2.3,2.4};
486 size_t num_links = 24;
487 enum yac_location src_locations[2] = {YAC_LOC_CORNER, YAC_LOC_CELL};
488 enum yac_location tgt_location = YAC_LOC_CORNER;
489 unsigned num_src_fields = 2;
490 int num_links_per_field[2] = {num_links, 0};
491 int * tgt_id_fixed = NULL;
492 size_t num_fixed_tgt = 0;
493 double * fixed_values = NULL;
494 int * num_tgt_per_fixed_value = NULL;
495 size_t num_fixed_values = 0;
496
498 file_name, src_indices, tgt_indices, weights, num_links,
499 src_locations, num_src_fields, num_links_per_field, tgt_id_fixed,
500 num_fixed_tgt, fixed_values, num_tgt_per_fixed_value,
501 num_fixed_values, tgt_location, src_grid_name, tgt_grid_name);
502 }
503
504 double coordinates_x[] = {0.0, 1.0, 2.0, 3.0};
505 double coordinates_y[] = {0.0, 1.0, 2.0};
506 size_t const num_global_cells[2] = {3,2};
507 size_t local_start[2][2] = {{0,0},{2,0}};
508 size_t local_count[2][2] = {{2,2},{1,2}};
509 int global_src_vertex_mask[] = {1, 1, 1, 0,
510 1, 1, 1, 1,
511 0, 1, 1, 1};
512 int global_src_cell_mask[] = {1, 1, 0,
513 0, 1, 1};
514 int with_halo = 1;
515 for (size_t i = 0; i <= num_global_cells[0]; ++i)
517 for (size_t i = 0; i <= num_global_cells[1]; ++i)
519
522 coordinates_x, coordinates_y, num_global_cells,
523 local_start[my_source_rank], local_count[my_source_rank], with_halo);
524
525 int * src_vertex_mask = xmalloc(12 * sizeof(*src_vertex_mask));
526 int * src_cell_mask = xmalloc(6 * sizeof(*src_cell_mask));;
527 for (size_t i = 0; i < grid_data.num_vertices; ++i)
528 src_vertex_mask[i] =
529 global_src_vertex_mask[grid_data.vertex_ids[i]];
530 for (size_t i = 0; i < grid_data.num_cells; ++i)
531 src_cell_mask[i] =
532 global_src_cell_mask[grid_data.cell_ids[i]];
533
536 src_grid, YAC_LOC_CORNER, src_vertex_mask, NULL);
538 src_grid, YAC_LOC_CELL, src_cell_mask, NULL);
539 struct yac_basic_grid * tgt_grid =
541
542 struct yac_dist_grid_pair * grid_pair =
543 yac_dist_grid_pair_new(src_grid, tgt_grid, MPI_COMM_WORLD);
544 struct yac_interp_field src_fields[] =
545 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = 0},
546 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = 0}};
547 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
549 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
550
551 struct yac_interp_grid * interp_grid =
554
555 //----------------------------------------
556 // test generation of interpolation method
557 //----------------------------------------
558
559 struct interp_method * method_stack[2] = {
563
564 //-----------------
565 // generate weights
566 //-----------------
567
568 struct yac_interp_weights * weights =
569 yac_interp_method_do_search(method_stack, interp_grid);
570
571 yac_interp_method_delete(method_stack);
572
573 enum yac_interp_weights_reorder_type reorder_type[2] =
575
576 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
577 ++i) {
578
579 struct yac_interpolation * interpolation =
581 weights, reorder_type[i], 1,
582 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
583
584 //------------------------------
585 // check generated interpolation
586 //------------------------------
587 {
588 double ** src_fields = xmalloc(1 * sizeof(*src_fields));
589 double *** src_data = &src_fields;
590
591 double * src_field =
592 xmalloc(grid_data.num_vertices * sizeof(*src_field));
593 for (size_t i = 0; i < grid_data.num_vertices; ++i)
594 src_field[i] = (double)(grid_data.vertex_ids[i]);
595 src_fields[0] = src_field;
596
597 yac_interpolation_execute_put(interpolation, src_data);
598
599 free(src_fields[0]);
600 free(src_fields);
601 }
602
603 //---------------
604 // cleanup
605 //---------------
606
607 yac_interpolation_delete(interpolation);
608 }
609
610 //---------------
611 // cleanup
612 //---------------
613
615 yac_interp_grid_delete(interp_grid);
616 yac_dist_grid_pair_delete(grid_pair);
617 yac_basic_grid_delete(tgt_grid);
618 yac_basic_grid_delete(src_grid);
619
620 if (my_source_rank == 0) unlink(file_name);
621 }
622
623 { // simple weight file interpolation (weight file contains no weights and
624 // not fixed target points) with two source processes and
625 // a single target process the source fields have two struct points per
626 // grid
627
628 // the global grid has 4x2 cells:
629 // 08--14--09--15--10--16--11
630 // | | | |
631 // 08 03 10 04 12 05 13
632 // | | | |
633 // 04--07--05--09--06--11--07
634 // | | | |
635 // 01 00 03 01 05 02 06
636 // | | | |
637 // 00--00--01--02--02--04--03
638 //
639 //---------------
640 // setup
641 //---------------
642
643 // create weight file
644 if (my_source_rank == 0) {
645
646 int * tgt_indices = NULL;
647 int * src_indices = NULL;
648 double * weights = NULL;
649 size_t num_links = 0;
650 enum yac_location src_locations[2] = {YAC_LOC_CORNER, YAC_LOC_CELL};
651 enum yac_location tgt_location = YAC_LOC_CORNER;
652 unsigned num_src_fields = 2;
653 int num_links_per_field[2] = {num_links, 0};
654 int * tgt_id_fixed = NULL;
655 size_t num_fixed_tgt = 0;
656 double * fixed_values = NULL;
657 int * num_tgt_per_fixed_value = NULL;
658 size_t num_fixed_values = 0;
659
661 file_name, src_indices, tgt_indices, weights, num_links,
662 src_locations, num_src_fields, num_links_per_field, tgt_id_fixed,
663 num_fixed_tgt, fixed_values, num_tgt_per_fixed_value,
664 num_fixed_values, tgt_location, src_grid_name, tgt_grid_name);
665 }
666
667 double coordinates_x[] = {0.0, 1.0, 2.0, 3.0};
668 double coordinates_y[] = {0.0, 1.0, 2.0};
669 size_t const num_global_cells[2] = {3,2};
670 size_t local_start[2][2] = {{0,0},{2,0}};
671 size_t local_count[2][2] = {{2,2},{1,2}};
672 int with_halo = 1;
673 for (size_t i = 0; i <= num_global_cells[0]; ++i)
675 for (size_t i = 0; i <= num_global_cells[1]; ++i)
677
680 coordinates_x, coordinates_y, num_global_cells,
681 local_start[my_source_rank], local_count[my_source_rank], with_halo);
682
683 struct yac_basic_grid * src_grid =
685 struct yac_basic_grid * tgt_grid =
687
688 struct yac_dist_grid_pair * grid_pair =
689 yac_dist_grid_pair_new(src_grid, tgt_grid, MPI_COMM_WORLD);
690
691 struct yac_interp_field src_fields[] =
692 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
693 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
694 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
696 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
697
698 struct yac_interp_grid * interp_grid =
701
702 //----------------------------------------
703 // test generation of interpolation method
704 //----------------------------------------
705
706 struct interp_method * method_stack[2] = {
710
711 //-----------------
712 // generate weights
713 //-----------------
714
715 struct yac_interp_weights * weights =
716 yac_interp_method_do_search(method_stack, interp_grid);
717
718 yac_interp_method_delete(method_stack);
719
720 enum yac_interp_weights_reorder_type reorder_type[2] =
722
723 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
724 ++i) {
725
726 struct yac_interpolation * interpolation =
728 weights, reorder_type[i], 1,
729 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
730
731 //------------------------------
732 // check generated interpolation
733 //------------------------------
734 {
735 double ** src_fields = xmalloc(1 * sizeof(*src_fields));
736 double *** src_data = &src_fields;
737
738 double * src_field =
739 xmalloc(grid_data.num_vertices * sizeof(*src_field));
740 for (size_t i = 0; i < grid_data.num_vertices; ++i)
741 src_field[i] = (double)(grid_data.vertex_ids[i]);
742 src_fields[0] = src_field;
743
744 yac_interpolation_execute_put(interpolation, src_data);
745
746 free(src_fields[0]);
747 free(src_fields);
748 }
749
750 //---------------
751 // cleanup
752 //---------------
753
754 yac_interpolation_delete(interpolation);
755 }
756
757 //---------------
758 // cleanup
759 //---------------
760
762 yac_interp_grid_delete(interp_grid);
763 yac_dist_grid_pair_delete(grid_pair);
764 yac_basic_grid_delete(tgt_grid);
765 yac_basic_grid_delete(src_grid);
766
767 if (my_source_rank == 0) unlink(file_name);
768 }
769
770 { // simple weight file interpolation (weight file contains only fixed target
771 // points) with two source processes and a single target process
772
773 // the global grid has 4x2 cells:
774 // 08--14--09--15--10--16--11
775 // | | | |
776 // 08 03 10 04 12 05 13
777 // | | | |
778 // 04--07--05--09--06--11--07
779 // | | | |
780 // 01 00 03 01 05 02 06
781 // | | | |
782 // 00--00--01--02--02--04--03
783 //
784 //---------------
785 // setup
786 //---------------
787
788 // create weight file
789 if (my_source_rank == 0) {
790
791 int * tgt_indices = NULL;
792 int * src_indices = NULL;
793 double * weights = NULL;
794 size_t num_links = 0;
795 enum yac_location src_locations[2] = {YAC_LOC_CORNER, YAC_LOC_CELL};
796 enum yac_location tgt_location = YAC_LOC_CORNER;
797 unsigned num_src_fields = 2;
798 int num_links_per_field[2] = {num_links, 0};
799 int tgt_id_fixed[] = {0, 2, 4, 6};
800 size_t num_fixed_tgt = 4;
801 double fixed_values[] = {-1.0, -2.0};
802 int num_tgt_per_fixed_value[] = {1, 3};
803 size_t num_fixed_values = 2;
804
806 file_name, src_indices, tgt_indices, weights, num_links,
807 src_locations, num_src_fields, num_links_per_field, tgt_id_fixed,
808 num_fixed_tgt, fixed_values, num_tgt_per_fixed_value,
809 num_fixed_values, tgt_location, src_grid_name, tgt_grid_name);
810 }
811
812 double coordinates_x[] = {0.0, 1.0, 2.0, 3.0};
813 double coordinates_y[] = {0.0, 1.0, 2.0};
814 size_t const num_global_cells[2] = {3,2};
815 size_t local_start[2][2] = {{0,0},{2,0}};
816 size_t local_count[2][2] = {{2,2},{1,2}};
817 int with_halo = 1;
818 for (size_t i = 0; i <= num_global_cells[0]; ++i)
820 for (size_t i = 0; i <= num_global_cells[1]; ++i)
822
825 coordinates_x, coordinates_y, num_global_cells,
826 local_start[my_source_rank], local_count[my_source_rank], with_halo);
827
828 struct yac_basic_grid * src_grid =
830 struct yac_basic_grid * tgt_grid =
832
833 struct yac_dist_grid_pair * grid_pair =
834 yac_dist_grid_pair_new(src_grid, tgt_grid, MPI_COMM_WORLD);
835
836 struct yac_interp_field src_fields[] =
837 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
838 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
839 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
841 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
842
843 struct yac_interp_grid * interp_grid =
846
847 //----------------------------------------
848 // test generation of interpolation method
849 //----------------------------------------
850
851 struct interp_method * method_stack[2] = {
855
856 //-----------------
857 // generate weights
858 //-----------------
859
860 struct yac_interp_weights * weights =
861 yac_interp_method_do_search(method_stack, interp_grid);
862
863 yac_interp_method_delete(method_stack);
864
865 enum yac_interp_weights_reorder_type reorder_type[2] =
867
868 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
869 ++i) {
870
871 struct yac_interpolation * interpolation =
873 weights, reorder_type[i], 1,
874 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
875
876 //------------------------------
877 // check generated interpolation
878 //------------------------------
879 {
880 double ** src_fields = xmalloc(1 * sizeof(*src_fields));
881 double *** src_data = &src_fields;
882
883 double * src_field =
884 xmalloc(grid_data.num_vertices * sizeof(*src_field));
885 for (size_t i = 0; i < grid_data.num_vertices; ++i)
886 src_field[i] = (double)(grid_data.vertex_ids[i]);
887 src_fields[0] = src_field;
888
889 yac_interpolation_execute_put(interpolation, src_data);
890
891 free(src_fields[0]);
892 free(src_fields);
893 }
894
895 //---------------
896 // cleanup
897 //---------------
898
899 yac_interpolation_delete(interpolation);
900 }
901
902 //---------------
903 // cleanup
904 //---------------
905
907 yac_interp_grid_delete(interp_grid);
908 yac_dist_grid_pair_delete(grid_pair);
909 yac_basic_grid_delete(tgt_grid);
910 yac_basic_grid_delete(src_grid);
911
912 if (my_source_rank == 0) unlink(file_name);
913 }
914
915 { // simple weight file interpolation (weight file contains only fixed target
916 // points) with two source processes and a single target process
917
918 // the global grid has 4x2 cells:
919 // 08--14--09--15--10--16--11
920 // | | | |
921 // 08 03 10 04 12 05 13
922 // | | | |
923 // 04--07--05--09--06--11--07
924 // | | | |
925 // 01 00 03 01 05 02 06
926 // | | | |
927 // 00--00--01--02--02--04--03
928 //
929 //---------------
930 // setup
931 //---------------
932
933 // create weight file
934 if (my_source_rank == 0) {
935
936 int * tgt_indices = NULL;
937 int * src_indices = NULL;
938 double * weights = NULL;
939 size_t num_links = 0;
940 enum yac_location src_locations[] = {YAC_LOC_CORNER};
941 enum yac_location tgt_location = YAC_LOC_EDGE;
942 unsigned num_src_fields = 1;
943 int num_links_per_field[1] = {num_links};
944 int tgt_id_fixed[] = {1,3,5,7,9,11,0,2,4,6,8,10};
945 size_t num_fixed_tgt = 12;
946 double fixed_values[] = {-1.0, -2.0};
947 int num_tgt_per_fixed_value[] = {6, 6};
948 size_t num_fixed_values = 2;
949
951 file_name, src_indices, tgt_indices, weights, num_links,
952 src_locations, num_src_fields, num_links_per_field, tgt_id_fixed,
953 num_fixed_tgt, fixed_values, num_tgt_per_fixed_value,
954 num_fixed_values, tgt_location, src_grid_name, tgt_grid_name);
955 }
956
957 double coordinates_x[] = {0.0, 1.0, 2.0, 3.0};
958 double coordinates_y[] = {0.0, 1.0, 2.0};
959 size_t const num_global_cells[2] = {3,2};
960 size_t local_start[2][2] = {{0,0},{2,0}};
961 size_t local_count[2][2] = {{2,2},{1,2}};
962 int with_halo = 1;
963 for (size_t i = 0; i <= num_global_cells[0]; ++i)
965 for (size_t i = 0; i <= num_global_cells[1]; ++i)
967
970 coordinates_x, coordinates_y, num_global_cells,
971 local_start[my_source_rank], local_count[my_source_rank], with_halo);
972
973 struct yac_basic_grid * src_grid =
975 struct yac_basic_grid * tgt_grid =
977
978 struct yac_dist_grid_pair * grid_pair =
979 yac_dist_grid_pair_new(src_grid, tgt_grid, MPI_COMM_WORLD);
980
981 struct yac_interp_field src_fields[] =
982 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
983 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
985 {.location = YAC_LOC_EDGE, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
986
987 struct yac_interp_grid * interp_grid =
990
991 //----------------------------------------
992 // test generation of interpolation method
993 //----------------------------------------
994
995 struct interp_method * method_stack[2] = {
999
1000 //-----------------
1001 // generate weights
1002 //-----------------
1003
1004 struct yac_interp_weights * weights =
1005 yac_interp_method_do_search(method_stack, interp_grid);
1006
1007 yac_interp_method_delete(method_stack);
1008
1009 enum yac_interp_weights_reorder_type reorder_type[2] =
1011
1012 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
1013 ++i) {
1014
1015 struct yac_interpolation * interpolation =
1017 weights, reorder_type[i], 1,
1018 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
1019
1020 //------------------------------
1021 // check generated interpolation
1022 //------------------------------
1023 {
1024 double ** src_fields = xmalloc(1 * sizeof(*src_fields));
1025 double *** src_data = &src_fields;
1026
1027 double * src_field =
1028 xmalloc(grid_data.num_vertices * sizeof(*src_field));
1029 for (size_t i = 0; i < grid_data.num_vertices; ++i)
1030 src_field[i] = (double)(grid_data.vertex_ids[i]);
1031 src_fields[0] = src_field;
1032
1033 yac_interpolation_execute_put(interpolation, src_data);
1034
1035 free(src_fields[0]);
1036 free(src_fields);
1037 }
1038
1039 //---------------
1040 // cleanup
1041 //---------------
1042
1043 yac_interpolation_delete(interpolation);
1044 }
1045
1046 //---------------
1047 // cleanup
1048 //---------------
1049
1051 yac_interp_grid_delete(interp_grid);
1052 yac_dist_grid_pair_delete(grid_pair);
1053 yac_basic_grid_delete(tgt_grid);
1054 yac_basic_grid_delete(src_grid);
1055
1056 if (my_source_rank == 0) unlink(file_name);
1057 }
1058
1059 { // test with 2 fixed values one of them is NaN
1060
1061 // the global grid has 4x2 cells:
1062 // 08--14--09--15--10--16--11
1063 // | | | |
1064 // 08 03 10 04 12 05 13
1065 // | | | |
1066 // 04--07--05--09--06--11--07
1067 // | | | |
1068 // 01 00 03 01 05 02 06
1069 // | | | |
1070 // 00--00--01--02--02--04--03
1071 //
1072 //---------------
1073 // setup
1074 //---------------
1075
1076 // create weight file
1077 if (my_source_rank == 0) {
1078
1079 int * tgt_indices = NULL;
1080 int * src_indices = NULL;
1081 double * weights = NULL;
1082 size_t num_links = 0;
1083 enum yac_location src_locations[] = {YAC_LOC_CORNER};
1084 enum yac_location tgt_location = YAC_LOC_EDGE;
1085 unsigned num_src_fields = 1;
1086 int num_links_per_field[1] = {num_links};
1087 int tgt_id_fixed[] = {1,3,5,7,9,11,0,2,4,6,8,10};
1088 size_t num_fixed_tgt = 12;
1089 double fixed_values[] = {-1.0, NAN};
1090 int num_tgt_per_fixed_value[] = {6, 6};
1091 size_t num_fixed_values = 2;
1092
1094 file_name, src_indices, tgt_indices, weights, num_links,
1095 src_locations, num_src_fields, num_links_per_field, tgt_id_fixed,
1096 num_fixed_tgt, fixed_values, num_tgt_per_fixed_value,
1097 num_fixed_values, tgt_location, src_grid_name, tgt_grid_name);
1098 }
1099
1100 double coordinates_x[] = {0.0, 1.0, 2.0, 3.0};
1101 double coordinates_y[] = {0.0, 1.0, 2.0};
1102 size_t const num_global_cells[2] = {3,2};
1103 size_t local_start[2][2] = {{0,0},{2,0}};
1104 size_t local_count[2][2] = {{2,2},{1,2}};
1105 int with_halo = 1;
1106 for (size_t i = 0; i <= num_global_cells[0]; ++i)
1107 coordinates_x[i] *= YAC_RAD;
1108 for (size_t i = 0; i <= num_global_cells[1]; ++i)
1109 coordinates_y[i] *= YAC_RAD;
1110
1113 coordinates_x, coordinates_y, num_global_cells,
1114 local_start[my_source_rank], local_count[my_source_rank], with_halo);
1115
1116 struct yac_basic_grid * src_grid =
1118 struct yac_basic_grid * tgt_grid =
1120
1121 struct yac_dist_grid_pair * grid_pair =
1122 yac_dist_grid_pair_new(src_grid, tgt_grid, MPI_COMM_WORLD);
1123
1124 struct yac_interp_field src_fields[] =
1125 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
1126 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
1128 {.location = YAC_LOC_EDGE, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
1129
1130 struct yac_interp_grid * interp_grid =
1133
1134 //----------------------------------------
1135 // test generation of interpolation method
1136 //----------------------------------------
1137
1138 struct interp_method * method_stack[2] = {
1142
1143 //-----------------
1144 // generate weights
1145 //-----------------
1146
1147 struct yac_interp_weights * weights =
1148 yac_interp_method_do_search(method_stack, interp_grid);
1149
1150 yac_interp_method_delete(method_stack);
1151
1152 //-----------------
1153 // test to write and read them again
1154 //-----------------
1156 weights, file_name_2, src_grid_name, tgt_grid_name, 0, 0,
1158
1159 // read weights
1160 struct interp_method * method_stack_file[2] = {
1164 struct yac_interp_weights * weights_from_file =
1165 yac_interp_method_do_search(method_stack_file, interp_grid);
1166 yac_interp_method_delete(method_stack_file);
1167
1168 enum yac_interp_weights_reorder_type reorder_type[2] =
1170
1171 for (int from_file = 0; from_file <= 1; ++from_file) {
1172 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
1173 ++i) {
1174
1175 struct yac_interpolation * interpolation =
1177 (from_file)?weights_from_file:weights,
1178 reorder_type[i], 1,
1179 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
1180
1181 //------------------------------
1182 // check generated interpolation
1183 //------------------------------
1184 {
1185 double ** src_fields = xmalloc(1 * sizeof(*src_fields));
1186 double *** src_data = &src_fields;
1187
1188 double * src_field =
1189 xmalloc(grid_data.num_vertices * sizeof(*src_field));
1190 for (size_t i = 0; i < grid_data.num_vertices; ++i)
1191 src_field[i] = (double)(grid_data.vertex_ids[i]);
1192 src_fields[0] = src_field;
1193
1194 yac_interpolation_execute_put(interpolation, src_data);
1195
1196 free(src_fields[0]);
1197 free(src_fields);
1198 }
1199
1200 //---------------
1201 // cleanup
1202 //---------------
1203
1204 yac_interpolation_delete(interpolation);
1205 }
1206 }
1207
1208 //---------------
1209 // cleanup
1210 //---------------
1211
1213 yac_interp_grid_delete(interp_grid);
1214 yac_dist_grid_pair_delete(grid_pair);
1215 yac_basic_grid_delete(tgt_grid);
1216 yac_basic_grid_delete(src_grid);
1217
1218 if (my_source_rank == 0) unlink(file_name);
1219 if (my_source_rank == 0) unlink(file_name_2);
1220 }
1221
1222 { // multi source field weight file interpolation
1223 // with two source processes and a single target process
1224
1225 // the global grid has 2x2 cells:
1226 // 06--10--07--11--08
1227 // | | |
1228 // 06 02 08 03 09
1229 // | | |
1230 // 03--05--04--07--05
1231 // | | |
1232 // 01 00 03 01 04
1233 // | | |
1234 // 00--00--01--02--02
1235 //
1236 //---------------
1237 // setup
1238 //---------------
1239
1240 // weight_type == 0 => weights have different values
1241 // weight_type == 1 => all weights have the value 1.0
1242 // weight_type == 2 => each target gets assigned a value
1243 // from a single source point (from
1244 // varying source field)
1245 for (int weight_type = 0; weight_type <= 2; ++weight_type) {
1246
1247 // create weight file
1248 if (my_source_rank == 0) {
1249
1250 int src_indices[3][36] = {{0,1,2,3,
1251 0,1,3,4, 1,2,4,5, 3,4,6,7, 4,5,7,8,
1252 0,1,3,5, 2,3,4,7, 5,6,8,10, 7,8,9,11},
1253 {0,1,2,3,
1254 0,1,3,4, 1,2,4,5, 3,4,6,7, 4,5,7,8,
1255 0,1,3,5, 2,3,4,7, 5,6,8,10, 7,8,9,11},
1256 {1,2,
1257 4,
1258 11}};
1259 int tgt_indices[3][36] = {{0,1,2,3,
1260 0,0,0,0, 1,1,1,1, 2,2,2,2, 3,3,3,3,
1261 0,0,0,0, 1,1,1,1, 2,2,2,2, 3,3,3,3},
1262 {0,1,2,3,
1263 0,0,0,0, 1,1,1,1, 2,2,2,2, 3,3,3,3,
1264 0,0,0,0, 1,1,1,1, 2,2,2,2, 3,3,3,3},
1265 {1,2,
1266 0,
1267 3}};
1268 double weights[3][36] = {{1,1,1,1,
1269 0.25,0.25,0.25,0.25, 0.25,0.25,0.25,0.25,
1270 0.25,0.25,0.25,0.25, 0.25,0.25,0.25,0.25,
1271 0.25,0.25,0.25,0.25, 0.25,0.25,0.25,0.25,
1272 0.25,0.25,0.25,0.25, 0.25,0.25,0.25,0.25},
1273 {1,1,1,1,
1274 1,1,1,1, 1,1,1,1,
1275 1,1,1,1, 1,1,1,1,
1276 1,1,1,1, 1,1,1,1,
1277 1,1,1,1, 1,1,1,1},
1278 {1,1,1,1}};
1279 size_t num_links[3] = {1*4 + 4*4 + 4*4,
1280 1*4 + 4*4 + 4*4,
1281 1*2 + 1*1 + 1*1};
1282 enum yac_location src_locations[3] =
1284 enum yac_location tgt_location = YAC_LOC_CORNER;
1285 unsigned num_src_fields = 3;
1286 int num_links_per_field[3][3] = {{1*4, 4*4, 4*4},
1287 {1*4, 4*4, 4*4},
1288 {2, 1, 1}};
1289 int * tgt_id_fixed = NULL;
1290 size_t num_fixed_tgt = 0;
1291 double * fixed_values = NULL;
1292 int * num_tgt_per_fixed_value = NULL;
1293 size_t num_fixed_values = 0;
1294
1296 file_name, src_indices[weight_type], tgt_indices[weight_type],
1297 weights[weight_type], num_links[weight_type], src_locations,
1298 num_src_fields, num_links_per_field[weight_type], tgt_id_fixed,
1299 num_fixed_tgt, fixed_values, num_tgt_per_fixed_value,
1300 num_fixed_values, tgt_location, src_grid_name, tgt_grid_name);
1301 }
1302
1303 double coordinates_x[] = {0.0, 1.0, 2.0};
1304 double coordinates_y[] = {0.0, 1.0, 2.0};
1305 size_t const num_global_cells[2] = {2,2};
1306 size_t local_start[2][2] = {{0,0},{1,0}};
1307 size_t local_count[2][2] = {{1,2},{1,2}};
1308 int with_halo = 1;
1309 for (size_t i = 0; i <= num_global_cells[0]; ++i)
1310 coordinates_x[i] *= YAC_RAD;
1311 for (size_t i = 0; i <= num_global_cells[1]; ++i)
1312 coordinates_y[i] *= YAC_RAD;
1313
1316 coordinates_x, coordinates_y, num_global_cells,
1317 local_start[my_source_rank], local_count[my_source_rank], with_halo);
1318
1319 struct yac_basic_grid * src_grid =
1321 struct yac_basic_grid * tgt_grid =
1323
1324 struct yac_dist_grid_pair * grid_pair =
1325 yac_dist_grid_pair_new(src_grid, tgt_grid, MPI_COMM_WORLD);
1326
1327 struct yac_interp_field src_fields[] =
1328 {{.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
1329 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
1330 {.location = YAC_LOC_EDGE, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
1331 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
1333 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
1334
1335 struct yac_interp_grid * interp_grid =
1338
1339 //----------------------------------------
1340 // test generation of interpolation method
1341 //----------------------------------------
1342
1343 //-----------------
1344 // generate weights
1345 //-----------------
1346
1347 struct interp_method * method_stack[2] = {
1351 struct yac_interp_weights * weights =
1352 yac_interp_method_do_search(method_stack, interp_grid);
1353 yac_interp_method_delete(method_stack);
1354
1355 // write weights to file
1356
1358 weights, file_name_2, src_grid_name, tgt_grid_name, 0, 0,
1360
1361 // read weights
1362 struct interp_method * method_stack_file[2] = {
1366 struct yac_interp_weights * weights_from_file =
1367 yac_interp_method_do_search(method_stack_file, interp_grid);
1368 yac_interp_method_delete(method_stack_file);
1369
1370 enum yac_interp_weights_reorder_type reorder_type[2] =
1372
1373 for (int from_file = 0; from_file <= 1; ++from_file) {
1374
1375 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
1376 ++i) {
1377
1378 for (size_t collection_size = 1; collection_size <= 16;
1379 collection_size *= 2) {
1380
1381 struct yac_interpolation * interpolation =
1383 (from_file)?weights_from_file:weights,
1384 reorder_type[i], collection_size,
1385 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
1386
1387 //------------------------------
1388 // check generated interpolation
1389 //------------------------------
1390 {
1391 double *** src_data = xmalloc(collection_size * sizeof(*src_data));
1392
1393 for (size_t collection_idx = 0; collection_idx < collection_size;
1394 ++collection_idx) {
1395
1396 double ** src_fields = xmalloc(3 * sizeof(*src_fields));
1397 src_data[collection_idx] = src_fields;
1398
1399 {
1400 double * src_field =
1401 xmalloc(grid_data.num_cells * sizeof(*src_field));
1402 for (size_t i = 0; i < grid_data.num_cells; ++i)
1403 src_field[i] =
1404 (double)(grid_data.cell_ids[i] + 10 * collection_idx) + 0.0;
1405 src_fields[0] = src_field;
1406 }
1407 {
1408 double * src_field =
1409 xmalloc(grid_data.num_vertices * sizeof(*src_field));
1410 for (size_t i = 0; i < grid_data.num_vertices; ++i)
1411 src_field[i] =
1412 (double)(grid_data.vertex_ids[i] + 10 * collection_idx) + 0.3;
1413 src_fields[1] = src_field;
1414 }
1415 {
1416 double * src_field =
1417 xmalloc(grid_data.num_edges * sizeof(*src_field));
1418 for (size_t i = 0; i < grid_data.num_edges; ++i)
1419 src_field[i] =
1420 (double)(grid_data.edge_ids[i] + 10 * collection_idx) + 0.7;
1421 src_fields[2] = src_field;
1422 }
1423 }
1424
1425 yac_interpolation_execute_put(interpolation, src_data);
1426
1427 for (size_t collection_idx = 0; collection_idx < collection_size;
1428 ++collection_idx) {
1429 for (size_t i = 0; i < 3; ++i) free(src_data[collection_idx][i]);
1430 free(src_data[collection_idx]);
1431 }
1432 free(src_data);
1433 }
1434
1435 //---------------
1436 // cleanup
1437 //---------------
1438
1439 yac_interpolation_delete(interpolation);
1440 }
1441 }
1442 }
1443
1444 //---------------
1445 // cleanup
1446 //---------------
1447
1448 yac_interp_weights_delete(weights_from_file);
1450 yac_interp_grid_delete(interp_grid);
1451 yac_dist_grid_pair_delete(grid_pair);
1452 yac_basic_grid_delete(tgt_grid);
1453 yac_basic_grid_delete(src_grid);
1454
1455 if (my_source_rank == 0) {
1456 unlink(file_name);
1457 unlink(file_name_2);
1458 }
1459 }
1460 }
1461
1462 { // multi source field weight file interpolation
1463 // with two source processes and a single target process
1464
1465 // the global source grid is a 4x4 grid:
1466 //
1467 // 20--36--21--37--22--38--23--39--24
1468 // | | | | |
1469 // 28 12 30 13 32 14 34 15 35
1470 // | | | | |
1471 // 15--27--16--29--17--31--18--33--19
1472 // | | | | |
1473 // 19 08 21 09 23 10 25 11 26
1474 // | | | | |
1475 // 10--18--11--20--12--22--13--24--14
1476 // | | | | |
1477 // 10 04 12 05 14 06 16 07 17
1478 // | | | | |
1479 // 05--09--06--11--07--13--08--15--09
1480 // | | | | |
1481 // 01 00 03 01 05 02 07 03 08
1482 // | | | | |
1483 // 00--00--01--02--02--04--03--06--04
1484 //
1485 //---------------
1486 // setup
1487 //---------------
1488
1489 // create weight file
1490 if (my_source_rank == 0) {
1491
1492 int src_indices[16] = {0,1,4,8,13,14,
1493 8,12,13,17,24,
1494 8,17,25,26,30};
1495 int tgt_indices[16] = {0,1,4,8,13,14,
1496 2,5,6,9,15,
1497 3,7,10,11,12};
1498 double weights[16] = {1,1,1,1,1,1,
1499 1,1,1,1,1,
1500 1,1,1,1,1};
1501 size_t num_links = 16;
1502 enum yac_location src_locations[3] =
1504 enum yac_location tgt_location = YAC_LOC_CELL;
1505 unsigned num_src_fields = 3;
1506 int num_links_per_field[3] = {6, 5, 5};
1507 int * tgt_id_fixed = NULL;
1508 size_t num_fixed_tgt = 0;
1509 double * fixed_values = NULL;
1510 int * num_tgt_per_fixed_value = NULL;
1511 size_t num_fixed_values = 0;
1512
1514 file_name, src_indices, tgt_indices, weights, num_links,
1515 src_locations, num_src_fields, num_links_per_field, tgt_id_fixed,
1516 num_fixed_tgt, fixed_values, num_tgt_per_fixed_value,
1517 num_fixed_values, tgt_location, src_grid_name, tgt_grid_name);
1518 }
1519
1520 double coordinates_x[] = {0.0, 1.0, 2.0, 3.0, 4.0};
1521 double coordinates_y[] = {0.0, 1.0, 2.0, 3.0, 4.0};
1522 size_t const num_global_cells[2] = {4,4};
1523 size_t local_start[2][2] = {{0,0},{2,0}};
1524 size_t local_count[2][2] = {{2,4},{2,4}};
1525 int with_halo = 1;
1526 for (size_t i = 0; i <= num_global_cells[0]; ++i)
1527 coordinates_x[i] *= YAC_RAD;
1528 for (size_t i = 0; i <= num_global_cells[1]; ++i)
1529 coordinates_y[i] *= YAC_RAD;
1530
1533 coordinates_x, coordinates_y, num_global_cells,
1534 local_start[my_source_rank], local_count[my_source_rank], with_halo);
1535
1536 struct yac_basic_grid * src_grid =
1538 struct yac_basic_grid * tgt_grid =
1540
1541 struct yac_dist_grid_pair * grid_pair =
1542 yac_dist_grid_pair_new(src_grid, tgt_grid, MPI_COMM_WORLD);
1543
1544 struct yac_interp_field src_fields[] =
1545 {{.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
1546 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
1547 {.location = YAC_LOC_EDGE, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
1548 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
1550 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
1551
1552 struct yac_interp_grid * interp_grid =
1555
1556 //----------------------------------------
1557 // test generation of interpolation method
1558 //----------------------------------------
1559
1560 //-----------------
1561 // generate weights
1562 //-----------------
1563
1564 struct interp_method * method_stack[2] = {
1568 struct yac_interp_weights * weights =
1569 yac_interp_method_do_search(method_stack, interp_grid);
1570 yac_interp_method_delete(method_stack);
1571
1572 // write weights to file
1573
1575 weights, file_name_2, src_grid_name, tgt_grid_name, 0, 0,
1577
1578 // read weights
1579 struct interp_method * method_stack_file[2] = {
1583 struct yac_interp_weights * weights_from_file =
1584 yac_interp_method_do_search(method_stack_file, interp_grid);
1585 yac_interp_method_delete(method_stack_file);
1586
1587 enum yac_interp_weights_reorder_type reorder_type[2] =
1589
1590 for (int from_file = 0; from_file <= 1; ++from_file) {
1591
1592 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
1593 ++i) {
1594
1595 for (size_t collection_size = 1; collection_size <= 16;
1596 collection_size *= 2) {
1597
1598 struct yac_interpolation * interpolation =
1600 (from_file)?weights_from_file:weights,
1601 reorder_type[i], collection_size,
1602 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
1603
1604 //------------------------------
1605 // check generated interpolation
1606 //------------------------------
1607 {
1608 double *** src_data = xmalloc(collection_size * sizeof(*src_data));
1609
1610 for (size_t collection_idx = 0; collection_idx < collection_size;
1611 ++collection_idx) {
1612
1613 double ** src_fields = xmalloc(3 * sizeof(*src_fields));
1614 src_data[collection_idx] = src_fields;
1615
1616 {
1617 double * src_field =
1618 xmalloc(grid_data.num_cells * sizeof(*src_field));
1619 for (size_t i = 0; i < grid_data.num_cells; ++i)
1620 src_field[i] =
1621 (double)(grid_data.cell_ids[i] + 10 * collection_idx) + 0.0;
1622 src_fields[0] = src_field;
1623 }
1624 {
1625 double * src_field =
1626 xmalloc(grid_data.num_vertices * sizeof(*src_field));
1627 for (size_t i = 0; i < grid_data.num_vertices; ++i)
1628 src_field[i] =
1629 (double)(grid_data.vertex_ids[i] + 10 * collection_idx) + 0.3;
1630 src_fields[1] = src_field;
1631 }
1632 {
1633 double * src_field =
1634 xmalloc(grid_data.num_edges * sizeof(*src_field));
1635 for (size_t i = 0; i < grid_data.num_edges; ++i)
1636 src_field[i] =
1637 (double)(grid_data.edge_ids[i] + 10 * collection_idx) + 0.7;
1638 src_fields[2] = src_field;
1639 }
1640 }
1641
1642 yac_interpolation_execute_put(interpolation, src_data);
1643
1644 for (size_t collection_idx = 0; collection_idx < collection_size;
1645 ++collection_idx) {
1646 for (size_t i = 0; i < 3; ++i) free(src_data[collection_idx][i]);
1647 free(src_data[collection_idx]);
1648 }
1649 free(src_data);
1650 }
1651
1652 //---------------
1653 // cleanup
1654 //---------------
1655
1656 yac_interpolation_delete(interpolation);
1657 }
1658 }
1659 }
1660
1661 //---------------
1662 // cleanup
1663 //---------------
1664
1665 yac_interp_weights_delete(weights_from_file);
1667 yac_interp_grid_delete(interp_grid);
1668 yac_dist_grid_pair_delete(grid_pair);
1669 yac_basic_grid_delete(tgt_grid);
1670 yac_basic_grid_delete(src_grid);
1671
1672 if (my_source_rank == 0) {
1673 unlink(file_name);
1674 unlink(file_name_2);
1675 }
1676 }
1677
1678 { // check the behaviour of on_success
1679
1680 //---------------
1681 // setup
1682 //---------------
1683
1684 // create weight file (one empty and one with a fixed value)
1685 if (my_source_rank == 0) {
1686
1687 { // empty file
1688 int * tgt_indices = NULL;
1689 int * src_indices = NULL;
1690 double * weights = NULL;
1691 size_t num_links = 0;
1692 enum yac_location src_locations[] = {YAC_LOC_CELL};
1693 enum yac_location tgt_location = YAC_LOC_CELL;
1694 enum {
1695 NUM_SRC_FIELDS = sizeof(src_locations) / sizeof(src_locations[0])};
1696 int num_links_per_field[NUM_SRC_FIELDS] = {num_links};
1697 int * tgt_id_fixed = NULL;
1698 size_t num_fixed_tgt = 0;
1699 double * fixed_values = NULL;
1700 int * num_tgt_per_fixed_value = NULL;
1701 size_t num_fixed_values = 0;
1702
1704 file_name, src_indices, tgt_indices, weights, num_links,
1705 src_locations, NUM_SRC_FIELDS, num_links_per_field, tgt_id_fixed,
1706 num_fixed_tgt, fixed_values, num_tgt_per_fixed_value,
1707 num_fixed_values, tgt_location, src_grid_name, tgt_grid_name);
1708 }
1709
1710 { // file with fixed value
1711 int * tgt_indices = NULL;
1712 int * src_indices = NULL;
1713 double * weights = NULL;
1714 size_t num_links = 0;
1715 enum yac_location src_locations[] = {YAC_LOC_CELL};
1716 enum yac_location tgt_location = YAC_LOC_CELL;
1717 enum {
1718 NUM_SRC_FIELDS = sizeof(src_locations) / sizeof(src_locations[0])};
1719 int num_links_per_field[NUM_SRC_FIELDS] = {num_links};
1720 int tgt_id_fixed[] = {0, 1, 2, 3};
1721 size_t num_fixed_tgt = 4;
1722 double fixed_values[] = {999.0};
1723 int num_tgt_per_fixed_value[] = {4};
1724 size_t num_fixed_values = 1;
1725
1727 file_name_2, src_indices, tgt_indices, weights, num_links,
1728 src_locations, NUM_SRC_FIELDS, num_links_per_field, tgt_id_fixed,
1729 num_fixed_tgt, fixed_values, num_tgt_per_fixed_value,
1730 num_fixed_values, tgt_location, src_grid_name, tgt_grid_name);
1731 }
1732 }
1733
1734 double coordinates_x[] = {0.0, 1.0, 2.0};
1735 double coordinates_y[] = {0.0, 1.0, 2.0};
1736 size_t num_vertices[2] = {3,3};
1737 int cyclic[2] = {0,0};
1738
1739 struct yac_basic_grid * src_grid =
1743
1744 struct yac_dist_grid_pair * grid_pair =
1745 yac_dist_grid_pair_new(src_grid, tgt_grid, MPI_COMM_WORLD);
1746
1747 struct yac_interp_field src_fields[] =
1748 {{.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
1749 enum {NUM_SRC_FIELDS = sizeof(src_fields) / sizeof(src_fields[0])};
1751 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
1752
1753 struct yac_interp_grid * interp_grid =
1756
1757 for (int on_success_idx = 0; on_success_idx < ON_SUCCESS_COUNT;
1758 ++on_success_idx) {
1759
1760 enum yac_interp_file_on_success curr_on_success =
1761 on_success_types[on_success_idx];
1762
1763 //-----------------------------
1764 // generate interpolation stack
1765 //-----------------------------
1766
1767 // the first method reads an empty file and the second
1768 // contains a fixed value
1769 struct interp_method * method_stack[] = {
1771 file_name, YAC_INTERP_FILE_MISSING_ERROR, curr_on_success),
1773 file_name_2, YAC_INTERP_FILE_MISSING_ERROR, curr_on_success),
1774 NULL};
1775
1776 //-----------------
1777 // generate weights
1778 //-----------------
1779
1780 struct yac_interp_weights * weights =
1781 yac_interp_method_do_search(method_stack, interp_grid);
1782
1783 yac_interp_method_delete(method_stack);
1784
1785 enum {COLLECTION_SIZE = 1, NUM_CELLS = 4};
1786 struct yac_interpolation * interpolation =
1789 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
1790
1791 //------------------------------
1792 // check generated interpolation
1793 //------------------------------
1794
1795 double src_data_raw[NUM_CELLS] = {0.0, 0.0, 0.0, 0.0};
1796 double * src_data_fields[NUM_SRC_FIELDS] = {&(src_data_raw[0])};
1797 double ** src_data[COLLECTION_SIZE] = {&(src_data_fields[0])};
1798
1799 yac_interpolation_execute_put(interpolation, src_data);
1800
1801 //---------------
1802 // cleanup
1803 //---------------
1804
1805 yac_interpolation_delete(interpolation);
1807
1808 } // on_success_idx
1809
1810 //---------------
1811 // cleanup
1812 //---------------
1813
1814 yac_interp_grid_delete(interp_grid);
1815 yac_dist_grid_pair_delete(grid_pair);
1816 yac_basic_grid_delete(tgt_grid);
1817 yac_basic_grid_delete(src_grid);
1818
1819 if (my_source_rank == 0) {
1820 unlink(file_name);
1821 unlink(file_name_2);
1822 }
1823 }
1824}
1825
1826static void utest_source_main_abort(MPI_Comm source_comm) {
1827
1828 int my_source_rank;
1829 MPI_Comm_rank(source_comm, &my_source_rank);
1830
1831 { // check the behaviour of on_misssing_file
1832
1833 //---------------
1834 // setup
1835 //---------------
1836
1837 double coordinates_x[] = {0.0, 1.0, 2.0};
1838 double coordinates_y[] = {0.0, 1.0, 2.0};
1839 size_t num_vertices[2] = {3,3};
1840 int cyclic[2] = {0,0};
1841
1842 struct yac_basic_grid * src_grid =
1846
1847 struct yac_dist_grid_pair * grid_pair =
1848 yac_dist_grid_pair_new(src_grid, tgt_grid, MPI_COMM_WORLD);
1849
1850 struct yac_interp_field src_fields[] =
1851 {{.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
1852 enum {NUM_SRC_FIELDS = sizeof(src_fields) / sizeof(src_fields[0])};
1854 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
1855
1856 struct yac_interp_grid * interp_grid =
1859
1862
1863 for (int on_missing_file_idx = 0;
1864 on_missing_file_idx < ON_MISSING_FILE_COUNT; ++on_missing_file_idx) {
1865
1866 enum yac_interp_file_on_missing_file curr_on_missing_file =
1867 on_missing_file_types[on_missing_file_idx];
1868
1869 //-----------------------------
1870 // generate interpolation stack
1871 //-----------------------------
1872
1873 struct interp_method * method_stack[] = {
1875 "missing_file.nc", curr_on_missing_file,
1877 NULL};
1878
1879 //-----------------
1880 // generate weights
1881 //-----------------
1882
1883 struct yac_interp_weights * weights =
1884 yac_interp_method_do_search(method_stack, interp_grid);
1885
1886 int abort_handler_was_called = 0;
1887 MPI_Allreduce(
1888 MPI_IN_PLACE, &abort_handler_was_called, 1,
1889 MPI_INT, MPI_MAX, MPI_COMM_WORLD);
1890
1891 YAC_ASSERT(
1892 (curr_on_missing_file == YAC_INTERP_FILE_MISSING_CONT) ||
1893 (curr_on_missing_file == YAC_INTERP_FILE_MISSING_ERROR),
1894 "ERROR unsupported value for on_missing_file");
1895
1896 switch(curr_on_missing_file) {
1897 default:
1899 if (abort_handler_was_called)
1900 PUT_ERR("error in handling of YAC_INTERP_FILE_MISSING_CONT");
1901 break;
1903 if (!abort_handler_was_called)
1904 PUT_ERR("error in handling of YAC_INTERP_FILE_MISSING_ERROR");
1905 break;
1906 }
1907
1908 if (abort_handler_was_called) {
1909 MPI_Comm_free(&split_comm);
1910 xt_finalize();
1911 MPI_Finalize();
1912 exit(TEST_EXIT_CODE);
1913 }
1914
1915
1916 //---------------
1917 // cleanup
1918 //---------------
1919
1920 yac_interp_method_delete(method_stack);
1922
1923 } // on_success_idx
1924
1925 //---------------
1926 // cleanup
1927 //---------------
1928
1929 yac_interp_grid_delete(interp_grid);
1930 yac_dist_grid_pair_delete(grid_pair);
1931 yac_basic_grid_delete(tgt_grid);
1932 yac_basic_grid_delete(src_grid);
1933 }
1934
1935 // The test above is expected to call the abort handler, hence the code
1936 // should never reach this point. New tests should be added above.
1937 PUT_ERR("test internal error");
1938}
1939
1940static void utest_target_main(MPI_Comm target_comm) {
1941
1942 int my_target_rank;
1943 MPI_Comm_rank(target_comm, &my_target_rank);
1944
1945 { // simple weight file interpolation (one link per target point) with two
1946 // source processes and a single target process the source fields have two
1947 // struct points per grid (the test check how the interpolation
1948 // methods handle NULL target coordinates )
1949
1950 // the global target grid has 2x2 cells:
1951 // 06--10--07--11--08
1952 // | | |
1953 // 06 02 08 03 09
1954 // | | |
1955 // 03--05--04--07--05
1956 // | | |
1957 // 01 00 03 01 04
1958 // | | |
1959 // 00--00--01--02--02
1960 //
1961 //---------------
1962 // setup
1963 //---------------
1964
1965 double coordinates_x[] = {0.5, 1.5, 2.5};
1966 double coordinates_y[] = {0.5, 1.5, 2.5};
1967 size_t const num_global_cells[2] = {2,2};
1968 size_t local_start[2] = {0,0};
1969 size_t local_count[2] = {2,2};
1970 int with_halo = 0;
1971 for (size_t i = 0; i <= num_global_cells[0]; ++i)
1972 coordinates_x[i] *= YAC_RAD;
1973 for (size_t i = 0; i <= num_global_cells[1]; ++i)
1974 coordinates_y[i] *= YAC_RAD;
1975
1978 coordinates_x, coordinates_y, num_global_cells,
1979 local_start, local_count, with_halo);
1980
1981 struct yac_basic_grid * tgt_grid =
1983 struct yac_basic_grid * src_grid =
1985
1986 struct yac_dist_grid_pair * grid_pair =
1987 yac_dist_grid_pair_new(tgt_grid, src_grid, MPI_COMM_WORLD);
1988
1989 struct yac_interp_field src_fields[] =
1990 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = 0},
1991 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
1992 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
1994 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
1995
1996 struct yac_interp_grid * interp_grid =
1999
2000 //----------------------------------------
2001 // test generation of interpolation method
2002 //----------------------------------------
2003
2004 struct interp_method * method_stack[2] = {
2008
2009 //-----------------
2010 // generate weights
2011 //-----------------
2012
2013 struct yac_interp_weights * weights =
2014 yac_interp_method_do_search(method_stack, interp_grid);
2015
2016 yac_interp_method_delete(method_stack);
2017
2018 enum yac_interp_weights_reorder_type reorder_type[2] =
2020
2021 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
2022 ++i) {
2023 for (size_t collection_size = 1; collection_size < 4;
2024 collection_size += 2) {
2025
2026 struct yac_interpolation * interpolation =
2028 weights, reorder_type[i], collection_size,
2029 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
2030
2031 //------------------------------
2032 // check generated interpolation
2033 //------------------------------
2034
2035 double ** tgt_data = xmalloc(collection_size * sizeof(*tgt_data));
2036 for (size_t collection_idx = 0; collection_idx < collection_size;
2037 ++collection_idx) {
2038 tgt_data[collection_idx] =
2039 xmalloc(grid_data.num_vertices * sizeof(**tgt_data));
2040 for (size_t i = 0; i < grid_data.num_vertices; ++i)
2041 tgt_data[collection_idx][i] = -1;
2042 }
2043
2044 yac_interpolation_execute_get(interpolation, tgt_data);
2045
2046 for (size_t collection_idx = 0; collection_idx < collection_size;
2047 ++collection_idx)
2048 for (size_t i = 0; i < grid_data.num_vertices; ++i)
2049 if (i >= 6) {
2050 if (tgt_data[collection_idx][i] != -1.0)
2051 PUT_ERR("wrong interpolation result");
2052 } else if (fabs((double)(i * (i + 12 * collection_idx)) -
2053 tgt_data[collection_idx][i]) > 1e-9) {
2054 PUT_ERR("wrong interpolation result");
2055 }
2056
2057 for (size_t collection_idx = 0; collection_idx < collection_size;
2058 ++collection_idx)
2059 free(tgt_data[collection_idx]);
2060 free(tgt_data);
2061
2062 //---------------
2063 // cleanup
2064 //---------------
2065
2066 yac_interpolation_delete(interpolation);
2067 }
2068 }
2069
2070 //---------------
2071 // cleanup
2072 //---------------
2073
2075 yac_interp_grid_delete(interp_grid);
2076 yac_dist_grid_pair_delete(grid_pair);
2077 yac_basic_grid_delete(src_grid);
2078 yac_basic_grid_delete(tgt_grid);
2079 }
2080
2081 { // simple weight file interpolation (multiple links per target point)
2082 // with two source processes and a single target process
2083 // there are two source fields
2084
2085 // the global target grid has 2x2 cells:
2086 // 06--10--07--11--08
2087 // | | |
2088 // 06 02 08 03 09
2089 // | | |
2090 // 03--05--04--07--05
2091 // | | |
2092 // 01 00 03 01 04
2093 // | | |
2094 // 00--00--01--02--02
2095 //
2096 //---------------
2097 // setup
2098 //---------------
2099
2100 double coordinates_x[] = {0.5, 1.5, 2.5};
2101 double coordinates_y[] = {0.5, 1.5, 2.5};
2102 size_t const num_global_cells[2] = {2,2};
2103 size_t local_start[2] = {0,0};
2104 size_t local_count[2] = {2,2};
2105 int with_halo = 0;
2106 for (size_t i = 0; i <= num_global_cells[0]; ++i)
2107 coordinates_x[i] *= YAC_RAD;
2108 for (size_t i = 0; i <= num_global_cells[1]; ++i)
2109 coordinates_y[i] *= YAC_RAD;
2110
2113 coordinates_x, coordinates_y, num_global_cells,
2114 local_start, local_count, with_halo);
2115
2116 struct yac_basic_grid * tgt_grid =
2118 struct yac_basic_grid * src_grid =
2120
2121 struct yac_dist_grid_pair * grid_pair =
2122 yac_dist_grid_pair_new(tgt_grid, src_grid, MPI_COMM_WORLD);
2123
2124 struct yac_interp_field src_fields[] =
2125 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
2126 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
2127 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
2129 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
2130
2131 struct yac_interp_grid * interp_grid =
2134
2135 //----------------------------------------
2136 // test generation of interpolation method
2137 //----------------------------------------
2138
2139 struct interp_method * method_stack[2] = {
2143
2144 //-----------------
2145 // generate weights
2146 //-----------------
2147
2148 struct yac_interp_weights * weights =
2149 yac_interp_method_do_search(method_stack, interp_grid);
2150
2151 yac_interp_method_delete(method_stack);
2152
2153 enum yac_interp_weights_reorder_type reorder_type[2] =
2155
2156 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
2157 ++i) {
2158
2159 struct yac_interpolation * interpolation =
2161 weights, reorder_type[i], 1,
2162 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
2163
2164 //------------------------------
2165 // check generated interpolation
2166 //------------------------------
2167
2168 double ** tgt_data = xmalloc(1 * sizeof(*tgt_data));
2169 tgt_data[0] =
2170 xmalloc(grid_data.num_vertices * sizeof(**tgt_data));
2171 for (size_t i = 0; i < grid_data.num_vertices; ++i)
2172 tgt_data[0][i] = -1;
2173
2174 double ref_tgt_field[9] =
2175 {0.1*0+0.2*1+0.3*4+0.4*5,
2176 0.5*1+0.6*2+0.7*5+0.8*6,
2177 0.9*2+1.0*3+1.1*6+1.2*7,
2178 1.3*4+1.4*5+1.5*8+1.6*9,
2179 1.7*5+1.8*6+1.9*9+2.0*10,
2180 2.1*6+2.2*7+2.3*10+2.4*11,
2181 -1,-1,-1};
2182
2183 yac_interpolation_execute_get(interpolation, tgt_data);
2184
2185 for (size_t i = 0; i < grid_data.num_vertices; ++i)
2186 if (i >= 6) {
2187 if (tgt_data[0][i] != -1.0)
2188 PUT_ERR("wrong interpolation result");
2189 } else if (fabs(ref_tgt_field[i] - tgt_data[0][i]) > 1e-9) {
2190 PUT_ERR("wrong interpolation result");
2191 }
2192
2193 free(tgt_data[0]);
2194 free(tgt_data);
2195
2196 //---------------
2197 // cleanup
2198 //---------------
2199
2200 yac_interpolation_delete(interpolation);
2201 }
2202
2203 //---------------
2204 // cleanup
2205 //---------------
2206
2208 yac_interp_grid_delete(interp_grid);
2209 yac_dist_grid_pair_delete(grid_pair);
2210 yac_basic_grid_delete(src_grid);
2211 yac_basic_grid_delete(tgt_grid);
2212 }
2213
2214 { // simple weight file interpolation (multiple links per target point)
2215 // with two source processes and a single target process
2216 // there are two source fields and source masks
2217
2218 // the global target grid has 2x2 cells:
2219 // 06--10--07--11--08
2220 // | | |
2221 // 06 02 08 03 09
2222 // | | |
2223 // 03--05--04--07--05
2224 // | | |
2225 // 01 00 03 01 04
2226 // | | |
2227 // 00--00--01--02--02
2228 //
2229 //---------------
2230 // setup
2231 //---------------
2232
2233 double coordinates_x[] = {0.5, 1.5, 2.5};
2234 double coordinates_y[] = {0.5, 1.5, 2.5};
2235 size_t const num_global_cells[2] = {2,2};
2236 size_t local_start[2] = {0,0};
2237 size_t local_count[2] = {2,2};
2238 int with_halo = 0;
2239 for (size_t i = 0; i <= num_global_cells[0]; ++i)
2240 coordinates_x[i] *= YAC_RAD;
2241 for (size_t i = 0; i <= num_global_cells[1]; ++i)
2242 coordinates_y[i] *= YAC_RAD;
2243
2246 coordinates_x, coordinates_y, num_global_cells,
2247 local_start, local_count, with_halo);
2248
2249 struct yac_basic_grid * tgt_grid =
2251 struct yac_basic_grid * src_grid =
2253
2254 struct yac_dist_grid_pair * grid_pair =
2255 yac_dist_grid_pair_new(tgt_grid, src_grid, MPI_COMM_WORLD);
2256
2257 struct yac_interp_field src_fields[] =
2258 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = 0},
2259 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = 0}};
2260 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
2262 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
2263
2264 struct yac_interp_grid * interp_grid =
2267
2268 //----------------------------------------
2269 // test generation of interpolation method
2270 //----------------------------------------
2271
2272 struct interp_method * method_stack[2] = {
2276
2277 //-----------------
2278 // generate weights
2279 //-----------------
2280
2281 struct yac_interp_weights * weights =
2282 yac_interp_method_do_search(method_stack, interp_grid);
2283
2284 yac_interp_method_delete(method_stack);
2285
2286 enum yac_interp_weights_reorder_type reorder_type[2] =
2288
2289 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
2290 ++i) {
2291
2292 struct yac_interpolation * interpolation =
2294 weights, reorder_type[i], 1,
2295 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
2296
2297 //------------------------------
2298 // check generated interpolation
2299 //------------------------------
2300
2301 double ** tgt_data = xmalloc(1 * sizeof(*tgt_data));
2302 tgt_data[0] =
2303 xmalloc(grid_data.num_vertices * sizeof(**tgt_data));
2304 for (size_t i = 0; i < grid_data.num_vertices; ++i)
2305 tgt_data[0][i] = -1;
2306
2307 double ref_tgt_field[9] =
2308 {0.1*0+0.2*1+0.3*4+0.4*5,
2309 0.5*1+0.6*2+0.7*5+0.8*6,
2310 -1,
2311 -1,
2312 1.7*5+1.8*6+1.9*9+2.0*10,
2313 2.1*6+2.2*7+2.3*10+2.4*11,
2314 -1,-1,-1};
2315
2316 yac_interpolation_execute_get(interpolation, tgt_data);
2317
2318 for (size_t i = 0; i < grid_data.num_vertices; ++i)
2319 if (i >= 6) {
2320 if (tgt_data[0][i] != -1.0)
2321 PUT_ERR("wrong interpolation result");
2322 } else if (fabs(ref_tgt_field[i] - tgt_data[0][i]) > 1e-9) {
2323 PUT_ERR("wrong interpolation result");
2324 }
2325
2326 free(tgt_data[0]);
2327 free(tgt_data);
2328
2329 //---------------
2330 // cleanup
2331 //---------------
2332
2333 yac_interpolation_delete(interpolation);
2334 }
2335
2336 //---------------
2337 // cleanup
2338 //---------------
2339
2341 yac_interp_grid_delete(interp_grid);
2342 yac_dist_grid_pair_delete(grid_pair);
2343 yac_basic_grid_delete(src_grid);
2344 yac_basic_grid_delete(tgt_grid);
2345 }
2346
2347 { // simple weight file interpolation (weight file contains only fixed target
2348 // points) with two source processes and a single target process
2349
2350 // the global target grid has 2x2 cells:
2351 // 06--10--07--11--08
2352 // | | |
2353 // 06 02 08 03 09
2354 // | | |
2355 // 03--05--04--07--05
2356 // | | |
2357 // 01 00 03 01 04
2358 // | | |
2359 // 00--00--01--02--02
2360 //
2361 //---------------
2362 // setup
2363 //---------------
2364
2365 double coordinates_x[] = {0.5, 1.5, 2.5};
2366 double coordinates_y[] = {0.5, 1.5, 2.5};
2367 size_t const num_global_cells[2] = {2,2};
2368 size_t local_start[2] = {0,0};
2369 size_t local_count[2] = {2,2};
2370 int with_halo = 0;
2371 for (size_t i = 0; i <= num_global_cells[0]; ++i)
2372 coordinates_x[i] *= YAC_RAD;
2373 for (size_t i = 0; i <= num_global_cells[1]; ++i)
2374 coordinates_y[i] *= YAC_RAD;
2375
2378 coordinates_x, coordinates_y, num_global_cells,
2379 local_start, local_count, with_halo);
2380
2381 struct yac_basic_grid * tgt_grid =
2383 struct yac_basic_grid * src_grid =
2385
2386 struct yac_dist_grid_pair * grid_pair =
2387 yac_dist_grid_pair_new(tgt_grid, src_grid, MPI_COMM_WORLD);
2388
2389 struct yac_interp_field src_fields[] =
2390 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
2391 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
2392 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
2394 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
2395
2396 struct yac_interp_grid * interp_grid =
2399
2400 //----------------------------------------
2401 // test generation of interpolation method
2402 //----------------------------------------
2403
2404 struct interp_method * method_stack[2] = {
2408
2409 //-----------------
2410 // generate weights
2411 //-----------------
2412
2413 struct yac_interp_weights * weights =
2414 yac_interp_method_do_search(method_stack, interp_grid);
2415
2416 yac_interp_method_delete(method_stack);
2417
2418 enum yac_interp_weights_reorder_type reorder_type[2] =
2420
2421 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
2422 ++i) {
2423
2424 struct yac_interpolation * interpolation =
2426 weights, reorder_type[i], 1,
2427 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
2428
2429 //------------------------------
2430 // check generated interpolation
2431 //------------------------------
2432
2433 double ** tgt_data = xmalloc(1 * sizeof(*tgt_data));
2434 tgt_data[0] =
2435 xmalloc(grid_data.num_vertices * sizeof(**tgt_data));
2436 for (size_t i = 0; i < grid_data.num_vertices; ++i)
2437 tgt_data[0][i] = -1;
2438
2439 yac_interpolation_execute_get(interpolation, tgt_data);
2440
2441 for (size_t i = 0; i < grid_data.num_vertices; ++i)
2442 if (tgt_data[0][i] != -1.0)
2443 PUT_ERR("wrong interpolation result");
2444
2445 free(tgt_data[0]);
2446 free(tgt_data);
2447
2448 //---------------
2449 // cleanup
2450 //---------------
2451
2452 yac_interpolation_delete(interpolation);
2453 }
2454
2455 //---------------
2456 // cleanup
2457 //---------------
2458
2460 yac_interp_grid_delete(interp_grid);
2461 yac_dist_grid_pair_delete(grid_pair);
2462 yac_basic_grid_delete(src_grid);
2463 yac_basic_grid_delete(tgt_grid);
2464 }
2465
2466 { // simple weight file interpolation (weight file contains only fixed target
2467 // points) with two source processes and a single target process
2468
2469 // the global target grid has 2x2 cells:
2470 // 06--10--07--11--08
2471 // | | |
2472 // 06 02 08 03 09
2473 // | | |
2474 // 03--05--04--07--05
2475 // | | |
2476 // 01 00 03 01 04
2477 // | | |
2478 // 00--00--01--02--02
2479 //
2480 //---------------
2481 // setup
2482 //---------------
2483
2484 double coordinates_x[] = {0.5, 1.5, 2.5};
2485 double coordinates_y[] = {0.5, 1.5, 2.5};
2486 size_t const num_global_cells[2] = {2,2};
2487 size_t local_start[2] = {0,0};
2488 size_t local_count[2] = {2,2};
2489 int with_halo = 0;
2490 for (size_t i = 0; i <= num_global_cells[0]; ++i)
2491 coordinates_x[i] *= YAC_RAD;
2492 for (size_t i = 0; i <= num_global_cells[1]; ++i)
2493 coordinates_y[i] *= YAC_RAD;
2494
2497 coordinates_x, coordinates_y, num_global_cells,
2498 local_start, local_count, with_halo);
2499
2500 struct yac_basic_grid * tgt_grid =
2502 struct yac_basic_grid * src_grid =
2504
2505 struct yac_dist_grid_pair * grid_pair =
2506 yac_dist_grid_pair_new(tgt_grid, src_grid, MPI_COMM_WORLD);
2507
2508 struct yac_interp_field src_fields[] =
2509 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
2510 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
2511 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
2513 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
2514
2515 struct yac_interp_grid * interp_grid =
2518
2519 //----------------------------------------
2520 // test generation of interpolation method
2521 //----------------------------------------
2522
2523 struct interp_method * method_stack[2] = {
2527
2528 //-----------------
2529 // generate weights
2530 //-----------------
2531
2532 struct yac_interp_weights * weights =
2533 yac_interp_method_do_search(method_stack, interp_grid);
2534
2535 yac_interp_method_delete(method_stack);
2536
2537 enum yac_interp_weights_reorder_type reorder_type[2] =
2539
2540 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
2541 ++i) {
2542
2543 struct yac_interpolation * interpolation =
2545 weights, reorder_type[i], 1,
2546 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
2547
2548 //------------------------------
2549 // check generated interpolation
2550 //------------------------------
2551
2552 double ** tgt_data = xmalloc(1 * sizeof(*tgt_data));
2553 tgt_data[0] =
2554 xmalloc(grid_data.num_vertices * sizeof(**tgt_data));
2555 for (size_t i = 0; i < grid_data.num_vertices; ++i) tgt_data[0][i] = -3;
2556
2557 double ref_tgt_field[9] =
2558 {-1,-3,-2, -3,-2,-3, -2,-3,-3};
2559
2560 yac_interpolation_execute_get(interpolation, tgt_data);
2561
2562 for (size_t i = 0; i < grid_data.num_vertices; ++i)
2563 if (ref_tgt_field[i] != tgt_data[0][i])
2564 PUT_ERR("wrong interpolation result");
2565
2566 free(tgt_data[0]);
2567 free(tgt_data);
2568
2569 //---------------
2570 // cleanup
2571 //---------------
2572
2573 yac_interpolation_delete(interpolation);
2574 }
2575
2576 //---------------
2577 // cleanup
2578 //---------------
2579
2581 yac_interp_grid_delete(interp_grid);
2582 yac_dist_grid_pair_delete(grid_pair);
2583 yac_basic_grid_delete(src_grid);
2584 yac_basic_grid_delete(tgt_grid);
2585 }
2586
2587 { // simple weight file interpolation (weight file contains only fixed target
2588 // points) with two source processes and a single target process
2589
2590 // the global target grid has 2x2 cells:
2591 // 06--10--07--11--08
2592 // | | |
2593 // 06 02 08 03 09
2594 // | | |
2595 // 03--05--04--07--05
2596 // | | |
2597 // 01 00 03 01 04
2598 // | | |
2599 // 00--00--01--02--02
2600 //
2601 //---------------
2602 // setup
2603 //---------------
2604
2605 double coordinates_x[] = {0.5, 1.5, 2.5};
2606 double coordinates_y[] = {0.5, 1.5, 2.5};
2607 size_t const num_global_cells[2] = {2,2};
2608 size_t local_start[2] = {0,0};
2609 size_t local_count[2] = {2,2};
2610 int with_halo = 0;
2611 for (size_t i = 0; i <= num_global_cells[0]; ++i)
2612 coordinates_x[i] *= YAC_RAD;
2613 for (size_t i = 0; i <= num_global_cells[1]; ++i)
2614 coordinates_y[i] *= YAC_RAD;
2615
2618 coordinates_x, coordinates_y, num_global_cells,
2619 local_start, local_count, with_halo);
2620
2621 struct yac_basic_grid * tgt_grid =
2623 struct yac_basic_grid * src_grid =
2625
2626 struct yac_dist_grid_pair * grid_pair =
2627 yac_dist_grid_pair_new(tgt_grid, src_grid, MPI_COMM_WORLD);
2628
2629 struct yac_interp_field src_fields[] =
2630 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
2631 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
2633 {.location = YAC_LOC_EDGE, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
2634
2635 struct yac_interp_grid * interp_grid =
2638
2639 //----------------------------------------
2640 // test generation of interpolation method
2641 //----------------------------------------
2642
2643 struct interp_method * method_stack[2] = {
2647
2648 //-----------------
2649 // generate weights
2650 //-----------------
2651
2652 struct yac_interp_weights * weights =
2653 yac_interp_method_do_search(method_stack, interp_grid);
2654
2655 yac_interp_method_delete(method_stack);
2656
2657 enum yac_interp_weights_reorder_type reorder_type[2] =
2659
2660 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
2661 ++i) {
2662
2663 struct yac_interpolation * interpolation =
2665 weights, reorder_type[i], 1,
2666 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
2667
2668 //------------------------------
2669 // check generated interpolation
2670 //------------------------------
2671
2672 double ** tgt_data = xmalloc(1 * sizeof(*tgt_data));
2673 tgt_data[0] = xmalloc(grid_data.num_edges * sizeof(**tgt_data));
2674 for (size_t i = 0; i < grid_data.num_edges; ++i) tgt_data[0][i] = -3;
2675
2676 double ref_tgt_field[12] = {-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1};
2677
2678 yac_interpolation_execute_get(interpolation, tgt_data);
2679
2680 for (size_t i = 0; i < grid_data.num_edges; ++i)
2681 if (ref_tgt_field[i] != tgt_data[0][i])
2682 PUT_ERR("wrong interpolation result");
2683
2684 free(tgt_data[0]);
2685 free(tgt_data);
2686
2687 //---------------
2688 // cleanup
2689 //---------------
2690
2691 yac_interpolation_delete(interpolation);
2692 }
2693
2694 //---------------
2695 // cleanup
2696 //---------------
2697
2699 yac_interp_grid_delete(interp_grid);
2700 yac_dist_grid_pair_delete(grid_pair);
2701 yac_basic_grid_delete(src_grid);
2702 yac_basic_grid_delete(tgt_grid);
2703 }
2704
2705 { // test with two fixed values one is NaN (on the source side)
2706
2707 // the global target grid has 2x2 cells:
2708 // 06--10--07--11--08
2709 // | | |
2710 // 06 02 08 03 09
2711 // | | |
2712 // 03--05--04--07--05
2713 // | | |
2714 // 01 00 03 01 04
2715 // | | |
2716 // 00--00--01--02--02
2717 //
2718 //---------------
2719 // setup
2720 //---------------
2721
2722 double coordinates_x[] = {0.5, 1.5, 2.5};
2723 double coordinates_y[] = {0.5, 1.5, 2.5};
2724 size_t const num_global_cells[2] = {2,2};
2725 size_t local_start[2] = {0,0};
2726 size_t local_count[2] = {2,2};
2727 int with_halo = 0;
2728 for (size_t i = 0; i <= num_global_cells[0]; ++i)
2729 coordinates_x[i] *= YAC_RAD;
2730 for (size_t i = 0; i <= num_global_cells[1]; ++i)
2731 coordinates_y[i] *= YAC_RAD;
2732
2735 coordinates_x, coordinates_y, num_global_cells,
2736 local_start, local_count, with_halo);
2737
2738 struct yac_basic_grid * tgt_grid =
2740 struct yac_basic_grid * src_grid =
2742
2743 struct yac_dist_grid_pair * grid_pair =
2744 yac_dist_grid_pair_new(tgt_grid, src_grid, MPI_COMM_WORLD);
2745
2746 struct yac_interp_field src_fields[] =
2747 {{.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
2748 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
2750 {.location = YAC_LOC_EDGE, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
2751
2752 struct yac_interp_grid * interp_grid =
2755
2756 //----------------------------------------
2757 // test generation of interpolation method
2758 //----------------------------------------
2759
2760 struct interp_method * method_stack[2] = {
2764
2765 //-----------------
2766 // generate weights
2767 //-----------------
2768
2769 struct yac_interp_weights * weights =
2770 yac_interp_method_do_search(method_stack, interp_grid);
2771
2772 yac_interp_method_delete(method_stack);
2773
2774 // write weights to file
2776 weights, file_name_2, src_grid_name, tgt_grid_name, 0, 0,
2778
2779 // read weights
2780 struct interp_method * method_stack_file[2] = {
2784 struct yac_interp_weights * weights_from_file =
2785 yac_interp_method_do_search(method_stack_file, interp_grid);
2786 yac_interp_method_delete(method_stack_file);
2787
2788 enum yac_interp_weights_reorder_type reorder_type[2] =
2790
2791 for (int from_file = 0; from_file <= 1; ++from_file) {
2792 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
2793 ++i) {
2794
2795 struct yac_interpolation * interpolation =
2797 (from_file)?weights_from_file:weights,
2798 reorder_type[i], 1,
2799 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
2800
2801 //------------------------------
2802 // check generated interpolation
2803 //------------------------------
2804
2805 double ** tgt_data = xmalloc(1 * sizeof(*tgt_data));
2806 tgt_data[0] = xmalloc(grid_data.num_edges * sizeof(**tgt_data));
2807 for (size_t i = 0; i < grid_data.num_edges; ++i) tgt_data[0][i] = -3;
2808
2809 double ref_tgt_field[12] = {NAN,-1,NAN,-1,NAN,-1,NAN,-1,NAN,-1,NAN,-1};
2810
2811 yac_interpolation_execute_get(interpolation, tgt_data);
2812
2813 // use memcmp to handle NaN correctly
2814 for (size_t i = 0; i < grid_data.num_edges; ++i)
2815 if (memcmp(&ref_tgt_field[i], &tgt_data[0][i], sizeof(tgt_data[0][i])))
2816 PUT_ERR("wrong interpolation result");
2817
2818 free(tgt_data[0]);
2819 free(tgt_data);
2820
2821 //---------------
2822 // cleanup
2823 //---------------
2824
2825 yac_interpolation_delete(interpolation);
2826 }
2827 }
2828
2829 //---------------
2830 // cleanup
2831 //---------------
2832
2834 yac_interp_grid_delete(interp_grid);
2835 yac_dist_grid_pair_delete(grid_pair);
2836 yac_basic_grid_delete(src_grid);
2837 yac_basic_grid_delete(tgt_grid);
2838 }
2839
2840 { // multi source field weight file interpolation
2841 // with two source processes and a single target process
2842
2843 // the global target grid has 1x1 cells:
2844 //
2845 // 02--03--03
2846 // | |
2847 // 01 00 02
2848 // | |
2849 // 00--00--01
2850 //
2851 //---------------
2852 // setup
2853 //---------------
2854
2855 // weight_type == 0 => weights have different values
2856 // weight_type == 1 => all weights have the value 1.0
2857 // weight_type == 2 => each target gets assigned a value
2858 // from a single source point (from
2859 // varying source field)
2860 for (int weight_type = 0; weight_type <= 2; ++weight_type) {
2861
2862 double coordinates_x[] = {0.5, 1.5};
2863 double coordinates_y[] = {0.5, 1.5};
2864 size_t const num_global_cells[2] = {1,1};
2865 size_t local_start[2] = {0,0};
2866 size_t local_count[2] = {1,1};
2867 int with_halo = 0;
2868 for (size_t i = 0; i <= num_global_cells[0]; ++i)
2869 coordinates_x[i] *= YAC_RAD;
2870 for (size_t i = 0; i <= num_global_cells[1]; ++i)
2871 coordinates_y[i] *= YAC_RAD;
2872
2875 coordinates_x, coordinates_y, num_global_cells,
2876 local_start, local_count, with_halo);
2877
2878 struct yac_basic_grid * tgt_grid =
2880 struct yac_basic_grid * src_grid =
2882
2883 struct yac_dist_grid_pair * grid_pair =
2884 yac_dist_grid_pair_new(tgt_grid, src_grid, MPI_COMM_WORLD);
2885
2886 struct yac_interp_field src_fields[] =
2887 {{.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
2888 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
2889 {.location = YAC_LOC_EDGE, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
2890 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
2892 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
2893
2894 struct yac_interp_grid * interp_grid =
2897
2898 //----------------------------------------
2899 // test generation of interpolation method
2900 //----------------------------------------
2901
2902 //-----------------
2903 // generate weights
2904 //-----------------
2905
2906 struct interp_method * method_stack[2] = {
2910 struct yac_interp_weights * weights =
2911 yac_interp_method_do_search(method_stack, interp_grid);
2912 yac_interp_method_delete(method_stack);
2913
2914 // write weights to file
2916 weights, file_name_2, src_grid_name, tgt_grid_name, 0, 0,
2918
2919 // read weights
2920 struct interp_method * method_stack_file[2] = {
2924 struct yac_interp_weights * weights_from_file =
2925 yac_interp_method_do_search(method_stack_file, interp_grid);
2926 yac_interp_method_delete(method_stack_file);
2927
2928 enum yac_interp_weights_reorder_type reorder_type[2] =
2930
2931 for (int from_file = 0; from_file <= 1; ++from_file) {
2932
2933 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
2934 ++i) {
2935
2936 for (size_t collection_size = 1; collection_size <= 16;
2937 collection_size *= 2) {
2938
2939 struct yac_interpolation * interpolation =
2941 (from_file)?weights_from_file:weights,
2942 reorder_type[i], collection_size,
2943 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
2944
2945 //------------------------------
2946 // check generated interpolation
2947 //------------------------------
2948
2949 double ** tgt_data = xmalloc(collection_size * sizeof(*tgt_data));
2950 for (size_t collection_idx = 0; collection_idx < collection_size;
2951 ++collection_idx) {
2952 tgt_data[collection_idx] =
2953 xmalloc(grid_data.num_vertices * sizeof(**tgt_data));
2954 for (size_t i = 0; i < grid_data.num_vertices; ++i)
2955 tgt_data[collection_idx][i] = -3;
2956 }
2957
2958 double ref_tgt_field[3][4] =
2959 {{0.0 + 0.25 * (0.3+1.3+3.3+4.3) + 0.25 * (0.7+1.7+3.7+ 5.7),
2960 1.0 + 0.25 * (1.3+2.3+4.3+5.3) + 0.25 * (2.7+3.7+4.7+ 7.7),
2961 2.0 + 0.25 * (3.3+4.3+6.3+7.3) + 0.25 * (5.7+6.7+8.7+10.7),
2962 3.0 + 0.25 * (4.3+5.3+7.3+8.3) + 0.25 * (7.7+8.7+9.7+11.7)},
2963 {0.0 + (0.3+1.3+3.3+4.3) + (0.7+1.7+3.7+ 5.7),
2964 1.0 + (1.3+2.3+4.3+5.3) + (2.7+3.7+4.7+ 7.7),
2965 2.0 + (3.3+4.3+6.3+7.3) + (5.7+6.7+8.7+10.7),
2966 3.0 + (4.3+5.3+7.3+8.3) + (7.7+8.7+9.7+11.7)},
2967 {4.3, 1.0, 2.0, 11.7}};
2968 double collection_factor[3] = {30.0, 90.0, 10.0};
2969
2970 yac_interpolation_execute_get(interpolation, tgt_data);
2971
2972 for (size_t collection_idx = 0; collection_idx < collection_size;
2973 collection_idx++)
2974 for (size_t i = 0; i < grid_data.num_vertices; ++i)
2975 if (fabs((ref_tgt_field[weight_type][i] +
2976 collection_factor[weight_type] *
2977 (double)collection_idx) -
2978 tgt_data[collection_idx][i]) > 1e-9)
2979 PUT_ERR("wrong interpolation result");
2980
2981 for (size_t collection_idx = 0; collection_idx < collection_size;
2982 ++collection_idx) free(tgt_data[collection_idx]);
2983 free(tgt_data);
2984
2985 //---------------
2986 // cleanup
2987 //---------------
2988
2989 yac_interpolation_delete(interpolation);
2990 }
2991 }
2992 }
2993
2994 //---------------
2995 // cleanup
2996 //---------------
2997
2998 yac_interp_weights_delete(weights_from_file);
3000 yac_interp_grid_delete(interp_grid);
3001 yac_dist_grid_pair_delete(grid_pair);
3002 yac_basic_grid_delete(src_grid);
3003 yac_basic_grid_delete(tgt_grid);
3004 }
3005 }
3006
3007 { // multi source field weight file interpolation
3008 // with two source processes and a single target process
3009
3010 // the global target grid is a 4x4 grid:
3011 //
3012 // 20--36--21--37--22--38--23--39--24
3013 // | | | | |
3014 // 28 12 30 13 32 14 34 15 35
3015 // | | | | |
3016 // 15--27--16--29--17--31--18--33--19
3017 // | | | | |
3018 // 19 08 21 09 23 10 25 11 26
3019 // | | | | |
3020 // 10--18--11--20--12--22--13--24--14
3021 // | | | | |
3022 // 10 04 12 05 14 06 16 07 17
3023 // | | | | |
3024 // 05--09--06--11--07--13--08--15--09
3025 // | | | | |
3026 // 01 00 03 01 05 02 07 03 08
3027 // | | | | |
3028 // 00--00--01--02--02--04--03--06--04
3029 //
3030 //---------------
3031 // setup
3032 //---------------
3033
3034 // weight_type == 0 => weights have different values
3035 // weight_type == 1 => all weights have the value 1.0
3036 // weight_type == 2 => each target gets assigned a value
3037 // from a single source point (from
3038 // varying source field)
3039
3040 double coordinates_x[] = {0.0, 1.0, 2.0, 3.0, 4.0};
3041 double coordinates_y[] = {0.0, 1.0, 2.0, 3.0, 4.0};
3042 size_t const num_global_cells[2] = {4,4};
3043 size_t local_start[2] = {0,0};
3044 size_t local_count[2] = {4,4};
3045 int with_halo = 0;
3046 for (size_t i = 0; i <= num_global_cells[0]; ++i)
3047 coordinates_x[i] *= YAC_RAD;
3048 for (size_t i = 0; i <= num_global_cells[1]; ++i)
3049 coordinates_y[i] *= YAC_RAD;
3050
3053 coordinates_x, coordinates_y, num_global_cells,
3054 local_start, local_count, with_halo);
3055
3056 struct yac_basic_grid * tgt_grid =
3058 struct yac_basic_grid * src_grid =
3060
3061 struct yac_dist_grid_pair * grid_pair =
3062 yac_dist_grid_pair_new(tgt_grid, src_grid, MPI_COMM_WORLD);
3063
3064 struct yac_interp_field src_fields[] =
3065 {{.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
3066 {.location = YAC_LOC_CORNER, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX},
3067 {.location = YAC_LOC_EDGE, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
3068 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
3070 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
3071
3072 struct yac_interp_grid * interp_grid =
3075
3076 //----------------------------------------
3077 // test generation of interpolation method
3078 //----------------------------------------
3079
3080 //-----------------
3081 // generate weights
3082 //-----------------
3083
3084 struct interp_method * method_stack[2] = {
3088 struct yac_interp_weights * weights =
3089 yac_interp_method_do_search(method_stack, interp_grid);
3090 yac_interp_method_delete(method_stack);
3091
3092 // write weights to file
3094 weights, file_name_2, src_grid_name, tgt_grid_name, 0, 0,
3096
3097 // read weights
3098 struct interp_method * method_stack_file[2] = {
3102 struct yac_interp_weights * weights_from_file =
3103 yac_interp_method_do_search(method_stack_file, interp_grid);
3104 yac_interp_method_delete(method_stack_file);
3105
3106 enum yac_interp_weights_reorder_type reorder_type[2] =
3108
3109 for (int from_file = 0; from_file <= 1; ++from_file) {
3110
3111 for (size_t i = 0; i < sizeof(reorder_type) / sizeof(reorder_type[0]);
3112 ++i) {
3113
3114 for (size_t collection_size = 1; collection_size <= 16;
3115 collection_size *= 2) {
3116
3117 struct yac_interpolation * interpolation =
3119 (from_file)?weights_from_file:weights,
3120 reorder_type[i], collection_size,
3121 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
3122
3123 //------------------------------
3124 // check generated interpolation
3125 //------------------------------
3126
3127 double ** tgt_data = xmalloc(collection_size * sizeof(*tgt_data));
3128 for (size_t collection_idx = 0; collection_idx < collection_size;
3129 ++collection_idx) {
3130 tgt_data[collection_idx] =
3131 xmalloc(grid_data.num_cells * sizeof(**tgt_data));
3132 for (size_t i = 0; i < grid_data.num_cells; ++i)
3133 tgt_data[collection_idx][i] = -3;
3134 }
3135
3136 double ref_tgt_field[16] =
3137 { 0.0, 1.0, 8.3, 8.7,
3138 4.0, 12.3, 13.3, 17.7,
3139 8.0, 17.3, 25.7, 26.7,
3140 30.7, 13.0, 14.0, 24.3};
3141
3142 yac_interpolation_execute_get(interpolation, tgt_data);
3143
3144 for (size_t collection_idx = 0; collection_idx < collection_size;
3145 collection_idx++)
3146 for (size_t i = 0; i < grid_data.num_cells; ++i)
3147 if (fabs((ref_tgt_field[i] + 10.0 * (double)collection_idx) -
3148 tgt_data[collection_idx][i]) > 1e-9)
3149 PUT_ERR("wrong interpolation result");
3150
3151 for (size_t collection_idx = 0; collection_idx < collection_size;
3152 ++collection_idx) free(tgt_data[collection_idx]);
3153 free(tgt_data);
3154
3155 //---------------
3156 // cleanup
3157 //---------------
3158
3159 yac_interpolation_delete(interpolation);
3160 }
3161 }
3162 }
3163
3164 //---------------
3165 // cleanup
3166 //---------------
3167
3168 yac_interp_weights_delete(weights_from_file);
3170 yac_interp_grid_delete(interp_grid);
3171 yac_dist_grid_pair_delete(grid_pair);
3172 yac_basic_grid_delete(src_grid);
3173 yac_basic_grid_delete(tgt_grid);
3174 }
3175
3176 { // check the behaviour of on_success
3177
3178 //---------------
3179 // setup
3180 //---------------
3181
3182 double coordinates_x[] = {0.0, 1.0, 2.0};
3183 double coordinates_y[] = {0.0, 1.0, 2.0};
3184 size_t num_vertices[2] = {3,3};
3185 int cyclic[2] = {0,0};
3186
3188 struct yac_basic_grid * tgt_grid =
3191
3192 struct yac_dist_grid_pair * grid_pair =
3193 yac_dist_grid_pair_new(src_grid, tgt_grid, MPI_COMM_WORLD);
3194
3195 struct yac_interp_field src_fields[] =
3196 {{.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
3197 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
3199 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
3200
3201 struct yac_interp_grid * interp_grid =
3204
3205 for (int on_success_idx = 0; on_success_idx < ON_SUCCESS_COUNT;
3206 ++on_success_idx) {
3207
3208 enum yac_interp_file_on_success curr_on_success =
3209 on_success_types[on_success_idx];
3210
3211 //-----------------------------
3212 // generate interpolation stack
3213 //-----------------------------
3214
3215 // the first method reads an empty file and the second
3216 // contains a fixed value
3217 struct interp_method * method_stack[] = {
3219 file_name, YAC_INTERP_FILE_MISSING_ERROR, curr_on_success),
3221 file_name_2, YAC_INTERP_FILE_MISSING_ERROR, curr_on_success),
3222 NULL};
3223
3224 //-----------------
3225 // generate weights
3226 //-----------------
3227
3228 struct yac_interp_weights * weights =
3229 yac_interp_method_do_search(method_stack, interp_grid);
3230
3231 yac_interp_method_delete(method_stack);
3232
3233 enum {COLLECTION_SIZE = 1, NUM_CELLS = 4};
3234 struct yac_interpolation * interpolation =
3237 YAC_FRAC_MASK_NO_VALUE, 1.0, 0.0, NULL, 1, 1);
3238
3239 //------------------------------
3240 // check generated interpolation
3241 //------------------------------
3242
3243 double tgt_data_raw[NUM_CELLS];
3244 double * tgt_data[] = {&(tgt_data_raw[0])};
3245 for (size_t i = 0; i < NUM_CELLS; ++i) tgt_data_raw[i] = -1.0;
3246
3247 double ref_tgt_field_value[ON_SUCCESS_COUNT] = {-1.0,999.0};
3248
3249 yac_interpolation_execute_get(interpolation, tgt_data);
3250
3251 for (size_t i = 0; i < NUM_CELLS; ++i)
3252 if (tgt_data_raw[i] != ref_tgt_field_value[on_success_idx])
3253 PUT_ERR("wrong interpolation result");
3254
3255 //---------------
3256 // cleanup
3257 //---------------
3258
3259 yac_interpolation_delete(interpolation);
3261
3262 } // on_success_idx
3263
3264 yac_interp_grid_delete(interp_grid);
3265 yac_dist_grid_pair_delete(grid_pair);
3266 yac_basic_grid_delete(tgt_grid);
3267 yac_basic_grid_delete(src_grid);
3268 }
3269}
3270
3271static void utest_target_main_abort(MPI_Comm target_comm) {
3272
3273 int my_target_rank;
3274 MPI_Comm_rank(target_comm, &my_target_rank);
3275
3276 { // check the behaviour of on_misssing_file
3277
3278 //---------------
3279 // setup
3280 //---------------
3281
3282 double coordinates_x[] = {0.0, 1.0, 2.0};
3283 double coordinates_y[] = {0.0, 1.0, 2.0};
3284 size_t num_vertices[2] = {3,3};
3285 int cyclic[2] = {0,0};
3286
3288 struct yac_basic_grid * tgt_grid =
3291
3292 struct yac_dist_grid_pair * grid_pair =
3293 yac_dist_grid_pair_new(src_grid, tgt_grid, MPI_COMM_WORLD);
3294
3295 struct yac_interp_field src_fields[] =
3296 {{.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX}};
3297 size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
3299 {.location = YAC_LOC_CELL, .coordinates_idx = SIZE_MAX, .masks_idx = SIZE_MAX};
3300
3301 struct yac_interp_grid * interp_grid =
3304
3307
3308 for (int on_missing_file_idx = 0;
3309 on_missing_file_idx < ON_MISSING_FILE_COUNT; ++on_missing_file_idx) {
3310
3311 enum yac_interp_file_on_missing_file curr_on_missing_file =
3312 on_missing_file_types[on_missing_file_idx];
3313
3314 //-----------------------------
3315 // generate interpolation stack
3316 //-----------------------------
3317
3318 struct interp_method * method_stack[] = {
3320 "missing_file.nc", curr_on_missing_file,
3322 NULL};
3323
3324 //-----------------
3325 // generate weights
3326 //-----------------
3327
3328 struct yac_interp_weights * weights =
3329 yac_interp_method_do_search(method_stack, interp_grid);
3330
3331 int abort_handler_was_called = 0;
3332 MPI_Allreduce(
3333 MPI_IN_PLACE, &abort_handler_was_called, 1,
3334 MPI_INT, MPI_MAX, MPI_COMM_WORLD);
3335
3336 YAC_ASSERT(
3337 (curr_on_missing_file == YAC_INTERP_FILE_MISSING_CONT) ||
3338 (curr_on_missing_file == YAC_INTERP_FILE_MISSING_ERROR),
3339 "ERROR unsupported value for on_missing_file");
3340
3341 switch(curr_on_missing_file) {
3342 default:
3344 if (abort_handler_was_called)
3345 PUT_ERR("error in handling of YAC_INTERP_FILE_MISSING_CONT");
3346 break;
3348 if (!abort_handler_was_called)
3349 PUT_ERR("error in handling of YAC_INTERP_FILE_MISSING_ERROR");
3350 break;
3351 }
3352
3353 if (abort_handler_was_called) {
3354 MPI_Comm_free(&split_comm);
3355 xt_finalize();
3356 MPI_Finalize();
3357 exit(TEST_EXIT_CODE);
3358 }
3359
3360 //---------------
3361 // cleanup
3362 //---------------
3363
3364 yac_interp_method_delete(method_stack);
3366
3367 } // on_missing_file_idx
3368
3369 yac_interp_grid_delete(interp_grid);
3370 yac_dist_grid_pair_delete(grid_pair);
3371 yac_basic_grid_delete(tgt_grid);
3372 yac_basic_grid_delete(src_grid);
3373 }
3374
3375 // The test above is expected to call the abort handler, hence the code
3376 // should never reach this point. New tests should be added above.
3377 PUT_ERR("test internal error");
3378
3379}
3380
3382 MPI_Comm comm, char const * msg, char const * source, int line) {
3383
3384 UNUSED(comm);
3385 UNUSED(msg);
3386 UNUSED(source);
3387 UNUSED(line);
3388
3389 int interpolation_complete = 0;
3391 MPI_Allreduce(
3392 MPI_IN_PLACE, &interpolation_complete, 1, MPI_INT, MPI_MAX, comm), comm);
3393
3394 int abort_handler_was_called = 1;
3395 MPI_Allreduce(
3396 MPI_IN_PLACE, &abort_handler_was_called, 1,
3397 MPI_INT, MPI_MAX, MPI_COMM_WORLD);
3398
3399 MPI_Comm_free(&split_comm);
3400 xt_finalize();
3401 MPI_Finalize();
3402
3403 exit(TEST_EXIT_CODE);
3404}
#define YAC_ASSERT(exp, msg)
struct yac_basic_grid * yac_basic_grid_new(char const *name, struct yac_basic_grid_data grid_data)
Definition basic_grid.c:50
struct yac_basic_grid * yac_basic_grid_reg_2d_deg_new(char const *name, size_t nbr_vertices[2], int cyclic[2], double *lon_vertices, double *lat_vertices)
Definition basic_grid.c:335
struct yac_basic_grid * yac_basic_grid_empty_new(char const *name)
Definition basic_grid.c:63
void yac_basic_grid_delete(struct yac_basic_grid *grid)
Definition basic_grid.c:70
size_t yac_basic_grid_add_mask_nocpy(struct yac_basic_grid *grid, enum yac_location location, int const *mask, char const *mask_name)
Definition basic_grid.c:258
#define UNUSED(x)
Definition core.h:73
void yac_dist_grid_pair_delete(struct yac_dist_grid_pair *grid_pair)
Definition dist_grid.c:2313
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)
Definition dist_grid.c:2061
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)
#define YAC_RAD
void yac_interp_grid_delete(struct yac_interp_grid *interp_grid)
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)
Definition interp_grid.c:31
MPI_Comm yac_interp_grid_get_MPI_Comm(struct yac_interp_grid *interp_grid)
void yac_interp_method_delete(struct interp_method **method)
struct yac_interp_weights * yac_interp_method_do_search(struct interp_method **method, struct yac_interp_grid *interp_grid)
struct interp_method * yac_interp_method_file_new(char const *weight_file_name, enum yac_interp_file_on_missing_file on_missing_file, enum yac_interp_file_on_success on_success)
yac_interp_file_on_missing_file
@ YAC_INTERP_FILE_MISSING_CONT
continue on missing file
@ YAC_INTERP_FILE_MISSING_ERROR
abort on missing file
yac_interp_file_on_success
@ YAC_INTERP_FILE_SUCCESS_CONT
@ YAC_INTERP_FILE_SUCCESS_STOP
struct yac_interpolation * yac_interp_weights_get_interpolation(struct yac_interp_weights *weights, enum yac_interp_weights_reorder_type reorder, size_t collection_size, double frac_mask_fallback_value, double scaling_factor, double scaling_summand, char const *yaxt_exchanger_name, int is_source, int is_target)
void yac_interp_weights_delete(struct yac_interp_weights *weights)
void yac_interp_weights_write_to_file(struct yac_interp_weights *weights, char const *filename, char const *src_grid_name, char const *tgt_grid_name, size_t src_grid_size, size_t tgt_grid_size, enum yac_weight_file_on_existing on_existing)
yac_interp_weights_reorder_type
@ YAC_MAPPING_ON_TGT
weights will be applied at target processes
@ YAC_MAPPING_ON_SRC
weights will be applied at source processes
@ YAC_WEIGHT_FILE_ERROR
error when weight file existis already
void yac_interpolation_delete(struct yac_interpolation *interp)
Free an interpolation object and release all resources.
void yac_interpolation_execute_get(struct yac_interpolation *interp, double **tgt_field)
Complete interpolation and write results to the target field (get phase).
void yac_interpolation_execute_put(struct yac_interpolation *interp, double ***src_fields)
Provide source field data and start asynchronous execution of interpolation (put phase).
double const YAC_FRAC_MASK_NO_VALUE
yac_location
Definition location.h:12
@ YAC_LOC_CORNER
Definition location.h:15
@ YAC_LOC_EDGE
Definition location.h:16
@ YAC_LOC_CELL
Definition location.h:14
#define xmalloc(size)
Definition ppm_xfuncs.h:66
enum yac_location location
Definition basic_grid.h:16
struct yac_interp_field tgt_field
Definition interp_grid.c:26
size_t num_src_fields
Definition interp_grid.c:27
struct yac_dist_grid_pair * grid_pair
Definition interp_grid.c:25
struct yac_interp_field src_fields[]
Definition interp_grid.c:28
void clear_yac_io_env()
@ COLLECTION_SIZE
int collection_size
enum yac_interp_file_on_success on_success_types[]
char const file_name[]
char const src_grid_name[]
char const tgt_grid_name[]
char const file_name_2[]
double const err_tol
static MPI_Comm split_comm
enum yac_interp_file_on_missing_file on_missing_file_types[]
double const tol
static void on_missing_abort_handler(MPI_Comm comm, char const *msg, char const *source, int line)
double coordinates_x[]
double coordinates_y[]
unsigned cyclic[2]
#define TEST_EXIT_CODE
Definition tests.h:14
#define PUT_ERR(string)
Definition tests.h:10
void write_weight_file(char const *file_name, int const *src_id, int const *tgt_id, double const *weights, unsigned num_links, enum yac_location const *src_locations, unsigned num_src_fields, int const *num_links_per_src_field, int *tgt_id_fixed, unsigned num_fixed_tgt, double *fixed_values, int *num_tgt_per_fixed_value, unsigned num_fixed_values, enum yac_location tgt_location, char const *src_grid_name, char const *tgt_grid_name)
void yac_set_default_comm(MPI_Comm comm)
void(* yac_abort_func)(MPI_Comm comm, const char *msg, const char *source, int line) __attribute__((noreturn))
Definition yac.h:3237
void yac_set_abort_handler(yac_abort_func custom_abort)
#define yac_mpi_call(call, comm)