YetAnotherCoupler 3.5.2
Loading...
Searching...
No Matches
instance.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#ifdef HAVE_CONFIG_H
6#include "config.h"
7#endif
8
9#include <stdlib.h>
10#include <stdio.h>
11#include <string.h>
12
13#include "utils_core.h"
14#include "yac.h"
15#include "instance.h"
16#include "event.h"
17#include "yac_mpi_common.h"
18#include "fields.h"
19#include "component.h"
20#include "config_yaml.h"
21
23 INSTANCE_DEFINITION = 0, // after yac_cinit
24 INSTANCE_DEFINITION_COMP = 1, // after yac_cdef_comp
25 INSTANCE_DEFINITION_SYNC = 2, // after yac_csync_def
26 INSTANCE_EXCHANGE = 3, // after yac_cenddef
28};
29
30static const char * yac_instance_phase_str[] =
31 {"definition phase",
32 "definition phase (after component definition)",
33 "definition phase (after synchronisation)",
34 "exchange phase",
35 "unknown phase"};
36
37#define CHECK_PHASE(FUNC_NAME, REF_PHASE, NEW_PHASE) \
38 { \
39 enum yac_instance_phase ref_phase_ = (REF_PHASE); \
40 YAC_ASSERT_F( \
41 instance->phase == (ref_phase_), \
42 "ERROR(%s): Invalid phase " \
43 "(current phase: \"%s\" expected phase: \"%s\")", \
44 #FUNC_NAME, yac_instance_phase_str[instance->phase], \
45 yac_instance_phase_str[(ref_phase_)]); \
46 instance->phase = (NEW_PHASE); \
47 }
48#define CHECK_MIN_PHASE(FUNC_NAME, MIN_REF_PHASE) \
49 { \
50 enum yac_instance_phase ref_min_phase_ = (MIN_REF_PHASE); \
51 YAC_ASSERT_F( \
52 instance->phase >= (ref_min_phase_), \
53 "ERROR(%s): Invalid phase " \
54 "(current phase: \"%s\" minimum expected phase: \"%s\")", \
55 #FUNC_NAME, yac_instance_phase_str[instance->phase], \
56 yac_instance_phase_str[(ref_min_phase_)]); \
57 }
58#define CHECK_MAX_PHASE(FUNC_NAME, MAX_REF_PHASE) \
59 { \
60 enum yac_instance_phase ref_max_phase_ = (MAX_REF_PHASE); \
61 YAC_ASSERT_F( \
62 instance->phase <= (ref_max_phase_), \
63 "ERROR(%s): Invalid phase " \
64 "(current phase: \"%s\" maximum expected phase: \"%s\")", \
65 #FUNC_NAME, \
66 yac_instance_phase_str[ \
67 MIN(instance->phase,INSTANCE_UNKNOWN)], \
68 yac_instance_phase_str[(ref_max_phase_)]); \
69 }
70
84
86 SRC = 1,
87 TGT = 2
88};
89
91 const char * grid_name;
92 const char * comp_name;
93};
94
98
107 {.timestep = NULL,
108 .coupling_period = NULL,
109 .timelag = 0,
110 .reduction_operation = TIME_NONE,
111 .start_datetime = NULL,
112 .end_datetime = NULL};
113
116 char const * name;
117 int id;
118
119 char const * const * mask_names;
121
123 const char * weight_file_name;
125};
126
129 char const * name;
130 int id;
131 char const * mask_name;
133};
134
156
158 char const * grid_name;
159 char const * filename;
161};
162
164 const char * grid_name, struct yac_basic_grid ** grids, size_t num_grids,
165 int * delete_flag) {
166
167 struct yac_basic_grid * grid = NULL;
168 for (size_t i = 0; (i < num_grids) && (grid == NULL); ++i)
169 if (!strcmp(grid_name, yac_basic_grid_get_name(grids[i])))
170 grid = grids[i];
171
172 *delete_flag = grid == NULL;
173 return (grid == NULL)?yac_basic_grid_empty_new(grid_name):grid;
174}
175
176static
177int compare_comp_grid_config(const void * a, const void * b) {
178
179 struct comp_grid_config * a_ = (struct comp_grid_config *)a,
180 * b_ = (struct comp_grid_config *)b;
181
182 int ret;
183 if ((ret = strcmp(a_->comp_name, b_->comp_name))) return ret;
184 else return strcmp(a_->grid_name, b_->grid_name);
185}
186
188 char const * component_name, const char * field_name,
189 const char * grid_name, size_t num_fields,
190 struct coupling_field ** coupling_fields) {
191
192 for (size_t i = 0; i < num_fields; ++i) {
193 struct coupling_field * curr_field = coupling_fields[i];
194 if (!strcmp(component_name, yac_get_coupling_field_comp_name(curr_field)) &&
195 !strcmp(field_name, yac_get_coupling_field_name(curr_field)) &&
196 !strcmp(grid_name,
199 return curr_field;
200 }
201
202 return NULL;
203}
204
206 struct yac_couple_config * couple_config,
207 size_t couple_idx, size_t field_couple_idx) {
208
209 char const * const * src_mask_names;
210 size_t num_src_mask_names;
212 couple_config, couple_idx, field_couple_idx,
213 &src_mask_names, &num_src_mask_names);
214
215 return
216 (struct src_field_config) {
217 .field = NULL,
218 .name = NULL,
219 .id = INT_MAX,
220 .mask_names = src_mask_names,
221 .num_mask_names = num_src_mask_names,
222 .interp_stack =
224 couple_config, couple_idx, field_couple_idx),
225 .weight_file_name =
227 couple_config, couple_idx, field_couple_idx))?
229 couple_config, couple_idx, field_couple_idx):NULL,
230 .event_data = empty_event_data,
231 };
232}
233
235 struct yac_couple_config * couple_config,
236 size_t couple_idx, size_t field_couple_idx) {
237
238 return
239 (struct tgt_field_config) {
240 .field = NULL,
241 .name = NULL,
242 .id = INT_MAX,
243 .mask_name =
245 couple_config, couple_idx, field_couple_idx),
246 .event_data = empty_event_data,
247 };
248}
249
251 struct coupling_field * a,
252 size_t num_mask_names_a, char const * const * mask_names_a,
253 struct coupling_field * b,
254 size_t num_mask_names_b, char const * const * mask_names_b) {
255
256 if ((a == NULL) || (b == NULL)) return (a == NULL) - (b == NULL);
257
258 size_t num_interp_fields[2] =
261
263 (num_mask_names_a == 0) ||
264 (num_mask_names_a == num_interp_fields[0]),
265 "ERROR(compare_field_config_fields): inconsistent mask names defined")
267 (num_mask_names_b == 0) ||
268 (num_mask_names_b == num_interp_fields[1]),
269 "ERROR(compare_field_config_fields): inconsistent mask names defined")
270
271 // if both fields have different numbers of interpolation fields
272 if (num_interp_fields[0] != num_interp_fields[1])
273 return (int)num_interp_fields[0] - (int)num_interp_fields[1];
274
275 struct yac_basic_grid * grid[2] =
278
279 struct yac_interp_field const * interp_fields[2] =
282
283 for (size_t i = 0; i < num_interp_fields[0]; ++i) {
284
285 int ret;
286
287 enum yac_location location_a = interp_fields[0][i].location;
288 enum yac_location location_b = interp_fields[1][i].location;
289
290 if ((ret = (location_a > location_b) -
291 (location_a < location_b))) return ret;
292
293 yac_const_coordinate_pointer coordinates_a =
294 yac_basic_grid_get_field_coordinates(grid[0], interp_fields[0][i]);
295 yac_const_coordinate_pointer coordinates_b =
296 yac_basic_grid_get_field_coordinates(grid[1], interp_fields[1][i]);
297
298 if ((ret = (coordinates_a > coordinates_b) -
299 (coordinates_a < coordinates_b))) return ret;
300
301 char const * const * mask_names[2] =
302 {num_mask_names_a?mask_names_a:NULL,
303 num_mask_names_b?mask_names_b:NULL};
304 int const * masks[2];
305
306 for (int j = 0; j < 2; ++j) {
307 struct yac_interp_field temp_interp_field = interp_fields[j][i];
308 if (mask_names[j] != NULL)
309 temp_interp_field.masks_idx =
311 grid[j], temp_interp_field.location, mask_names[j][i]);
312
313 masks[j] = yac_basic_grid_get_field_mask(grid[j], temp_interp_field);
314 }
315 if ((ret = (masks[0] > masks[1]) - (masks[0] < masks[1]))) return ret;
316 }
317
318 return 0;
319}
320
321static int compare_field_config_field_ids(const void * a, const void * b) {
322
323 struct field_config * a_ = (struct field_config *)a,
324 * b_ = (struct field_config *)b;
325
326 int ret;
327 if ((ret = a_->src_interp_config.id - b_->src_interp_config.id)) return ret;
328 return a_->tgt_interp_config.id - b_->tgt_interp_config.id;
329
330}
331
332static int
333compare_field_config_interp_method(const void * a, const void * b) {
334
335 struct field_config * a_ = (struct field_config *)a,
336 * b_ = (struct field_config *)b;
337
338 int ret;
339 if ((ret = (int)(a_->src_interp_config.weight_file_name == NULL) -
340 (int)(b_->src_interp_config.weight_file_name == NULL))) return ret;
341 if ((a_->src_interp_config.weight_file_name != NULL) &&
342 (ret = strcmp(a_->src_interp_config.weight_file_name,
343 b_->src_interp_config.weight_file_name))) return ret;
344
345 return
348 b_->src_interp_config.interp_stack);
349}
350
351static
352int compare_field_config(const void * a, const void * b) {
353
354 struct field_config * a_ = (struct field_config *)a,
355 * b_ = (struct field_config *)b;
356
357 int ret;
358 if ((ret = strcmp(a_->comp_grid_pair.config[0].comp_name,
359 b_->comp_grid_pair.config[0].comp_name))) return ret;
360 if ((ret = strcmp(a_->comp_grid_pair.config[1].comp_name,
361 b_->comp_grid_pair.config[1].comp_name))) return ret;
362 if ((ret = strcmp(a_->comp_grid_pair.config[0].grid_name,
363 b_->comp_grid_pair.config[0].grid_name))) return ret;
364 if ((ret = strcmp(a_->comp_grid_pair.config[1].grid_name,
365 b_->comp_grid_pair.config[1].grid_name))) return ret;
366 if ((ret = compare_field_config_field_ids(a_, b_))) return ret;
367 if ((ret = compare_field_config_interp_method(a_, b_))) return ret;
368 if ((ret = (int)(a_->reorder_type) - (int)(b_->reorder_type))) return ret;
369 if ((ret = (a_->scale_factor > b_->scale_factor) -
370 (a_->scale_factor < b_->scale_factor))) return ret;
371 if ((ret = (a_->scale_summand > b_->scale_summand) -
372 (a_->scale_summand < b_->scale_summand))) return ret;
373 if ((ret = (a_->yaxt_exchanger_name == NULL) -
374 (b_->yaxt_exchanger_name == NULL))) return ret;
375 if (a_->yaxt_exchanger_name != NULL)
376 if ((ret = strcmp(a_->yaxt_exchanger_name, b_->yaxt_exchanger_name)))
377 return ret;
378
379 // use memcmp to compare frac_mask_fallback_value, because they can be nan
380 return
381 memcmp(
383 &(b_->frac_mask_fallback_value), sizeof(double));
384}
385
387 struct yac_instance * instance, int couple_idx, int field_couple_idx,
388 enum field_type field_type) {
389
390 struct yac_couple_config * couple_config = instance->couple_config;
391
392 enum yac_reduction_type reduction_operation =
394 couple_config, couple_idx, field_couple_idx);
395
396 char const * coupling_period =
398 couple_config, couple_idx, field_couple_idx);
399 char const * timestep;
400 int timelag;
401 if ( field_type == SRC ){
402 timestep =
404 couple_config, couple_idx, field_couple_idx);
405 timelag =
407 couple_config, couple_idx, field_couple_idx);
408 }else{
409 reduction_operation = TIME_NONE;
410 timestep =
412 couple_config, couple_idx, field_couple_idx);
413 timelag =
415 couple_config, couple_idx, field_couple_idx);
416 }
417
418 return
420 {.timestep = timestep,
421 .coupling_period = coupling_period,
422 .timelag = timelag,
423 .reduction_operation = reduction_operation,
424 .start_datetime = yac_couple_config_get_start_datetime(couple_config),
425 .end_datetime = yac_couple_config_get_end_datetime(couple_config)};
426}
427
428static struct event * generate_event(
429 struct field_config_event_data event_data) {
430
431 struct event * event = yac_event_new();
433 event, event_data.timestep, event_data.coupling_period,
434 event_data.timelag, event_data.reduction_operation,
435 event_data.start_datetime, event_data.end_datetime);
436 return event;
437}
438
440 struct yac_instance * instance,
441 struct field_config ** field_configs_, size_t * count) {
442
443 struct yac_couple_config * couple_config = instance->couple_config;
444 MPI_Comm comm = instance->comm;
445 size_t num_fields = instance->num_cpl_fields;
446 struct coupling_field ** coupling_fields = instance->cpl_fields;
447
448 size_t num_couples = yac_couple_config_get_num_couples(couple_config);
449 size_t total_num_fields = 0;
450 for (size_t couple_idx = 0; couple_idx < num_couples; ++couple_idx)
451 total_num_fields +=
452 yac_couple_config_get_num_couple_fields(couple_config, couple_idx);
453
454 // determine for which configuration source and target field
455 // are available
456 int (*fields_available)[2] =
457 xmalloc(total_num_fields * sizeof(*fields_available));
458 for (size_t couple_idx = 0, i = 0; couple_idx < num_couples;
459 ++couple_idx) {
460 size_t curr_num_fields =
461 yac_couple_config_get_num_couple_fields(couple_config, couple_idx);
462 for (size_t field_couple_idx = 0; field_couple_idx < curr_num_fields;
463 ++field_couple_idx, ++i) {
464 char const * src_component_name;
465 char const * tgt_component_name;
466 char const * src_grid_name;
467 char const * tgt_grid_name;
468 const char * src_field_name;
469 const char * tgt_field_name;
471 couple_config, couple_idx, field_couple_idx,
472 &src_component_name, &tgt_component_name);
474 couple_config, couple_idx, field_couple_idx,
475 &src_grid_name, &tgt_grid_name);
477 couple_config, couple_idx, field_couple_idx,
478 &src_field_name, &tgt_field_name);
479 fields_available[i][0] =
481 src_component_name, src_field_name, src_grid_name,
482 num_fields, coupling_fields) != NULL;
483 fields_available[i][1] =
485 tgt_component_name, tgt_field_name, tgt_grid_name,
486 num_fields, coupling_fields) != NULL;
487 }
488 }
490 MPI_Allreduce(MPI_IN_PLACE, fields_available,
491 2 * total_num_fields,
492 MPI_INT, MPI_MAX, comm), comm);
493 int comm_rank;
494 yac_mpi_call(MPI_Comm_rank(comm, &comm_rank), comm);
495 size_t new_total_num_fields = 0;
496 for (size_t couple_idx = 0, i = 0; couple_idx < num_couples;
497 ++couple_idx) {
498 size_t curr_num_fields =
499 yac_couple_config_get_num_couple_fields(couple_config, couple_idx);
500 for (size_t field_couple_idx = 0; field_couple_idx < curr_num_fields;
501 ++field_couple_idx, ++i) {
502 if (fields_available[i][0] && fields_available[i][1]) {
503 ++new_total_num_fields;
504 } else if (comm_rank == 0) {
505 int missing_definition_is_fatal =
507 char const * src_component_name;
508 char const * tgt_component_name;
509 char const * src_grid_name;
510 char const * tgt_grid_name;
511 const char * src_field_name;
512 const char * tgt_field_name;
514 couple_config, couple_idx, field_couple_idx,
515 &src_component_name, &tgt_component_name);
517 couple_config, couple_idx, field_couple_idx,
518 &src_grid_name, &tgt_grid_name);
520 couple_config, couple_idx, field_couple_idx,
521 &src_field_name, &tgt_field_name);
522 fprintf(stderr, "%s: couple defined for field: \n"
523 " source (%s):\n"
524 " component name: \"%s\"\n"
525 " grid name: \"%s\"\n"
526 " field name: \"%s\"\n"
527 " target(%s):\n"
528 " component name: \"%s\"\n"
529 " grid name: \"%s\"\n"
530 " field name: \"%s\"\n",
531 missing_definition_is_fatal?"ERROR":"WARNING",
532 (fields_available[i][0])?"defined":"not defined",
533 src_component_name, src_grid_name, src_field_name,
534 (fields_available[i][1])?"defined":"not defined",
535 tgt_component_name, tgt_grid_name, tgt_field_name);
537 !missing_definition_is_fatal,
538 "ERROR(get_field_configuration): missing definition")
539 }
540 }
541 }
542 total_num_fields = new_total_num_fields;
543
544 struct field_config * field_configs =
545 xmalloc(total_num_fields * sizeof(*field_configs));
546
547 size_t field_config_idx = 0;
548
549 // extract component, grid configurations from all fields in
550 // the coupling configuration
551 for (size_t couple_idx = 0, i = 0; couple_idx < num_couples; ++couple_idx) {
552
553 size_t curr_num_fields =
554 yac_couple_config_get_num_couple_fields(couple_config, couple_idx);
555
556 for (size_t field_couple_idx = 0; field_couple_idx < curr_num_fields;
557 ++field_couple_idx, ++i) {
558
559 if (!fields_available[i][0] || !fields_available[i][1]) continue;
560
561 struct comp_grid_config src_config, tgt_config;
562
564 couple_config, couple_idx, field_couple_idx,
565 &(src_config.comp_name), &(tgt_config.comp_name));
566
568 couple_config, couple_idx, field_couple_idx,
569 &(src_config.grid_name), &(tgt_config.grid_name));
570
571 int src_comp_idx =
572 compare_comp_grid_config(&src_config, &tgt_config) > 0;
573
574 const char * src_field_name;
575 const char * tgt_field_name;
577 couple_config, couple_idx, field_couple_idx,
578 &src_field_name, &tgt_field_name);
579 struct coupling_field * src_field =
581 src_config.comp_name, src_field_name, src_config.grid_name,
582 num_fields, coupling_fields);
583 struct coupling_field * tgt_field =
585 tgt_config.comp_name, tgt_field_name, tgt_config.grid_name,
586 num_fields, coupling_fields);
587
588 double frac_mask_fallback_value =
590 couple_config, src_config.comp_name, src_config.grid_name,
591 src_field_name);
592 double scale_factor =
594 couple_config, couple_idx, field_couple_idx);
595 double scale_summand =
597 couple_config, couple_idx, field_couple_idx);
598 char const * yaxt_exchanger_name =
600 couple_config, couple_idx, field_couple_idx);
601 size_t collection_size =
603 couple_config, src_config.comp_name, src_config.grid_name,
604 src_field_name);
605
609 couple_config, tgt_config.comp_name, tgt_config.grid_name,
610 tgt_field_name),
611 "ERROR: collection sizes do not match for coupled fields (%zu != %zu): \n"
612 " source:\n"
613 " component name: \"%s\"\n"
614 " grid name: \"%s\"\n"
615 " field name: \"%s\"\n"
616 " target:\n"
617 " component name: \"%s\"\n"
618 " grid name: \"%s\"\n"
619 " field name: \"%s\"\n",
622 couple_config, tgt_config.comp_name, tgt_config.grid_name,
623 tgt_field_name),
624 src_config.comp_name, src_config.grid_name, src_field_name,
625 tgt_config.comp_name, tgt_config.grid_name, tgt_field_name);
626
627 field_configs[field_config_idx].comp_grid_pair.config[src_comp_idx] =
628 src_config;
629 field_configs[field_config_idx].comp_grid_pair.config[src_comp_idx^1] =
630 tgt_config;
631 field_configs[field_config_idx].src_comp_idx = src_comp_idx;
632 field_configs[field_config_idx].src_interp_config =
633 get_src_interp_config(couple_config, couple_idx, field_couple_idx);
634 field_configs[field_config_idx].tgt_interp_config =
635 get_tgt_interp_config(couple_config, couple_idx, field_couple_idx);
636 field_configs[field_config_idx].src_interp_config.field = src_field;
637 field_configs[field_config_idx].tgt_interp_config.field = tgt_field;
638 field_configs[field_config_idx].reorder_type =
640 couple_config, couple_idx, field_couple_idx))?
642 field_configs[field_config_idx].src_interp_config.event_data =
643 get_event_data(instance, couple_idx, field_couple_idx, SRC);
644 field_configs[field_config_idx].tgt_interp_config.event_data =
645 get_event_data(instance, couple_idx, field_couple_idx, TGT);
646 field_configs[field_config_idx].frac_mask_fallback_value =
647 frac_mask_fallback_value;
648 field_configs[field_config_idx].scale_factor = scale_factor;
649 field_configs[field_config_idx].scale_summand = scale_summand;
650 field_configs[field_config_idx].yaxt_exchanger_name = yaxt_exchanger_name;
651 field_configs[field_config_idx].collection_size = collection_size;
652 field_configs[field_config_idx].src_interp_config.name = src_field_name;
653 field_configs[field_config_idx].tgt_interp_config.name = tgt_field_name;
654 ++field_config_idx;
655 }
656 }
657
658 free(fields_available);
659
660 { // determine unique field config ids, for each unique configuration
661 int * field_src_field_config_compare_matrix =
662 xmalloc((size_t)(total_num_fields * (total_num_fields - 1)) *
663 sizeof(*field_src_field_config_compare_matrix));
664 int * field_tgt_field_config_compare_matrix =
665 field_src_field_config_compare_matrix +
666 (size_t)(total_num_fields * (total_num_fields - 1)) / 2;
667
668 for (unsigned i = 0, k = 0; i < total_num_fields; ++i) {
669 for (unsigned j = i + 1; j < total_num_fields; ++j, ++k) {
670 field_src_field_config_compare_matrix[k] =
672 field_configs[i].src_interp_config.field,
673 field_configs[i].src_interp_config.num_mask_names,
674 field_configs[i].src_interp_config.mask_names,
675 field_configs[j].src_interp_config.field,
676 field_configs[j].src_interp_config.num_mask_names,
677 field_configs[j].src_interp_config.mask_names) != 0;
678 field_tgt_field_config_compare_matrix[k] =
680 field_configs[i].tgt_interp_config.field,
681 field_configs[i].tgt_interp_config.mask_name != NULL,
682 &(field_configs[i].tgt_interp_config.mask_name),
683 field_configs[j].tgt_interp_config.field,
684 field_configs[j].tgt_interp_config.mask_name != NULL,
685 &(field_configs[j].tgt_interp_config.mask_name)) != 0;
686 }
687 }
688
690 MPI_Allreduce(MPI_IN_PLACE, field_src_field_config_compare_matrix,
691 total_num_fields * (total_num_fields - 1),
692 MPI_INT, MPI_LOR, comm), comm);
693
694 int * field_src_field_config_ids =
695 xcalloc(2 * (size_t)total_num_fields,
696 sizeof(*field_src_field_config_ids));
697 int * field_tgt_field_config_ids =
698 field_src_field_config_ids + (size_t)total_num_fields;
699
700 for (unsigned i = 0, k = 0, id = 1; i < total_num_fields; ++i) {
701 if (field_src_field_config_ids[i] != 0) {
702 k += total_num_fields - i - 1;
703 continue;
704 } else {
705 field_src_field_config_ids[i] = (int)id;
706 for (unsigned j = i + 1; j < total_num_fields; ++j, ++k)
707 if (!field_src_field_config_compare_matrix[k])
708 field_src_field_config_ids[j] = (int)id;
709 id++;
710 }
711 }
712 for (unsigned i = 0, k = 0, id = 1; i < total_num_fields; ++i) {
713 if (field_tgt_field_config_ids[i] != 0) {
714 k += total_num_fields - i - 1;
715 continue;
716 } else {
717 field_tgt_field_config_ids[i] = (int)id;
718 for (unsigned j = i + 1; j < total_num_fields; ++j, ++k)
719 if (!field_tgt_field_config_compare_matrix[k])
720 field_tgt_field_config_ids[j] = (int)id;
721 id++;
722 }
723 }
724 free(field_src_field_config_compare_matrix);
725
726 for (unsigned i = 0; i < total_num_fields; ++i) {
727 field_configs[i].src_interp_config.id =
728 field_src_field_config_ids[i];
729 field_configs[i].tgt_interp_config.id =
730 field_tgt_field_config_ids[i];
731 }
732 free(field_src_field_config_ids);
733 }
734
735 { // determine unique field config ids, for each unique configuration
736 int * field_config_compare_matrix =
737 xmalloc((size_t)(total_num_fields * (total_num_fields - 1)) / 2 *
738 sizeof(*field_config_compare_matrix));
739 for (unsigned i = 0, k = 0; i < total_num_fields; ++i)
740 for (unsigned j = i + 1; j < total_num_fields; ++j, ++k)
741 field_config_compare_matrix[k] =
743 &(field_configs[i]), &(field_configs[j])) != 0;
744
746 MPI_Allreduce(MPI_IN_PLACE, field_config_compare_matrix,
747 (total_num_fields * (total_num_fields - 1)) / 2,
748 MPI_INT, MPI_LOR, comm), comm);
749
750 int * field_config_ids =
751 xcalloc((size_t)total_num_fields, sizeof(*field_config_ids));
752
753 for (unsigned i = 0, k = 0, id = 1; i < total_num_fields; ++i) {
754 if (field_config_ids[i] != 0) {
755 k += total_num_fields - i - 1;
756 continue;
757 } else {
758 field_config_ids[i] = (int)id;
759 for (unsigned j = i + 1; j < total_num_fields; ++j, ++k)
760 if (!field_config_compare_matrix[k])
761 field_config_ids[j] = (int)id;
762 id++;
763 }
764 }
765 free(field_config_compare_matrix);
766
767 for (unsigned i = 0; i < total_num_fields; ++i)
768 field_configs[i].id = field_config_ids[i];
769 free(field_config_ids);
770 }
771
772 *field_configs_ = field_configs;
773 *count = total_num_fields;
774}
775
776static
777int compare_field_config_ids(const void * a, const void * b) {
778
779 struct field_config * a_ = (struct field_config *)a,
780 * b_ = (struct field_config *)b;
781
782 return a_->id - b_->id;
783}
784
786 struct src_field_config src_interp_config,
787 struct yac_interp_grid * interp_grid) {
788
789 struct interp_method ** method_stack =
791 struct yac_interp_weights * weights =
792 yac_interp_method_do_search(method_stack, interp_grid);
793
794 yac_interp_method_delete(method_stack);
795 free(method_stack);
796
797 return weights;
798}
799
801 struct coupling_field * field, char const * const * mask_names,
802 size_t num_mask_names, struct yac_interp_field ** interp_fields,
803 size_t * num_fields, MPI_Comm comm) {
804
805 struct yac_interp_field * interp_fields_;
806 size_t num_fields_;
807
808 if (field != NULL) {
809
810 num_fields_ = yac_coupling_field_get_num_interp_fields(field);
811
813 (num_mask_names == 0) || (num_fields_ == num_mask_names),
814 "ERROR(get_interp_fields_from_coupling_field): "
815 "missmatch in number of interpolation fields of coupling field \"%s\" "
816 "and number of provided mask names (%zu != %zu)",
817 yac_get_coupling_field_name(field), num_fields_, num_mask_names)
818
819 uint64_t local_counts[2] =
820 {(uint64_t)num_fields_, (uint64_t)num_mask_names};
821 uint64_t global_counts[2];
822
824 MPI_Allreduce(
825 local_counts, global_counts, 2, MPI_UINT64_T, MPI_MAX, comm), comm);
826
828 local_counts[0] == global_counts[0],
829 "ERROR(get_interp_fields_from_coupling_field): missmatch in number of"
830 "local interpolation fields for coupling field \"%s\" and global "
831 "(%zu != %zu)",
832 yac_get_coupling_field_name(field), num_fields_, (size_t)(global_counts[0]))
833
835 (num_mask_names != 0) || (global_counts[1] == 0),
836 "ERROR(get_interp_fields_from_coupling_field): local process did "
837 "not provide mask names for coupling field \"%s\" while others did",
839
840 // make a copy of the interpolation fields of the coupling field
841 interp_fields_ = xmalloc(num_fields_ * sizeof(*interp_fields_));
842 memcpy(
843 interp_fields_, yac_coupling_field_get_interp_fields(field),
844 num_fields_ * sizeof(*interp_fields_));
845
846 // if mask names are provided, overwrite already existing masks
848 for (size_t i = 0; i < num_mask_names; ++i) {
849 char const * mask_name = mask_names[i];
851 mask_name != NULL,
852 "ERROR(get_interp_fields_from_coupling_field): "
853 "make_names[%zu] is NULL", i);
854 interp_fields_[i].masks_idx =
856 grid, interp_fields_[i].location, mask_name);
857 }
858
859 uint64_t data[num_fields_][3];
860
861 for (size_t i = 0; i < num_fields_; ++i) {
862 data[i][0] = (uint64_t)interp_fields_[i].location;
863 data[i][1] = (uint64_t)interp_fields_[i].coordinates_idx;
864 data[i][2] = (uint64_t)interp_fields_[i].masks_idx;
865 }
866
868 MPI_Allreduce(
869 MPI_IN_PLACE, data, 3 * (int)num_fields_,
870 MPI_UINT64_T, MPI_MIN, comm), comm);
871
872 for (size_t i = 0; i < num_fields_; ++i) {
874 data[i][0] == (uint64_t)(interp_fields_[i].location),
875 "ERROR(get_interp_fields_from_coupling_field): location mismatch")
877 data[i][1] == (uint64_t)(interp_fields_[i].coordinates_idx),
878 "ERROR(get_interp_fields_from_coupling_field): "
879 "coordinates index mismatch")
881 data[i][2] == (uint64_t)(interp_fields_[i].masks_idx),
882 "ERROR(get_interp_fields_from_coupling_field): "
883 "masks index mismatch")
884 }
885
886 } else {
887
888 uint64_t zero_counts[2] = {0,0};
889 uint64_t counts[2];
890
892 MPI_Allreduce(
893 zero_counts, counts, 2,
894 MPI_UINT64_T, MPI_MAX, comm), comm);
895
896 num_fields_ = (size_t)(counts[0]);
897 interp_fields_ = xmalloc(num_fields_ * sizeof(*interp_fields_));
898
899 uint64_t data[num_fields_][3];
900
901 for (size_t i = 0; i < num_fields_; ++i) {
902 data[i][0] = (uint64_t)YAC_LOC_UNDEFINED;
903 data[i][1] = (uint64_t)UINT64_MAX;
904 data[i][2] = (uint64_t)UINT64_MAX;
905 }
906
908 MPI_Allreduce(
909 MPI_IN_PLACE, data, 3 * (int)num_fields_,
910 MPI_UINT64_T, MPI_MIN, comm), comm);
911
912 for (size_t i = 0; i < num_fields_; ++i) {
913 interp_fields_[i].location = (enum yac_location)data[i][0];
914 interp_fields_[i].coordinates_idx = (size_t)data[i][1];
915 interp_fields_[i].masks_idx = (size_t)data[i][2];
916 }
917 }
918
919 *interp_fields = interp_fields_;
920 *num_fields = num_fields_;
921}
922
924 struct yac_instance * instance, struct yac_basic_grid ** local_grids,
925 size_t num_local_grids, struct output_grid ** output_grids,
926 size_t * output_grid_count) {
927
928 struct yac_couple_config * couple_config = instance->couple_config;
929
930 // count number of output grids
931 size_t num_grids = yac_couple_config_get_num_grids(couple_config);
932 *output_grid_count = 0;
933 for (size_t grid_idx = 0; grid_idx < num_grids; ++grid_idx)
935 couple_config,
936 yac_couple_config_get_grid_name(couple_config, grid_idx)) != NULL)
937 ++*output_grid_count;
938
939 *output_grids = xmalloc(*output_grid_count * sizeof(**output_grids));
940
941 // extract output grids and check whether the respective grids are
942 // locally available
943 for (size_t grid_idx = 0, output_grid_idx = 0; grid_idx < num_grids; ++grid_idx) {
944 char const * grid_name =
945 yac_couple_config_get_grid_name(couple_config, grid_idx);
946 char const * filename =
947 yac_couple_config_grid_get_output_filename(couple_config, grid_name);
948 if (filename != NULL) {
949 struct yac_basic_grid * local_grid = NULL;
950 for (size_t i = 0; (i < num_local_grids) && (local_grid == NULL); ++i)
951 if (!strcmp(grid_name, yac_basic_grid_get_name(local_grids[i])))
952 local_grid = local_grids[i];
953 (*output_grids)[output_grid_idx].grid_name = grid_name;
954 (*output_grids)[output_grid_idx].filename = filename;
955 (*output_grids)[output_grid_idx].grid = local_grid;
956 ++output_grid_idx;
957 }
958 }
959}
960
961static int compare_output_grids(const void * a, const void * b) {
962
963 return
964 strcmp(
965 ((struct output_grid*)a)->grid_name,
966 ((struct output_grid*)b)->grid_name);
967}
968
970 struct yac_instance * instance, struct yac_basic_grid ** grids, size_t num_grids) {
971
972 MPI_Comm comm = instance->comm;
973
974 // get information about all grids that have to be written to file
975 struct output_grid * output_grids;
976 size_t output_grid_count;
978 instance, grids, num_grids, &output_grids, &output_grid_count);
979
980 // sort output grids
981 qsort(
982 output_grids, output_grid_count, sizeof(*output_grids),
984
985 // for all grids that have to be written to file
986 for (size_t i = 0; i < output_grid_count; ++i) {
987
988 struct yac_basic_grid * grid = output_grids[i].grid;
989 int split_key = (grid != NULL)?1:MPI_UNDEFINED;
990
991 // generate a communicator containing all processes that
992 // have parts of the current grid locally available
993 MPI_Comm output_comm;
994 yac_mpi_call(MPI_Comm_split(comm, split_key, 0, &output_comm), comm);
995
996 // if the local process has some data of the grid locally available
997 if (grid != NULL) {
998
999 // write grid to file in parallel
1001 grid, output_grids[i].filename, output_comm);
1002
1003 yac_mpi_call(MPI_Comm_free(&output_comm), comm);
1004 }
1005 }
1006
1007 free(output_grids);
1008
1009 // wait until all grids have been written
1010 yac_mpi_call(MPI_Barrier(comm), comm);
1011}
1012
1014 struct yac_instance * instance, struct yac_basic_grid ** grids, size_t num_grids) {
1015
1016 MPI_Comm comm = instance->comm;
1017
1018 // get information about all fields
1019 struct field_config * field_configs;
1020 size_t field_count;
1022 instance, &field_configs, &field_count);
1023
1024 // sort field configurations
1025 qsort(field_configs, field_count, sizeof(*field_configs),
1027
1028 struct yac_dist_grid_pair * dist_grid_pair = NULL;
1029 struct yac_interp_grid * interp_grid = NULL;
1030 struct yac_interp_weights * interp_weights = NULL;
1031 struct yac_interpolation * interp = NULL;
1032 struct comp_grid_pair_config * prev_comp_grid_pair = NULL;
1033 MPI_Comm comp_pair_comm = MPI_COMM_NULL;
1034 int is_active = 0;
1035
1036 // loop over all fields to build interpolations
1037 for (size_t i = 0; i < field_count; ++i) {
1038
1039 struct field_config * curr_field_config = field_configs + i;
1040 struct comp_grid_pair_config * curr_comp_grid_pair =
1041 &(curr_field_config->comp_grid_pair);
1042
1043 int build_flag = 0;
1044 // if the current comp pair is different from the previous one
1045 // => generate a component pair communicator
1046 if ((prev_comp_grid_pair == NULL) ||
1047 (strcmp(prev_comp_grid_pair->config[0].comp_name,
1048 curr_comp_grid_pair->config[0].comp_name) ||
1049 strcmp(prev_comp_grid_pair->config[1].comp_name,
1050 curr_comp_grid_pair->config[1].comp_name))) {
1051
1052 build_flag = 1;
1053
1054 if (comp_pair_comm != MPI_COMM_NULL)
1055 yac_mpi_call(MPI_Comm_free(&comp_pair_comm), comm);
1056
1057 int comp_is_available[2] =
1059 instance->comp_config,
1060 curr_comp_grid_pair->config[0].comp_name),
1062 instance->comp_config,
1063 curr_comp_grid_pair->config[1].comp_name)};
1064
1065 is_active = comp_is_available[0] || comp_is_available[1];
1066
1067 yac_mpi_call(MPI_Comm_split(comm, is_active, 0,
1068 &comp_pair_comm), comm);
1069
1070 // determine whether both components are available in the setup
1071 yac_mpi_call(MPI_Allreduce(MPI_IN_PLACE, comp_is_available, 2,
1072 MPI_INT, MPI_LOR, comp_pair_comm), comm);
1073 is_active = comp_is_available[0] && comp_is_available[1];
1074 }
1075
1076 // if the current configuration differs from the previous one and the local
1077 // process is involved in this configuration
1078 if (is_active &&
1079 (build_flag ||
1080 strcmp(prev_comp_grid_pair->config[0].grid_name,
1081 curr_comp_grid_pair->config[0].grid_name) ||
1082 strcmp(prev_comp_grid_pair->config[1].grid_name,
1083 curr_comp_grid_pair->config[1].grid_name))) {
1084
1085 build_flag = 1;
1086
1087 if (dist_grid_pair != NULL) yac_dist_grid_pair_delete(dist_grid_pair);
1088
1089 char const * grid_names[2] =
1090 {curr_comp_grid_pair->config[0].grid_name,
1091 curr_comp_grid_pair->config[1].grid_name};
1092
1093 int delete_flags[2];
1094 struct yac_basic_grid * basic_grid[2] =
1095 {get_basic_grid(grid_names[0], grids, num_grids, &delete_flags[0]),
1096 get_basic_grid(grid_names[1], grids, num_grids, &delete_flags[1])};
1097
1098 dist_grid_pair =
1099 yac_dist_grid_pair_new(basic_grid[0], basic_grid[1], comp_pair_comm);
1100
1101 for (int i = 0; i < 2; ++i)
1102 if (delete_flags[i]) yac_basic_grid_delete(basic_grid[i]);
1103 }
1104
1105 // if the current source or target field data differes from the previous
1106 // one
1107 if (is_active &&
1108 (build_flag ||
1110 curr_field_config - 1, curr_field_config))) {
1111
1112 build_flag = 1;
1113
1114 struct yac_interp_field * src_fields;
1115 size_t num_src_fields;
1117 curr_field_config->src_interp_config.field,
1118 curr_field_config->src_interp_config.mask_names,
1119 curr_field_config->src_interp_config.num_mask_names,
1120 &src_fields, &num_src_fields, comp_pair_comm);
1121 struct yac_interp_field * tgt_fields;
1122 size_t num_tgt_fields;
1124 curr_field_config->tgt_interp_config.field,
1125 &(curr_field_config->tgt_interp_config.mask_name),
1126 curr_field_config->tgt_interp_config.mask_name != NULL,
1127 &tgt_fields, &num_tgt_fields, comp_pair_comm);
1128
1129 YAC_ASSERT(
1130 num_tgt_fields == 1,
1131 "ERROR(generate_interpolations): "
1132 "only one point set per target field supported")
1133
1134 if (interp_grid != NULL) yac_interp_grid_delete(interp_grid);
1135
1136 int src_comp_idx = field_configs[i].src_comp_idx;
1137 interp_grid = yac_interp_grid_new(
1138 dist_grid_pair,
1139 curr_comp_grid_pair->config[src_comp_idx].grid_name,
1140 curr_comp_grid_pair->config[src_comp_idx^1].grid_name,
1141 num_src_fields, src_fields, *tgt_fields);
1142
1143 free(tgt_fields);
1144 free(src_fields);
1145 }
1146
1147 // if the current interpolation method stack differes from the previous
1148 // configuration
1149 if (is_active &&
1150 (build_flag ||
1152 curr_field_config - 1, curr_field_config))) {
1153
1154 build_flag = 1;
1155
1156 if (interp_weights != NULL) yac_interp_weights_delete(interp_weights);
1157
1158 // generate interp weights
1159 interp_weights = generate_interp_weights(
1160 curr_field_config->src_interp_config, interp_grid);
1161 }
1162
1163 if (is_active &&
1164 (curr_field_config->src_interp_config.weight_file_name != NULL)) {
1165
1166 int src_comp_idx = field_configs[i].src_comp_idx;
1167
1169 interp_weights,
1170 curr_field_config->src_interp_config.weight_file_name,
1171 curr_comp_grid_pair->config[src_comp_idx].grid_name,
1172 curr_comp_grid_pair->config[src_comp_idx^1].grid_name, 0, 0);
1173 }
1174
1175 // if the current weight reorder method differs from the previous
1176 // configuration
1177 // (use memcmp to compare frac_mask_fallback_value, because they can be nan)
1178 if (is_active &&
1179 (build_flag ||
1180 (curr_field_config[-1].reorder_type !=
1181 curr_field_config->reorder_type) ||
1182 (curr_field_config[-1].collection_size !=
1183 curr_field_config->collection_size) ||
1184 (curr_field_config[-1].scale_factor !=
1185 curr_field_config->scale_factor) ||
1186 (curr_field_config[-1].scale_summand !=
1187 curr_field_config->scale_summand) ||
1188 ((curr_field_config[-1].yaxt_exchanger_name == NULL) !=
1189 (curr_field_config->yaxt_exchanger_name == NULL)) ||
1190 ((curr_field_config->yaxt_exchanger_name != NULL) &&
1191 strcmp(curr_field_config[-1].yaxt_exchanger_name,
1192 curr_field_config->yaxt_exchanger_name)) ||
1193 memcmp(
1194 &(curr_field_config[-1].frac_mask_fallback_value),
1195 &(curr_field_config->frac_mask_fallback_value),
1196 sizeof(double)))) {
1197
1198 if (interp != NULL) yac_interpolation_delete(interp);
1199
1200 // generate interpolation
1201 interp =
1203 interp_weights, curr_field_config->reorder_type,
1204 curr_field_config->collection_size,
1205 curr_field_config->frac_mask_fallback_value,
1206 curr_field_config->scale_factor,
1207 curr_field_config->scale_summand,
1208 curr_field_config->yaxt_exchanger_name);
1209 }
1210
1211 if (is_active) {
1212
1213 int is_source = curr_field_config->src_interp_config.field != NULL;
1214 int is_target = curr_field_config->tgt_interp_config.field != NULL;
1215
1216 struct yac_interpolation * interp_copy = yac_interpolation_copy(interp);
1217
1218 if (is_source) {
1220 curr_field_config->src_interp_config.field,
1222 curr_field_config->src_interp_config.event_data),
1223 interp_copy);
1225 }
1226
1227 if (is_target) {
1229 curr_field_config->tgt_interp_config.field,
1231 curr_field_config->tgt_interp_config.event_data),
1232 interp_copy);
1234 }
1235
1236 yac_interpolation_delete(interp_copy);
1237
1238 }
1239
1240 prev_comp_grid_pair = curr_comp_grid_pair;
1241 }
1242
1244 yac_interp_weights_delete(interp_weights);
1245 yac_interp_grid_delete(interp_grid);
1246 yac_dist_grid_pair_delete(dist_grid_pair);
1247 if (comp_pair_comm != MPI_COMM_NULL)
1248 yac_mpi_call(MPI_Comm_free(&comp_pair_comm), comm);
1249 for (size_t i = 0; i < field_count; ++i) {
1250 free((void*)(field_configs[i].src_interp_config.event_data.start_datetime));
1251 free((void*)(field_configs[i].src_interp_config.event_data.end_datetime));
1252 free((void*)(field_configs[i].tgt_interp_config.event_data.start_datetime));
1253 free((void*)(field_configs[i].tgt_interp_config.event_data.end_datetime));
1254 }
1255 free(field_configs);
1256}
1257
1258void yac_instance_sync_def(struct yac_instance * instance) {
1261 YAC_ASSERT(instance->comp_config,
1262 "ERROR(yac_instance_sync_def): no components have been defined");
1264 instance->couple_config, instance->comm,
1266}
1267
1269 struct yac_instance * instance, struct yac_basic_grid ** grids, size_t num_grids) {
1270 // if definitions have not yet been synced
1271 int requires_def_sync = (instance->phase == INSTANCE_DEFINITION_COMP);
1272 if (requires_def_sync)
1273 yac_instance_sync_def(instance);
1275
1276 YAC_ASSERT(
1277 instance->comp_config,
1278 "ERROR(yac_instance_setup): no components have been defined");
1279
1280 // sync again, in case a process has done additional definitions
1281 // after the yac_instance_sync_def call
1283 instance->couple_config, instance->comm,
1285
1286 // write grids to file (if enabled in coupling configuration)
1288
1290}
1291
1293 struct yac_instance * instance, struct yac_basic_grid ** grids,
1294 size_t num_grids, int emit_flags) {
1295
1297
1298 int include_definitions = 0;
1299 return
1301 instance->couple_config, emit_flags, include_definitions);
1302}
1303
1305 struct yac_instance * instance,
1306 char const ** comp_names, size_t num_comp_names) {
1308 return
1310 instance->comp_config, comp_names, num_comp_names);
1311}
1312
1314 struct yac_instance * instance,
1315 const char* comp_name){
1317 return
1319 instance->comp_config, comp_name);
1320}
1321
1323 struct yac_instance * instance,
1324 const char* comp_name){
1326 return
1328 instance->comp_config, comp_name);
1329}
1330
1332
1333 struct yac_instance * instance = xmalloc(1 * sizeof(*instance));
1334
1336
1337 instance->comp_config = NULL;
1338
1339 instance->cpl_fields = NULL;
1340 instance->num_cpl_fields = 0;
1341
1342 yac_mpi_call(MPI_Comm_split(comm, 0, 0, &(instance->comm)), comm);
1343
1344 instance->phase = INSTANCE_DEFINITION;
1345
1346 return instance;
1347}
1348
1349
1351
1352 MPI_Comm dummy_comm;
1353 yac_mpi_call(MPI_Comm_split(comm, MPI_UNDEFINED, 0, &dummy_comm), comm);
1354}
1355
1356void yac_instance_delete(struct yac_instance * instance) {
1357
1358 if (instance == NULL) return;
1359
1361
1362 for (size_t i = 0; i < instance->num_cpl_fields; ++i)
1364 free(instance->cpl_fields);
1365
1367
1368 yac_mpi_call(MPI_Comm_free(&(instance->comm)), MPI_COMM_WORLD);
1369
1370 free(instance);
1371}
1372
1374 struct yac_instance * instance) {
1375
1376 return instance->couple_config;
1377}
1378
1380 struct yac_instance * instance,
1381 struct yac_couple_config * couple_config) {
1382 CHECK_MAX_PHASE("yac_instance_set_couple_config", INSTANCE_DEFINITION);
1383 if (instance->couple_config == couple_config) return;
1385 instance->couple_config = couple_config;
1386}
1387
1389 struct yac_instance * instance, const char * start_datetime,
1390 const char * end_datetime ) {
1391 CHECK_MAX_PHASE("yac_instance_def_datetime", INSTANCE_DEFINITION_COMP);
1394}
1395
1397 CHECK_MIN_PHASE("yac_instance_get_start_datetime", INSTANCE_DEFINITION_COMP);
1398 return (char*)yac_couple_config_get_start_datetime(instance->couple_config);
1399}
1400
1402 CHECK_MIN_PHASE("yac_instance_get_end_datetime", INSTANCE_DEFINITION_COMP);
1403 return (char*)yac_couple_config_get_end_datetime(instance->couple_config);
1404}
1405
1407 struct yac_instance * instance,
1408 char const ** comp_names, size_t num_comps) {
1411
1412 YAC_ASSERT(
1413 !instance->comp_config,
1414 "ERROR(yac_instance_def_components): components have already been defined")
1415
1416 // add components to coupling configuration
1417 for (size_t i = 0; i < num_comps; ++i)
1418 yac_couple_config_add_component(instance->couple_config, comp_names[i]);
1419
1420 // synchronise coupling configuration
1422 instance->couple_config, instance->comm,
1424
1425 instance->comp_config =
1427 instance->couple_config, comp_names, num_comps, instance->comm);
1428}
1429
1431 struct yac_instance * instance) {
1432 return instance->phase > INSTANCE_DEFINITION_COMP;
1433}
1434
1436 struct yac_instance * instance, char const * field_name,
1437 char const * comp_name, struct yac_basic_grid * grid,
1439 int collection_size, char const * timestep) {
1442
1443 struct yac_couple_config * couple_config = instance->couple_config;
1444 char const * grid_name = yac_basic_grid_get_name(grid);
1445 if(!yac_couple_config_contains_grid_name(couple_config, grid_name))
1446 yac_couple_config_add_grid(couple_config, grid_name);
1447
1448 YAC_ASSERT(
1449 field_name, "ERROR(yac_instance_add_field): "
1450 "\"NULL\" is not a valid field name")
1451 YAC_ASSERT(
1452 strlen(field_name) <= YAC_MAX_CHARLEN,
1453 "ERROR(yac_instance_add_field): field name is too long "
1454 "(maximum is YAC_MAX_CHARLEN)")
1456 (collection_size > 0) && (collection_size < INT_MAX),
1457 "ERROR(yac_instance_add_field): \"%d\" is not a valid collection size "
1458 "(component \"%s\" grid \"%s\" field \"%s\")",
1459 collection_size, comp_name, grid_name, field_name)
1460
1461 // add field to coupling configuration
1463 couple_config, comp_name, grid_name, field_name,
1464 timestep, collection_size);
1465
1466 // check whether the field is already defined
1467 for (size_t i = 0; i < instance->num_cpl_fields; ++i) {
1468 struct coupling_field * cpl_field = instance->cpl_fields[i];
1470 strcmp(yac_get_coupling_field_name(cpl_field), field_name) ||
1471 (strcmp(
1472 yac_get_coupling_field_comp_name(cpl_field), comp_name)) ||
1474 "ERROR(yac_instance_add_field): "
1475 "field with the name \"%s\" has already been defined",
1476 field_name);
1477 }
1478
1479 struct coupling_field * cpl_field =
1481 field_name, comp_name, grid, interp_fields, num_interp_fields,
1483
1484 instance->cpl_fields =
1485 xrealloc(
1486 instance->cpl_fields,
1487 (instance->num_cpl_fields + 1) * sizeof(*(instance->cpl_fields)));
1488 instance->cpl_fields[instance->num_cpl_fields] = cpl_field;
1489 instance->num_cpl_fields++;
1490
1491 return cpl_field;
1492}
1493
1495 struct yac_instance * instance,
1496 char const * src_comp_name, char const * src_grid_name, char const * src_field_name,
1497 char const * tgt_comp_name, char const * tgt_grid_name, char const * tgt_field_name,
1498 char const * coupling_period, int time_reduction,
1499 struct yac_interp_stack_config * interp_stack_config, int src_lag, int tgt_lag,
1500 const char* weight_file_name, int mapping_on_source,
1501 double scale_factor, double scale_summand, size_t num_src_mask_names,
1502 char const * const * src_mask_names, char const * tgt_mask_name,
1503 char const * yaxt_exchanger_name) {
1504
1507
1509 instance->couple_config, src_comp_name, src_grid_name, src_field_name,
1510 tgt_comp_name, tgt_grid_name, tgt_field_name, coupling_period,
1511 time_reduction, interp_stack_config, src_lag, tgt_lag, weight_file_name,
1512 mapping_on_source, scale_factor, scale_summand, num_src_mask_names,
1513 src_mask_names, tgt_mask_name, yaxt_exchanger_name);
1514}
1515
1517 const char * comp_name, const char* grid_name, const char * field_name){
1518 CHECK_MIN_PHASE("yac_instance_get_field", INSTANCE_DEFINITION_COMP);
1519 return get_coupling_field(comp_name, field_name,
1520 grid_name, instance->num_cpl_fields, instance->cpl_fields);
1521}
size_t yac_basic_grid_get_named_mask_idx(struct yac_basic_grid *grid, enum yac_location location, char const *mask_name)
Definition basic_grid.c:177
int const * yac_basic_grid_get_field_mask(struct yac_basic_grid *grid, struct yac_interp_field field)
Definition basic_grid.c:118
void yac_basic_grid_to_file_parallel(struct yac_basic_grid *grid, char const *filename, MPI_Comm comm)
Definition basic_grid.c:742
yac_const_coordinate_pointer yac_basic_grid_get_field_coordinates(struct yac_basic_grid *grid, struct yac_interp_field field)
Definition basic_grid.c:81
char const * yac_basic_grid_get_name(struct yac_basic_grid *grid)
Definition basic_grid.c:128
struct yac_basic_grid * yac_basic_grid_empty_new(char const *name)
Definition basic_grid.c:63
void yac_basic_grid_delete(struct yac_basic_grid *grid)
Definition basic_grid.c:70
int yac_component_config_comp_size(struct yac_component_config *comp_config, char const *comp_name)
Definition component.c:271
int yac_component_config_comp_rank(struct yac_component_config *comp_config, char const *comp_name)
Definition component.c:281
void yac_component_config_delete(struct yac_component_config *comp_config)
Definition component.c:291
MPI_Comm yac_component_config_get_comps_comm(struct yac_component_config *comp_config, const char **names, size_t num_names)
Definition component.c:142
int yac_component_config_contains_component(struct yac_component_config *comp_config, char const *comp_name)
Definition component.c:244
struct yac_component_config * yac_component_config_new(struct yac_couple_config *couple_config, char const **names, size_t num_names, MPI_Comm comm_)
Definition component.c:38
char * yac_yaml_emit_coupling(struct yac_couple_config *couple_config, int emit_flags, int include_definitions)
char const * yac_couple_config_get_yaxt_exchanger_name(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
void yac_couple_config_sync(struct yac_couple_config *couple_config, MPI_Comm comm, char const *output_ref)
void yac_couple_config_get_field_grid_names(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx, char const **src_grid_name, char const **tgt_grid_name)
int yac_couple_config_contains_grid_name(struct yac_couple_config *couple_config, char const *grid_name)
const char * yac_couple_config_grid_get_output_filename(struct yac_couple_config *couple_config, const char *grid_name)
char * yac_couple_config_get_start_datetime(struct yac_couple_config *couple_config)
void yac_couple_config_set_datetime(struct yac_couple_config *couple_config, char const *start, char const *end)
void yac_couple_config_component_add_field(struct yac_couple_config *couple_config, const char *component_name, const char *grid_name, const char *name, char const *timestep, size_t collection_size)
int yac_couple_config_mapping_on_source(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
char const * yac_couple_config_get_coupling_period(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
struct yac_interp_stack_config * yac_couple_config_get_interp_stack(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
size_t yac_couple_config_get_field_collection_size(struct yac_couple_config *couple_config, char const *component_name, char const *grid_name, char const *field_name)
size_t yac_couple_config_get_num_couple_fields(struct yac_couple_config *couple_config, size_t couple_idx)
void yac_couple_config_get_src_mask_names(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx, char const *const **mask_names, size_t *num_mask_names)
size_t yac_couple_config_get_num_couples(struct yac_couple_config *couple_config)
int yac_couple_config_get_target_lag(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
void yac_couple_config_def_couple(struct yac_couple_config *couple_config, char const *src_comp_name, char const *src_grid_name, char const *src_field_name, char const *tgt_comp_name, char const *tgt_grid_name, char const *tgt_field_name, char const *coupling_period, int time_reduction, struct yac_interp_stack_config *interp_stack, int src_lag, int tgt_lag, const char *weight_file_name, int mapping_on_source, double scale_factor, double scale_summand, size_t num_src_mask_names, char const *const *src_mask_names, char const *tgt_mask_name, char const *yaxt_exchanger_name)
double yac_couple_config_get_frac_mask_fallback_value(struct yac_couple_config *couple_config, char const *component_name, char const *grid_name, char const *field_name)
int yac_couple_config_get_source_lag(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
double yac_couple_config_get_scale_factor(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
char const * yac_couple_config_get_tgt_mask_name(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
void yac_couple_config_add_grid(struct yac_couple_config *couple_config, char const *name)
char const * yac_couple_config_get_grid_name(struct yac_couple_config *couple_config, size_t grid_idx)
double yac_couple_config_get_scale_summand(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
enum yac_reduction_type yac_couple_config_get_coupling_period_operation(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
int yac_couple_config_enforce_write_weight_file(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
void yac_couple_config_get_field_names(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx, char const **src_field_name, const char **tgt_field_name)
struct yac_couple_config * yac_couple_config_new()
char const * yac_couple_config_get_weight_file_name(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
int yac_couple_config_get_missing_definition_is_fatal(struct yac_couple_config *couple_config)
void yac_couple_config_get_field_couple_component_names(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx, char const **src_component_name, char const **tgt_component_name)
char const * yac_couple_config_get_source_timestep(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
void yac_couple_config_add_component(struct yac_couple_config *couple_config, char const *name)
size_t yac_couple_config_get_num_grids(struct yac_couple_config *couple_config)
char * yac_couple_config_get_end_datetime(struct yac_couple_config *couple_config)
char const * yac_couple_config_get_target_timestep(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
void yac_couple_config_delete(struct yac_couple_config *couple_config)
yac_reduction_type
@ TIME_NONE
void yac_dist_grid_pair_delete(struct yac_dist_grid_pair *grid_pair)
Definition dist_grid.c:2608
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:2359
struct event * yac_event_new()
Definition event.c:36
void yac_event_add(struct event *event, char const *delta_model_time, char const *delta_coupling_time, int lag, enum yac_reduction_type time_operation, const char *startdate, const char *stopdate)
Definition event.c:55
void yac_set_coupling_field_put_op(struct coupling_field *field, struct event *event, struct yac_interpolation *interpolation)
Definition fields.c:464
void yac_set_coupling_field_get_op(struct coupling_field *field, struct event *event, struct yac_interpolation *interpolation)
Definition fields.c:494
char const * yac_get_coupling_field_comp_name(struct coupling_field *field)
Definition fields.c:119
struct yac_basic_grid * yac_coupling_field_get_basic_grid(struct coupling_field *field)
Definition fields.c:113
size_t yac_coupling_field_get_num_interp_fields(struct coupling_field *field)
Definition fields.c:96
struct yac_interp_field const * yac_coupling_field_get_interp_fields(struct coupling_field *cpl_field)
Definition fields.c:509
struct coupling_field * yac_coupling_field_new(char const *field_name, char const *component_name, struct yac_basic_grid *grid, struct yac_interp_field *interp_fields, unsigned num_interp_fields, size_t collection_size, const char *timestep)
Definition fields.c:54
const char * yac_get_coupling_field_name(struct coupling_field *field)
Definition fields.c:108
void yac_coupling_field_delete(struct coupling_field *cpl_field)
Definition fields.c:532
void yac_instance_delete(struct yac_instance *instance)
Definition instance.c:1356
char * yac_instance_setup_and_emit_config(struct yac_instance *instance, struct yac_basic_grid **grids, size_t num_grids, int emit_flags)
Definition instance.c:1292
int yac_instance_get_comp_rank(struct yac_instance *instance, const char *comp_name)
Definition instance.c:1322
char * yac_instance_get_start_datetime(struct yac_instance *instance)
Definition instance.c:1396
char * yac_instance_get_end_datetime(struct yac_instance *instance)
Definition instance.c:1401
void yac_instance_def_datetime(struct yac_instance *instance, const char *start_datetime, const char *end_datetime)
Definition instance.c:1388
void yac_instance_setup(struct yac_instance *instance, struct yac_basic_grid **grids, size_t num_grids)
Definition instance.c:1268
void yac_instance_sync_def(struct yac_instance *instance)
Definition instance.c:1258
static void get_output_grids(struct yac_instance *instance, struct yac_basic_grid **local_grids, size_t num_local_grids, struct output_grid **output_grids, size_t *output_grid_count)
Definition instance.c:923
struct yac_instance * yac_instance_new(MPI_Comm comm)
Definition instance.c:1331
int yac_instance_components_are_defined(struct yac_instance *instance)
Definition instance.c:1430
void yac_instance_def_couple(struct yac_instance *instance, char const *src_comp_name, char const *src_grid_name, char const *src_field_name, char const *tgt_comp_name, char const *tgt_grid_name, char const *tgt_field_name, char const *coupling_period, int time_reduction, struct yac_interp_stack_config *interp_stack_config, int src_lag, int tgt_lag, const char *weight_file_name, int mapping_on_source, double scale_factor, double scale_summand, size_t num_src_mask_names, char const *const *src_mask_names, char const *tgt_mask_name, char const *yaxt_exchanger_name)
Definition instance.c:1494
static int compare_output_grids(const void *a, const void *b)
Definition instance.c:961
static void generate_interpolations(struct yac_instance *instance, struct yac_basic_grid **grids, size_t num_grids)
Definition instance.c:1013
struct coupling_field * yac_instance_add_field(struct yac_instance *instance, char const *field_name, char const *comp_name, struct yac_basic_grid *grid, struct yac_interp_field *interp_fields, size_t num_interp_fields, int collection_size, char const *timestep)
Definition instance.c:1435
void yac_instance_set_couple_config(struct yac_instance *instance, struct yac_couple_config *couple_config)
Definition instance.c:1379
static struct coupling_field * get_coupling_field(char const *component_name, const char *field_name, const char *grid_name, size_t num_fields, struct coupling_field **coupling_fields)
Definition instance.c:187
void yac_instance_dummy_new(MPI_Comm comm)
Definition instance.c:1350
static struct yac_basic_grid * get_basic_grid(const char *grid_name, struct yac_basic_grid **grids, size_t num_grids, int *delete_flag)
Definition instance.c:163
void yac_instance_def_components(struct yac_instance *instance, char const **comp_names, size_t num_comps)
Definition instance.c:1406
#define CHECK_MIN_PHASE(FUNC_NAME, MIN_REF_PHASE)
Definition instance.c:48
static void get_field_configuration(struct yac_instance *instance, struct field_config **field_configs_, size_t *count)
Definition instance.c:439
static int compare_field_config_ids(const void *a, const void *b)
Definition instance.c:777
static int compare_field_config_fields(struct coupling_field *a, size_t num_mask_names_a, char const *const *mask_names_a, struct coupling_field *b, size_t num_mask_names_b, char const *const *mask_names_b)
Definition instance.c:250
struct yac_couple_config * yac_instance_get_couple_config(struct yac_instance *instance)
Definition instance.c:1373
struct field_config_event_data get_event_data(struct yac_instance *instance, int couple_idx, int field_couple_idx, enum field_type field_type)
Definition instance.c:386
static int compare_comp_grid_config(const void *a, const void *b)
Definition instance.c:177
static struct tgt_field_config get_tgt_interp_config(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
Definition instance.c:234
static struct field_config_event_data empty_event_data
static struct src_field_config get_src_interp_config(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
Definition instance.c:205
static const char * yac_instance_phase_str[]
Definition instance.c:30
static struct event * generate_event(struct field_config_event_data event_data)
Definition instance.c:428
static int compare_field_config_field_ids(const void *a, const void *b)
Definition instance.c:321
#define CHECK_PHASE(FUNC_NAME, REF_PHASE, NEW_PHASE)
Definition instance.c:37
static void write_grids_to_file(struct yac_instance *instance, struct yac_basic_grid **grids, size_t num_grids)
Definition instance.c:969
#define CHECK_MAX_PHASE(FUNC_NAME, MAX_REF_PHASE)
Definition instance.c:58
static void get_interp_fields_from_coupling_field(struct coupling_field *field, char const *const *mask_names, size_t num_mask_names, struct yac_interp_field **interp_fields, size_t *num_fields, MPI_Comm comm)
Definition instance.c:800
yac_instance_phase
Definition instance.c:22
@ INSTANCE_EXCHANGE
Definition instance.c:26
@ INSTANCE_DEFINITION_COMP
Definition instance.c:24
@ INSTANCE_DEFINITION_SYNC
Definition instance.c:25
@ INSTANCE_DEFINITION
Definition instance.c:23
@ INSTANCE_UNKNOWN
Definition instance.c:27
static int compare_field_config(const void *a, const void *b)
Definition instance.c:352
int yac_instance_get_comp_size(struct yac_instance *instance, const char *comp_name)
Definition instance.c:1313
field_type
Definition instance.c:85
@ TGT
Definition instance.c:87
@ SRC
Definition instance.c:86
MPI_Comm yac_instance_get_comps_comm(struct yac_instance *instance, char const **comp_names, size_t num_comp_names)
Definition instance.c:1304
static int compare_field_config_interp_method(const void *a, const void *b)
Definition instance.c:333
static struct yac_interp_weights * generate_interp_weights(struct src_field_config src_interp_config, struct yac_interp_grid *interp_grid)
Definition instance.c:785
struct coupling_field * yac_instance_get_field(struct yac_instance *instance, const char *comp_name, const char *grid_name, const char *field_name)
Definition instance.c:1516
#define YAC_INSTANCE_CONFIG_OUTPUT_REF_ENDDEF
Definition instance.h:35
#define YAC_INSTANCE_CONFIG_OUTPUT_REF_COMP
Definition instance.h:33
#define YAC_INSTANCE_CONFIG_OUTPUT_REF_SYNC
Definition instance.h:34
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
void yac_interp_method_delete(struct interp_method **method)
struct yac_interp_weights * yac_interp_method_do_search(struct interp_method **method, struct yac_interp_grid *interp_grid)
int yac_interp_stack_config_compare(void const *a_, void const *b_)
struct interp_method ** yac_interp_stack_config_generate(struct yac_interp_stack_config *interp_stack)
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)
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)
yac_interp_weights_reorder_type
@ YAC_MAPPING_ON_TGT
weights will be applied at target processes
@ YAC_MAPPING_ON_SRC
weights will be appied at source processes
struct yac_interpolation * yac_interpolation_copy(struct yac_interpolation *interp)
void yac_interpolation_inc_ref_count(struct yac_interpolation *interpolation)
void yac_interpolation_delete(struct yac_interpolation *interp)
yac_location
Definition location.h:12
@ YAC_LOC_UNDEFINED
Definition location.h:17
#define xrealloc(ptr, size)
Definition ppm_xfuncs.h:67
#define xcalloc(nmemb, size)
Definition ppm_xfuncs.h:64
#define xmalloc(size)
Definition ppm_xfuncs.h:66
const char * comp_name
Definition instance.c:92
const char * grid_name
Definition instance.c:91
struct comp_grid_config config[2]
Definition instance.c:96
struct yac_basic_grid * grid
Definition fields.c:20
struct yac_interp_field * interp_fields
Definition fields.c:22
size_t num_interp_fields
Definition fields.c:23
char * timestep
Definition fields.c:25
char * component_name
Definition fields.c:18
size_t collection_size
number of vertical levels or bundles
Definition fields.c:24
char * name
Definition fields.c:16
Definition event.c:18
char const * end_datetime
Definition instance.c:105
char const * start_datetime
Definition instance.c:104
enum yac_reduction_type reduction_operation
Definition instance.c:103
char const * timestep
Definition instance.c:100
char const * coupling_period
Definition instance.c:101
double scale_summand
Definition instance.c:150
char const * yaxt_exchanger_name
Definition instance.c:152
double scale_factor
Definition instance.c:150
struct comp_grid_pair_config comp_grid_pair
Definition instance.c:140
enum yac_interp_weights_reorder_type reorder_type
Definition instance.c:146
struct tgt_field_config tgt_interp_config
Definition instance.c:144
size_t collection_size
Definition instance.c:154
char const * name
Definition instance.c:137
struct src_field_config src_interp_config
Definition instance.c:143
double frac_mask_fallback_value
Definition instance.c:148
int src_comp_idx
Definition instance.c:141
char const * filename
Definition instance.c:159
struct yac_basic_grid * grid
Definition instance.c:160
char const * grid_name
Definition instance.c:158
const char * weight_file_name
Definition instance.c:123
char const *const * mask_names
Definition instance.c:119
struct field_config_event_data event_data
Definition instance.c:124
struct yac_interp_stack_config * interp_stack
Definition instance.c:122
struct coupling_field * field
Definition instance.c:115
char const * name
Definition instance.c:116
size_t num_mask_names
Definition instance.c:120
struct field_config_event_data event_data
Definition instance.c:132
char const * name
Definition instance.c:129
char const * mask_name
Definition instance.c:131
struct coupling_field * field
Definition instance.c:128
struct yac_basic_grid_data data
Definition basic_grid.c:21
struct _datetime * end_datetime
struct _datetime * start_datetime
struct coupling_field ** cpl_fields
Definition instance.c:77
enum yac_instance_phase phase
Definition instance.c:82
MPI_Comm comm
Definition instance.c:80
struct yac_component_config * comp_config
Definition instance.c:75
size_t num_cpl_fields
Definition instance.c:78
struct yac_couple_config * couple_config
Definition instance.c:73
enum yac_location location
Definition basic_grid.h:18
size_t coordinates_idx
Definition basic_grid.h:19
static struct user_input_data_masks ** masks
Definition yac.c:139
size_t num_grids
Definition yac.c:131
struct yac_basic_grid ** grids
Definition yac.c:130
#define YAC_MAX_CHARLEN
Definition yac.h:81
#define YAC_ASSERT_F(exp, format,...)
Definition yac_assert.h:19
#define YAC_ASSERT(exp, msg)
Definition yac_assert.h:16
#define yac_mpi_call(call, comm)
double const (* yac_const_coordinate_pointer)[3]
Definition yac_types.h:20