YAC 3.20.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_dummy_coupling3_c.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#define EXACT
6
7#include <mpi.h>
8#include <yaxt.h>
9
10#include <stdlib.h>
11#include <stdio.h>
12#include <string.h>
13#include <unistd.h>
14#include <limits.h>
15
16#include "yac.h"
17#include "utils_common.h"
18#include "io_utils.h"
19#include "geometry.h"
20#include "read_icon_grid.h"
21#include "read_mpiom_grid.h"
23#include "test_function.h"
24
25#include "tests.h"
26
34#define DUMMY_VALUE (-1337.0)
35
36struct grid_data {
37
38 char const * name;
39
44 double * x_vertices;
45 double * y_vertices;
46 double * x_cells;
47 double * y_cells;
48
49 int * cell_mask;
54};
55
62
69
70static struct intra_comp_yac_info utest_setup_intra_comp_yac(
71 MPI_Comm comp_comm, char const * comp_name,
72 int base_point_id, int regional_point_id, char const * config_dir);
73
74static struct comp_pair_yac_info utest_setup_comp_pair_yac(
75 char const * comp_pair_names[2], int point_ids[2], int nbr_cells[2],
76 int local_comp_indices[2], char const * config_dir);
77
78static struct grid_data utest_generate_icon_grid_data(
79 MPI_Comm comm, char const * grid_dir);
80static struct grid_data utest_generate_cube_grid_data(MPI_Comm comm);
81static struct grid_data utest_generate_mpiom_grid_data(
82 MPI_Comm comm, char const * grid_dir);
83static void utest_grid_data_free(struct grid_data grid_data);
84
85static void utest_def_default_fields(
86 int comp_id, char const * comp_name, int cell_point_id,
87 int * in_field_ids, int * out_field_id);
88
109int main(int argc, char** argv) {
110 MPI_Init(NULL, NULL);
111 xt_initialize(MPI_COMM_WORLD);
112
113 int global_rank, global_size;
114 MPI_Comm_rank(MPI_COMM_WORLD, &global_rank);
115 MPI_Comm_size(MPI_COMM_WORLD, &global_size);
116
117 if (argc != 4) {
118 fprintf(stderr, "Wrong number of arguments (should be 4)\n");
119 exit(EXIT_FAILURE);
120 }
121
122 if (global_size != 10) {
123 fprintf(stderr, "Wrong number of processes (should be 10)\n");
124 exit(EXIT_FAILURE);
125 }
126
127 // ranks 8 and 9 do not initialise YAC, but still need to call the
128 // respective dummy initilialisation and finalise routines
129 if (global_rank > 7) {
130
132 xt_finalize();
133 MPI_Finalize();
134 return TEST_EXIT_CODE;
135 }
136
137 // determine the local components
138 char const * global_comp_names[] = {"comp_a", "comp_b", "comp_c", "dummy"};
139 char const * local_comp_names[2];
140 int num_local_comps;
141 int is_dummy = 0;
142 switch (global_rank) {
143 default:
144 case(0): {
145 local_comp_names[0] = global_comp_names[0];
146 num_local_comps = 1;
147 break;
148 }
149 case(1): {
150 local_comp_names[0] = global_comp_names[1];
151 num_local_comps = 1;
152 break;
153 }
154 case(2): {
155 local_comp_names[0] = global_comp_names[2];
156 num_local_comps = 1;
157 break;
158 }
159 case(4): {
160 local_comp_names[0] = global_comp_names[0];
161 local_comp_names[1] = global_comp_names[1];
162 num_local_comps = 2;
163 break;
164 }
165 case(5): {
166 local_comp_names[0] = global_comp_names[0];
167 local_comp_names[1] = global_comp_names[2];
168 num_local_comps = 2;
169 break;
170 }
171 case(6): {
172 local_comp_names[0] = global_comp_names[1];
173 local_comp_names[1] = global_comp_names[2];
174 num_local_comps = 2;
175 break;
176 }
177 case(3):
178 case(7): {
179 local_comp_names[0] = global_comp_names[3];
180 num_local_comps = 1;
181 is_dummy = 1;
182 break;
183 }
184 }
185
186 // initialise default YAC instance
187 yac_cinit ();
189 char * yaml_filename =
190 strcat(
191 strcpy(
192 malloc(strlen(argv[1]) + 32), argv[1]), "coupling_test3_default_c.yaml");
194 free(yaml_filename);
195
196 // register local components in default YAC instance
197 int default_comp_ids[2];
198 int default_num_comps = num_local_comps;
199 yac_cdef_comps(local_comp_names, default_num_comps, default_comp_ids);
200
201 MPI_Comm default_comp_comms[2];
202 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx)
204 default_comp_ids[comp_idx], &(default_comp_comms[comp_idx]));
205
206 // generate and register grid, global ids, core mask, and points
207 int grid_ids[2], cell_point_ids[2];
208 int regional_grid_id = -1, regional_point_id = -1;
209 int nbr_vertices_regional = 0;
210 struct grid_data comp_grid_data[2];
211 if (!is_dummy) {
212 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx) {
213 switch(local_comp_names[comp_idx][5]) {
214 case('a'): {
215 comp_grid_data[comp_idx] =
216 utest_generate_icon_grid_data(default_comp_comms[comp_idx], argv[2]);
217 break;
218 }
219 case('b'): {
220 comp_grid_data[comp_idx] =
221 utest_generate_cube_grid_data(default_comp_comms[comp_idx]);
222 break;
223 }
224 case('c'): {
225 comp_grid_data[comp_idx] =
226 utest_generate_mpiom_grid_data(default_comp_comms[comp_idx], argv[3]);
227 break;
228 }
229 default:
230 exit(EXIT_FAILURE);
231 };
233 comp_grid_data[comp_idx].name,
234 comp_grid_data[comp_idx].nbr_vertices,
235 comp_grid_data[comp_idx].nbr_cells,
236 comp_grid_data[comp_idx].num_vertices_per_cell,
237 comp_grid_data[comp_idx].x_vertices,
238 comp_grid_data[comp_idx].y_vertices,
239 comp_grid_data[comp_idx].cell_to_vertex,
240 &(grid_ids[comp_idx]));
242 comp_grid_data[comp_idx].global_corner_id, YAC_LOCATION_CORNER,
243 grid_ids[comp_idx]);
245 comp_grid_data[comp_idx].corner_core_mask, YAC_LOCATION_CORNER,
246 grid_ids[comp_idx]);
248 comp_grid_data[comp_idx].global_cell_id, YAC_LOCATION_CELL,
249 grid_ids[comp_idx]);
251 comp_grid_data[comp_idx].cell_core_mask, YAC_LOCATION_CELL,
252 grid_ids[comp_idx]);
253
255 grid_ids[comp_idx], comp_grid_data[comp_idx].nbr_cells,
256 YAC_LOCATION_CELL, comp_grid_data[comp_idx].x_cells,
257 comp_grid_data[comp_idx].y_cells, &(cell_point_ids[comp_idx]));
258 if (comp_grid_data[comp_idx].cell_mask != NULL)
260 comp_grid_data[comp_idx].cell_mask, cell_point_ids[comp_idx]);
261 }
262
263 // regional grid on root processes of each component
264 if ((global_rank == 0) || (global_rank == 1) || (global_rank == 2)) {
265
266 // register regional grid on rank 0
267 double regional_coord_x[] = {
268 -20,-18,-16,-14,-12,-10, -8, -6, -4, -2,
269 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20};
270 double regional_coord_y[] = {
271 -20,-18,-16,-14,-12,-10, -8, -6, -4, -2,
272 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20};
273 int num_vertices_regional[2] =
274 {sizeof(regional_coord_x) / sizeof(regional_coord_x[0]),
275 sizeof(regional_coord_y) / sizeof(regional_coord_y[0])};
276 nbr_vertices_regional =
277 num_vertices_regional[0] * num_vertices_regional[1];
278 int cyclic[2] = {0, 0};
279 for (int i = 0; i < num_vertices_regional[0]; ++i)
280 regional_coord_x[i] *= YAC_RAD;
281 for (int i = 0; i < num_vertices_regional[1]; ++i)
282 regional_coord_y[i] *= YAC_RAD;
284 "regional_grid", num_vertices_regional, cyclic,
285 regional_coord_x, regional_coord_y, &regional_grid_id);
286
288 regional_grid_id, num_vertices_regional, YAC_LOCATION_CORNER,
289 regional_coord_x, regional_coord_y, &regional_point_id);
290 }
291 }
292
293 // setup YAC instance which couples a component to one of its own ranks
294 struct intra_comp_yac_info yac_intra_infos[2];
295 if (!is_dummy)
296 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx)
297 yac_intra_infos[comp_idx] =
298 utest_setup_intra_comp_yac(
299 default_comp_comms[comp_idx], local_comp_names[comp_idx],
300 cell_point_ids[comp_idx], regional_point_id, argv[1]);
301
302 // register in and out fields
303 int default_in_field_ids[2][2];// = {{INT_MAX, INT_MAX}, {INT_MAX, INT_MAX}};
304 int default_out_field_ids[2];// = {INT_MAX, INT_MAX};
305 if (!is_dummy)
306 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx)
307 utest_def_default_fields(
308 default_comp_ids[comp_idx], local_comp_names[comp_idx],
309 cell_point_ids[comp_idx], default_in_field_ids[comp_idx],
310 &(default_out_field_ids[comp_idx]));
311
313
314 char * start_datetime = yac_cget_start_datetime();
315 if (strcmp(start_datetime, "1800-01-01T00:00:00.000"))
316 PUT_ERR("error in yac_cget_start_datetime");
317 free(start_datetime);
318
319 char * end_datetime = yac_cget_end_datetime();
320 if (strcmp(end_datetime, "2100-01-01T00:00:00.000"))
321 PUT_ERR("error in yac_cget_end_datetime");
322 free(end_datetime);
323
324 // generate interpolations for the default YAC instance
325 yac_cenddef();
326
327 if (global_rank == 0) {
328 char yaml_filename_enddef[] = "coupling_test3_default_c_enddef.yaml";
329 if (!yac_file_exists(yaml_filename_enddef))
330 PUT_ERR("error in writing config file");
331 unlink(yaml_filename_enddef);
332 }
333
334
335 // setup YAC instances that only couple all component combinations
336 struct comp_pair_yac_info yac_comp_pair_infos[3];
337 for (int i = 0, k = 0; i < 3; ++i) {
338
339 int local_comp_idx[2];
340
341 local_comp_idx[0] = INT_MAX;
342 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx)
343 if (!strcmp(global_comp_names[i], local_comp_names[comp_idx]))
344 local_comp_idx[0] = comp_idx;
345
346 for (int j = i + 1; j < 3; ++j, ++k) {
347
348 local_comp_idx[1] = INT_MAX;
349 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx)
350 if (!strcmp(global_comp_names[j], local_comp_names[comp_idx]))
351 local_comp_idx[1] = comp_idx;
352
353 char const * comp_pair_names[2] =
354 {global_comp_names[i], global_comp_names[j]};
355 int nbr_cells[2] =
356 {comp_grid_data[0].nbr_cells, comp_grid_data[1].nbr_cells};
357
358 yac_comp_pair_infos[k] =
359 utest_setup_comp_pair_yac(
360 comp_pair_names, cell_point_ids, nbr_cells, local_comp_idx, argv[1]);
361 }
362 }
363
364 // if this is not the dummy process, which is not involved in any coupling
365 if (!is_dummy) {
366
367 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx) {
368
369 int collection_size;
370 char field_name[64];
371 sprintf(field_name, "%s_out", local_comp_names[comp_idx]);
372 const char* timestep_string = yac_cget_timestep_from_field_id(
373 default_out_field_ids[comp_idx]);
374 if (strcmp(timestep_string, "PT01.000S"))
375 PUT_ERR("error in yac_cget_model_timestep_id");
377 default_out_field_ids[comp_idx]);
378 if (collection_size != 1)
379 PUT_ERR("error in yac_cget_collection_size_from_field_id");
380 }
381
382 double * out_field_data[2];
383 double * in_field_data[2];
384 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx) {
385 out_field_data[comp_idx] =
386 xmalloc(comp_grid_data[comp_idx].nbr_cells * sizeof(double));
387 for (int i = 0; i < comp_grid_data[comp_idx].nbr_cells; ++i)
388 out_field_data[comp_idx][i] =
389 (comp_grid_data[comp_idx].cell_core_mask[i])?
391 comp_grid_data[comp_idx].x_cells[i],
392 comp_grid_data[comp_idx].y_cells[i])):DUMMY_VALUE;
393 in_field_data[comp_idx] =
394 xmalloc(comp_grid_data[comp_idx].nbr_cells * sizeof(double));
395 }
396
397 // do some ping-pongs in the default YAC instance
398 for (int t = 0; t < 10; ++t) {
399
400 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx) {
401 int info, err;
402 int id = default_out_field_ids[comp_idx];
403 double *point_set_data[1];
404 double **collection_data[1] = {point_set_data};
405 point_set_data[0] = out_field_data[comp_idx];
406 yac_cput(id, 1, collection_data, &info, &err);
407 }
408
409 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx) {
410 for (int field_idx = 0; field_idx < 2; ++field_idx) {
411 int info, err;
412 int id = default_in_field_ids[comp_idx][field_idx];
413 double *collection_data[1] = {in_field_data[comp_idx]};
414
415 for (int i = 0; i < comp_grid_data[comp_idx].nbr_cells; ++i)
416 in_field_data[comp_idx][i] = DUMMY_VALUE;
417 yac_cget(id, 1, collection_data, &info, &err);
418 }
419 }
420 }
421
422 // interpolate received results to the regional grid defined on
423 // rank 0 of the current component
424 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx) {
425
426 if (yac_intra_infos[comp_idx].is_comp_root) {
427 int out_info, in_info, err;
428 int out_id = yac_intra_infos[comp_idx].out_field_id;
429 double *out_point_set_data[1];
430 double **out_collection_data[1] = {out_point_set_data};
431 out_point_set_data[0] = in_field_data[comp_idx];
432
433 int in_id = yac_intra_infos[comp_idx].in_field_id;
434 double *in_collection_data[1] = {
435 xmalloc(nbr_vertices_regional * sizeof(double))};
436 for (int i = 0; i < nbr_vertices_regional; ++i)
437 in_collection_data[0][i] = DUMMY_VALUE;
438
440 out_id, in_id, 1, out_collection_data, in_collection_data,
441 &out_info, &in_info, &err);
442
443 free(in_collection_data[0]);
444 } else {
445 int info, err;
446 int id = yac_intra_infos[comp_idx].out_field_id;
447 double *point_set_data[1];
448 double **collection_data[1] = {point_set_data};
449 point_set_data[0] = in_field_data[comp_idx];
450 yac_cput(id, 1, collection_data, &info, &err);
451 }
452 }
453
454 // clean-up
455
456 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx) {
457 free(out_field_data[comp_idx]);
458 free(in_field_data[comp_idx]);
459 utest_grid_data_free(comp_grid_data[comp_idx]);
460 }
461
462 // do some exchanges between within the component pair YAC instances
463 // for all available component pairs
464 for (int i = 0; i < 3; ++i) {
465
466 // if the local process is not a part of the current component pair
467 if (yac_comp_pair_infos[i].yac_id == INT_MAX) continue;
468
469 // if the local process has both components of the current pair
470 if ((yac_comp_pair_infos[i].nbr_cells[0] > 0) &&
471 (yac_comp_pair_infos[i].nbr_cells[1] > 0)) {
472
473 double * out_field_data[2];
474 double * in_field_data[2];
475
476 for (int j = 0; j < 2; ++j) {
477 int nbr_cells = yac_comp_pair_infos[i].nbr_cells[j];
478 out_field_data[j] = xmalloc(nbr_cells * sizeof(double));
479 for (int k = 0; k < nbr_cells; ++k) out_field_data[j][k] = 0.0;
480 in_field_data[j] = xmalloc(nbr_cells * sizeof(double));
481 for (int k = 0; k < nbr_cells; ++k) in_field_data[j][k] = DUMMY_VALUE;
482 }
483
484 for (int j = 0; j < 2; ++j) {
485
486 int out_info, in_info, err;
487 int out_id = yac_comp_pair_infos[i].out_field_ids[j];
488 double *out_point_set_data[1];
489 double **out_collection_data[1] = {out_point_set_data};
490 out_point_set_data[0] = out_field_data[j];
491
492 int in_id = yac_comp_pair_infos[i].in_field_ids[j^1];
493 double *in_collection_data[1] = {in_field_data[j^1]};
494
496 out_id, in_id, 1, out_collection_data, in_collection_data,
497 &out_info, &in_info, &err);
498 }
499 for (int j = 0; j < 2; ++j) {
500 free(out_field_data[j]);
501 free(in_field_data[j]);
502 }
503
504 } else {
505
506 for (int j = 0; j < 2; ++j) {
507
508 // if the source component is available locally
509 if (yac_comp_pair_infos[i].nbr_cells[j] > 0) {
510
511 int nbr_cells = yac_comp_pair_infos[i].nbr_cells[j];
512
513 double * out_field_data = xmalloc(nbr_cells * sizeof(double));
514 // just some dummy data
515 for (int j = 0; j < nbr_cells; ++j) out_field_data[j] = 0.0;
516
517 int info, err;
518 int id = yac_comp_pair_infos[i].out_field_ids[j];
519 double *point_set_data[1];
520 double **collection_data[1] = {point_set_data};
521 point_set_data[0] = out_field_data;
522 yac_cput(id, 1, collection_data, &info, &err);
523
524 free(out_field_data);
525
526 } else {
527
528 int nbr_cells = yac_comp_pair_infos[i].nbr_cells[j^1];
529
530 double * in_field_data = xmalloc(nbr_cells * sizeof(double));
531
532 int info, err;
533 int id = yac_comp_pair_infos[i].in_field_ids[j^1];
534 double *collection_data[1] = {in_field_data};
535
536 for (int j = 0; j < nbr_cells; ++j) in_field_data[j] = DUMMY_VALUE;
537 yac_cget(id, 1, collection_data, &info, &err);
538
539 free(in_field_data);
540 }
541 }
542 }
543 }
544 }
545
546 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx)
547 MPI_Comm_free(&(default_comp_comms[comp_idx]));
548
549 if (!is_dummy) {
550 for (int i = 0; i < 3; ++i)
551 if (yac_comp_pair_infos[i].yac_id != INT_MAX)
552 yac_ccleanup_instance(yac_comp_pair_infos[i].yac_id);
553 for (int comp_idx = 0; comp_idx < num_local_comps; ++comp_idx)
554 yac_ccleanup_instance(yac_intra_infos[comp_idx].yac_id);
555 }
557
558 xt_finalize();
559 MPI_Finalize();
560
561 return TEST_EXIT_CODE;
562}
563
564static struct intra_comp_yac_info utest_setup_intra_comp_yac(
565 MPI_Comm comp_comm, char const * comp_name,
566 int base_point_id, int regional_point_id, char const * config_dir) {
567
568 // initialise intra component YAC instance
569 int yac_id;
570 char yaml_filename[256];
571 snprintf(
573 "%scoupling_test3_%s_intra.yaml", config_dir, comp_name);
574 yac_cinit_comm_instance(comp_comm, &yac_id);
576
577 int comp_rank;
578 MPI_Comm_rank(comp_comm, &comp_rank);
579
580 // register component(s) (all processes are part of the base component
581 // process 0 has an additional component)
582 char const * comp_names[2] = {comp_name, "comp_regional"};
583 int num_comps = (regional_point_id != -1)?2:1;
584 int comp_ids[2];
585 if (regional_point_id != -1)
586 yac_cdef_comps_instance(yac_id, comp_names, num_comps, comp_ids);
587 else
588 yac_cdef_comp_instance(yac_id, comp_names[0], &comp_ids[0]);
589
590 // register field (from base component to regional one)
591 int field_ids[2];
593 "base_to_regional", comp_ids[0], &base_point_id, 1, 1, "1",
594 YAC_TIME_UNIT_SECOND, &(field_ids[0]));
595 if (regional_point_id != -1)
597 "base_to_regional", comp_ids[1], &regional_point_id, 1, 1, "1",
598 YAC_TIME_UNIT_SECOND, &(field_ids[1]));
599
600 char yaml_filename_sync[256];
601 snprintf(
602 yaml_filename_sync, sizeof(yaml_filename_sync),
603 "coupling_test3_c_%s_intra_sync.yaml", comp_name);
604 int include_definitions = 0;
606 yac_id, yaml_filename_sync, YAC_CONFIG_OUTPUT_FORMAT_YAML,
607 YAC_CONFIG_OUTPUT_SYNC_LOC_SYNC_DEF, include_definitions);
608
610
611 if (comp_rank == 0) {
612 if (!yac_file_exists(yaml_filename_sync))
613 PUT_ERR("error in yac_cset_config_output_file_instance");
614 unlink(yaml_filename_sync);
615 }
616
617 char * start_datetime = yac_cget_start_datetime_instance(yac_id);
618 if (strcmp(start_datetime, "1800-01-01T00:00:00.000"))
619 PUT_ERR("error in yac_cget_start_datetime_instance");
620 free(start_datetime);
621
622 char * end_datetime = yac_cget_end_datetime_instance(yac_id);
623 if (strcmp(end_datetime, "2100-01-01T00:00:00.000"))
624 PUT_ERR("error in yac_cget_end_datetime_instance");
625 free(end_datetime);
626
627 char json_filename_enddef[256];
628 snprintf(
629 json_filename_enddef, sizeof(yaml_filename_sync),
630 "coupling_test3_c_%s_intra_enddef.json", comp_name);
632 yac_id, json_filename_enddef, YAC_CONFIG_OUTPUT_FORMAT_JSON,
633 YAC_CONFIG_OUTPUT_SYNC_LOC_ENDDEF, include_definitions);
634
635 // generate interpolations for the default YAC instance
637
638 if (comp_rank == 0) {
639 if (!yac_file_exists(json_filename_enddef))
640 PUT_ERR("error in yac_cset_config_output_file_instance");
641 unlink(json_filename_enddef);
642 }
643
644 struct intra_comp_yac_info yac_intra_info;
645 yac_intra_info.yac_id = yac_id;
646 yac_intra_info.is_comp_root = regional_point_id != -1;
647 yac_intra_info.out_field_id = field_ids[0];
648 yac_intra_info.in_field_id = field_ids[1];
649
650 int collection_size;
651 const char* timestep_string = yac_cget_timestep_from_field_id(field_ids[0]);
652 if (strcmp(timestep_string, "PT01.000S"))
653 PUT_ERR("error in yac_cget_model_timestep_id");
655 if (collection_size != 1)
656 PUT_ERR("error in yac_cget_collection_size_from_field_id");
657 return yac_intra_info;
658}
659
660static struct comp_pair_yac_info utest_setup_comp_pair_yac(
661 char const * comp_pair_names[2], int point_ids[2], int nbr_cells[2],
662 int local_comp_indices[2], char const * config_dir) {
663
664 if ((local_comp_indices[0] == INT_MAX) &&
665 (local_comp_indices[1] == INT_MAX))
666 return (struct comp_pair_yac_info){.yac_id = INT_MAX};
667
668 // get the communicator for the component pair
669 MPI_Comm comp_pair_comm;
671 (char const *[]){comp_pair_names[0], comp_pair_names[1]}, 2,
672 &comp_pair_comm);
673
674 char * yaml_file_name =
675 malloc(
676 strlen(config_dir) + strlen(comp_pair_names[0]) +
677 strlen(comp_pair_names[1]) + 32);
678 sprintf(yaml_file_name, "%scoupling_test3_%s_%s.yaml",
679 config_dir, comp_pair_names[0], comp_pair_names[1]);
680
681 // initialise component pair YAC instance
682 int yac_id;
683 yac_cinit_comm_instance(comp_pair_comm, &yac_id);
684 yac_cread_config_yaml_instance(yac_id, yaml_file_name);
685 free(yaml_file_name);
686
687 // register component(s) the local process can have one or two components
688 // associated to the YAC instance
689 char const * comp_names[2];
690 int num_comps = 0;
691 int comp_ids[2];
692 for (int i = 0; i < 2; ++i)
693 if (local_comp_indices[i] != INT_MAX)
694 comp_names[num_comps++] = comp_pair_names[i];
695 yac_cdef_comps_instance(yac_id, comp_names, num_comps, comp_ids);
696
697 int field_ids[2][2];
698 for (int i = 0, k = 0; i < 2; ++i) {
699
700 int comp_idx = local_comp_indices[i];
701 if (comp_idx == INT_MAX) continue;
702
703 // register field
704 for (int j = 0; j < 2; ++j) {
705 char field_name[16];
706 sprintf(field_name, "comp_%c_out", comp_pair_names[j][5]);
708 field_name, comp_ids[k], &(point_ids[comp_idx]), 1, 1, "1",
709 YAC_TIME_UNIT_SECOND, &(field_ids[i][j]));
710 }
711 ++k;
712 }
713
714 // generate interpolations for the component pair YAC instance
716
717 MPI_Comm_free(&comp_pair_comm);
718
719 struct comp_pair_yac_info yac_info;
720
721 yac_info.yac_id = yac_id;
722 for (int i = 0; i < 2; ++i) {
723 int comp_idx = local_comp_indices[i];
724 if (comp_idx == INT_MAX) {
725 yac_info.nbr_cells[i] = 0;
726 yac_info.out_field_ids[i] = INT_MAX;
727 yac_info.in_field_ids[i] = INT_MAX;
728 } else {
729 yac_info.nbr_cells[i] = nbr_cells[comp_idx];
730 int roles[2];
731 for (int j = 0; j < 2; ++j) {
732 roles[j] = yac_cget_role_from_field_id(field_ids[i][j]);
733 switch (roles[j]) {
734 case(0):
735 default:
736 PUT_ERR("invalid role");
737 break;
738 case(1):
739 yac_info.out_field_ids[i] = field_ids[i][j];
740 break;
741 case(2):
742 yac_info.in_field_ids[i] = field_ids[i][j];
743 break;
744 }
745 }
746 if (roles[0] == roles[1]) PUT_ERR("roles should not match");
747 }
748 }
749
750 return yac_info;
751}
752
753static void utest_def_default_fields(
754 int comp_id, char const * comp_name, int cell_point_id,
755 int * in_field_ids, int * out_field_id) {
756
757 int num_in_fields = 0;
758
759 for (int i = 0; i < 3; ++i) {
760 char const * field_names[3] = {"comp_a_out", "comp_b_out", "comp_c_out"};
761 int field_id;
762 char const * curr_field_name = field_names[i];
764 curr_field_name, comp_id, &cell_point_id, 1, 1, "1",
766
767 if (comp_name[5] == curr_field_name[5])
768 *out_field_id = field_id;
769 else
770 in_field_ids[num_in_fields++] = field_id;
771 }
772}
773
774static struct grid_data utest_generate_icon_grid_data(
775 MPI_Comm comm, char const * grid_dir) {
776
777 int comm_rank, comm_size;
778 MPI_Comm_rank(comm, &comm_rank);
779 MPI_Comm_size(comm, &comm_size);
780
781 struct grid_data grid_data;
782
783 static char const * icon_grid_name = "icon_grid";
784 grid_data.name = icon_grid_name;
785
786 char * grid_filename =
787 strcat(
788 strcpy(
789 malloc(strlen(grid_dir) + 32), grid_dir), "icon_grid_R02B01.nc");
790
792 grid_filename, &grid_data.nbr_vertices, &grid_data.nbr_cells,
798 &grid_data.corner_core_mask, comm_rank, comm_size);
799
800 free(grid_filename);
801
802 for (int i = 0; i < grid_data.nbr_cells; ++i)
804
805 return grid_data;
806}
807
808static struct grid_data utest_generate_cube_grid_data(MPI_Comm comm) {
809
810 int comm_rank, comm_size;
811 MPI_Comm_rank(comm, &comm_rank);
812 MPI_Comm_size(comm, &comm_size);
813
814 struct grid_data grid_data;
815
816 static char const * cube_grid_name = "cube_grid";
817 grid_data.name = cube_grid_name;
818
819 unsigned n = 50;
820
822 n, (unsigned*)&grid_data.nbr_vertices, (unsigned*)&grid_data.nbr_cells,
823 (unsigned**)&grid_data.num_vertices_per_cell,
824 (unsigned**)&grid_data.cell_to_vertex,
828 &grid_data.corner_core_mask, comm_rank, comm_size);
829
830 grid_data.cell_mask = NULL;
831
832 return grid_data;
833}
834
835static struct grid_data utest_generate_mpiom_grid_data(
836 MPI_Comm comm, char const * grid_dir) {
837
838 int comm_rank, comm_size;
839 MPI_Comm_rank(comm, &comm_rank);
840 MPI_Comm_size(comm, &comm_size);
841
842 struct grid_data grid_data;
843
844 static char const * mpiom_grid_name = "mpiom_grid";
845 grid_data.name = mpiom_grid_name;
846
847 char * grid_filename =
848 strcat(
849 strcpy(
850 malloc(strlen(grid_dir) + 32), grid_dir), "GR30_lsm.nc");
851
853 grid_filename, &grid_data.nbr_vertices, &grid_data.nbr_cells,
859 &grid_data.corner_core_mask, comm_rank, comm_size);
860
861 free(grid_filename);
862
863 for (int i = 0; i < grid_data.nbr_cells; ++i)
865
866 return grid_data;
867}
868
869static void utest_grid_data_free(struct grid_data grid_data) {
870
873 free(grid_data.x_vertices);
874 free(grid_data.y_vertices);
875 free(grid_data.x_cells);
876 free(grid_data.y_cells);
877
878 free(grid_data.cell_mask);
883}
char const * field_names[8]
#define YAC_RAD
void yac_generate_part_cube_grid_information(unsigned n, unsigned *nbr_vertices, unsigned *nbr_cells, unsigned **num_vertices_per_cell, unsigned **cell_to_vertex, double **x_vertices, double **y_vertices, double **x_cells, double **y_cells, int **global_cell_id, int **cell_core_mask, int **global_corner_id, int **corner_core_mask, int rank, int size)
int yac_file_exists(const char *filename)
Check whether a file exists.
Definition io_utils.c:394
#define xmalloc(size)
Definition ppm_xfuncs.h:66
void yac_read_part_icon_grid_information(const char *filename, int *nbr_vertices, int *nbr_cells, int **num_vertices_per_cell, int **cell_to_vertex, double **x_vertices, double **y_vertices, double **x_cells, double **y_cells, int **global_cell_id, int **cell_mask, int **cell_core_mask, int **global_corner_id, int **corner_core_mask, int rank, int size)
void yac_read_part_mpiom_grid_information(const char *filename, int *num_vertices, int *num_cells, int **num_vertices_per_cell, int **cell_to_vertex, double **x_vertices, double **y_vertices, double **x_cells, double **y_cells, int **global_cell_id, int **cell_mask, int **cell_core_mask, int **global_corner_id, int **corner_core_mask, int rank, int size)
char const * name
#define DUMMY_VALUE
int * cell_to_vertex
int * cell_mask
int collection_size
char * yaml_filename
int cell_point_ids[1]
double yac_test_harmonic(double lon, double lat)
unsigned cyclic[2]
#define TEST_EXIT_CODE
Definition tests.h:15
#define PUT_ERR(string)
Definition tests.h:10
int info
int comp_ids[1]
int * cell_core_mask
int cell_point_id
int * field_id
int comp_id
char const * name
Definition toy_scrip.c:114
void yac_cenddef(void)
Definition yac.c:4947
int const YAC_CONFIG_OUTPUT_SYNC_LOC_ENDDEF
after end of definitions
Definition yac.c:133
char * yac_cget_start_datetime_instance(int yac_instance_id)
Definition yac.c:1012
void yac_cset_global_index(int const *global_index, int location, int grid_id)
Definition yac.c:5667
int yac_cget_role_from_field_id(int field_id)
Definition yac.c:5332
char * yac_cget_end_datetime_instance(int yac_instance_id)
Definition yac.c:1027
int const YAC_LOCATION_CELL
Definition yac.c:37
const char * yac_cget_timestep_from_field_id(int field_id)
Definition yac.c:5318
void yac_csync_def_instance(int yac_instance_id)
Definition yac.c:4859
void yac_csync_def(void)
Definition yac.c:4864
void yac_cinit(void)
Definition yac.c:721
void yac_cfinalize()
Finalises YAC.
Definition yac.c:971
void yac_cenddef_instance(int yac_instance_id)
Definition yac.c:4925
void yac_cread_config_yaml_instance(int yac_instance_id, const char *yaml_filename)
Definition yac.c:792
int const YAC_LOCATION_CORNER
Definition yac.c:38
void yac_cget_comp_comm(int comp_id, MPI_Comm *comp_comm)
Definition yac.c:1094
void yac_cget(int const field_id, int collection_size, double **recv_field, int *info, int *ierr)
Definition yac.c:3246
void yac_cdef_comp_instance(int yac_instance_id, char const *comp_name, int *comp_id)
Definition yac.c:1301
int yac_cget_collection_size_from_field_id(int field_id)
Definition yac.c:5325
void yac_cdef_grid_reg2d(const char *grid_name, int nbr_vertices[2], int cyclic[2], double *x_vertices, double *y_vertices, int *grid_id)
Definition yac.c:5452
void yac_cset_config_output_file_instance(int yac_instance_id, const char *filename, int fileformat, int sync_location, int include_definitions)
Definition yac.c:822
void yac_cdef_points_reg2d(int const grid_id, int const *nbr_points, int const located, double const *x_points, double const *y_points, int *point_id)
Definition yac.c:1502
void yac_cget_comps_comm(const char **comp_names, int num_comps, MPI_Comm *comps_comm)
Definition yac.c:1144
void yac_cinit_comm_instance(MPI_Comm comm, int *yac_instance_id)
Definition yac.c:684
char * yac_cget_start_datetime(void)
Definition yac.c:1019
int const YAC_CONFIG_OUTPUT_FORMAT_YAML
Definition yac.c:116
int const YAC_TIME_UNIT_SECOND
Definition yac.c:63
void yac_cdef_grid_unstruct(const char *grid_name, int nbr_vertices, int nbr_cells, int *num_vertices_per_cell, double *x_vertices, double *y_vertices, int *cell_to_vertex, int *grid_id)
Definition yac.c:5488
void yac_cexchange(int const send_field_id, int const recv_field_id, int const collection_size, double ***const send_field, double **recv_field, int *send_info, int *recv_info, int *ierr)
Definition yac.c:4824
void yac_cdef_points_unstruct(int const grid_id, int const nbr_points, int const located, double const *x_points, double const *y_points, int *point_id)
Definition yac.c:1601
void yac_cput(int const field_id, int const collection_size, double ***const send_field, int *info, int *ierr)
Definition yac.c:4212
void yac_cread_config_yaml(const char *yaml_filename)
Definition yac.c:801
char * yac_cget_end_datetime(void)
Definition yac.c:1034
void yac_cdef_calendar(int calendar)
Definition yac.c:1000
void yac_cset_core_mask(int const *is_core, int location, int grid_id)
Definition yac.c:5683
int const YAC_CONFIG_OUTPUT_SYNC_LOC_SYNC_DEF
after synchronization of definition
Definition yac.c:131
void yac_cdef_comps(char const **comp_names, int num_comps, int *comp_ids)
Definition yac.c:1293
int const YAC_PROLEPTIC_GREGORIAN
Definition yac.c:72
void yac_cset_mask(int const *is_valid, int points_id)
Definition yac.c:1795
void yac_ccleanup_instance(int yac_instance_id)
Clean-up a YAC instance (see Restarting YAC)
Definition yac.c:933
int const YAC_CONFIG_OUTPUT_FORMAT_JSON
Definition yac.c:117
void yac_cinit_dummy(void)
Definition yac.c:747
void yac_cdef_field(char const *name, int const comp_id, int const *point_ids, int const num_pointsets, int collection_size, const char *timestep, int time_unit, int *field_id)
Definition yac.c:1891
void yac_cdef_comps_instance(int yac_instance_id, char const **comp_names, int num_comps, int *comp_ids)
Definition yac.c:1256