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