YetAnotherCoupler 3.4.0
Loading...
Searching...
No Matches
couple_config.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#include <math.h>
13
14#include "couple_config.h"
15#include "yac_mpi_common.h"
16#include "yac.h"
17#include "mtime_calendar.h"
18#include "utils_common.h"
19#include "config_yaml.h"
20#include "dist_merge.h"
21#include "mtime_datetime.h"
22
28
30 char const * name; //< name of the file
31 enum yac_text_filetype type; //< type of the file
32 char const * ref; //< name of the synchronization location
33 //< at which this file is to be written
34 //< out
35 enum flag_value include_definitions; //< include user definitions (components,
36 //< grids, and fields)
37};
38
40 char const * name;
41 char* metadata;
42 char const * output_filename;
43};
44
46 char const * name;
47 size_t grid_idx;
48 char const * timestep;
49 char * metadata;
52};
53
55
57 size_t num_fields;
58
59 char const * name;
60 char * metadata;
61};
62
87
95
97
98 struct _datetime * start_datetime;
99 struct _datetime * end_datetime;
100
103
105 size_t num_grids;
106
109
112
113 // this flag indicates whether YAC aborts if for a defined couple at least
114 // one associated field was not defined by the user
116};
117
119
120 struct yac_couple_config * couple_config =
121 xmalloc(1 * sizeof(*couple_config));
122
123 couple_config->start_datetime = NULL;
124 couple_config->end_datetime = NULL;
125
126 couple_config->config_outputs = NULL;
127 couple_config->num_config_outputs = 0;
128
129 couple_config->grids = NULL;
130 couple_config->num_grids = 0;
131
132 couple_config->components = NULL;
133 couple_config->num_components = 0;
134
135 couple_config->couples = NULL;
136 couple_config->num_couples = 0;
137
139
140 return couple_config;
141}
142
143static char const * string_dup(char const * string) {
144 return (string != NULL)?strdup(string):NULL;
145}
146
147static void yac_couple_config_field_free(void * field_){
148 struct yac_couple_config_field * field = field_;
149 free((void*)field->name);
150 free((void*)field->timestep);
151 free(field->metadata);
152}
153
154
155static void yac_couple_config_component_free(void * component_) {
156
157 struct yac_couple_config_component * component = component_;
158
159 for (size_t i = 0; i < component->num_fields; ++i)
160 yac_couple_config_field_free(component->fields + i);
161 free(component->fields);
162 free((void*)(component->name));
163 free(component->metadata);
164}
165
166static void yac_couple_config_field_couple_free(void * field_couple_) {
167
168 struct yac_couple_config_field_couple * field_couple = field_couple_;
170 free((void*)field_couple->coupling_period);
171 free((void*)field_couple->weight_file_name);
172 for (size_t i = 0; i < field_couple->num_src_mask_names; ++i)
173 free((void*)field_couple->src_mask_names[i]);
174 free(field_couple->src_mask_names);
175 free(field_couple->tgt_mask_name);
176}
177
178static void yac_couple_config_couple_free(void * couple_) {
179
180 struct yac_couple_config_couple * couple = couple_;
181 for (size_t i = 0; i < couple->num_field_couples; ++i)
183 free(couple->field_couples);
184 couple->field_couples = NULL;
185 couple->num_field_couples = 0;
186}
187
188static void yac_couple_config_grid_free(void * grid_) {
189
190 struct yac_couple_config_grid * grid = grid_;
191
192 free((void*)grid->name);
193 free((void*)grid->output_filename);
194 free(grid->metadata);
195}
196
198 void * config_output_) {
199
200 struct yac_couple_config_config_output * config_output = config_output_;
201
202 free((void*)config_output->name);
203 free((void*)config_output->ref);
204}
205
206static int yac_couple_config_grid_compare(void const * a, void const * b) {
207 YAC_ASSERT(((struct yac_couple_config_grid const *)a)->name != NULL &&
208 ((struct yac_couple_config_grid const *)b)->name != NULL,
209 "ERROR(yac_couple_config_grid_compare): "
210 "invalid name (NULL is not allowed)");
211 return strcmp(((struct yac_couple_config_grid const *)a)->name,
212 ((struct yac_couple_config_grid const *)b)->name);
213}
214
215static int yac_couple_config_field_compare(void const * a_, void const * b_) {
216 struct yac_couple_config_field const * a = a_;
217 struct yac_couple_config_field const * b = b_;
218 int ret = (a->grid_idx > b->grid_idx) - (a->grid_idx < b->grid_idx);
219 if (ret) return ret;
221 a->name != NULL && b->name != NULL,
222 "ERROR(yac_couple_config_field_compare): "
223 "invalid name (NULL is not allowed)");
224 return strcmp(a->name, b->name);
225}
226
228 void const * a_, void const * b_) {
229 struct yac_couple_config_component const * a = a_;
230 struct yac_couple_config_component const * b = b_;
231 YAC_ASSERT(a->name != NULL && b->name != NULL,
232 "ERROR(yac_couple_config_component_compare): "
233 "invalid name (NULL is not allowed)");
234 return strcmp(a->name, b->name);
235}
236
238 void const * a_, void const * b_) {
239 struct yac_couple_config_field_couple const * a = a_;
240 struct yac_couple_config_field_couple const * b = b_;
241 int ret;
242 ret = (a->source.component_idx > b->source.component_idx) -
244 if (ret) return ret;
245 ret = (a->target.component_idx > b->target.component_idx) -
247 if (ret) return ret;
248 ret = (a->source.field_idx > b->source.field_idx) -
250 if (ret) return ret;
251 return (a->target.field_idx > b->target.field_idx) -
253}
254
256 void const * a_, void const * b_) {
257 struct yac_couple_config_couple const * a = a_;
258 struct yac_couple_config_couple const * b = b_;
259 int ret;
260 ret = (a->component_indices[0] > b->component_indices[0]) -
261 (a->component_indices[0] < b->component_indices[0]);
262 if (ret) return ret;
263 return (a->component_indices[1] > b->component_indices[1]) -
264 (a->component_indices[1] < b->component_indices[1]);
265}
266
268 void const * a, void const * b) {
270 ((struct yac_couple_config_config_output const *)a)->ref != NULL &&
271 ((struct yac_couple_config_config_output const *)b)->ref != NULL,
272 "ERROR(yac_couple_config_config_output_compare): "
273 "invalid ref (NULL is not allowed)");
274 return strcmp(((struct yac_couple_config_config_output const *)a)->ref,
275 ((struct yac_couple_config_config_output const *)b)->ref);
276}
277
279 char const * string_name, char ** string, MPI_Comm comm) {
280
281 int rank;
282 MPI_Comm_rank(comm, &rank);
283 struct {
284 int len;
285 int rank;
286 } data_pair;
287 size_t len = (*string != NULL)?(strlen(*string) + 1):0;
289 len <= INT_MAX,
290 "ERROR(couple_config_sync_string): \"%s\" too long", string_name);
291 data_pair.len = (int)len;
292 data_pair.rank = rank;
293
294 // determine the broadcaster
296 MPI_Allreduce(
297 MPI_IN_PLACE, &data_pair, 1, MPI_2INT, MPI_MAXLOC, comm), comm);
298 if (data_pair.len == 0) return;
299
300 // broadcast string
301 char const * string_bak = NULL;
302 if (data_pair.rank != rank) {
303 string_bak = *string;
304 *string = xmalloc((size_t)data_pair.len * sizeof(**string));
305 }
307 MPI_Bcast(*string, data_pair.len, MPI_CHAR, data_pair.rank, comm), comm);
308
309 // check for consistency
310 if (data_pair.rank != rank) {
312 (string_bak == NULL) ||
313 !strcmp(string_bak, *string),
314 "ERROR(couple_config_sync_string): inconsistent \"%s\" definition "
315 "(\"%s\" != \"%s\")", string_name, string_bak, *string);
316 free((void*)string_bak);
317 }
318}
319
321 char const * flag_value_name, enum flag_value * flag, MPI_Comm comm) {
322
323 int int_flag = (*flag == FLAG_UNSET)?INT_MAX:((int)*flag);
324
325 // broadcast flag value
327 MPI_Allreduce(
328 MPI_IN_PLACE, &int_flag, 1, MPI_INT, MPI_MIN, comm), comm);
329
330 // if no process has defined a flag value
331 if (int_flag == INT_MAX) return;
332
333 // check for consistency
335 (*flag == FLAG_UNSET) || ((int)(*flag) == int_flag),
336 "ERROR(couple_config_sync_flag_value): inconsistent \"%s\"-flag definition "
337 "(%s != %s)", flag_value_name, ((int_flag == FLAG_TRUE)?"TRUE":"FALSE"),
338 ((*flag == FLAG_TRUE)?"TRUE":"FALSE"));
339
340 // update flag
341 *flag = (enum flag_value)int_flag;
342}
343
344static void couple_config_sync_calendar(MPI_Comm comm) {
345
346 int calendar = (int)getCalendarType();
347 if (calendar == CALENDAR_NOT_SET) calendar = INT_MAX;
348
349 // broadcast calendar
351 MPI_Allreduce(
352 MPI_IN_PLACE, &calendar, 1, MPI_INT, MPI_MIN, comm), comm);
353
354 // if no process has defined a calendar
355 if (calendar == INT_MAX) return;
356
357 // set calendar (if local process has already defined a calendar,
358 // the definition is checked for consistency)
359 yac_cdef_calendar(calendar);
360}
361
363 void * a_, void * b_, MPI_Comm comm) {
364
365 struct yac_couple_config_component * a = a_;
366 struct yac_couple_config_component * b = b_;
367
368 if (b) {
369 a->num_fields = b->num_fields;
370 a->fields = b->fields;
371 b->num_fields = 0;
372 b->fields = NULL;
373 a->metadata = b->metadata;
374 b->metadata = NULL;
375 }
376
378 "component metadata", (char **)&(a->metadata), comm);
379}
380
382 void * a_, void * b_, MPI_Comm comm) {
383
384 struct yac_couple_config_grid * a = a_;
385 struct yac_couple_config_grid * b = b_;
386
387 if (b!= NULL) {
389 b->output_filename = NULL;
390 a->metadata = b->metadata;
391 b->metadata = NULL;
392 }
393
395 "grid output_filename", (char **)&(a->output_filename), comm);
396 couple_config_sync_string("grid metadata", (char **)&(a->metadata), comm);
397}
398
400 void * a_, void * b_, MPI_Comm comm) {
401
402 struct yac_couple_config_field * a = a_;
403 struct yac_couple_config_field * b = b_;
404
405 enum {
406 TIMESTEP_IDX,
407 METADATA_IDX,
408 FRAC_MASK_IDX,
409 COLLECTION_SIZE_IDX,
410 DATA_PAIR_COUNT
411 };
412
413 int rank;
414 MPI_Comm_rank(comm, &rank);
415 struct {
416 int len;
417 int rank;
418 } data_pairs[DATA_PAIR_COUNT];
419 size_t timestep_len =
420 ((b != NULL) && (b->timestep != NULL))?(strlen(b->timestep) + 1):0;
421 size_t metadata_len =
422 ((b != NULL) && (b->metadata != NULL))?(strlen(b->metadata) + 1):0;
424 timestep_len <= INT_MAX,
425 "ERROR(yac_couple_config_field_merge): timestep string too long");
427 metadata_len <= INT_MAX,
428 "ERROR(yac_couple_config_field_merge): metadata string too long");
430 (b == NULL) || (b->collection_size <= INT_MAX) ||
431 (b->collection_size == SIZE_MAX),
432 "ERROR(yac_couple_config_field_merge): invalid collection size \"%zu\"",
433 b->collection_size);
434 data_pairs[TIMESTEP_IDX].len = (int)timestep_len;
435 data_pairs[TIMESTEP_IDX].rank = rank;
436 data_pairs[METADATA_IDX].len = (int)metadata_len;
437 data_pairs[METADATA_IDX].rank = rank;
438 data_pairs[FRAC_MASK_IDX].len =
440 data_pairs[FRAC_MASK_IDX].rank = rank;
441 data_pairs[COLLECTION_SIZE_IDX].len =
442 ((b == NULL) || (b->collection_size == SIZE_MAX))?
443 -1:(int)b->collection_size;
444 data_pairs[COLLECTION_SIZE_IDX].rank = rank;
445
446 // determine the broadcaster
448 MPI_Allreduce(
449 MPI_IN_PLACE, data_pairs, DATA_PAIR_COUNT, MPI_2INT,
450 MPI_MAXLOC, comm), comm);
451
452 // if at least one process has a valid timestep
453 if (data_pairs[TIMESTEP_IDX].len > 0) {
454
455 // broadcast timestep
456 char * timestep_buffer = xmalloc((size_t)data_pairs[TIMESTEP_IDX].len);
457 if (data_pairs[TIMESTEP_IDX].rank == rank)
458 strcpy(timestep_buffer, b->timestep);
460 MPI_Bcast(
461 timestep_buffer, data_pairs[TIMESTEP_IDX].len, MPI_CHAR,
462 data_pairs[TIMESTEP_IDX].rank, comm), comm);
463
464 // check for consistency
466 (b == NULL) || (b->timestep == NULL) ||
467 !strcmp(b->timestep, timestep_buffer),
468 "ERROR(yac_couple_config_field_merge): "
469 "inconsistent timestep definition (\"%s\" != \"%s\")",
470 b->timestep, timestep_buffer);
471
472 // update timestep
473 free((void*)(a->timestep));
474 a->timestep = timestep_buffer;
475 }
476
477 // if at least one process has a valid metadata
478 if (data_pairs[METADATA_IDX].len > 0) {
479
480 // broadcast metadata
481 char * metadata_buffer = xmalloc((size_t)data_pairs[METADATA_IDX].len);
482 if (data_pairs[METADATA_IDX].rank == rank)
483 strcpy(metadata_buffer, b->metadata);
485 MPI_Bcast(
486 metadata_buffer, data_pairs[METADATA_IDX].len, MPI_CHAR,
487 data_pairs[METADATA_IDX].rank, comm), comm);
488
489 // check for consistency
491 (b == NULL) || (b->metadata == NULL) ||
492 !strcmp(b->metadata, metadata_buffer),
493 "ERROR(yac_couple_config_field_merge): "
494 "inconsistent metadata definition (\"%s\" != \"%s\")",
495 b->metadata, metadata_buffer);
496
497 // update metadata
498 free(a->metadata);
499 a->metadata = metadata_buffer;
500 }
501
502 // if at least one process has a valid fractional mask fallback value
503 if (data_pairs[FRAC_MASK_IDX].len != 0) {
504
505 // broadcast fractional mask fallback value
506 double frac_mask_fallback_value;
507 if (data_pairs[FRAC_MASK_IDX].rank == rank)
508 frac_mask_fallback_value = b->frac_mask_fallback_value;
510 MPI_Bcast(
511 &frac_mask_fallback_value, 1, MPI_DOUBLE,
512 data_pairs[FRAC_MASK_IDX].rank, comm), comm);
513
514 // check for consistency
515 // (use memcmp for comparison, because it can be nan)
517 (b == NULL) || (b->frac_mask_fallback_value == YAC_FRAC_MASK_NO_VALUE) ||
518 !memcmp(
519 &b->frac_mask_fallback_value, &frac_mask_fallback_value,
520 sizeof(frac_mask_fallback_value)),
521 "ERROR(yac_couple_config_field_merge): "
522 "inconsistent fractional mask fallback value definition "
523 "(%lf != %lf)",
524 b->frac_mask_fallback_value, frac_mask_fallback_value);
525
526 // update fractional mask fallback value
527 a->frac_mask_fallback_value = frac_mask_fallback_value;
528 }
529
530
531 // if at least one process has a valid collection size
532 if (data_pairs[COLLECTION_SIZE_IDX].len > -1) {
533
534 // check for consistency
536 (b == NULL) || (b->collection_size == SIZE_MAX) ||
537 (b->collection_size == (size_t)(data_pairs[COLLECTION_SIZE_IDX].len)),
538 "ERROR(yac_couple_config_field_merge): "
539 "inconsistent collection size definition (\"%zu\" != \"%d\")",
540 b->collection_size, data_pairs[COLLECTION_SIZE_IDX].len);
541
542 // update collection size
543 a->collection_size = (size_t)(data_pairs[COLLECTION_SIZE_IDX].len);
544 }
545}
546
548 void * a_, void * b_, MPI_Comm comm) {
549
550 UNUSED(comm);
551
552 if (b_ == NULL) return;
553
554 struct yac_couple_config_field_couple * a = a_;
555 struct yac_couple_config_field_couple * b = b_;
556
558 (a->source.lag == b->source.lag),
559 "ERROR(yac_couple_config_field_couple_merge): "
560 "inconsistent source lag (%d != %d)", a->source.lag, b->source.lag)
562 (a->target.lag == b->target.lag),
563 "ERROR(yac_couple_config_field_couple_merge): "
564 "inconsistent target lag (%d != %d)", a->target.lag, b->target.lag)
567 "ERROR(yac_couple_config_field_couple_merge): "
568 "inconsistent mapping side (%d != %d)",
572 "ERROR(yac_couple_config_field_couple_merge): "
573 "inconsistent interpolation stack")
576 "ERROR(yac_couple_config_field_couple_merge): "
577 "inconsistent coupling period operation (%d != %d)",
580 !strcmp(a->coupling_period, b->coupling_period),
581 "ERROR(yac_couple_config_field_couple_merge): "
582 "inconsistent coupling period (%s != %s)",
586 "ERROR(yac_couple_config_field_couple_merge): "
587 "inconsistent defintion of enforce_write_weight_file (%d != %d)",
591 !strcmp(a->weight_file_name, b->weight_file_name),
592 "ERROR(yac_couple_config_field_couple_merge): "
593 "inconsistent weight_file_name (%s != %s)",
596 a->scale_factor == b->scale_factor,
597 "ERROR(yac_couple_config_field_couple_merge): "
598 "inconsistent scale factor (%lf != %lf)",
602 "ERROR(yac_couple_config_field_couple_merge): "
603 "inconsistent scale summand (%lf != %lf)",
607 "ERROR(yac_couple_config_field_couple_merge): "
608 "inconsistent number of source mask names (%zu != %zu)",
611 (a->src_mask_names != NULL) == (b->src_mask_names != NULL),
612 "ERROR(yac_couple_config_field_couple_merge): "
613 "inconsistent availability of source mask names (%s != %s)",
614 (a->src_mask_names != NULL)?"TRUE":"FALSE",
615 (b->src_mask_names != NULL)?"TRUE":"FALSE")
616 for (size_t i = 0; i < a->num_src_mask_names; ++i)
618 !strcmp(a->src_mask_names[i], b->src_mask_names[i]),
619 "ERROR(yac_couple_config_field_couple_merge): "
620 "inconsistent source mask names at index %zu (\"%s\" != \"%s\")",
621 i, a->src_mask_names[i], b->src_mask_names[i])
623 (a->tgt_mask_name != NULL) == (b->tgt_mask_name != NULL),
624 "ERROR(yac_couple_config_field_couple_merge): "
625 "inconsistent availability of target mask name (%s != %s)",
626 (a->tgt_mask_name != NULL)?"TRUE":"FALSE",
627 (b->tgt_mask_name != NULL)?"TRUE":"FALSE")
629 (a->tgt_mask_name == NULL) ||
630 !strcmp(a->tgt_mask_name, b->tgt_mask_name),
631 "ERROR(yac_couple_config_field_couple_merge): "
632 "inconsistent target mask name (\"%s\" != \"%s\")",
634}
635
636static void merge_field_couples(
637 size_t * num_field_couples,
638 struct yac_couple_config_field_couple ** field_couples, MPI_Comm comm);
639
641 void * a_, void * b_, MPI_Comm comm) {
642
643 struct yac_couple_config_couple * a = a_;
644 struct yac_couple_config_couple * b = b_;
645
646 if (b) {
649 b->num_field_couples = 0;
650 b->field_couples = NULL;
651 }
652
653 // distribute and merge field couples
655}
656
658 void * a_, void * b_, MPI_Comm comm) {
659
660 struct yac_couple_config_config_output * a = a_;
661 struct yac_couple_config_config_output * b = b_;
662
663 if (b) {
664
666 !strcmp(a->name, b->name),
667 "ERROR(yac_couple_config_config_output_merge): "
668 "inconsistent file names for ref \"%s\" (\"%s\" != \"%s\")",
669 a->ref, a->name, b->name)
671 a->type == b->type,
672 "ERROR(yac_couple_config_config_output_merge): "
673 "inconsistent file types for ref \"%s\" (%d != %d)",
674 a->ref, a->type, b->type)
675
677 }
678
680 "include definitions", &(a->include_definitions), comm);
681}
682
683void yac_couple_config_delete(struct yac_couple_config * couple_config) {
684
685 deallocateDateTime((void*)couple_config->start_datetime);
686 deallocateDateTime((void*)couple_config->end_datetime);
687
688 for (size_t i = 0; i < couple_config->num_config_outputs; ++i)
690 couple_config->config_outputs + i);
691 free((void*)couple_config->config_outputs);
692
693 for (size_t i = 0; i < couple_config->num_grids; ++i){
694 yac_couple_config_grid_free(couple_config->grids + i);
695 }
696 free(couple_config->grids);
697
698 for (size_t i = 0;
699 i < couple_config->num_components; ++i)
701 free(couple_config->components);
702
703 for (size_t couple_idx = 0; couple_idx < couple_config->num_couples;
704 ++couple_idx)
705 yac_couple_config_couple_free(couple_config->couples + couple_idx);
706 free(couple_config->couples);
707 free(couple_config);
708}
709
711 struct yac_couple_config * couple_config, char const * name) {
712
714 name != NULL,
715 "ERROR(yac_couple_config_add_grid_): "
716 "invalid name (NULL is not allowed)")
717
718 for (size_t i = 0; i < couple_config->num_grids; ++i)
719 if (!strcmp(couple_config->grids[i].name, name)) return i;
720
721 size_t grid_idx = couple_config->num_grids;
722 couple_config->num_grids++;
723 couple_config->grids =
724 xrealloc(
725 couple_config->grids,
726 couple_config->num_grids * sizeof(*(couple_config->grids)));
727 couple_config->grids[grid_idx].name = string_dup(name);
728 couple_config->grids[grid_idx].output_filename = NULL;
729 couple_config->grids[grid_idx].metadata = NULL;
730 return grid_idx;
731}
732
734 struct yac_couple_config * couple_config, char const * name) {
735
736 yac_couple_config_add_grid_(couple_config, name);
737}
738
740 struct yac_couple_config * couple_config, char const * name) {
741
743 name != NULL,
744 "ERROR(yac_couple_config_add_component_): "
745 "invalid name (NULL is not allowed)")
746
747 for (size_t i = 0; i < couple_config->num_components; ++i)
748 if (!strcmp(couple_config->components[i].name, name)) return i;
749
750 size_t component_idx = couple_config->num_components;
751 couple_config->num_components++;
752 couple_config->components =
753 xrealloc(
754 couple_config->components,
755 couple_config->num_components * sizeof(*(couple_config->components)));
756 couple_config->components[component_idx].fields = NULL;
757 couple_config->components[component_idx].num_fields = 0;
758 couple_config->components[component_idx].name = strdup(name);
759 couple_config->components[component_idx].metadata = NULL;
760 return component_idx;
761}
762
764 struct yac_couple_config * couple_config, char const * name) {
765
767}
768
770 struct yac_couple_config * couple_config,
771 char const * comp_name, const char* metadata) {
772 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
773 free(couple_config->components[comp_idx].metadata);
774 couple_config->components[comp_idx].metadata
775 = metadata==NULL?NULL:strdup(metadata);
776}
777
779 struct yac_couple_config * couple_config,
780 char const * grid_name, const char* output_filename) {
781 if(!yac_couple_config_contains_grid_name(couple_config, grid_name))
782 yac_couple_config_add_grid(couple_config, grid_name);
783 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
785 output_filename != NULL,
786 "ERROR(yac_couple_config_grid_set_output_filename): invalid output filename "
787 "for grid \"%s\" (NULL is not allowed)",
788 grid_name);
790 (couple_config->grids[grid_idx].output_filename == NULL) ||
791 (!strcmp(couple_config->grids[grid_idx].output_filename, output_filename)),
792 "ERROR(yac_couple_config_grid_set_output_filename): output file name for grid "
793 "\"%s\" has already been set (\"%s\" != \"%s\")",
794 grid_name, couple_config->grids[grid_idx].output_filename, output_filename);
795 if (couple_config->grids[grid_idx].output_filename == NULL)
796 couple_config->grids[grid_idx].output_filename = strdup(output_filename);
797}
798
800 struct yac_couple_config * couple_config,
801 char const * grid_name, const char* metadata) {
802 if(!yac_couple_config_contains_grid_name(couple_config, grid_name))
803 yac_couple_config_add_grid(couple_config, grid_name);
804 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
805 free(couple_config->grids[grid_idx].metadata);
806 couple_config->grids[grid_idx].metadata
807 = metadata==NULL?NULL:strdup(metadata);
808}
809
811 struct yac_couple_config * couple_config,
812 const char* comp_name, const char * grid_name, const char* field_name,
813 const char* metadata) {
814 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
815 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
816 size_t field_idx = yac_couple_config_get_field_idx(couple_config,
817 comp_idx, grid_idx, field_name);
818 free(couple_config->components[comp_idx].fields[field_idx].metadata);
819 couple_config->components[comp_idx].fields[field_idx].metadata
820 = metadata==NULL?NULL:strdup(metadata);
821}
822
824 struct yac_couple_config * couple_config,
825 const char * comp_name) {
826 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
827 return couple_config->components[comp_idx].metadata;
828}
829
831 struct yac_couple_config * couple_config,
832 const char * grid_name) {
833 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
834 return couple_config->grids[grid_idx].output_filename;
835}
836
838 struct yac_couple_config * couple_config,
839 const char * grid_name) {
840 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
841 return couple_config->grids[grid_idx].metadata;
842}
843
845 struct yac_couple_config * couple_config,
846 const char* comp_name, const char * grid_name, const char* field_name) {
847 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
848 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
849 size_t field_idx = yac_couple_config_get_field_idx(couple_config,
850 comp_idx, grid_idx, field_name);
851 return couple_config->components[comp_idx].fields[field_idx].metadata;
852}
853
855 struct yac_couple_config * couple_config, size_t component_idx,
856 char const * routine_name, int line) {
857
859 component_idx < couple_config->num_components,
860 "ERROR(%s:%d:%s): invalid component_idx", __FILE__, line, routine_name)
861}
862
863static void check_grid_idx(
864 struct yac_couple_config * couple_config, size_t grid_idx,
865 char const * routine_name, int line) {
866
868 grid_idx < couple_config->num_grids,
869 "ERROR(%s:%d:%s): invalid grid_idx", __FILE__, line, routine_name)
870}
871
873 struct yac_couple_config * couple_config,
874 size_t comp_idx, size_t grid_idx, char const * name,
875 char const * timestep, size_t collection_size) {
876
878 couple_config, comp_idx,
879 "yac_couple_config_component_add_field_", __LINE__);
881 couple_config, grid_idx,
882 "yac_couple_config_component_add_field_", __LINE__);
883
884 // check whether the field already exists
885 struct yac_couple_config_component * component =
886 couple_config->components + comp_idx;
887 for (size_t i = 0; i < component->num_fields; i++) {
888 if((strcmp(component->fields[i].name, name) == 0) &&
889 (component->fields[i].grid_idx == grid_idx)) {
890 // if no timestep is defined for the field
891 if (!component->fields[i].timestep && timestep)
892 component->fields[i].timestep = strdup(timestep);
893 // if no collection size is defined for the field
894 if (component->fields[i].collection_size == SIZE_MAX)
895 component->fields[i].collection_size = collection_size;
897 !timestep ||
898 !strcmp(timestep, component->fields[i].timestep),
899 "ERROR(yac_couple_config_component_add_field): "
900 "inconsistent timestep definition (\"%s\" != \"%s\")",
901 timestep, component->fields[i].timestep);
903 collection_size == SIZE_MAX ||
904 collection_size == component->fields[i].collection_size,
905 "ERROR(yac_couple_config_component_add_field): "
906 "inconsistent collection_size definition (%zu != %zu)",
907 collection_size, component->fields[i].collection_size);
908 return i;
909 }
910 }
911
912 size_t field_idx = component->num_fields;
913 component->num_fields++;
914
915 component->fields =
916 xrealloc(
917 component->fields,
918 component->num_fields *
919 sizeof(*(component->fields)));
920 struct yac_couple_config_field * field =
921 component->fields + field_idx;
922
923 field->name = strdup(name);
924 field->grid_idx = grid_idx;
925 field->timestep = timestep?strdup(timestep):NULL;
926 field->metadata = NULL;
929 return field_idx;
930}
931
933 struct yac_couple_config * couple_config, const char* component_name,
934 const char* grid_name, const char* name, char const * timestep,
935 size_t collection_size) {
936
938 couple_config,
939 yac_couple_config_get_component_idx(couple_config, component_name),
940 yac_couple_config_get_grid_idx(couple_config, grid_name),
942}
943
945 struct yac_couple_config * couple_config) {
946
947 return couple_config->num_couples;
948}
949
951 struct yac_couple_config * couple_config) {
952
953 switch(couple_config->missing_definition_is_fatal) {
954 case(FLAG_FALSE): return 0;
955 case(FLAG_TRUE): return 1;
956 default:
958 }
959}
960
962 struct yac_couple_config * couple_config,
963 int missing_definition_is_fatal) {
964
965 enum flag_value user_value =
966 (missing_definition_is_fatal != 0)?FLAG_TRUE:FLAG_FALSE;
967
969 (couple_config->missing_definition_is_fatal == FLAG_UNSET) ||
970 (couple_config->missing_definition_is_fatal == user_value),
971 "ERROR(yac_couple_config_set_missing_definition_is_fatal): "
972 "inconsistent setting of \"missing_definition_is_fatal\"-flag "
973 "(old: %s new: %s)",
974 (couple_config->missing_definition_is_fatal == FLAG_TRUE)?"TRUE":"FALSE",
975 (user_value == FLAG_TRUE)?"TRUE":"FALSE");
976
977 couple_config->missing_definition_is_fatal = user_value;
978}
979
981 struct yac_couple_config * couple_config, size_t couple_idx,
982 char const * routine_name, int line) {
983
985 couple_idx < couple_config->num_couples,
986 "ERROR(%s:%d:%s): invalid couple_idx", __FILE__, line, routine_name);
987}
988
990 struct yac_couple_config * couple_config, size_t couple_idx) {
991
993 couple_config, couple_idx, "yac_couple_config_get_num_couple_fields",
994 __LINE__);
995
996 return couple_config->couples[couple_idx].num_field_couples;
997}
998
1000 struct yac_couple_config * couple_config, size_t couple_idx,
1001 char const * couple_component_names[2]) {
1002
1004 couple_config, couple_idx, "yac_couple_config_get_couple_component_names",
1005 __LINE__);
1006
1007 for (int i = 0; i < 2; ++i)
1008 couple_component_names[i] =
1009 couple_config->components[
1010 couple_config->couples[couple_idx].component_indices[i]].name;
1011}
1012
1014 struct yac_couple_config * couple_config, char const * component_name) {
1015
1016 YAC_ASSERT(
1017 component_name,
1018 "ERROR(yac_couple_config_component_name_is_valid): component name is NULL")
1019 YAC_ASSERT(
1020 strlen(component_name) <= YAC_MAX_CHARLEN,
1021 "ERROR(yac_couple_config_component_name_is_valid): "
1022 "component name is too long (maximum is YAC_MAX_CHARLEN)")
1023
1024 for (size_t component_idx = 0; component_idx < couple_config->num_components;
1025 ++component_idx)
1026 if (!strcmp(component_name, couple_config->components[component_idx].name))
1027 return 1;
1028 return 0;
1029}
1030
1032 struct yac_couple_config * couple_config) {
1033
1034 return couple_config->num_components;
1035}
1036
1038 struct yac_couple_config * couple_config) {
1039
1040 return couple_config->num_grids;
1041}
1042
1044 struct yac_couple_config * couple_config, size_t component_idx) {
1045 check_component_idx(couple_config, component_idx,
1046 "yac_couple_config_get_num_fields", __LINE__);
1047 return couple_config->components[component_idx].num_fields;
1048}
1049
1051 struct yac_couple_config * couple_config, char const * component_name) {
1052
1053 size_t component_idx = SIZE_MAX;
1054 for (size_t i = 0; (i < couple_config->num_components) &&
1055 (component_idx == SIZE_MAX); ++i)
1056 if (!strcmp(couple_config->components[i].name, component_name))
1057 component_idx = i;
1058
1060 component_idx != SIZE_MAX,
1061 "ERROR(yac_couple_config_get_component_idx): "
1062 "Component \"%s\" not found in coupling configuration",
1063 component_name);
1064
1065 return component_idx;
1066}
1067
1069 struct yac_couple_config * couple_config, char const * grid_name) {
1070
1071 size_t grid_idx = SIZE_MAX;
1072 for (size_t i = 0;
1073 (i < couple_config->num_grids) && (grid_idx == SIZE_MAX); ++i)
1074 if (!strcmp(couple_config->grids[i].name, grid_name))
1075 grid_idx = i;
1076
1078 grid_idx != SIZE_MAX,
1079 "ERROR(yac_couple_config_get_grid_idx): "
1080 "grid name \"%s\" not in list of grids", grid_name)
1081
1082 return grid_idx;
1083}
1084
1086 struct yac_couple_config * couple_config, size_t component_idx,
1087 size_t grid_idx, char const * field_name) {
1089 couple_config, component_idx,
1090 "yac_couple_config_get_component_name", __LINE__);
1091
1092 size_t field_idx = SIZE_MAX;
1093 struct yac_couple_config_component * component =
1094 couple_config->components + component_idx;
1095 size_t nbr_fields = component->num_fields;
1096 for(size_t i=0;
1097 (i<nbr_fields) && (field_idx == SIZE_MAX); ++i)
1098 if((component->fields[i].grid_idx == grid_idx) &&
1099 !strcmp(
1100 field_name,
1101 component->fields[i].name))
1102 field_idx = i;
1103
1105 field_idx != SIZE_MAX,
1106 "ERROR(yac_couple_config_get_field_idx): "
1107 "field not found "
1108 "(component_idx %zu grid_idx %zu field_name \"%s\"",
1109 component_idx, grid_idx, field_name);
1110
1111 return field_idx;
1112}
1113
1115 struct yac_couple_config * couple_config, size_t component_idx) {
1116
1118 couple_config, component_idx,
1119 "yac_couple_config_get_component_name", __LINE__);
1120
1121 return couple_config->components[component_idx].name;
1122}
1123
1125 struct yac_couple_config * couple_config, size_t component_idx,
1126 size_t field_idx, char const * routine_name, int line) {
1127
1129 couple_config, component_idx, routine_name, __LINE__);
1130
1132 field_idx <
1133 couple_config->components[component_idx].num_fields,
1134 "ERROR(%s:%d:%s): invalid field_idx", __FILE__,
1135 line, routine_name)
1136}
1137
1139 struct yac_couple_config * couple_config, size_t component_idx,
1140 size_t field_idx) {
1141
1143 couple_config, component_idx, field_idx,
1144 "yac_couple_config_get_field_grid_name", __LINE__);
1145
1146 return
1147 couple_config->grids[
1148 couple_config->
1149 components[component_idx].
1150 fields[field_idx].grid_idx].name;
1151}
1152
1154 struct yac_couple_config * couple_config, size_t component_idx,
1155 size_t field_idx) {
1156
1158 couple_config, component_idx, field_idx,
1159 "yac_couple_config_get_field_name", __LINE__);
1160
1161 return
1162 couple_config->
1163 components[component_idx].
1164 fields[field_idx].name;
1165}
1166
1168 struct yac_couple_config * couple_config,
1169 char const * component_name, char const * grid_name,
1170 char const * field_name) {
1171
1172 size_t component_idx =
1173 yac_couple_config_get_component_idx(couple_config, component_name);
1174 size_t grid_idx =
1175 yac_couple_config_get_grid_idx(couple_config, grid_name);
1176 size_t field_idx =
1178 couple_config, component_idx, grid_idx, field_name);
1179
1180 struct yac_couple_config_field * field =
1181 couple_config->components[component_idx].fields +
1182 field_idx;
1183
1184 return field->timestep;
1185}
1186
1188 struct yac_couple_config * couple_config,
1189 char const * component_name, char const * grid_name,
1190 char const * field_name) {
1191
1192 size_t component_idx =
1193 yac_couple_config_get_component_idx(couple_config, component_name);
1194 size_t grid_idx =
1195 yac_couple_config_get_grid_idx(couple_config, grid_name);
1196 size_t field_idx =
1198 couple_config, component_idx, grid_idx, field_name);
1199
1200 size_t nbr_couples = couple_config->num_couples;
1201 for(size_t couple_idx = 0; couple_idx<nbr_couples; ++couple_idx){
1202 struct yac_couple_config_couple * couple = couple_config->couples + couple_idx;
1203 if(couple->component_indices[0] != component_idx &&
1204 couple->component_indices[1] != component_idx)
1205 continue;
1206 size_t nbr_trans_couples = couple->num_field_couples;
1207 for(size_t trans_couple_idx = 0; trans_couple_idx < nbr_trans_couples;
1208 ++trans_couple_idx){
1209 struct yac_couple_config_field_couple * transcouple =
1210 couple->field_couples + trans_couple_idx;
1211 if(transcouple->source.component_idx == component_idx &&
1212 transcouple->source.field_idx == field_idx)
1214 if(transcouple->target.component_idx == component_idx &&
1215 transcouple->target.field_idx == field_idx)
1217 }
1218 }
1220}
1221
1223 struct yac_couple_config * couple_config,
1224 size_t component_idx, size_t field_idx) {
1225
1227 couple_config, component_idx,
1228 "yac_couple_config_field_is_valid", __LINE__);
1230 couple_config, component_idx, field_idx,
1231 "yac_couple_config_field_is_valid", __LINE__);
1232
1233 struct yac_couple_config_field * field =
1234 couple_config->components[component_idx].fields +
1235 field_idx;
1236
1237 return (field->collection_size != SIZE_MAX) &&
1238 (field->timestep != NULL);
1239}
1240
1242 struct yac_couple_config * couple_config, size_t couple_idx,
1243 size_t field_couple_idx, char const * routine_name, int line) {
1244
1245 check_couple_idx(couple_config, couple_idx, routine_name, __LINE__);
1246
1248 field_couple_idx <
1249 couple_config->couples[couple_idx].num_field_couples,
1250 "ERROR(%s:%d:%s): invalid field_couple_idx",
1251 __FILE__, line, routine_name)
1252}
1253
1255 struct yac_couple_config * couple_config,
1256 size_t couple_idx, size_t field_couple_idx) {
1257
1259 couple_config, couple_idx, field_couple_idx,
1260 "yac_couple_config_get_interp_stack", __LINE__);
1261
1262 return
1263 couple_config->
1264 couples[couple_idx].
1265 field_couples[field_couple_idx].interp_stack;
1266}
1267
1269 struct yac_couple_config * couple_config,
1270 size_t couple_idx, size_t field_couple_idx,
1271 char const ** src_grid_name, char const ** tgt_grid_name) {
1272
1274 couple_config, couple_idx, field_couple_idx,
1275 "yac_couple_config_get_field_grid_names", __LINE__);
1276
1277 size_t src_component_idx =
1278 couple_config->couples[couple_idx].
1279 field_couples[field_couple_idx].
1280 source.component_idx;
1281 size_t src_field_idx =
1282 couple_config->couples[couple_idx].
1283 field_couples[field_couple_idx].
1284 source.field_idx;
1285
1286 size_t tgt_component_idx =
1287 couple_config->couples[couple_idx].
1288 field_couples[field_couple_idx].
1289 target.component_idx;
1290 size_t tgt_field_idx =
1291 couple_config->couples[couple_idx].
1292 field_couples[field_couple_idx].
1293 target.field_idx;
1294
1295 *src_grid_name =
1296 couple_config->grids[
1297 couple_config->components[src_component_idx].
1298 fields[src_field_idx].grid_idx].name;
1299 *tgt_grid_name =
1300 couple_config->grids[
1301 couple_config->components[tgt_component_idx].
1302 fields[tgt_field_idx].grid_idx].name;
1303}
1304
1306 struct yac_couple_config * couple_config,
1307 char const * comp_name, char const * grid_name, char const * field_name,
1308 double frac_mask_fallback_value) {
1309
1311 (frac_mask_fallback_value != YAC_FRAC_MASK_UNDEF) &&
1312 (frac_mask_fallback_value != YAC_FRAC_MASK_NO_VALUE),
1313 "ERROR(yac_couple_config_field_enable_frac_mask): "
1314 "\"%lf\" is not a valid fractional mask fallback value "
1315 "(component: \"%s\" grid: \"%s\" field \"%s\")",
1316 frac_mask_fallback_value, comp_name, grid_name, field_name);
1317
1318 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
1319 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
1320 size_t field_idx = yac_couple_config_get_field_idx(couple_config,
1321 comp_idx, grid_idx, field_name);
1322
1323 double old_frac_mask_fallback_value =
1324 couple_config->components[comp_idx].fields[field_idx].
1325 frac_mask_fallback_value;
1326
1327 // (use memcmp for comparison, because it can be nan)
1329 (old_frac_mask_fallback_value == YAC_FRAC_MASK_UNDEF) ||
1330 (old_frac_mask_fallback_value == YAC_FRAC_MASK_NO_VALUE) ||
1331 !memcmp(
1332 &old_frac_mask_fallback_value, &frac_mask_fallback_value,
1333 sizeof(frac_mask_fallback_value)),
1334 "ERROR(yac_couple_config_field_enable_frac_mask): "
1335 "fractional mask fallback value was already set:\n"
1336 "\told value \"%lf\" new value \"%lf\" "
1337 "(component: \"%s\" grid: \"%s\" field \"%s\")",
1338 old_frac_mask_fallback_value, frac_mask_fallback_value,
1339 comp_name, grid_name, field_name);
1340
1341 couple_config->components[comp_idx].fields[field_idx].
1342 frac_mask_fallback_value = frac_mask_fallback_value;
1343}
1344
1346 struct yac_couple_config * couple_config,
1347 char const * component_name, char const * grid_name,
1348 char const * field_name) {
1349
1350 size_t component_idx =
1351 yac_couple_config_get_component_idx(couple_config, component_name);
1352 size_t grid_idx =
1353 yac_couple_config_get_grid_idx(couple_config, grid_name);
1354 size_t field_idx =
1356 couple_config, component_idx, grid_idx, field_name);
1357
1358 struct yac_couple_config_field * field =
1359 couple_config->components[component_idx].fields +
1360 field_idx;
1361
1364 "ERROR(yac_couple_config_get_frac_mask_fallback_value): "
1365 "no valid fractional mask fallback value defined "
1366 "(component: \"%s\" grid: \"%s\" field \"%s\")",
1367 couple_config->components[component_idx].name, grid_name, field->name);
1368
1369 return field->frac_mask_fallback_value;
1370}
1371
1373 struct yac_couple_config * couple_config,
1374 char const * component_name, char const * grid_name,
1375 char const * field_name) {
1376
1377 size_t component_idx =
1378 yac_couple_config_get_component_idx(couple_config, component_name);
1379 size_t grid_idx =
1380 yac_couple_config_get_grid_idx(couple_config, grid_name);
1381 size_t field_idx =
1383 couple_config, component_idx, grid_idx, field_name);
1384
1385 struct yac_couple_config_field * field =
1386 couple_config->components[component_idx].fields +
1387 field_idx;
1388
1389 return field->collection_size;
1390}
1391
1393 struct yac_couple_config * couple_config,
1394 size_t couple_idx, size_t field_couple_idx,
1395 char const ** src_component_name, char const ** tgt_component_name) {
1396
1398 couple_config, couple_idx, field_couple_idx,
1399 "yac_couple_config_get_field_couple_component_names", __LINE__);
1400
1401 *src_component_name =
1402 couple_config->components[
1403 couple_config->couples[couple_idx].
1404 field_couples[field_couple_idx].source.component_idx].name;
1405 *tgt_component_name =
1406 couple_config->components[
1407 couple_config->couples[couple_idx].
1408 field_couples[field_couple_idx].target.component_idx].name;
1409}
1410
1412 struct yac_couple_config * couple_config,
1413 size_t couple_idx, size_t field_couple_idx,
1414 char const ** src_field_name, const char ** tgt_field_name) {
1415
1417 couple_config, couple_idx, field_couple_idx,
1418 "yac_couple_config_get_field_names", __LINE__);
1419
1420 size_t src_component_idx =
1421 couple_config->couples[couple_idx].
1422 field_couples[field_couple_idx].source.component_idx;
1423 size_t tgt_component_idx =
1424 couple_config->couples[couple_idx].
1425 field_couples[field_couple_idx].target.component_idx;
1426 size_t src_field_idx =
1427 couple_config->couples[couple_idx].
1428 field_couples[field_couple_idx].source.field_idx;
1429 size_t tgt_field_idx =
1430 couple_config->couples[couple_idx].
1431 field_couples[field_couple_idx].target.field_idx;
1432
1433 *src_field_name =
1434 couple_config->components[src_component_idx].
1435 fields[src_field_idx].name;
1436 *tgt_field_name =
1437 couple_config->components[tgt_component_idx].
1438 fields[tgt_field_idx].name;
1439}
1440
1442 struct yac_couple_config * couple_config,
1443 size_t couple_idx, size_t field_couple_idx) {
1444
1446 couple_config, couple_idx, field_couple_idx,
1447 "yac_couple_config_mapping_on_source", __LINE__);
1448
1449 return
1450 couple_config->
1451 couples[couple_idx].
1452 field_couples[field_couple_idx].
1453 mapping_on_source;
1454}
1455
1457 struct yac_couple_config * couple_config,
1458 size_t couple_idx, size_t field_couple_idx) {
1459
1461 couple_config, couple_idx, field_couple_idx,
1462 "yac_couple_config_get_source_lag", __LINE__);
1463
1464 return
1465 couple_config->
1466 couples[couple_idx].
1467 field_couples[field_couple_idx].
1468 source.lag;
1469}
1470
1472 struct yac_couple_config * couple_config,
1473 size_t couple_idx, size_t field_couple_idx) {
1474
1476 couple_config, couple_idx, field_couple_idx,
1477 "yac_couple_config_get_target_lag", __LINE__);
1478
1479 return
1480 couple_config->
1481 couples[couple_idx].
1482 field_couples[field_couple_idx].
1483 target.lag;
1484}
1485
1487 struct yac_couple_config * couple_config,
1488 size_t couple_idx, size_t field_couple_idx) {
1489
1491 couple_config, couple_idx, field_couple_idx,
1492 "yac_couple_config_get_coupling_period", __LINE__);
1493
1494 return
1495 couple_config->
1496 couples[couple_idx].
1497 field_couples[field_couple_idx].
1498 coupling_period;
1499}
1500
1502 struct yac_couple_config * couple_config,
1503 size_t couple_idx, size_t field_couple_idx) {
1504
1506 couple_config, couple_idx, field_couple_idx,
1507 "yac_couple_config_get_source_timestep", __LINE__);
1508
1509 struct yac_couple_config_field_couple * tcouple =
1510 couple_config->couples[couple_idx].field_couples + field_couple_idx;
1511 char const * timestep =
1512 couple_config->components[tcouple->source.component_idx].
1513 fields[tcouple->source.field_idx].timestep;
1514
1516 timestep,
1517 "ERROR(yac_couple_config_get_source_timestep): "
1518 "no valid timestep defined (component: \"%s\" field \"%s\")",
1519 couple_config->components[tcouple->source.component_idx].name,
1520 couple_config->components[tcouple->source.component_idx].
1521 fields[tcouple->source.field_idx].name);
1522
1523 return timestep;
1524}
1525
1527 struct yac_couple_config * couple_config,
1528 size_t couple_idx, size_t field_couple_idx) {
1529
1531 couple_config, couple_idx, field_couple_idx,
1532 "yac_couple_config_get_target_timestep", __LINE__);
1533
1534 struct yac_couple_config_field_couple * tcouple =
1535 couple_config->couples[couple_idx].field_couples + field_couple_idx;
1536 char const * timestep =
1537 couple_config->components[tcouple->target.component_idx].
1538 fields[tcouple->target.field_idx].timestep;
1539
1540 return timestep;
1541}
1542
1544 struct yac_couple_config * couple_config,
1545 size_t couple_idx, size_t field_couple_idx) {
1546
1548 couple_config, couple_idx, field_couple_idx,
1549 "yac_couple_config_get_coupling_period_operation", __LINE__);
1550
1551 return
1552 couple_config->
1553 couples[couple_idx].
1554 field_couples[field_couple_idx].
1556}
1557
1558static void set_datetime(
1559 char const * type_datetime, struct _datetime ** old, char const * str_new) {
1560
1561 if ((str_new == NULL) || (strlen(str_new) == 0)) return;
1562
1563 YAC_ASSERT(
1565 "ERROR(set_datetime): calendar has not yet been set");
1566
1567 struct _datetime * new = newDateTime(str_new);
1568
1570 new != NULL,
1571 "ERROR(set_datetime): failed to parse datetime \"%s\"", str_new);
1572
1573 char old_datetime_buffer[MAX_DATETIME_STR_LEN],
1574 new_datetime_buffer[MAX_DATETIME_STR_LEN];
1575
1577 (*old == NULL) || (equal_to == compareDatetime(*old, new)),
1578 "ERROR(set_datetime): inconsistent %s datetime "
1579 "(old: \"%s\" new: \"%s\")", type_datetime,
1580 datetimeToString(*old, old_datetime_buffer),
1581 datetimeToString(new, new_datetime_buffer));
1582
1583 deallocateDateTime(*old);
1584
1585 *old = new;
1586}
1587
1589 struct yac_couple_config * couple_config,
1590 char const * start, char const * end) {
1591
1592 set_datetime("start", &(couple_config->start_datetime), start);
1593 set_datetime("end", &(couple_config->end_datetime), end);
1594}
1595
1597 struct yac_couple_config * couple_config) {
1598
1599 YAC_ASSERT(couple_config->start_datetime,
1600 "ERROR(yac_couple_config_get_start_datetime): "
1601 "start_datetime not yet defined");
1602
1603 char datetime_buffer[MAX_DATETIME_STR_LEN];
1604
1605 return
1606 strdup(datetimeToString(couple_config->start_datetime, datetime_buffer));
1607}
1608
1610 struct yac_couple_config * couple_config) {
1611
1612 YAC_ASSERT(couple_config->end_datetime,
1613 "ERROR(yac_couple_config_get_start_datetime): "
1614 "start_datetime not yet defined");
1615
1616 char datetime_buffer[MAX_DATETIME_STR_LEN];
1617
1618 return
1619 strdup(datetimeToString(couple_config->end_datetime, datetime_buffer));
1620}
1621
1623 struct yac_couple_config * couple_config, size_t grid_idx) {
1624
1626 grid_idx < couple_config->num_grids,
1627 "ERROR(yac_couple_config_get_grid_name): "
1628 "Invalid grid idx %zu", grid_idx);
1629
1630 return couple_config->grids[grid_idx].name;
1631}
1632
1634 struct yac_couple_config * couple_config,
1635 size_t couple_idx, size_t field_couple_idx) {
1636
1638 couple_config, couple_idx, field_couple_idx,
1639 "yac_couple_config_enforce_write_weight_file", __LINE__);
1640
1641 return
1642 couple_config->
1643 couples[couple_idx].
1644 field_couples[field_couple_idx].
1645 enforce_write_weight_file;
1646}
1647
1649 struct yac_couple_config * couple_config,
1650 size_t couple_idx, size_t field_couple_idx) {
1651
1653 couple_config, couple_idx, field_couple_idx,
1654 "yac_couple_config_get_weight_file_name", __LINE__);
1655
1656 static char dummy[] = "\0";
1657 char const * weight_file_name =
1658 couple_config->
1659 couples[couple_idx].
1660 field_couples[field_couple_idx].
1661 weight_file_name;
1662
1663 return (weight_file_name != NULL)?weight_file_name:dummy;
1664}
1665
1667 struct yac_couple_config * couple_config,
1668 size_t couple_idx, size_t field_couple_idx) {
1669
1671 couple_config, couple_idx, field_couple_idx,
1672 "yac_couple_config_get_scale_factor", __LINE__);
1673
1674 return
1675 couple_config->
1676 couples[couple_idx].
1677 field_couples[field_couple_idx].
1678 scale_factor;
1679}
1680
1682 struct yac_couple_config * couple_config,
1683 size_t couple_idx, size_t field_couple_idx) {
1684
1686 couple_config, couple_idx, field_couple_idx,
1687 "yac_couple_config_get_scale_summand", __LINE__);
1688
1689 return
1690 couple_config->
1691 couples[couple_idx].
1692 field_couples[field_couple_idx].
1693 scale_summand;
1694}
1695
1697 struct yac_couple_config * couple_config,
1698 size_t couple_idx, size_t field_couple_idx,
1699 char const * const ** mask_names, size_t * num_mask_names) {
1700
1702 couple_config, couple_idx, field_couple_idx,
1703 "yac_couple_config_get_src_mask_names", __LINE__);
1704
1705 *mask_names =
1706 (char const * const *)(
1707 couple_config->
1708 couples[couple_idx].
1709 field_couples[field_couple_idx].
1710 src_mask_names);
1711 *num_mask_names =
1712 couple_config->
1713 couples[couple_idx].
1714 field_couples[field_couple_idx].
1715 num_src_mask_names;
1716}
1717
1719 struct yac_couple_config * couple_config,
1720 size_t couple_idx, size_t field_couple_idx) {
1721
1723 couple_config, couple_idx, field_couple_idx,
1724 "yac_couple_config_get_tgt_mask_name", __LINE__);
1725
1726 return
1727 couple_config->
1728 couples[couple_idx].
1729 field_couples[field_couple_idx].
1730 tgt_mask_name;
1731}
1732
1734 struct yac_couple_config * couple_config, char const * grid_name) {
1735
1736 for (size_t grid_idx = 0; grid_idx < couple_config->num_grids;
1737 ++grid_idx)
1738 if (!strcmp(couple_config->grids[grid_idx].name, grid_name))
1739 return 1;
1740 return 0;
1741}
1742
1744 char const * string, MPI_Comm comm) {
1745
1746 int strlen_pack_size, string_pack_size;
1747 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &strlen_pack_size), comm);
1748
1749 if (string != NULL) {
1751 MPI_Pack_size(
1752 (int)(strlen(string)), MPI_CHAR, comm, &string_pack_size), comm);
1753 } else {
1754 string_pack_size = 0;
1755 }
1756
1757 return (size_t)strlen_pack_size + (size_t)string_pack_size;
1758}
1759
1761 void * grid_, MPI_Comm comm) {
1762
1763 struct yac_couple_config_grid * grid = grid_;
1764
1765 return yac_couple_config_get_string_pack_size(grid->name, comm);
1766}
1767
1769 void * field_, MPI_Comm comm) {
1770
1771 struct yac_couple_config_field * field =
1772 (struct yac_couple_config_field *)field_;
1773
1774 YAC_ASSERT(
1775 field->grid_idx <= INT_MAX,
1776 "ERROR(yac_couple_config_get_field_pack_size):"
1777 "grid_idx is too big")
1778
1779 int int_pack_size;
1780 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &int_pack_size), comm);
1781 size_t name_pack_size = yac_couple_config_get_string_pack_size(
1782 field->name, comm);
1783
1784 return int_pack_size + // grid_idx
1785 name_pack_size;
1786}
1787
1789 void * component_, MPI_Comm comm) {
1790
1791 struct yac_couple_config_component * component =
1792 (struct yac_couple_config_component *)component_;
1793
1794 return
1796}
1797
1799 void * field_couple_, MPI_Comm comm) {
1800
1801 struct yac_couple_config_field_couple * field_couple =
1802 (struct yac_couple_config_field_couple *)field_couple_;
1803
1804 int ints_pack_size;
1805 yac_mpi_call(MPI_Pack_size(10, MPI_INT, comm, &ints_pack_size), comm);
1806 int doubles_pack_size;
1807 yac_mpi_call(MPI_Pack_size(2, MPI_DOUBLE, comm, &doubles_pack_size), comm);
1808 int src_mask_names_pack_size = 0;
1809 if (field_couple->num_src_mask_names > 0)
1810 for (size_t i = 0; i < field_couple->num_src_mask_names; ++i)
1811 src_mask_names_pack_size +=
1813 field_couple->src_mask_names[i], comm);
1814
1815 return
1816 (size_t)ints_pack_size + // source.component_idx
1817 // source.field_idx
1818 // source.lag
1819 // target.component_idx
1820 // target.field_idx
1821 // target.lag
1822 // mapping_on_source
1823 // coupling_period_operation
1824 // enforce_write_weight_file
1825 // num_src_mask_names
1827 field_couple->interp_stack, comm) +
1829 field_couple->coupling_period, comm) +
1831 field_couple->weight_file_name, comm) +
1832 doubles_pack_size + // scale_factor
1833 // scale_summand
1834 src_mask_names_pack_size +
1836 field_couple->tgt_mask_name, comm);
1837}
1838
1840 void * couple_, MPI_Comm comm) {
1841
1842 UNUSED(couple_);
1843
1844 int component_indices_pack_size;
1846 MPI_Pack_size(2, MPI_INT, comm, &component_indices_pack_size), comm);
1847
1848 return (size_t)component_indices_pack_size;
1849}
1850
1852 void * config_output_, MPI_Comm comm) {
1853
1854 struct yac_couple_config_config_output * config_output = config_output_;
1855
1856 int filetype_pack_size;
1858 MPI_Pack_size(1, MPI_INT, comm, &filetype_pack_size), comm);
1859
1860 return
1861 filetype_pack_size +
1862 yac_couple_config_get_string_pack_size(config_output->name, comm) +
1863 yac_couple_config_get_string_pack_size(config_output->ref, comm);
1864}
1865
1867 char const * string, void * buffer, int buffer_size, int * position,
1868 MPI_Comm comm) {
1869
1870 size_t len = (string == NULL)?0:strlen(string);
1871
1872 YAC_ASSERT(
1873 len <= INT_MAX, "ERROR(yac_couple_config_pack_string): string too long")
1874
1875 int len_int = (int)len;
1876
1878 MPI_Pack(
1879 &len_int, 1, MPI_INT, buffer, buffer_size, position, comm), comm);
1880
1881 if (len > 0)
1883 MPI_Pack(
1884 string, len_int, MPI_CHAR, buffer, buffer_size, position, comm),
1885 comm);
1886}
1887
1889 void * grid_, void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1890
1891 struct yac_couple_config_grid * grid =
1892 (struct yac_couple_config_grid *)grid_;
1894 grid->name, buffer, buffer_size, position, comm);
1895}
1896
1898 void * field_, void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1899
1900 struct yac_couple_config_field * field =
1901 (struct yac_couple_config_field *)field_;
1902
1903 YAC_ASSERT(
1904 field->grid_idx <= INT_MAX,
1905 "ERROR(yac_couple_config_pack_field): grid_idx is too big")
1906
1907 int grid_idx = (int)field->grid_idx;
1908
1910 MPI_Pack(
1911 &grid_idx, 1, MPI_INT, buffer, buffer_size, position, comm), comm);
1912 yac_couple_config_pack_string(field->name, buffer,
1913 buffer_size, position, comm);
1914}
1915
1917 void * component_, void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1918
1919 struct yac_couple_config_component * component =
1920 (struct yac_couple_config_component *)component_;
1921
1923 component->name, buffer, buffer_size, position, comm);
1924}
1925
1927 void * field_couple_, void * buffer, int buffer_size, int * position,
1928 MPI_Comm comm) {
1929
1930 struct yac_couple_config_field_couple * field_couple =
1931 (struct yac_couple_config_field_couple *)field_couple_;
1932
1933 YAC_ASSERT(
1934 field_couple->source.component_idx <= INT_MAX,
1935 "ERROR(yac_couple_config_pack_field_couple): "
1936 "source.component_idx bigger than INT_MAX")
1937 YAC_ASSERT(
1938 field_couple->source.field_idx <= INT_MAX,
1939 "ERROR(yac_couple_config_pack_field_couple): "
1940 "source.field_idx bigger than INT_MAX")
1941 YAC_ASSERT(
1942 field_couple->target.component_idx <= INT_MAX,
1943 "ERROR(yac_couple_config_pack_field_couple): "
1944 "target.component_idx bigger than INT_MAX")
1945 YAC_ASSERT(
1946 field_couple->target.field_idx <= INT_MAX,
1947 "ERROR(yac_couple_config_pack_field_couple): "
1948 "target.field_idx bigger than INT_MAX")
1949 YAC_ASSERT(
1950 field_couple->mapping_on_source <= INT_MAX,
1951 "ERROR(yac_couple_config_pack_field_couple): "
1952 "mapping_on_source bigger than INT_MAX")
1953 YAC_ASSERT(
1954 field_couple->coupling_period_operation <= INT_MAX,
1955 "ERROR(yac_couple_config_pack_field_couple): "
1956 "coupling_period_operation bigger than INT_MAX")
1957 YAC_ASSERT(
1958 field_couple->enforce_write_weight_file <= INT_MAX,
1959 "ERROR(yac_couple_config_pack_field_couple): "
1960 "enforce_write_weight_file bigger than INT_MAX")
1961 YAC_ASSERT(
1962 field_couple->num_src_mask_names <= INT_MAX,
1963 "ERROR(yac_couple_config_pack_field_couple): "
1964 "num_src_mask_names bigger than INT_MAX")
1965
1966 int ints[10] = {
1967 field_couple->source.component_idx,
1968 field_couple->source.field_idx,
1969 field_couple->source.lag,
1970 field_couple->target.component_idx,
1971 field_couple->target.field_idx,
1972 field_couple->target.lag,
1973 field_couple->mapping_on_source,
1974 field_couple->coupling_period_operation,
1975 field_couple->enforce_write_weight_file,
1976 field_couple->num_src_mask_names};
1977
1979 MPI_Pack(ints, 10, MPI_INT, buffer, buffer_size, position, comm), comm);
1980
1982 field_couple->coupling_period, buffer, buffer_size, position, comm);
1984 field_couple->weight_file_name, buffer, buffer_size, position, comm);
1985
1986 double doubles[2] = {
1987 field_couple->scale_factor,
1988 field_couple->scale_summand};
1989
1991 MPI_Pack(doubles, 2, MPI_DOUBLE, buffer, buffer_size, position, comm),
1992 comm);
1993
1995 field_couple->interp_stack, buffer, buffer_size, position, comm);
1996
1997 if (field_couple->num_src_mask_names > 0)
1998 for (size_t i = 0; i < field_couple->num_src_mask_names; ++i)
2000 field_couple->src_mask_names[i], buffer, buffer_size, position, comm);
2001
2003 field_couple->tgt_mask_name, buffer, buffer_size, position, comm);
2004}
2005
2007 void * couple_, void * buffer, int buffer_size, int * position, MPI_Comm comm) {
2008
2009 struct yac_couple_config_couple * couple =
2010 (struct yac_couple_config_couple *)couple_;
2011
2012 YAC_ASSERT(
2013 (couple->component_indices[0] <= INT_MAX) &&
2014 (couple->component_indices[1] <= INT_MAX),
2015 "ERROR(yac_couple_config_pack_couple): "
2016 "component_indices bigger than INT_MAX")
2017
2018 int component_indices[2] = {(int)(couple->component_indices[0]),
2019 (int)(couple->component_indices[1])};
2020
2022 MPI_Pack(
2023 component_indices, 2, MPI_INT, buffer, buffer_size, position, comm),
2024 comm);
2025}
2026
2028 void * config_output_, void * buffer, int buffer_size, int * position,
2029 MPI_Comm comm) {
2030
2031 struct yac_couple_config_config_output * config_output =
2032 (struct yac_couple_config_config_output *)config_output_;
2033
2035 config_output->name, buffer, buffer_size, position, comm);
2036 int filetype_int = (int)config_output->type;
2038 MPI_Pack(
2039 &filetype_int, 1, MPI_INT, buffer, buffer_size, position, comm), comm);
2041 config_output->ref, buffer, buffer_size, position, comm);
2042}
2043
2045 void * buffer, int buffer_size, int * position, MPI_Comm comm) {
2046
2047 int string_len;
2049 MPI_Unpack(
2050 buffer, buffer_size, position, &string_len, 1, MPI_INT, comm), comm);
2051
2052 if (string_len <= 0) return NULL;
2053
2054 char * string = xmalloc(((size_t)string_len + 1) * sizeof(*string));
2056 MPI_Unpack(
2057 buffer, buffer_size, position, string, string_len, MPI_CHAR, comm), comm);
2058 string[string_len] = '\0';
2059 return string;
2060}
2061
2063 void * buffer, int buffer_size, int * position, void * grid_,
2064 MPI_Comm comm) {
2065
2066 struct yac_couple_config_grid * grid =
2067 (struct yac_couple_config_grid *)grid_;
2068
2069 grid->name =
2070 yac_couple_config_unpack_string(buffer, buffer_size, position, comm);
2071 grid->output_filename = NULL;
2072 grid->metadata = NULL;
2073}
2074
2076 void * buffer, int buffer_size, int * position, void * field_,
2077 MPI_Comm comm) {
2078
2079 struct yac_couple_config_field * field =
2080 (struct yac_couple_config_field *)field_;
2081
2082 int grid_idx_int;
2084 MPI_Unpack(
2085 buffer, buffer_size, position, &grid_idx_int, 1, MPI_INT, comm), comm);
2086
2087 YAC_ASSERT(
2088 grid_idx_int >= 0,
2089 "ERROR(yac_couple_config_unpack_field): invalid number of grid_idx_int")
2090
2091 field->grid_idx = (size_t)grid_idx_int;
2093 field->collection_size = SIZE_MAX;
2094 field->name = yac_couple_config_unpack_string(buffer,
2095 buffer_size, position, comm);
2096 field->timestep = NULL;
2097 field->metadata = NULL;
2098}
2099
2101 void * buffer, int buffer_size, int * position, void * component_,
2102 MPI_Comm comm) {
2103
2104 struct yac_couple_config_component * component =
2105 (struct yac_couple_config_component *)component_;
2106
2107 component->name =
2108 yac_couple_config_unpack_string(buffer, buffer_size, position, comm);
2109 component->metadata = NULL;
2110 component->num_fields = 0;
2111 component->fields = NULL;
2112}
2113
2115 void * buffer, int buffer_size, int * position, void * field_couple_,
2116 MPI_Comm comm) {
2117
2118 struct yac_couple_config_field_couple * field_couple =
2119 (struct yac_couple_config_field_couple *)field_couple_;
2120
2121 int ints[10];
2123 MPI_Unpack(
2124 buffer, buffer_size, position, ints, 10, MPI_INT, comm), comm);
2125
2126 YAC_ASSERT(
2127 ints[0] >= 0,
2128 "ERROR(yac_couple_config_unpack_field_couple): "
2129 "invalid source.component_idx")
2130 YAC_ASSERT(
2131 ints[1] >= 0,
2132 "ERROR(yac_couple_config_unpack_field_couple): "
2133 "invalid source.field_idx")
2134 YAC_ASSERT(
2135 ints[3] >= 0,
2136 "ERROR(yac_couple_config_unpack_field_couple): "
2137 "target.component_idx bigger than INT_MAX")
2138 YAC_ASSERT(
2139 ints[4] >= 0,
2140 "ERROR(yac_couple_config_unpack_field_couple): "
2141 "invalid target.field_idx")
2142 YAC_ASSERT(
2143 ints[6] >= 0,
2144 "ERROR(yac_couple_config_unpack_field_couple): "
2145 "invalid mapping_on_source")
2146 YAC_ASSERT(
2147 ints[7] >= 0,
2148 "ERROR(yac_couple_config_unpack_field_couple): "
2149 "invalid coupling_period_operation")
2150 YAC_ASSERT(
2151 ints[8] >= 0,
2152 "ERROR(yac_couple_config_unpack_field_couple): "
2153 "invalid enforce_write_weight_file")
2154 YAC_ASSERT(
2155 ints[9] >= 0,
2156 "ERROR(yac_couple_config_unpack_field_couple): "
2157 "invalid num_src_mask_names")
2158
2159 field_couple->source.component_idx = (size_t)(ints[0]);
2160 field_couple->source.field_idx = (size_t)(ints[1]);
2161 field_couple->source.lag = ints[2];
2162 field_couple->target.component_idx = (size_t)(ints[3]);
2163 field_couple->target.field_idx = (size_t)(ints[4]);
2164 field_couple->target.lag = ints[5];
2165 field_couple->mapping_on_source = ints[6];
2166 field_couple->coupling_period_operation =
2167 (enum yac_reduction_type)(ints[7]);
2168 field_couple->enforce_write_weight_file = ints[8];
2169 field_couple->num_src_mask_names = (size_t)(ints[9]);
2170
2171 field_couple->coupling_period =
2172 yac_couple_config_unpack_string(buffer, buffer_size, position, comm);
2173 field_couple->weight_file_name =
2174 yac_couple_config_unpack_string(buffer, buffer_size, position, comm);
2175
2176 double doubles[2];
2178 MPI_Unpack(
2179 buffer, buffer_size, position, doubles, 2, MPI_DOUBLE, comm), comm);
2180
2181 field_couple->scale_factor = doubles[0];
2182 field_couple->scale_summand = doubles[1];
2183
2184 field_couple->interp_stack =
2185 yac_interp_stack_config_unpack(buffer, buffer_size, position, comm);
2186
2187 if (field_couple->num_src_mask_names > 0) {
2188 field_couple->src_mask_names =
2189 xmalloc(
2190 field_couple->num_src_mask_names *
2191 sizeof(*(field_couple->src_mask_names)));
2192 for (size_t i = 0; i < field_couple->num_src_mask_names; ++i)
2193 field_couple->src_mask_names[i] =
2195 buffer, buffer_size, position, comm);
2196 } else {
2197 field_couple->src_mask_names = NULL;
2198 }
2199
2200 field_couple->tgt_mask_name =
2202 buffer, buffer_size, position, comm);
2203}
2204
2206 void * buffer, int buffer_size, int * position, void * couple_,
2207 MPI_Comm comm) {
2208
2209 struct yac_couple_config_couple * couple =
2210 (struct yac_couple_config_couple *)couple_;
2211
2212 int component_indices[2];
2214 MPI_Unpack(
2215 buffer, buffer_size, position, component_indices, 2, MPI_INT, comm),
2216 comm);
2217
2218 YAC_ASSERT(
2219 (component_indices[0] >= 0) && (component_indices[1] >= 0),
2220 "ERROR(yac_couple_config_unpack_couple): invalid component indices")
2221
2222 couple->component_indices[0] = (size_t)(component_indices[0]);
2223 couple->component_indices[1] = (size_t)(component_indices[1]);
2224 couple->num_field_couples = 0;
2225 couple->field_couples = NULL;
2226}
2227
2229 void * buffer, int buffer_size, int * position, void * config_output_,
2230 MPI_Comm comm) {
2231
2232 struct yac_couple_config_config_output * config_output =
2233 (struct yac_couple_config_config_output *)config_output_;
2234
2235 config_output->name =
2236 yac_couple_config_unpack_string(buffer, buffer_size, position, comm);
2237 int filetype_int;
2239 MPI_Unpack(
2240 buffer, buffer_size, position, &filetype_int, 1, MPI_INT, comm),
2241 comm);
2242 config_output->type = (enum yac_text_filetype)filetype_int;
2243 config_output->ref =
2244 yac_couple_config_unpack_string(buffer, buffer_size, position, comm);
2245 config_output->include_definitions = FLAG_UNSET;
2246}
2247
2249 struct yac_couple_config * couple_config,
2250 char const * src_comp_name, char const * src_grid_name, char const * src_field_name,
2251 char const * tgt_comp_name, char const * tgt_grid_name, char const * tgt_field_name,
2252 char const * coupling_period, int time_reduction,
2253 struct yac_interp_stack_config * interp_stack,
2254 int src_lag, int tgt_lag,
2255 const char* weight_file_name, int mapping_on_source,
2256 double scale_factor, double scale_summand,
2257 size_t num_src_mask_names, char const * const * src_mask_names,
2258 char const * tgt_mask_name) {
2259
2260 YAC_ASSERT(src_comp_name && src_comp_name[0] != '\0',
2261 "ERROR(yac_couple_config_def_couple): invalid parameter: src_comp_name");
2262 YAC_ASSERT(src_grid_name && src_grid_name[0] != '\0',
2263 "ERROR(yac_couple_config_def_couple): invalid parameter: src_grid_name");
2264 YAC_ASSERT(src_field_name && src_field_name[0] != '\0',
2265 "ERROR(yac_couple_config_def_couple): invalid parameter: src_field_name");
2266 YAC_ASSERT(tgt_comp_name && tgt_comp_name[0] != '\0',
2267 "ERROR(yac_couple_config_def_couple): invalid parameter: tgt_comp_name");
2268 YAC_ASSERT(tgt_grid_name && tgt_grid_name[0] != '\0',
2269 "ERROR(yac_couple_config_def_couple): invalid parameter: tgt_grid_name");
2270 YAC_ASSERT(tgt_field_name && tgt_field_name[0] != '\0',
2271 "ERROR(yac_couple_config_def_couple): invalid parameter: tgt_field_name");
2272 YAC_ASSERT(coupling_period && coupling_period[0] != '\0',
2273 "ERROR(yac_couple_config_def_couple): invalid parameter: coupling_period");
2274 YAC_ASSERT(
2275 (time_reduction == TIME_NONE) ||
2276 (time_reduction == TIME_ACCUMULATE) ||
2277 (time_reduction == TIME_AVERAGE) ||
2278 (time_reduction == TIME_MINIMUM) ||
2279 (time_reduction == TIME_MAXIMUM),
2280 "ERROR(yac_couple_config_def_couple): invalid parameter: time_reduction");
2281 YAC_ASSERT_F(isnormal(scale_factor),
2282 "ERROR(yac_couple_config_def_couple): \"%lf\" is not a valid scale factor",
2283 scale_factor);
2284 YAC_ASSERT_F(isnormal(scale_summand) || (scale_summand == 0.0),
2285 "ERROR(yac_couple_config_def_couple): \"%lf\" is not a valid scale summand",
2286 scale_summand);
2287
2288 // get component indices
2289 size_t src_comp_idx =
2290 yac_couple_config_add_component_(couple_config, src_comp_name);
2291 size_t tgt_comp_idx =
2292 yac_couple_config_add_component_(couple_config, tgt_comp_name);
2293 size_t src_grid_idx =
2294 yac_couple_config_add_grid_(couple_config, src_grid_name);
2295 size_t tgt_grid_idx =
2296 yac_couple_config_add_grid_(couple_config, tgt_grid_name);
2297
2298 // check if couple exists
2299 size_t component_indices[2];
2300 if(src_comp_idx < tgt_comp_idx){
2301 component_indices[0] = src_comp_idx;
2302 component_indices[1] = tgt_comp_idx;
2303 }else{
2304 component_indices[0] = tgt_comp_idx;
2305 component_indices[1] = src_comp_idx;
2306 }
2307 struct yac_couple_config_couple * couple = NULL;
2308 for(size_t i = 0; (i < couple_config->num_couples) && !couple; ++i)
2309 if(couple_config->couples[i].component_indices[0] == component_indices[0] &&
2310 couple_config->couples[i].component_indices[1] == component_indices[1])
2311 couple = &couple_config->couples[i];
2312
2313 // create if couple does not exists
2314 if(!couple){
2315 couple_config->couples =
2316 xrealloc(
2317 couple_config->couples,
2318 (couple_config->num_couples + 1) * sizeof(*couple_config->couples));
2319 couple = &couple_config->couples[couple_config->num_couples];
2320 couple_config->num_couples++;
2321 couple->component_indices[0] = component_indices[0];
2322 couple->component_indices[1] = component_indices[1];
2323 couple->num_field_couples = 0;
2324 couple->field_couples = NULL;
2325 }
2326
2327 // get field indices
2328 size_t src_field_idx =
2330 couple_config, src_comp_idx, src_grid_idx,
2331 src_field_name, NULL, SIZE_MAX);
2332 size_t tgt_field_idx =
2334 couple_config, tgt_comp_idx, tgt_grid_idx,
2335 tgt_field_name, NULL, SIZE_MAX);
2336
2337 struct yac_couple_config_field_couple field_couple;
2338 field_couple.source.component_idx = src_comp_idx;
2339 field_couple.source.field_idx = src_field_idx;
2340 field_couple.source.lag = src_lag;
2341 field_couple.target.component_idx = tgt_comp_idx;
2342 field_couple.target.field_idx = tgt_field_idx;
2343 field_couple.target.lag = tgt_lag;
2344 field_couple.coupling_period = strdup(coupling_period);
2345 field_couple.coupling_period_operation =
2346 (enum yac_reduction_type)time_reduction;
2348 field_couple.mapping_on_source = mapping_on_source;
2349 field_couple.weight_file_name =
2351 field_couple.scale_factor = scale_factor;
2352 field_couple.scale_summand = scale_summand;
2353 field_couple.enforce_write_weight_file = weight_file_name != NULL;
2355 if (num_src_mask_names > 0) {
2356 field_couple.src_mask_names =
2358 for (size_t i = 0; i < num_src_mask_names; ++i)
2359 field_couple.src_mask_names[i] = strdup(src_mask_names[i]);
2360 } else {
2361 field_couple.src_mask_names = NULL;
2362 }
2363 field_couple.tgt_mask_name =
2364 (tgt_mask_name != NULL)?strdup(tgt_mask_name):NULL;
2365
2366 // check if field_couple exists
2367 int found_flag = 0;
2368 for(size_t i = 0; (i < couple->num_field_couples) && !found_flag; ++i) {
2370 couple->field_couples + i, &field_couple)) {
2372 couple->field_couples + i, &field_couple, MPI_COMM_SELF);
2374 found_flag = 1;
2375 }
2376 }
2377
2378 if (!found_flag) {
2379 couple->field_couples = xrealloc(couple->field_couples,
2380 (couple->num_field_couples + 1) * sizeof(*couple->field_couples));
2381 couple->field_couples[couple->num_field_couples] = field_couple;
2382 couple->num_field_couples++;
2383 }
2384}
2385
2387 char const * type_datetime, struct _datetime ** datetime, MPI_Comm comm) {
2388
2389 // convert datetime to string
2390 char datetime_buffer[MAX_DATETIME_STR_LEN];
2391 char * str_datetime = datetimeToString(*datetime, datetime_buffer);
2392
2393 // copy from static to dynamic memory
2394 if (str_datetime != NULL) str_datetime = strdup(str_datetime);
2395
2396 // delete old datetime
2397 deallocateDateTime(*datetime);
2398
2399 // synchronize datetime string across processes
2400 couple_config_sync_string(type_datetime, &str_datetime, comm);
2401
2402 // convert datetime string to _datetime struct
2403 *datetime = newDateTime(str_datetime);
2404
2405 free(str_datetime);
2406}
2407
2409 struct yac_couple_config * couple_config, MPI_Comm comm) {
2410
2413 "start_datetime", &(couple_config->start_datetime), comm);
2415 "end_datetime", &(couple_config->end_datetime), comm);
2416}
2417
2461
2462static void merge_grids(
2463 struct yac_couple_config * couple_config, MPI_Comm comm) {
2464
2465 size_t* old_to_new_idx;
2466 void * p_grids = couple_config->grids;
2468 &couple_config->num_grids, &p_grids,
2469 sizeof(couple_config->grids[0]),
2470 comm, &dist_merge_vtable_grid, &old_to_new_idx);
2471 couple_config->grids = p_grids;
2472
2473 // set new grid_idx in fields
2474 for(size_t comp_idx = 0; comp_idx < couple_config->num_components;
2475 ++comp_idx) {
2476 struct yac_couple_config_component * component =
2477 couple_config->components + comp_idx;
2478 for(size_t field_idx = 0; field_idx < component->num_fields; ++field_idx)
2479 component->fields[field_idx].grid_idx =
2480 old_to_new_idx[component->fields[field_idx].grid_idx];
2481 }
2482
2483 free(old_to_new_idx);
2484}
2485
2486static void merge_fields(
2487 struct yac_couple_config * couple_config, size_t comp_idx, MPI_Comm comm) {
2488
2489 struct yac_couple_config_component * component =
2490 couple_config->components + comp_idx;
2491
2492 size_t* old_to_new_idx;
2493 void * p_fields = component->fields;
2495 &component->num_fields, &p_fields,
2496 sizeof(component->fields[0]),
2497 comm, &dist_merge_vtable_field, &old_to_new_idx);
2498 component->fields = p_fields;
2499
2500 // set new field_idx in all field_couples
2501 for(size_t couple_idx = 0; couple_idx < couple_config->num_couples;
2502 ++couple_idx) {
2503 struct yac_couple_config_couple * couple =
2504 couple_config->couples + couple_idx;
2505 for(size_t field_couple_idx = 0;
2506 field_couple_idx < couple->num_field_couples; ++field_couple_idx){
2507 struct yac_couple_config_field_couple * field_couple =
2508 couple->field_couples + field_couple_idx;
2509 if(field_couple->source.component_idx == comp_idx)
2510 field_couple->source.field_idx =
2511 old_to_new_idx[field_couple->source.field_idx];
2512 if(field_couple->target.component_idx == comp_idx)
2513 field_couple->target.field_idx =
2514 old_to_new_idx[field_couple->target.field_idx];
2515 }
2516 }
2517
2518 free(old_to_new_idx);
2519}
2520
2522 struct yac_couple_config * couple_config, MPI_Comm comm) {
2523
2524 // distribute and merge basic component information while keeping the
2525 // individual fields
2526 size_t* old_to_new_idx;
2527 void * p_components = couple_config->components;
2529 &couple_config->num_components, &p_components,
2530 sizeof(couple_config->components[0]),
2531 comm, &dist_merge_vtable_component, &old_to_new_idx);
2532 couple_config->components = p_components;
2533
2534 // set new component_idx in couples
2535 for(size_t couple_idx = 0; couple_idx < couple_config->num_couples;
2536 ++couple_idx) {
2537 struct yac_couple_config_couple * couple =
2538 couple_config->couples + couple_idx;
2539 couple->component_indices[0] = old_to_new_idx[couple->component_indices[0]];
2540 couple->component_indices[1] = old_to_new_idx[couple->component_indices[1]];
2541 if (couple->component_indices[1] < couple->component_indices[0]) {
2542 size_t temp_component_index = couple->component_indices[0];
2543 couple->component_indices[0] = couple->component_indices[1];
2544 couple->component_indices[1] = temp_component_index;
2545 }
2546 for(size_t field_couple_idx = 0;
2547 field_couple_idx < couple->num_field_couples; ++field_couple_idx) {
2548 couple->field_couples[field_couple_idx].source.component_idx =
2549 old_to_new_idx[
2550 couple->field_couples[field_couple_idx].source.component_idx];
2551 couple->field_couples[field_couple_idx].target.component_idx =
2552 old_to_new_idx[
2553 couple->field_couples[field_couple_idx].target.component_idx];
2554 }
2555 }
2556 free(old_to_new_idx);
2557
2558 // merge the fields of each component
2559 for (size_t comp_idx = 0; comp_idx < couple_config->num_components; ++comp_idx)
2560 merge_fields(couple_config, comp_idx, comm);
2561}
2562
2564 size_t * num_field_couples,
2565 struct yac_couple_config_field_couple ** field_couples, MPI_Comm comm) {
2566
2567 void * p_field_couples = *field_couples;
2569 num_field_couples, &p_field_couples, sizeof(**field_couples),
2570 comm, &dist_merge_vtable_field_couple, NULL);
2571 *field_couples = p_field_couples;
2572}
2573
2574static void merge_couples(
2575 struct yac_couple_config * couple_config, MPI_Comm comm) {
2576
2577 // distribute and merge basic couple information while keeping the
2578 // individual field couples
2579 void * p_couples = couple_config->couples;
2581 &couple_config->num_couples, &p_couples,
2582 sizeof(couple_config->couples[0]),
2583 comm, &dist_merge_vtable_couple, NULL);
2584 couple_config->couples = p_couples;
2585}
2586
2588 struct yac_couple_config * couple_config, MPI_Comm comm) {
2589
2590 // distribute and merge basic couple information while keeping the
2591 // individual field couples
2592 void * p_config_outputs = couple_config->config_outputs;
2594 &couple_config->num_config_outputs, &p_config_outputs,
2595 sizeof(couple_config->config_outputs[0]),
2596 comm, &dist_merge_vtable_config_output, NULL);
2597 couple_config->config_outputs = p_config_outputs;
2598}
2599
2601 struct yac_couple_config * couple_config, MPI_Comm comm,
2602 char const * output_ref){
2603
2604 // sync time stuff
2605 couple_config_sync_time(couple_config, comm);
2606
2607 merge_config_output(couple_config, comm);
2608 merge_grids(couple_config, comm);
2609 merge_components(couple_config, comm);
2610 merge_couples(couple_config, comm);
2611
2613 "missing_definition_is_fatal",
2614 &(couple_config->missing_definition_is_fatal), comm);
2615
2616 struct yac_couple_config_config_output * config_output = NULL;
2617 if (output_ref != NULL)
2618 for (size_t i = 0; (i < couple_config->num_config_outputs) &&
2619 (config_output == NULL); ++i)
2620 if (!strcmp(output_ref, couple_config->config_outputs[i].ref))
2621 config_output = couple_config->config_outputs + i;
2622
2623 if (config_output != NULL) {
2624
2625 int rank;
2626 MPI_Comm_rank(comm, &rank);
2627
2628 // rank 0 writes the coupling configuration to file
2629 if (rank == 0) {
2630
2631 FILE * config_file = fopen(config_output->name, "w");
2632
2634 config_file != NULL,
2635 "ERROR(yac_couple_config_sync): "
2636 "failed to create coupling configuration file \"%s\"",
2637 config_output->name);
2638
2640 (config_output->type == YAC_TEXT_FILETYPE_YAML) ||
2641 (config_output->type == YAC_TEXT_FILETYPE_JSON),
2642 "ERROR(yac_couple_config_sync): "
2643 "invalid coupling configuration filetype (type = %d)",
2644 config_output->type);
2645
2646 int emit_flags;
2647 switch(config_output->type) {
2648 default:
2650 emit_flags = YAC_YAML_EMITTER_DEFAULT;
2651 break;
2653 emit_flags = YAC_YAML_EMITTER_JSON;
2654 break;
2655 }
2656
2657 enum flag_value include_definitions = FLAG_FALSE; // default value
2658 if (config_output->include_definitions != FLAG_UNSET)
2660 char * str_couple_config =
2662 couple_config, emit_flags, (int)include_definitions);
2663
2664 fputs(str_couple_config, config_file);
2665 free(str_couple_config);
2666 fclose(config_file);
2667 }
2668 yac_mpi_call(MPI_Barrier(comm), comm);
2669 }
2670}
2671
2673 struct yac_couple_config * couple_config,
2674 char const * filename, enum yac_text_filetype filetype, char const * ref,
2675 int include_definitions) {
2676
2677 YAC_ASSERT(
2678 filename != NULL,
2679 "ERROR(yac_couple_config_set_config_output_filename): filename is NULL");
2680
2682 (filetype == YAC_TEXT_FILETYPE_YAML) ||
2683 (filetype == YAC_TEXT_FILETYPE_JSON),
2684 "ERROR(yac_couple_config_set_config_output_filename): "
2685 "invalid output configuration filetype (type = %d)",
2686 (int)filetype);
2687
2688 YAC_ASSERT(
2689 ref != NULL,
2690 "ERROR(yac_couple_config_set_config_output_filename): ref is NULL");
2691
2692 // check whether there already exists a config output with the same reference
2693 for (size_t i = 0; i < couple_config->num_config_outputs; ++i) {
2694 if (!strcmp(couple_config->config_outputs[i].ref, ref)) {
2696 !strcmp(couple_config->config_outputs[i].name, filename) &&
2697 couple_config->config_outputs[i].type == filetype,
2698 "ERROR(yac_couple_config_set_config_output_filename): "
2699 "an filename has already been set for reference "
2700 "(ref \"%s\" curr filename \"%s\" filetype %d; "
2701 "new filename \"%s\" filetype %d",
2702 ref, couple_config->config_outputs[i].name,
2703 couple_config->config_outputs[i].type, filename, filetype);
2704 return;
2705 }
2706 }
2707
2708 couple_config->config_outputs =
2709 xrealloc(
2710 couple_config->config_outputs,
2711 (couple_config->num_config_outputs + 1) *
2712 sizeof(*(couple_config->config_outputs)));
2713
2714 couple_config->config_outputs[
2715 couple_config->num_config_outputs].name = strdup(filename);
2716 couple_config->config_outputs[
2717 couple_config->num_config_outputs].type = filetype;
2718 couple_config->config_outputs[
2719 couple_config->num_config_outputs].ref = strdup(ref);
2720 couple_config->config_outputs[
2721 couple_config->num_config_outputs].include_definitions =
2722 (enum flag_value)(include_definitions != 0);
2723 couple_config->num_config_outputs++;
2724}
char * yac_yaml_emit_coupling(struct yac_couple_config *couple_config, int emit_flags, int include_definitions)
int const YAC_YAML_EMITTER_DEFAULT
emit to YAML format
Definition config_yaml.c:63
int const YAC_YAML_EMITTER_JSON
emit to JSON format
Definition config_yaml.c:64
#define UNUSED(x)
Definition core.h:71
void yac_couple_config_grid_set_metadata(struct yac_couple_config *couple_config, char const *grid_name, const char *metadata)
struct yac_dist_merge_vtable dist_merge_vtable_couple
static void check_field_couple_idx(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx, char const *routine_name, int line)
static void yac_couple_config_grid_merge(void *a_, void *b_, MPI_Comm comm)
int yac_couple_config_field_is_valid(struct yac_couple_config *couple_config, size_t component_idx, size_t field_idx)
static void set_datetime(char const *type_datetime, struct _datetime **old, char const *str_new)
static void couple_config_sync_time(struct yac_couple_config *couple_config, MPI_Comm comm)
static void yac_couple_config_field_couple_free(void *field_couple_)
struct yac_dist_merge_vtable dist_merge_vtable_config_output
static int yac_couple_config_grid_compare(void const *a, void const *b)
static size_t yac_couple_config_get_grid_pack_size(void *grid_, MPI_Comm comm)
void yac_couple_config_sync(struct yac_couple_config *couple_config, MPI_Comm comm, char const *output_ref)
static void yac_couple_config_component_merge(void *a_, void *b_, MPI_Comm comm)
void yac_couple_config_field_enable_frac_mask(struct yac_couple_config *couple_config, char const *comp_name, char const *grid_name, char const *field_name, double frac_mask_fallback_value)
static void couple_config_sync_string(char const *string_name, char **string, MPI_Comm comm)
static void yac_couple_config_config_output_free(void *config_output_)
static void couple_config_sync_datetime(char const *type_datetime, struct _datetime **datetime, MPI_Comm comm)
static size_t yac_couple_config_get_field_couple_pack_size(void *field_couple_, MPI_Comm comm)
static void merge_fields(struct yac_couple_config *couple_config, size_t comp_idx, MPI_Comm comm)
static char const * string_dup(char const *string)
static void yac_couple_config_couple_free(void *couple_)
size_t yac_couple_config_get_num_fields(struct yac_couple_config *couple_config, size_t component_idx)
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)
static void yac_couple_config_unpack_field(void *buffer, int buffer_size, int *position, void *field_, MPI_Comm comm)
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)
char const * yac_couple_config_get_field_timestep(struct yac_couple_config *couple_config, char const *component_name, char const *grid_name, char const *field_name)
static void yac_couple_config_unpack_config_output(void *buffer, int buffer_size, int *position, void *config_output_, MPI_Comm comm)
int yac_couple_config_mapping_on_source(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
int yac_couple_config_get_field_role(struct yac_couple_config *couple_config, char const *component_name, char const *grid_name, char const *field_name)
int yac_couple_config_component_name_is_valid(struct yac_couple_config *couple_config, char const *component_name)
struct yac_dist_merge_vtable dist_merge_vtable_grid
static void yac_couple_config_pack_field(void *field_, void *buffer, int buffer_size, int *position, MPI_Comm comm)
static char * yac_couple_config_unpack_string(void *buffer, int buffer_size, int *position, MPI_Comm comm)
char const * yac_couple_config_get_coupling_period(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
flag_value
@ FLAG_UNSET
@ FLAG_FALSE
@ FLAG_TRUE
void yac_couple_config_field_set_metadata(struct yac_couple_config *couple_config, const char *comp_name, const char *grid_name, const char *field_name, const char *metadata)
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)
char const * yac_couple_config_get_field_name(struct yac_couple_config *couple_config, size_t component_idx, size_t field_idx)
size_t yac_couple_config_get_field_idx(struct yac_couple_config *couple_config, size_t component_idx, size_t grid_idx, char const *field_name)
static void couple_config_sync_calendar(MPI_Comm comm)
static size_t yac_couple_config_add_component_(struct yac_couple_config *couple_config, char const *name)
void yac_couple_config_component_set_metadata(struct yac_couple_config *couple_config, char const *comp_name, const char *metadata)
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)
static size_t yac_couple_config_add_grid_(struct yac_couple_config *couple_config, char const *name)
static size_t yac_couple_config_get_config_output_pack_size(void *config_output_, MPI_Comm comm)
static void merge_components(struct yac_couple_config *couple_config, MPI_Comm comm)
static void check_couple_idx(struct yac_couple_config *couple_config, size_t couple_idx, char const *routine_name, int line)
static void couple_config_sync_flag_value(char const *flag_value_name, enum flag_value *flag, MPI_Comm comm)
static void yac_couple_config_unpack_grid(void *buffer, int buffer_size, int *position, void *grid_, MPI_Comm comm)
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)
static int yac_couple_config_component_compare(void const *a_, void const *b_)
static size_t yac_couple_config_get_couple_pack_size(void *couple_, MPI_Comm comm)
static void yac_couple_config_pack_config_output(void *config_output_, void *buffer, int buffer_size, int *position, MPI_Comm comm)
static void yac_couple_config_pack_field_couple(void *field_couple_, void *buffer, int buffer_size, int *position, MPI_Comm comm)
struct yac_dist_merge_vtable dist_merge_vtable_field
static size_t yac_couple_config_get_field_pack_size(void *field_, MPI_Comm comm)
static void yac_couple_config_pack_grid(void *grid_, void *buffer, int buffer_size, int *position, MPI_Comm comm)
size_t yac_couple_config_get_num_couples(struct yac_couple_config *couple_config)
static int yac_couple_config_field_compare(void const *a_, void const *b_)
static void yac_couple_config_couple_merge(void *a_, void *b_, MPI_Comm comm)
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)
const char * yac_couple_config_field_get_metadata(struct yac_couple_config *couple_config, const char *comp_name, const char *grid_name, const char *field_name)
static void merge_grids(struct yac_couple_config *couple_config, MPI_Comm comm)
static int yac_couple_config_couple_compare(void const *a_, void const *b_)
void yac_couple_config_get_couple_component_names(struct yac_couple_config *couple_config, size_t couple_idx, char const *couple_component_names[2])
const char * yac_couple_config_grid_get_metadata(struct yac_couple_config *couple_config, const char *grid_name)
static void merge_field_couples(size_t *num_field_couples, struct yac_couple_config_field_couple **field_couples, MPI_Comm comm)
const char * yac_couple_config_component_get_metadata(struct yac_couple_config *couple_config, const char *comp_name)
double yac_couple_config_get_scale_factor(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
size_t yac_couple_config_get_grid_idx(struct yac_couple_config *couple_config, char const *grid_name)
size_t yac_couple_config_get_component_idx(struct yac_couple_config *couple_config, char const *component_name)
char const * yac_couple_config_get_tgt_mask_name(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
struct yac_dist_merge_vtable dist_merge_vtable_component
void yac_couple_config_add_grid(struct yac_couple_config *couple_config, char const *name)
static void yac_couple_config_unpack_couple(void *buffer, int buffer_size, int *position, void *couple_, MPI_Comm comm)
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)
static void yac_couple_config_unpack_field_couple(void *buffer, int buffer_size, int *position, void *field_couple_, MPI_Comm comm)
static size_t yac_couple_config_get_string_pack_size(char const *string, MPI_Comm comm)
static void yac_couple_config_config_output_merge(void *a_, void *b_, MPI_Comm comm)
static size_t yac_couple_config_get_component_pack_size(void *component_, MPI_Comm comm)
int yac_couple_config_enforce_write_weight_file(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
static void yac_couple_config_pack_couple(void *couple_, void *buffer, int buffer_size, int *position, MPI_Comm comm)
static void yac_couple_config_grid_free(void *grid_)
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_grid_set_output_filename(struct yac_couple_config *couple_config, char const *grid_name, const char *output_filename)
static void merge_config_output(struct yac_couple_config *couple_config, MPI_Comm comm)
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)
static void yac_couple_config_unpack_component(void *buffer, int buffer_size, int *position, void *component_, MPI_Comm comm)
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)
static void check_grid_idx(struct yac_couple_config *couple_config, size_t grid_idx, char const *routine_name, int line)
static size_t yac_couple_config_component_add_field_(struct yac_couple_config *couple_config, size_t comp_idx, size_t grid_idx, char const *name, char const *timestep, size_t collection_size)
int yac_couple_config_get_missing_definition_is_fatal(struct yac_couple_config *couple_config)
struct yac_dist_merge_vtable dist_merge_vtable_field_couple
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)
static void yac_couple_config_field_free(void *field_)
char const * yac_couple_config_get_component_name(struct yac_couple_config *couple_config, size_t component_idx)
static void yac_couple_config_field_couple_merge(void *a_, void *b_, MPI_Comm comm)
void yac_couple_config_set_missing_definition_is_fatal(struct yac_couple_config *couple_config, int missing_definition_is_fatal)
static int yac_couple_config_field_couple_compare(void const *a_, void const *b_)
char const * yac_couple_config_get_source_timestep(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
static void yac_couple_config_component_free(void *component_)
static void yac_couple_config_pack_string(char const *string, void *buffer, int buffer_size, int *position, MPI_Comm comm)
void yac_couple_config_add_component(struct yac_couple_config *couple_config, char const *name)
static int yac_couple_config_config_output_compare(void const *a, void const *b)
size_t yac_couple_config_get_num_grids(struct yac_couple_config *couple_config)
char const * yac_couple_config_get_field_grid_name(struct yac_couple_config *couple_config, size_t component_idx, size_t field_idx)
void yac_couple_config_set_config_output_filename(struct yac_couple_config *couple_config, char const *filename, enum yac_text_filetype filetype, char const *ref, int include_definitions)
static void check_field_idx(struct yac_couple_config *couple_config, size_t component_idx, size_t field_idx, char const *routine_name, int line)
char * yac_couple_config_get_end_datetime(struct yac_couple_config *couple_config)
static void check_component_idx(struct yac_couple_config *couple_config, size_t component_idx, char const *routine_name, int line)
static void merge_couples(struct yac_couple_config *couple_config, MPI_Comm comm)
static void yac_couple_config_pack_component(void *component_, void *buffer, int buffer_size, int *position, MPI_Comm comm)
char const * yac_couple_config_get_target_timestep(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
static void yac_couple_config_field_merge(void *a_, void *b_, MPI_Comm comm)
void yac_couple_config_delete(struct yac_couple_config *couple_config)
size_t yac_couple_config_get_num_components(struct yac_couple_config *couple_config)
#define MISSING_DEFINITION_IS_FATAL_DEFAULT_VALUE
yac_text_filetype
@ YAC_TEXT_FILETYPE_YAML
YAML format.
@ YAC_TEXT_FILETYPE_JSON
JSON format.
yac_reduction_type
@ TIME_NONE
@ TIME_ACCUMULATE
@ TIME_MAXIMUM
@ TIME_MINIMUM
@ TIME_AVERAGE
void yac_dist_merge(size_t *count, void **array, size_t element_size, MPI_Comm comm, struct yac_dist_merge_vtable *vtable, size_t **idx_old_to_new)
Definition dist_merge.c:64
int yac_interp_stack_config_compare(void const *a_, void const *b_)
struct yac_interp_stack_config * yac_interp_stack_config_unpack(void *buffer, int buffer_size, int *position, MPI_Comm comm)
void yac_interp_stack_config_delete(struct yac_interp_stack_config *interp_stack_config)
struct yac_interp_stack_config * yac_interp_stack_config_copy(struct yac_interp_stack_config *interp_stack)
size_t yac_interp_stack_config_get_pack_size(struct yac_interp_stack_config *interp_stack, MPI_Comm comm)
void yac_interp_stack_config_pack(struct yac_interp_stack_config *interp_stack, void *buffer, int buffer_size, int *position, MPI_Comm comm)
double const YAC_FRAC_MASK_UNDEF
double const YAC_FRAC_MASK_NO_VALUE
#define xrealloc(ptr, size)
Definition ppm_xfuncs.h:67
#define xmalloc(size)
Definition ppm_xfuncs.h:66
struct yac_couple_config_field * fields
enum yac_text_filetype type
struct yac_couple_config_field_couple * field_couples
struct yac_couple_config_field_couple::@60 source
struct yac_interp_stack_config * interp_stack
enum yac_reduction_type coupling_period_operation
struct yac_couple_config_field_couple::@60 target
char const * output_filename
struct yac_couple_config_couple * couples
struct yac_couple_config_config_output * config_outputs
struct _datetime * end_datetime
struct yac_couple_config_grid * grids
enum flag_value missing_definition_is_fatal
struct _datetime * start_datetime
struct yac_couple_config_component * components
size_t(* get_pack_size)(void *element, MPI_Comm comm)
Definition dist_merge.h:20
static struct user_input_data_component ** components
Definition yac.c:133
size_t num_grids
Definition yac.c:131
static size_t num_components
Definition yac.c:134
int const YAC_EXCHANGE_TYPE_SOURCE
Definition yac.c:32
int const YAC_EXCHANGE_TYPE_NONE
Definition yac.c:31
int const YAC_EXCHANGE_TYPE_TARGET
Definition yac.c:33
void yac_cdef_calendar(int calendar)
Definition yac.c:646
int yac_cget_calendar()
Definition yac.c:663
int const YAC_CALENDAR_NOT_SET
Definition yac.c:60
#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)