YetAnotherCoupler 3.2.0_a
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 "event.h"
16#include "yac_mpi_common.h"
17#include "fields.h"
18#include "component.h"
19#include "config_yaml.h"
20
22 INSTANCE_DEFINITION = 0, // after yac_cinit
23 INSTANCE_DEFINITION_COMP = 1, // after yac_cdef_comp
24 INSTANCE_DEFINITION_SYNC = 2, // after yac_csync_def
25 INSTANCE_EXCHANGE = 3, // after yac_cenddef
27};
28
29static const char * yac_instance_phase_str[] =
30 {"definition phase",
31 "definition phase (after component definition)",
32 "definition phase (after synchronisation)",
33 "exchange phase",
34 "unknown phase"};
35
36#define CHECK_PHASE(FUNC_NAME, REF_PHASE, NEW_PHASE) \
37 { \
38 enum yac_instance_phase ref_phase_ = (REF_PHASE); \
39 YAC_ASSERT_F( \
40 instance->phase == (ref_phase_), \
41 "ERROR(%s): Invalid phase " \
42 "(current phase: \"%s\" expected phase: \"%s\")", \
43 #FUNC_NAME, yac_instance_phase_str[instance->phase], \
44 yac_instance_phase_str[(ref_phase_)]); \
45 instance->phase = (NEW_PHASE); \
46 }
47#define CHECK_MIN_PHASE(FUNC_NAME, MIN_REF_PHASE) \
48 { \
49 enum yac_instance_phase ref_min_phase_ = (MIN_REF_PHASE); \
50 YAC_ASSERT_F( \
51 instance->phase >= (ref_min_phase_), \
52 "ERROR(%s): Invalid phase " \
53 "(current phase: \"%s\" minimum expected phase: \"%s\")", \
54 #FUNC_NAME, yac_instance_phase_str[instance->phase], \
55 yac_instance_phase_str[(ref_min_phase_)]); \
56 }
57#define CHECK_MAX_PHASE(FUNC_NAME, MAX_REF_PHASE) \
58 { \
59 enum yac_instance_phase ref_max_phase_ = (MAX_REF_PHASE); \
60 YAC_ASSERT_F( \
61 instance->phase <= (ref_max_phase_), \
62 "ERROR(%s): Invalid phase " \
63 "(current phase: \"%s\" maximum expected phase: \"%s\")", \
64 #FUNC_NAME, \
65 yac_instance_phase_str[ \
66 MIN(instance->phase,INSTANCE_UNKNOWN)], \
67 yac_instance_phase_str[(ref_max_phase_)]); \
68 }
69
83
85 SRC = 1,
86 TGT = 2
87};
88
90 const char * grid_name;
91 const char * comp_name;
92};
93
97
106 {.timestep = NULL,
107 .coupling_period = NULL,
108 .timelag = 0,
109 .reduction_operation = TIME_NONE,
110 .start_datetime = NULL,
111 .end_datetime = NULL};
112
115 char const * name;
116 int id;
117
118 char const * const * mask_names;
120
122 const char * weight_file_name;
124};
125
128 char const * name;
129 int id;
130 char const * mask_name;
132};
133
153
154static struct yac_basic_grid *
155 get_basic_grid(const char * grid_name, char const * component_name,
156 size_t num_fields, struct coupling_field ** coupling_fields,
157 int * delete_flag) {
158
159 *delete_flag = 0;
160
161 for (size_t i = 0; i < num_fields; ++i) {
162
163 struct coupling_field * field = coupling_fields[i];
164
166 continue;
167
169
170 if (strcmp(grid_name, yac_basic_grid_get_name(grid)) == 0)
171 return grid;
172 }
173
174 *delete_flag = 1;
175 return yac_basic_grid_empty_new(grid_name);
176}
177
178static
179int compare_comp_grid_config(const void * a, const void * b) {
180
181 struct comp_grid_config * a_ = (struct comp_grid_config *)a,
182 * b_ = (struct comp_grid_config *)b;
183
184 int ret;
185 if ((ret = strcmp(a_->comp_name, b_->comp_name))) return ret;
186 else return strcmp(a_->grid_name, b_->grid_name);
187}
188
190 char const * component_name, const char * field_name,
191 const char * grid_name, size_t num_fields,
192 struct coupling_field ** coupling_fields) {
193
194 for (size_t i = 0; i < num_fields; ++i) {
195 struct coupling_field * curr_field = coupling_fields[i];
196 if (!strcmp(component_name, yac_get_coupling_field_comp_name(curr_field)) &&
197 !strcmp(field_name, yac_get_coupling_field_name(curr_field)) &&
198 !strcmp(grid_name,
201 return curr_field;
202 }
203
204 return NULL;
205}
206
208 struct yac_couple_config * couple_config,
209 size_t couple_idx, size_t field_couple_idx) {
210
211 char const * const * src_mask_names;
212 size_t num_src_mask_names;
214 couple_config, couple_idx, field_couple_idx,
215 &src_mask_names, &num_src_mask_names);
216
217 return
218 (struct src_field_config) {
219 .field = NULL,
220 .name = NULL,
221 .id = INT_MAX,
222 .mask_names = src_mask_names,
223 .num_mask_names = num_src_mask_names,
224 .interp_stack =
226 couple_config, couple_idx, field_couple_idx),
227 .weight_file_name =
229 couple_config, couple_idx, field_couple_idx))?
231 couple_config, couple_idx, field_couple_idx):NULL,
232 .event_data = empty_event_data,
233 };
234}
235
237 struct yac_couple_config * couple_config,
238 size_t couple_idx, size_t field_couple_idx) {
239
240 return
241 (struct tgt_field_config) {
242 .field = NULL,
243 .name = NULL,
244 .id = INT_MAX,
245 .mask_name =
247 couple_config, couple_idx, field_couple_idx),
248 .event_data = empty_event_data,
249 };
250}
251
253 struct coupling_field * a,
254 size_t num_mask_names_a, char const * const * mask_names_a,
255 struct coupling_field * b,
256 size_t num_mask_names_b, char const * const * mask_names_b) {
257
258 if ((a == NULL) || (b == NULL)) return (a == NULL) - (b == NULL);
259
260 size_t num_interp_fields[2] =
263
265 (num_mask_names_a == 0) ||
266 (num_mask_names_a == num_interp_fields[0]),
267 "ERROR(compare_field_config_fields): inconsistent mask names defined")
269 (num_mask_names_b == 0) ||
270 (num_mask_names_b == num_interp_fields[1]),
271 "ERROR(compare_field_config_fields): inconsistent mask names defined")
272
273 // if both fields have different numbers of interpolation fields
274 if (num_interp_fields[0] != num_interp_fields[1])
275 return (int)num_interp_fields[0] - (int)num_interp_fields[1];
276
277 struct yac_basic_grid * grid[2] =
280
281 struct yac_interp_field const * interp_fields[2] =
284
285 for (size_t i = 0; i < num_interp_fields[0]; ++i) {
286
287 int ret;
288
289 enum yac_location location_a = interp_fields[0][i].location;
290 enum yac_location location_b = interp_fields[1][i].location;
291
292 if ((ret = (location_a > location_b) -
293 (location_a < location_b))) return ret;
294
296 yac_basic_grid_get_field_coordinates(grid[0], interp_fields[0][i]);
298 yac_basic_grid_get_field_coordinates(grid[1], interp_fields[1][i]);
299
300 if ((ret = (coordinates_a > coordinates_b) -
301 (coordinates_a < coordinates_b))) return ret;
302
303 char const * const * mask_names[2] =
306 int const * masks[2];
307
308 for (int j = 0; j < 2; ++j) {
309 struct yac_interp_field temp_interp_field = interp_fields[j][i];
310 if (mask_names[j] != NULL)
313 grid[j], temp_interp_field.location, mask_names[j][i]);
314
316 }
317 if ((ret = (masks[0] > masks[1]) - (masks[0] < masks[1]))) return ret;
318 }
319
320 return 0;
321}
322
323static int compare_field_config_field_ids(const void * a, const void * b) {
324
325 struct field_config * a_ = (struct field_config *)a,
326 * b_ = (struct field_config *)b;
327
328 int ret;
329 if ((ret = a_->src_interp_config.id - b_->src_interp_config.id)) return ret;
330 return a_->tgt_interp_config.id - b_->tgt_interp_config.id;
331
332}
333
334static int
335compare_field_config_interp_method(const void * a, const void * b) {
336
337 struct field_config * a_ = (struct field_config *)a,
338 * b_ = (struct field_config *)b;
339
340 int ret;
341 if ((ret = (int)(a_->src_interp_config.weight_file_name == NULL) -
342 (int)(b_->src_interp_config.weight_file_name == NULL))) return ret;
343 if ((a_->src_interp_config.weight_file_name != NULL) &&
344 (ret = strcmp(a_->src_interp_config.weight_file_name,
345 b_->src_interp_config.weight_file_name))) return ret;
346
347 return
350 b_->src_interp_config.interp_stack);
351}
352
353static
354int compare_field_config(const void * a, const void * b) {
355
356 struct field_config * a_ = (struct field_config *)a,
357 * b_ = (struct field_config *)b;
358
359 int ret;
360 if ((ret = strcmp(a_->comp_grid_pair.config[0].comp_name,
361 b_->comp_grid_pair.config[0].comp_name))) return ret;
362 if ((ret = strcmp(a_->comp_grid_pair.config[1].comp_name,
363 b_->comp_grid_pair.config[1].comp_name))) return ret;
364 if ((ret = strcmp(a_->comp_grid_pair.config[0].grid_name,
365 b_->comp_grid_pair.config[0].grid_name))) return ret;
366 if ((ret = strcmp(a_->comp_grid_pair.config[1].grid_name,
367 b_->comp_grid_pair.config[1].grid_name))) return ret;
368 if ((ret = compare_field_config_field_ids(a_, b_))) return ret;
369 if ((ret = compare_field_config_interp_method(a_, b_))) return ret;
370 if ((ret = (int)(a_->reorder_type) - (int)(b_->reorder_type))) return ret;
371 if ((ret = (a_->scale_factor > b_->scale_factor) -
372 (a_->scale_factor < b_->scale_factor))) return ret;
373 if ((ret = (a_->scale_summand > b_->scale_summand) -
374 (a_->scale_summand < b_->scale_summand))) return ret;
375
376 // use memcmp to compare frac_mask_fallback_value, because they can be nan
377 return
378 memcmp(
380 &(b_->frac_mask_fallback_value), sizeof(double));
381}
382
384 struct yac_instance * instance, int couple_idx, int field_couple_idx,
385 enum field_type field_type) {
386
387 struct yac_couple_config * couple_config = instance->couple_config;
388
389 enum yac_reduction_type reduction_operation =
391 couple_config, couple_idx, field_couple_idx);
392
393 char const * coupling_period =
395 couple_config, couple_idx, field_couple_idx);
396 char const * timestep;
397 int timelag;
398 if ( field_type == SRC ){
399 timestep =
401 couple_config, couple_idx, field_couple_idx);
402 timelag =
404 couple_config, couple_idx, field_couple_idx);
405 }else{
406 reduction_operation = TIME_NONE;
407 timestep =
409 couple_config, couple_idx, field_couple_idx);
410 timelag =
412 couple_config, couple_idx, field_couple_idx);
413 }
414
415 return
417 {.timestep = timestep,
418 .coupling_period = coupling_period,
419 .timelag = timelag,
420 .reduction_operation = reduction_operation,
421 .start_datetime = yac_couple_config_get_start_datetime(couple_config),
422 .end_datetime = yac_couple_config_get_end_datetime(couple_config)};
423}
424
425static struct event * generate_event(
426 struct field_config_event_data event_data) {
427
428 struct event * event = yac_event_new();
430 event, event_data.timestep, event_data.coupling_period,
431 event_data.timelag, event_data.reduction_operation,
432 event_data.start_datetime, event_data.end_datetime);
433 return event;
434}
435
437 struct yac_instance * instance,
438 struct field_config ** field_configs_, size_t * count) {
439
440 struct yac_couple_config * couple_config = instance->couple_config;
441 MPI_Comm comm = instance->comm;
442 size_t num_fields = instance->num_cpl_fields;
443 struct coupling_field ** coupling_fields = instance->cpl_fields;
444
445 size_t num_couples = yac_couple_config_get_num_couples(couple_config);
446 size_t total_num_fields = 0;
447 for (size_t couple_idx = 0; couple_idx < num_couples; ++couple_idx)
448 total_num_fields +=
449 yac_couple_config_get_num_couple_fields(couple_config, couple_idx);
450
451 // determine for which configuration source and target field
452 // are available
453 int (*fields_available)[2] =
454 xmalloc(total_num_fields * sizeof(*fields_available));
455 for (size_t couple_idx = 0, i = 0; couple_idx < num_couples;
456 ++couple_idx) {
457 size_t curr_num_fields =
458 yac_couple_config_get_num_couple_fields(couple_config, couple_idx);
459 for (size_t field_couple_idx = 0; field_couple_idx < curr_num_fields;
460 ++field_couple_idx, ++i) {
461 char const * src_component_name;
462 char const * tgt_component_name;
463 char const * src_grid_name;
464 char const * tgt_grid_name;
465 const char * src_field_name;
466 const char * tgt_field_name;
468 couple_config, couple_idx, field_couple_idx,
469 &src_component_name, &tgt_component_name);
471 couple_config, couple_idx, field_couple_idx,
472 &src_grid_name, &tgt_grid_name);
474 couple_config, couple_idx, field_couple_idx,
475 &src_field_name, &tgt_field_name);
476 fields_available[i][0] =
478 src_component_name, src_field_name, src_grid_name,
479 num_fields, coupling_fields) != NULL;
480 fields_available[i][1] =
482 tgt_component_name, tgt_field_name, tgt_grid_name,
483 num_fields, coupling_fields) != NULL;
484 }
485 }
487 MPI_Allreduce(MPI_IN_PLACE, fields_available,
488 2 * total_num_fields,
489 MPI_INT, MPI_MAX, comm), comm);
490 int comm_rank;
491 yac_mpi_call(MPI_Comm_rank(comm, &comm_rank), comm);
492 size_t new_total_num_fields = 0;
493 for (size_t couple_idx = 0, i = 0; couple_idx < num_couples;
494 ++couple_idx) {
495 size_t curr_num_fields =
496 yac_couple_config_get_num_couple_fields(couple_config, couple_idx);
497 for (size_t field_couple_idx = 0; field_couple_idx < curr_num_fields;
498 ++field_couple_idx, ++i) {
499 if (fields_available[i][0] && fields_available[i][1]) {
500 ++new_total_num_fields;
501 } else if (comm_rank == 0) {
502 char const * src_component_name;
503 char const * tgt_component_name;
504 char const * src_grid_name;
505 char const * tgt_grid_name;
506 const char * src_field_name;
507 const char * tgt_field_name;
509 couple_config, couple_idx, field_couple_idx,
510 &src_component_name, &tgt_component_name);
512 couple_config, couple_idx, field_couple_idx,
513 &src_grid_name, &tgt_grid_name);
515 couple_config, couple_idx, field_couple_idx,
516 &src_field_name, &tgt_field_name);
517 fprintf(stderr, "WARNING: couple defined for field: \n"
518 " source (%s):\n"
519 " component name: %s\n"
520 " grid name: %s\n"
521 " field name: %s\n"
522 " target(%s):\n"
523 " component name: %s\n"
524 " grid name: %s\n"
525 " field name: %s\n",
526 (fields_available[i][0])?"defined":"not defined",
527 src_component_name, src_grid_name, src_field_name,
528 (fields_available[i][1])?"defined":"not defined",
529 tgt_component_name, tgt_grid_name, tgt_field_name);
530 }
531 }
532 }
533 total_num_fields = new_total_num_fields;
534
535 struct field_config * field_configs =
536 xmalloc(total_num_fields * sizeof(*field_configs));
537
538 size_t field_config_idx = 0;
539
540 // extract component, grid configurations from all fields in
541 // the coupling configuration
542 for (size_t couple_idx = 0, i = 0; couple_idx < num_couples; ++couple_idx) {
543
544 size_t curr_num_fields =
545 yac_couple_config_get_num_couple_fields(couple_config, couple_idx);
546
547 for (size_t field_couple_idx = 0; field_couple_idx < curr_num_fields;
548 ++field_couple_idx, ++i) {
549
550 if (!fields_available[i][0] || !fields_available[i][1]) continue;
551
552 struct comp_grid_config src_config, tgt_config;
553
555 couple_config, couple_idx, field_couple_idx,
556 &(src_config.comp_name), &(tgt_config.comp_name));
557
559 couple_config, couple_idx, field_couple_idx,
560 &(src_config.grid_name), &(tgt_config.grid_name));
561
562 int src_comp_idx =
563 compare_comp_grid_config(&src_config, &tgt_config) > 0;
564
565 const char * src_field_name;
566 const char * tgt_field_name;
568 couple_config, couple_idx, field_couple_idx,
569 &src_field_name, &tgt_field_name);
570 struct coupling_field * src_field =
572 src_config.comp_name, src_field_name, src_config.grid_name,
573 num_fields, coupling_fields);
574 struct coupling_field * tgt_field =
576 tgt_config.comp_name, tgt_field_name, tgt_config.grid_name,
577 num_fields, coupling_fields);
578
579 double frac_mask_fallback_value =
581 couple_config, src_config.comp_name, src_config.grid_name,
582 src_field_name);
583 double scale_factor =
585 couple_config, couple_idx, field_couple_idx);
586 double scale_summand =
588 couple_config, couple_idx, field_couple_idx);
589 size_t collection_size =
591 couple_config, src_config.comp_name, src_config.grid_name,
592 src_field_name);
593
597 couple_config, tgt_config.comp_name, tgt_config.grid_name,
598 tgt_field_name),
599 "ERROR: collection sizes do not match for coupled fields (%zu != %zu): \n"
600 " source:\n"
601 " component name: %s\n"
602 " grid name: %s\n"
603 " field name: %s\n"
604 " target:\n"
605 " component name: %s\n"
606 " grid name: %s\n"
607 " field name: %s\n",
610 couple_config, tgt_config.comp_name, tgt_config.grid_name,
611 tgt_field_name),
612 src_config.comp_name, src_config.grid_name, src_field_name,
613 tgt_config.comp_name, tgt_config.grid_name, tgt_field_name);
614
615 field_configs[field_config_idx].comp_grid_pair.config[src_comp_idx] =
616 src_config;
617 field_configs[field_config_idx].comp_grid_pair.config[src_comp_idx^1] =
618 tgt_config;
619 field_configs[field_config_idx].src_comp_idx = src_comp_idx;
620 field_configs[field_config_idx].src_interp_config =
621 get_src_interp_config(couple_config, couple_idx, field_couple_idx);
622 field_configs[field_config_idx].tgt_interp_config =
623 get_tgt_interp_config(couple_config, couple_idx, field_couple_idx);
624 field_configs[field_config_idx].src_interp_config.field = src_field;
625 field_configs[field_config_idx].tgt_interp_config.field = tgt_field;
626 field_configs[field_config_idx].reorder_type =
628 couple_config, couple_idx, field_couple_idx))?
630 field_configs[field_config_idx].src_interp_config.event_data =
631 get_event_data(instance, couple_idx, field_couple_idx, SRC);
632 field_configs[field_config_idx].tgt_interp_config.event_data =
633 get_event_data(instance, couple_idx, field_couple_idx, TGT);
634 field_configs[field_config_idx].frac_mask_fallback_value =
635 frac_mask_fallback_value;
636 field_configs[field_config_idx].scale_factor = scale_factor;
637 field_configs[field_config_idx].scale_summand = scale_summand;
638 field_configs[field_config_idx].collection_size = collection_size;
639 field_configs[field_config_idx].src_interp_config.name = src_field_name;
640 field_configs[field_config_idx].tgt_interp_config.name = tgt_field_name;
641 ++field_config_idx;
642 }
643 }
644
645 free(fields_available);
646
647 { // determine unique field config ids, for each unique configuration
648 int * field_src_field_config_compare_matrix =
649 xmalloc((size_t)(total_num_fields * (total_num_fields - 1)) *
650 sizeof(*field_src_field_config_compare_matrix));
651 int * field_tgt_field_config_compare_matrix =
652 field_src_field_config_compare_matrix +
653 (size_t)(total_num_fields * (total_num_fields - 1)) / 2;
654
655 for (unsigned i = 0, k = 0; i < total_num_fields; ++i) {
656 for (unsigned j = i + 1; j < total_num_fields; ++j, ++k) {
657 field_src_field_config_compare_matrix[k] =
659 field_configs[i].src_interp_config.field,
660 field_configs[i].src_interp_config.num_mask_names,
661 field_configs[i].src_interp_config.mask_names,
662 field_configs[j].src_interp_config.field,
663 field_configs[j].src_interp_config.num_mask_names,
664 field_configs[j].src_interp_config.mask_names) != 0;
665 field_tgt_field_config_compare_matrix[k] =
667 field_configs[i].tgt_interp_config.field,
668 field_configs[i].tgt_interp_config.mask_name != NULL,
669 &(field_configs[i].tgt_interp_config.mask_name),
670 field_configs[j].tgt_interp_config.field,
671 field_configs[j].tgt_interp_config.mask_name != NULL,
672 &(field_configs[j].tgt_interp_config.mask_name)) != 0;
673 }
674 }
675
677 MPI_Allreduce(MPI_IN_PLACE, field_src_field_config_compare_matrix,
678 total_num_fields * (total_num_fields - 1),
679 MPI_INT, MPI_LOR, comm), comm);
680
681 int * field_src_field_config_ids =
682 xcalloc(2 * (size_t)total_num_fields,
683 sizeof(*field_src_field_config_ids));
684 int * field_tgt_field_config_ids =
685 field_src_field_config_ids + (size_t)total_num_fields;
686
687 for (unsigned i = 0, k = 0, id = 1; i < total_num_fields; ++i) {
688 if (field_src_field_config_ids[i] != 0) {
689 k += total_num_fields - i - 1;
690 continue;
691 } else {
692 field_src_field_config_ids[i] = (int)id;
693 for (unsigned j = i + 1; j < total_num_fields; ++j, ++k)
694 if (!field_src_field_config_compare_matrix[k])
695 field_src_field_config_ids[j] = (int)id;
696 id++;
697 }
698 }
699 for (unsigned i = 0, k = 0, id = 1; i < total_num_fields; ++i) {
700 if (field_tgt_field_config_ids[i] != 0) {
701 k += total_num_fields - i - 1;
702 continue;
703 } else {
704 field_tgt_field_config_ids[i] = (int)id;
705 for (unsigned j = i + 1; j < total_num_fields; ++j, ++k)
706 if (!field_tgt_field_config_compare_matrix[k])
707 field_tgt_field_config_ids[j] = (int)id;
708 id++;
709 }
710 }
711 free(field_src_field_config_compare_matrix);
712
713 for (unsigned i = 0; i < total_num_fields; ++i) {
714 field_configs[i].src_interp_config.id =
715 field_src_field_config_ids[i];
716 field_configs[i].tgt_interp_config.id =
717 field_tgt_field_config_ids[i];
718 }
719 free(field_src_field_config_ids);
720 }
721
722 { // determine unique field config ids, for each unique configuration
723 int * field_config_compare_matrix =
724 xmalloc((size_t)(total_num_fields * (total_num_fields - 1)) / 2 *
725 sizeof(*field_config_compare_matrix));
726 for (unsigned i = 0, k = 0; i < total_num_fields; ++i)
727 for (unsigned j = i + 1; j < total_num_fields; ++j, ++k)
728 field_config_compare_matrix[k] =
730 &(field_configs[i]), &(field_configs[j])) != 0;
731
733 MPI_Allreduce(MPI_IN_PLACE, field_config_compare_matrix,
734 (total_num_fields * (total_num_fields - 1)) / 2,
735 MPI_INT, MPI_LOR, comm), comm);
736
737 int * field_config_ids =
738 xcalloc((size_t)total_num_fields, sizeof(*field_config_ids));
739
740 for (unsigned i = 0, k = 0, id = 1; i < total_num_fields; ++i) {
741 if (field_config_ids[i] != 0) {
742 k += total_num_fields - i - 1;
743 continue;
744 } else {
745 field_config_ids[i] = (int)id;
746 for (unsigned j = i + 1; j < total_num_fields; ++j, ++k)
747 if (!field_config_compare_matrix[k])
748 field_config_ids[j] = (int)id;
749 id++;
750 }
751 }
752 free(field_config_compare_matrix);
753
754 for (unsigned i = 0; i < total_num_fields; ++i)
755 field_configs[i].id = field_config_ids[i];
756 free(field_config_ids);
757 }
758
759 *field_configs_ = field_configs;
760 *count = total_num_fields;
761}
762
763static
764int compare_field_config_ids(const void * a, const void * b) {
765
766 struct field_config * a_ = (struct field_config *)a,
767 * b_ = (struct field_config *)b;
768
769 return a_->id - b_->id;
770}
771
773 struct src_field_config src_interp_config,
774 struct yac_interp_grid * interp_grid) {
775
776 struct interp_method ** method_stack =
778 struct yac_interp_weights * weights =
779 yac_interp_method_do_search(method_stack, interp_grid);
780
781 yac_interp_method_delete(method_stack);
782 free(method_stack);
783
784 return weights;
785}
786
788 struct coupling_field * field, char const * const * mask_names,
789 size_t num_mask_names, struct yac_interp_field ** interp_fields,
790 size_t * num_fields, MPI_Comm comm) {
791
793 size_t num_fields_;
794
795 if (field != NULL) {
796
798
800 (num_mask_names == 0) || (num_fields_ == num_mask_names),
801 "ERROR(get_interp_fields_from_coupling_field): "
802 "missmatch in number of interpolation fields of coupling field \"%s\" "
803 "and number of provided mask names (%zu != %zu)",
804 yac_get_coupling_field_name(field), num_fields_, num_mask_names)
805
806 uint64_t local_counts[2] =
807 {(uint64_t)num_fields_, (uint64_t)num_mask_names};
808 uint64_t global_counts[2];
809
813
816 "ERROR(get_interp_fields_from_coupling_field): missmatch in number of"
817 "local interpolation fields for coupling field \"%s\" and global "
818 "(%zu != %zu)",
820
822 (num_mask_names != 0) || (global_counts[1] == 0),
823 "ERROR(get_interp_fields_from_coupling_field): local process did "
824 "not provide mask names for coupling field \"%s\" while others did",
826
827 // make a copy of the interpolation fields of the coupling field
829 memcpy(
831 num_fields_ * sizeof(*interp_fields_));
832
833 // if mask names are provided, overwrite already existing masks
835 for (size_t i = 0; i < num_mask_names; ++i) {
836 char const * mask_name = mask_names[i];
838 mask_name != NULL,
839 "ERROR(get_interp_fields_from_coupling_field): "
840 "make_names[%zu] is NULL", i);
841 interp_fields_[i].masks_idx =
843 grid, interp_fields_[i].location, mask_name);
844 }
845
846 uint64_t data[num_fields_][3];
847
848 for (size_t i = 0; i < num_fields_; ++i) {
849 data[i][0] = (uint64_t)interp_fields_[i].location;
850 data[i][1] = (uint64_t)interp_fields_[i].coordinates_idx;
851 data[i][2] = (uint64_t)interp_fields_[i].masks_idx;
852 }
853
855 MPI_Allreduce(
856 MPI_IN_PLACE, data, 3 * (int)num_fields_,
857 MPI_UINT64_T, MPI_MIN, comm), comm);
858
859 for (size_t i = 0; i < num_fields_; ++i) {
861 data[i][0] == (uint64_t)(interp_fields_[i].location),
862 "ERROR(get_interp_fields_from_coupling_field): location mismatch")
864 data[i][1] == (uint64_t)(interp_fields_[i].coordinates_idx),
865 "ERROR(get_interp_fields_from_coupling_field): "
866 "coordinates index mismatch")
868 data[i][2] == (uint64_t)(interp_fields_[i].masks_idx),
869 "ERROR(get_interp_fields_from_coupling_field): "
870 "masks index mismatch")
871 }
872
873 } else {
874
875 uint64_t zero_counts[2] = {0,0};
876 uint64_t counts[2];
877
879 MPI_Allreduce(
880 zero_counts, counts, 2,
881 MPI_UINT64_T, MPI_MAX, comm), comm);
882
883 num_fields_ = (size_t)(counts[0]);
884 interp_fields_ = xmalloc(num_fields_ * sizeof(*interp_fields_));
885
886 uint64_t data[num_fields_][3];
887
888 for (size_t i = 0; i < num_fields_; ++i) {
889 data[i][0] = (uint64_t)YAC_LOC_UNDEFINED;
890 data[i][1] = (uint64_t)UINT64_MAX;
891 data[i][2] = (uint64_t)UINT64_MAX;
892 }
893
895 MPI_Allreduce(
896 MPI_IN_PLACE, data, 3 * (int)num_fields_,
897 MPI_UINT64_T, MPI_MIN, comm), comm);
898
899 for (size_t i = 0; i < num_fields_; ++i) {
900 interp_fields_[i].location = (enum yac_location)data[i][0];
901 interp_fields_[i].coordinates_idx = (size_t)data[i][1];
902 interp_fields_[i].masks_idx = (size_t)data[i][2];
903 }
904 }
905
906 *interp_fields = interp_fields_;
907 *num_fields = num_fields_;
908}
909
910static void generate_interpolations(struct yac_instance * instance) {
911
912 MPI_Comm comm = instance->comm;
913
914 // get information about all fields
915 struct field_config * field_configs;
916 size_t field_count;
918 instance, &field_configs, &field_count);
919
920 // sort field configurations
921 qsort(field_configs, field_count, sizeof(*field_configs),
923
924 struct yac_dist_grid_pair * dist_grid_pair = NULL;
925 struct yac_interp_grid * interp_grid = NULL;
926 struct yac_interp_weights * interp_weights = NULL;
927 struct yac_interpolation * interp = NULL;
928 struct comp_grid_pair_config * prev_comp_grid_pair = NULL;
929 MPI_Comm comp_pair_comm = MPI_COMM_NULL;
930 int is_active = 0;
931
932 // loop over all fields to build interpolations
933 for (size_t i = 0; i < field_count; ++i) {
934
935 struct field_config * curr_field_config = field_configs + i;
936 struct comp_grid_pair_config * curr_comp_grid_pair =
937 &(curr_field_config->comp_grid_pair);
938
939 int build_flag = 0;
940 // if the current comp pair is different from the previous one
941 // => generate a component pair communicator
942 if ((prev_comp_grid_pair == NULL) ||
943 (strcmp(prev_comp_grid_pair->config[0].comp_name,
944 curr_comp_grid_pair->config[0].comp_name) ||
945 strcmp(prev_comp_grid_pair->config[1].comp_name,
946 curr_comp_grid_pair->config[1].comp_name))) {
947
948 build_flag = 1;
949
950 if (comp_pair_comm != MPI_COMM_NULL)
951 yac_mpi_call(MPI_Comm_free(&comp_pair_comm), comm);
952
953 int comp_is_available[2] =
955 instance->comp_config,
956 curr_comp_grid_pair->config[0].comp_name),
958 instance->comp_config,
959 curr_comp_grid_pair->config[1].comp_name)};
960
961 is_active = comp_is_available[0] || comp_is_available[1];
962
963 yac_mpi_call(MPI_Comm_split(comm, is_active, 0,
964 &comp_pair_comm), comm);
965
966 // determine whether both components are available in the setup
967 yac_mpi_call(MPI_Allreduce(MPI_IN_PLACE, comp_is_available, 2,
968 MPI_INT, MPI_LOR, comp_pair_comm), comm);
969 is_active = comp_is_available[0] && comp_is_available[1];
970 }
971
972 // if the current configuration differs from the previous one and the local
973 // process is involved in this configuration
974 if (is_active &&
975 (build_flag ||
976 strcmp(prev_comp_grid_pair->config[0].grid_name,
977 curr_comp_grid_pair->config[0].grid_name) ||
978 strcmp(prev_comp_grid_pair->config[1].grid_name,
979 curr_comp_grid_pair->config[1].grid_name))) {
980
981 build_flag = 1;
982
983 if (dist_grid_pair != NULL) yac_dist_grid_pair_delete(dist_grid_pair);
984
985 char const * grid_names[2] =
986 {curr_comp_grid_pair->config[0].grid_name,
987 curr_comp_grid_pair->config[1].grid_name};
988 char const * component_names[2] =
989 {curr_comp_grid_pair->config[0].comp_name,
990 curr_comp_grid_pair->config[1].comp_name};
991
992 int delete_flags[2];
993 struct yac_basic_grid * basic_grid[2] =
995 grid_names[0], component_names[0], instance->num_cpl_fields,
996 instance->cpl_fields, &delete_flags[0]),
998 grid_names[1], component_names[1], instance->num_cpl_fields,
999 instance->cpl_fields, &delete_flags[1])};
1000
1001 dist_grid_pair =
1002 yac_dist_grid_pair_new(basic_grid[0], basic_grid[1], comp_pair_comm);
1003
1004 for (int i = 0; i < 2; ++i)
1005 if (delete_flags[i]) yac_basic_grid_delete(basic_grid[i]);
1006 }
1007
1008 // if the current source or target field data differes from the previous
1009 // one
1010 if (is_active &&
1011 (build_flag ||
1013 curr_field_config - 1, curr_field_config))) {
1014
1015 build_flag = 1;
1016
1017 struct yac_interp_field * src_fields;
1018 size_t num_src_fields;
1020 curr_field_config->src_interp_config.field,
1021 curr_field_config->src_interp_config.mask_names,
1022 curr_field_config->src_interp_config.num_mask_names,
1023 &src_fields, &num_src_fields, comp_pair_comm);
1025 size_t num_tgt_fields;
1027 curr_field_config->tgt_interp_config.field,
1028 &(curr_field_config->tgt_interp_config.mask_name),
1029 curr_field_config->tgt_interp_config.mask_name != NULL,
1031
1032 YAC_ASSERT(
1033 num_tgt_fields == 1,
1034 "ERROR(generate_interpolations): "
1035 "only one point set per target field supported")
1036
1038
1039 int src_comp_idx = field_configs[i].src_comp_idx;
1042 curr_comp_grid_pair->config[src_comp_idx].grid_name,
1043 curr_comp_grid_pair->config[src_comp_idx^1].grid_name,
1044 num_src_fields, src_fields, *tgt_fields);
1045
1047 free(src_fields);
1048 }
1049
1050 // if the current interpolation method stack differes from the previous
1051 // configuration
1052 if (is_active &&
1053 (build_flag ||
1056
1057 build_flag = 1;
1058
1060
1061 // generate interp weights
1063 curr_field_config->src_interp_config, interp_grid);
1064 }
1065
1066 if (is_active &&
1067 (curr_field_config->src_interp_config.weight_file_name != NULL)) {
1068
1069 int src_comp_idx = field_configs[i].src_comp_idx;
1070
1073 curr_field_config->src_interp_config.weight_file_name,
1074 curr_comp_grid_pair->config[src_comp_idx].grid_name,
1075 curr_comp_grid_pair->config[src_comp_idx^1].grid_name, 0, 0);
1076 }
1077
1078 // if the current weight reorder method differs from the previous
1079 // configuration
1080 // (use memcmp to compare frac_mask_fallback_value, because they can be nan)
1081 if (is_active &&
1082 (build_flag ||
1083 (curr_field_config[-1].reorder_type !=
1084 curr_field_config->reorder_type) ||
1085 (curr_field_config[-1].collection_size !=
1086 curr_field_config->collection_size) ||
1087 (curr_field_config[-1].scale_factor !=
1088 curr_field_config->scale_factor) ||
1089 (curr_field_config[-1].scale_summand !=
1090 curr_field_config->scale_summand) ||
1091 memcmp(
1092 &(curr_field_config[-1].frac_mask_fallback_value),
1093 &(curr_field_config->frac_mask_fallback_value),
1094 sizeof(double)))) {
1095
1097
1098 // generate interpolation
1099 interp =
1101 interp_weights, curr_field_config->reorder_type,
1102 curr_field_config->collection_size,
1103 curr_field_config->frac_mask_fallback_value,
1104 curr_field_config->scale_factor,
1105 curr_field_config->scale_summand);
1106 }
1107
1108 if (is_active) {
1109
1110 int is_source = curr_field_config->src_interp_config.field != NULL;
1111 int is_target = curr_field_config->tgt_interp_config.field != NULL;
1112
1113 struct yac_interpolation * interp_copy = yac_interpolation_copy(interp);
1114
1115 if (is_source) {
1117 curr_field_config->src_interp_config.field,
1119 curr_field_config->src_interp_config.event_data),
1120 interp_copy);
1122 }
1123
1124 if (is_target) {
1126 curr_field_config->tgt_interp_config.field,
1128 curr_field_config->tgt_interp_config.event_data),
1129 interp_copy);
1131 }
1132
1133 yac_interpolation_delete(interp_copy);
1134
1135 }
1136
1137 prev_comp_grid_pair = curr_comp_grid_pair;
1138 }
1139
1141 yac_interp_weights_delete(interp_weights);
1142 yac_interp_grid_delete(interp_grid);
1143 yac_dist_grid_pair_delete(dist_grid_pair);
1144 if (comp_pair_comm != MPI_COMM_NULL)
1145 yac_mpi_call(MPI_Comm_free(&comp_pair_comm), comm);
1146 free(field_configs);
1147}
1148
1149void yac_instance_sync_def(struct yac_instance * instance) {
1152 YAC_ASSERT(instance->comp_config,
1153 "ERROR(yac_instance_sync_def): no components have been defined");
1154 yac_couple_config_sync(instance->couple_config, instance->comm);
1155}
1156
1157void yac_instance_setup(struct yac_instance * instance) {
1158 // if definitions have not yet been synced
1159 int requires_def_sync = (instance->phase == INSTANCE_DEFINITION_COMP);
1160 if (requires_def_sync)
1161 yac_instance_sync_def(instance);
1163
1164 YAC_ASSERT(
1165 instance->comp_config,
1166 "ERROR(yac_instance_setup): no components have been defined");
1167
1168 // if not all precesses have synced the definitions in this function
1169 // -> sync again
1171 MPI_Allreduce(
1172 MPI_IN_PLACE, &requires_def_sync, 1, MPI_INT, MPI_MIN, instance->comm),
1173 instance->comm);
1174 if(requires_def_sync == 0)
1175 yac_couple_config_sync(instance->couple_config, instance->comm);
1176
1177 generate_interpolations(instance);
1178}
1179
1181 struct yac_instance * instance, int emit_flags) {
1182
1183 yac_instance_setup(instance);
1184
1185 return yac_yaml_emit_coupling(instance->couple_config, emit_flags);
1186}
1187
1189 struct yac_instance * instance,
1190 char const ** comp_names, size_t num_comp_names) {
1192 return
1194 instance->comp_config, comp_names, num_comp_names);
1195}
1196
1198 struct yac_instance * instance,
1199 const char* comp_name){
1201 return
1203 instance->comp_config, comp_name);
1204}
1205
1207 struct yac_instance * instance,
1208 const char* comp_name){
1210 return
1212 instance->comp_config, comp_name);
1213}
1214
1216
1217 struct yac_instance * instance = xmalloc(1 * sizeof(*instance));
1218
1220
1221 instance->comp_config = NULL;
1222
1223 instance->cpl_fields = NULL;
1224 instance->num_cpl_fields = 0;
1225
1226 yac_mpi_call(MPI_Comm_split(comm, 0, 0, &(instance->comm)), comm);
1227
1228 instance->phase = INSTANCE_DEFINITION;
1229
1230 return instance;
1231}
1232
1233
1235
1236 MPI_Comm dummy_comm;
1237 yac_mpi_call(MPI_Comm_split(comm, MPI_UNDEFINED, 0, &dummy_comm), comm);
1238}
1239
1240void yac_instance_delete(struct yac_instance * instance) {
1241
1242 if (instance == NULL) return;
1243
1245
1246 for (size_t i = 0; i < instance->num_cpl_fields; ++i)
1248 free(instance->cpl_fields);
1249
1251
1252 yac_mpi_call(MPI_Comm_free(&(instance->comm)), MPI_COMM_WORLD);
1253
1254 free(instance);
1255}
1256
1258 struct yac_instance * instance) {
1259
1260 return instance->couple_config;
1261}
1262
1264 struct yac_instance * instance,
1265 struct yac_couple_config * couple_config) {
1266 CHECK_MAX_PHASE("yac_instance_set_couple_config", INSTANCE_DEFINITION);
1267 if (instance->couple_config == couple_config) return;
1269 instance->couple_config = couple_config;
1270}
1271
1273 struct yac_instance * instance, const char * start_datetime,
1274 const char * end_datetime ) {
1275 CHECK_MAX_PHASE("yac_instance_def_datetime", INSTANCE_DEFINITION_COMP);
1278}
1279
1281 CHECK_MIN_PHASE("yac_instance_get_start_datetime", INSTANCE_DEFINITION_COMP);
1282 return (char*)yac_couple_config_get_start_datetime(instance->couple_config);
1283}
1284
1286 CHECK_MIN_PHASE("yac_instance_get_end_datetime", INSTANCE_DEFINITION_COMP);
1287 return (char*)yac_couple_config_get_end_datetime(instance->couple_config);
1288}
1289
1291 struct yac_instance * instance,
1292 char const ** comp_names, size_t num_comps) {
1295
1296 YAC_ASSERT(
1297 !instance->comp_config,
1298 "ERROR(yac_instance_def_components): components have already been defined")
1299
1300 // add components to coupling configuration
1301 for (size_t i = 0; i < num_comps; ++i)
1302 yac_couple_config_add_component(instance->couple_config, comp_names[i]);
1303
1304 // synchronise coupling configuration
1305 yac_couple_config_sync(instance->couple_config, instance->comm);
1306
1307 instance->comp_config =
1309 instance->couple_config, comp_names, num_comps, instance->comm);
1310}
1311
1313 struct yac_instance * instance) {
1314 return instance->phase > INSTANCE_DEFINITION_COMP;
1315}
1316
1318 struct yac_instance * instance, char const * field_name,
1319 char const * comp_name, struct yac_basic_grid * grid,
1321 int collection_size, char const * timestep) {
1324
1325 struct yac_couple_config * couple_config = instance->couple_config;
1326 char const * grid_name = yac_basic_grid_get_name(grid);
1327 if(!yac_couple_config_contains_grid_name(couple_config, grid_name))
1328 yac_couple_config_add_grid(couple_config, grid_name);
1329
1330 YAC_ASSERT(
1331 field_name, "ERROR(yac_instance_add_field): "
1332 "\"NULL\" is not a valid field name")
1333 YAC_ASSERT(
1334 strlen(field_name) <= YAC_MAX_CHARLEN,
1335 "ERROR(yac_instance_add_field): field name is too long "
1336 "(maximum is YAC_MAX_CHARLEN)")
1338 (collection_size > 0) && (collection_size < INT_MAX),
1339 "ERROR(yac_instance_add_field): \"%d\" is not a valid collection size "
1340 "(component \"%s\" grid \"%s\" field \"%s\")",
1341 collection_size, comp_name, grid_name, field_name)
1342
1343 // add field to coupling configuration
1345 couple_config, comp_name, grid_name, field_name,
1346 timestep, collection_size);
1347
1348 // check whether the field is already defined
1349 for (size_t i = 0; i < instance->num_cpl_fields; ++i) {
1350 struct coupling_field * cpl_field = instance->cpl_fields[i];
1352 strcmp(yac_get_coupling_field_name(cpl_field), field_name) ||
1353 (strcmp(
1354 yac_get_coupling_field_comp_name(cpl_field), comp_name)) ||
1356 "ERROR(yac_instance_add_field): "
1357 "field with the name \"%s\" has already been defined",
1358 field_name);
1359 }
1360
1361 struct coupling_field * cpl_field =
1363 field_name, comp_name, grid, interp_fields, num_interp_fields,
1365
1366 instance->cpl_fields =
1367 xrealloc(
1368 instance->cpl_fields,
1369 (instance->num_cpl_fields + 1) * sizeof(*(instance->cpl_fields)));
1370 instance->cpl_fields[instance->num_cpl_fields] = cpl_field;
1371 instance->num_cpl_fields++;
1372
1373 return cpl_field;
1374}
1375
1377 struct yac_instance * instance,
1378 char const * src_comp_name, char const * src_grid_name, char const * src_field_name,
1379 char const * tgt_comp_name, char const * tgt_grid_name, char const * tgt_field_name,
1380 char const * coupling_period, int time_reduction,
1381 struct yac_interp_stack_config * interp_stack_config, int src_lag, int tgt_lag,
1382 const char* weight_file_name, int mapping_on_source,
1383 double scale_factor, double scale_summand, size_t num_src_mask_names,
1384 char const * const * src_mask_names, char const * tgt_mask_name) {
1385
1388
1390 instance->couple_config, src_comp_name, src_grid_name, src_field_name,
1391 tgt_comp_name, tgt_grid_name, tgt_field_name, coupling_period,
1392 time_reduction, interp_stack_config, src_lag, tgt_lag, weight_file_name,
1393 mapping_on_source, scale_factor, scale_summand, num_src_mask_names,
1394 src_mask_names, tgt_mask_name);
1395}
1396
1398 const char * comp_name, const char* grid_name, const char * field_name){
1399 CHECK_MIN_PHASE("yac_instance_get_field", INSTANCE_DEFINITION_COMP);
1400 return get_coupling_field(comp_name, field_name,
1401 grid_name, instance->num_cpl_fields, instance->cpl_fields);
1402}
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:172
int const * yac_basic_grid_get_field_mask(struct yac_basic_grid *grid, struct yac_interp_field field)
Definition basic_grid.c:113
yac_const_coordinate_pointer yac_basic_grid_get_field_coordinates(struct yac_basic_grid *grid, struct yac_interp_field field)
Definition basic_grid.c:76
char const * yac_basic_grid_get_name(struct yac_basic_grid *grid)
Definition basic_grid.c:123
struct yac_basic_grid * yac_basic_grid_empty_new(char const *name)
Definition basic_grid.c:58
void yac_basic_grid_delete(struct yac_basic_grid *grid)
Definition basic_grid.c:65
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)
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)
void yac_couple_config_sync(struct yac_couple_config *couple_config, MPI_Comm comm)
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_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)
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_end_datetime(struct yac_couple_config *couple_config)
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)
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_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)
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)
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)
char const * yac_couple_config_get_start_datetime(struct yac_couple_config *couple_config)
size_t yac_couple_config_get_collection_size(struct yac_couple_config *couple_config, char const *component_name, char const *grid_name, char const *field_name)
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:2957
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:2714
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:1240
char * yac_instance_setup_and_emit_config(struct yac_instance *instance, int emit_flags)
Definition instance.c:1180
int yac_instance_get_comp_rank(struct yac_instance *instance, const char *comp_name)
Definition instance.c:1206
char * yac_instance_get_start_datetime(struct yac_instance *instance)
Definition instance.c:1280
char * yac_instance_get_end_datetime(struct yac_instance *instance)
Definition instance.c:1285
static struct yac_basic_grid * get_basic_grid(const char *grid_name, char const *component_name, size_t num_fields, struct coupling_field **coupling_fields, int *delete_flag)
Definition instance.c:155
void yac_instance_def_datetime(struct yac_instance *instance, const char *start_datetime, const char *end_datetime)
Definition instance.c:1272
void yac_instance_sync_def(struct yac_instance *instance)
Definition instance.c:1149
struct yac_instance * yac_instance_new(MPI_Comm comm)
Definition instance.c:1215
int yac_instance_components_are_defined(struct yac_instance *instance)
Definition instance.c:1312
static void generate_interpolations(struct yac_instance *instance)
Definition instance.c:910
void yac_instance_setup(struct yac_instance *instance)
Definition instance.c:1157
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:1317
void yac_instance_set_couple_config(struct yac_instance *instance, struct yac_couple_config *couple_config)
Definition instance.c:1263
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:189
void yac_instance_dummy_new(MPI_Comm comm)
Definition instance.c:1234
void yac_instance_def_components(struct yac_instance *instance, char const **comp_names, size_t num_comps)
Definition instance.c:1290
#define CHECK_MIN_PHASE(FUNC_NAME, MIN_REF_PHASE)
Definition instance.c:47
static void get_field_configuration(struct yac_instance *instance, struct field_config **field_configs_, size_t *count)
Definition instance.c:436
static int compare_field_config_ids(const void *a, const void *b)
Definition instance.c:764
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:252
struct yac_couple_config * yac_instance_get_couple_config(struct yac_instance *instance)
Definition instance.c:1257
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:383
static int compare_comp_grid_config(const void *a, const void *b)
Definition instance.c:179
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:236
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:207
static const char * yac_instance_phase_str[]
Definition instance.c:29
static struct event * generate_event(struct field_config_event_data event_data)
Definition instance.c:425
static int compare_field_config_field_ids(const void *a, const void *b)
Definition instance.c:323
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)
Definition instance.c:1376
#define CHECK_PHASE(FUNC_NAME, REF_PHASE, NEW_PHASE)
Definition instance.c:36
#define CHECK_MAX_PHASE(FUNC_NAME, MAX_REF_PHASE)
Definition instance.c:57
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:787
yac_instance_phase
Definition instance.c:21
@ INSTANCE_EXCHANGE
Definition instance.c:25
@ INSTANCE_DEFINITION_COMP
Definition instance.c:23
@ INSTANCE_DEFINITION_SYNC
Definition instance.c:24
@ INSTANCE_DEFINITION
Definition instance.c:22
@ INSTANCE_UNKNOWN
Definition instance.c:26
static int compare_field_config(const void *a, const void *b)
Definition instance.c:354
int yac_instance_get_comp_size(struct yac_instance *instance, const char *comp_name)
Definition instance.c:1197
field_type
Definition instance.c:84
@ TGT
Definition instance.c:86
@ SRC
Definition instance.c:85
MPI_Comm yac_instance_get_comps_comm(struct yac_instance *instance, char const **comp_names, size_t num_comp_names)
Definition instance.c:1188
static int compare_field_config_interp_method(const void *a, const void *b)
Definition instance.c:335
static struct yac_interp_weights * generate_interp_weights(struct src_field_config src_interp_config, struct yac_interp_grid *interp_grid)
Definition instance.c:772
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:1397
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)
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)
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)
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:91
const char * grid_name
Definition instance.c:90
struct comp_grid_config config[2]
Definition instance.c:95
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:104
char const * start_datetime
Definition instance.c:103
enum yac_reduction_type reduction_operation
Definition instance.c:102
char const * timestep
Definition instance.c:99
char const * coupling_period
Definition instance.c:100
double scale_summand
Definition instance.c:149
double scale_factor
Definition instance.c:149
struct comp_grid_pair_config comp_grid_pair
Definition instance.c:139
enum yac_interp_weights_reorder_type reorder_type
Definition instance.c:145
struct tgt_field_config tgt_interp_config
Definition instance.c:143
size_t collection_size
Definition instance.c:151
char const * name
Definition instance.c:136
struct src_field_config src_interp_config
Definition instance.c:142
double frac_mask_fallback_value
Definition instance.c:147
int src_comp_idx
Definition instance.c:140
const char * weight_file_name
Definition instance.c:122
char const *const * mask_names
Definition instance.c:118
struct field_config_event_data event_data
Definition instance.c:123
struct yac_interp_stack_config * interp_stack
Definition instance.c:121
struct coupling_field * field
Definition instance.c:114
char const * name
Definition instance.c:115
size_t num_mask_names
Definition instance.c:119
struct field_config_event_data event_data
Definition instance.c:131
char const * name
Definition instance.c:128
char const * mask_name
Definition instance.c:130
struct coupling_field * field
Definition instance.c:127
struct yac_basic_grid_data data
Definition basic_grid.c:16
char const * end_datetime
char const * start_datetime
struct coupling_field ** cpl_fields
Definition instance.c:76
enum yac_instance_phase phase
Definition instance.c:81
MPI_Comm comm
Definition instance.c:79
struct yac_component_config * comp_config
Definition instance.c:74
size_t num_cpl_fields
Definition instance.c:77
struct yac_couple_config * couple_config
Definition instance.c:72
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:123
#define YAC_MAX_CHARLEN
Definition yac.h:74
#define YAC_ASSERT_F(exp, format,...)
Definition yac_assert.h:18
#define YAC_ASSERT(exp, msg)
Definition yac_assert.h:15
#define yac_mpi_call(call, comm)
double const (*const yac_const_coordinate_pointer)[3]
Definition yac_types.h:20