YAC 3.7.0
Yet Another Coupler
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
92
100
102
103 struct _datetime * start_datetime;
104 struct _datetime * end_datetime;
105
108
110 size_t num_grids;
111
114
117
118 // this flag indicates whether YAC aborts if for a defined couple at least
119 // one associated field was not defined by the user
121};
122
124
125 struct yac_couple_config * couple_config =
126 xmalloc(1 * sizeof(*couple_config));
127
128 couple_config->start_datetime = NULL;
129 couple_config->end_datetime = NULL;
130
131 couple_config->config_outputs = NULL;
132 couple_config->num_config_outputs = 0;
133
134 couple_config->grids = NULL;
135 couple_config->num_grids = 0;
136
137 couple_config->components = NULL;
138 couple_config->num_components = 0;
139
140 couple_config->couples = NULL;
141 couple_config->num_couples = 0;
142
144
145 return couple_config;
146}
147
148static char * string_dup(char const * string) {
149 return (string != NULL)?strdup(string):NULL;
150}
151
152static void yac_couple_config_field_free(void * field_){
153 struct yac_couple_config_field * field = field_;
154 free((void*)field->name);
155 free((void*)field->timestep);
156 free(field->metadata);
157}
158
159static void yac_couple_config_component_free(void * component_) {
160
161 struct yac_couple_config_component * component = component_;
162
163 for (size_t i = 0; i < component->num_fields; ++i)
164 yac_couple_config_field_free(component->fields + i);
165 free(component->fields);
166 free((void*)(component->name));
167 free(component->metadata);
168}
169
170static void yac_couple_config_field_couple_free(void * field_couple_) {
171
172 struct yac_couple_config_field_couple * field_couple = field_couple_;
174 free((void*)field_couple->coupling_period);
175 free((void*)field_couple->weight_file_name);
176 for (size_t i = 0; i < field_couple->num_src_mask_names; ++i)
177 free((void*)field_couple->src_mask_names[i]);
178 free(field_couple->src_mask_names);
179 free(field_couple->tgt_mask_name);
180 free(field_couple->yaxt_exchanger_name);
181}
182
183static void yac_couple_config_couple_free(void * couple_) {
184
185 struct yac_couple_config_couple * couple = couple_;
186 for (size_t i = 0; i < couple->num_field_couples; ++i)
188 free(couple->field_couples);
189 couple->field_couples = NULL;
190 couple->num_field_couples = 0;
191}
192
193static void yac_couple_config_grid_free(void * grid_) {
194
195 struct yac_couple_config_grid * grid = grid_;
196
197 free((void*)grid->name);
198 free((void*)grid->output_filename);
199 free(grid->metadata);
200}
201
203 void * config_output_) {
204
205 struct yac_couple_config_config_output * config_output = config_output_;
206
207 free((void*)config_output->name);
208 free((void*)config_output->ref);
209}
210
211static int yac_couple_config_grid_compare(void const * a, void const * b) {
212 YAC_ASSERT(((struct yac_couple_config_grid const *)a)->name != NULL &&
213 ((struct yac_couple_config_grid const *)b)->name != NULL,
214 "ERROR(yac_couple_config_grid_compare): "
215 "invalid name (NULL is not allowed)");
216 return strcmp(((struct yac_couple_config_grid const *)a)->name,
217 ((struct yac_couple_config_grid const *)b)->name);
218}
219
220static int yac_couple_config_field_compare(void const * a_, void const * b_) {
221 struct yac_couple_config_field const * a = a_;
222 struct yac_couple_config_field const * b = b_;
223 int ret = (a->grid_idx > b->grid_idx) - (a->grid_idx < b->grid_idx);
224 if (ret) return ret;
226 a->name != NULL && b->name != NULL,
227 "ERROR(yac_couple_config_field_compare): "
228 "invalid name (NULL is not allowed)");
229 return strcmp(a->name, b->name);
230}
231
233 void const * a_, void const * b_) {
234 struct yac_couple_config_component const * a = a_;
235 struct yac_couple_config_component const * b = b_;
236 YAC_ASSERT(a->name != NULL && b->name != NULL,
237 "ERROR(yac_couple_config_component_compare): "
238 "invalid name (NULL is not allowed)");
239 return strcmp(a->name, b->name);
240}
241
243 void const * a_, void const * b_) {
244 struct yac_couple_config_field_couple const * a = a_;
245 struct yac_couple_config_field_couple const * b = b_;
246 int ret;
247 ret = (a->source.component_idx > b->source.component_idx) -
249 if (ret) return ret;
250 ret = (a->target.component_idx > b->target.component_idx) -
252 if (ret) return ret;
253 ret = (a->source.field_idx > b->source.field_idx) -
255 if (ret) return ret;
256 return (a->target.field_idx > b->target.field_idx) -
258}
259
261 void const * a_, void const * b_) {
262 struct yac_couple_config_couple const * a = a_;
263 struct yac_couple_config_couple const * b = b_;
264 int ret;
265 ret = (a->component_indices[0] > b->component_indices[0]) -
266 (a->component_indices[0] < b->component_indices[0]);
267 if (ret) return ret;
268 return (a->component_indices[1] > b->component_indices[1]) -
269 (a->component_indices[1] < b->component_indices[1]);
270}
271
273 void const * a, void const * b) {
275 ((struct yac_couple_config_config_output const *)a)->ref != NULL &&
276 ((struct yac_couple_config_config_output const *)b)->ref != NULL,
277 "ERROR(yac_couple_config_config_output_compare): "
278 "invalid ref (NULL is not allowed)");
279 return strcmp(((struct yac_couple_config_config_output const *)a)->ref,
280 ((struct yac_couple_config_config_output const *)b)->ref);
281}
282
284 char const * string_name, char ** string, MPI_Comm comm) {
285
286 int rank;
287 MPI_Comm_rank(comm, &rank);
288 struct {
289 int len;
290 int rank;
291 } data_pair;
292 size_t len = (*string != NULL)?(strlen(*string) + 1):0;
294 len <= INT_MAX,
295 "ERROR(couple_config_sync_string): \"%s\" too long", string_name);
296 data_pair.len = (int)len;
297 data_pair.rank = rank;
298
299 // determine the broadcaster
301 MPI_Allreduce(
302 MPI_IN_PLACE, &data_pair, 1, MPI_2INT, MPI_MAXLOC, comm), comm);
303 if (data_pair.len == 0) return;
304
305 // broadcast string
306 char const * string_bak = NULL;
307 if (data_pair.rank != rank) {
308 string_bak = *string;
309 *string = xmalloc((size_t)data_pair.len * sizeof(**string));
310 }
312 MPI_Bcast(*string, data_pair.len, MPI_CHAR, data_pair.rank, comm), comm);
313
314 // check for consistency
315 if (data_pair.rank != rank) {
317 (string_bak == NULL) ||
318 !strcmp(string_bak, *string),
319 "ERROR(couple_config_sync_string): inconsistent \"%s\" definition "
320 "(\"%s\" != \"%s\")", string_name, string_bak, *string);
321 free((void*)string_bak);
322 }
323}
324
326 char const * flag_value_name, enum flag_value * flag, MPI_Comm comm) {
327
328 int int_flag = (*flag == FLAG_UNSET)?INT_MAX:((int)*flag);
329
330 // broadcast flag value
332 MPI_Allreduce(
333 MPI_IN_PLACE, &int_flag, 1, MPI_INT, MPI_MIN, comm), comm);
334
335 // if no process has defined a flag value
336 if (int_flag == INT_MAX) return;
337
338 // check for consistency
340 (*flag == FLAG_UNSET) || ((int)(*flag) == int_flag),
341 "ERROR(couple_config_sync_flag_value): inconsistent \"%s\"-flag definition "
342 "(%s != %s)", flag_value_name, ((int_flag == FLAG_TRUE)?"TRUE":"FALSE"),
343 ((*flag == FLAG_TRUE)?"TRUE":"FALSE"));
344
345 // update flag
346 *flag = (enum flag_value)int_flag;
347}
348
349static void couple_config_sync_calendar(MPI_Comm comm) {
350
351 int calendar = (int)getCalendarType();
352 if (calendar == CALENDAR_NOT_SET) calendar = INT_MAX;
353
354 // broadcast calendar
356 MPI_Allreduce(
357 MPI_IN_PLACE, &calendar, 1, MPI_INT, MPI_MIN, comm), comm);
358
359 // if no process has defined a calendar
360 if (calendar == INT_MAX) return;
361
362 // set calendar (if local process has already defined a calendar,
363 // the definition is checked for consistency)
364 yac_cdef_calendar(calendar);
365}
366
368 void * a_, void * b_, MPI_Comm comm) {
369
370 struct yac_couple_config_component * a = a_;
371 struct yac_couple_config_component * b = b_;
372
373 if (b) {
374 a->num_fields = b->num_fields;
375 a->fields = b->fields;
376 b->num_fields = 0;
377 b->fields = NULL;
378 a->metadata = b->metadata;
379 b->metadata = NULL;
380 }
381
383 "component metadata", (char **)&(a->metadata), comm);
384}
385
387 void * a_, void * b_, MPI_Comm comm) {
388
389 struct yac_couple_config_grid * a = a_;
390 struct yac_couple_config_grid * b = b_;
391
392 if (b!= NULL) {
394 b->output_filename = NULL;
395 a->metadata = b->metadata;
396 b->metadata = NULL;
397 }
398
400 "grid output_filename", (char **)&(a->output_filename), comm);
401 couple_config_sync_string("grid metadata", (char **)&(a->metadata), comm);
402}
403
405 void * a_, void * b_, MPI_Comm comm) {
406
407 struct yac_couple_config_field * a = a_;
408 struct yac_couple_config_field * b = b_;
409
410 enum {
411 TIMESTEP_IDX,
412 METADATA_IDX,
413 FRAC_MASK_IDX,
414 COLLECTION_SIZE_IDX,
415 DATA_PAIR_COUNT
416 };
417
418 int rank;
419 MPI_Comm_rank(comm, &rank);
420 struct {
421 int len;
422 int rank;
423 } data_pairs[DATA_PAIR_COUNT];
424 size_t timestep_len =
425 ((b != NULL) && (b->timestep != NULL))?(strlen(b->timestep) + 1):0;
426 size_t metadata_len =
427 ((b != NULL) && (b->metadata != NULL))?(strlen(b->metadata) + 1):0;
429 timestep_len <= INT_MAX,
430 "ERROR(yac_couple_config_field_merge): timestep string too long");
432 metadata_len <= INT_MAX,
433 "ERROR(yac_couple_config_field_merge): metadata string too long");
435 (b == NULL) || (b->collection_size <= INT_MAX) ||
436 (b->collection_size == SIZE_MAX),
437 "ERROR(yac_couple_config_field_merge): invalid collection size \"%zu\"",
438 b->collection_size);
439 data_pairs[TIMESTEP_IDX].len = (int)timestep_len;
440 data_pairs[TIMESTEP_IDX].rank = rank;
441 data_pairs[METADATA_IDX].len = (int)metadata_len;
442 data_pairs[METADATA_IDX].rank = rank;
443 data_pairs[FRAC_MASK_IDX].len =
445 data_pairs[FRAC_MASK_IDX].rank = rank;
446 data_pairs[COLLECTION_SIZE_IDX].len =
447 ((b == NULL) || (b->collection_size == SIZE_MAX))?
448 -1:(int)b->collection_size;
449 data_pairs[COLLECTION_SIZE_IDX].rank = rank;
450
451 // determine the broadcaster
453 MPI_Allreduce(
454 MPI_IN_PLACE, data_pairs, DATA_PAIR_COUNT, MPI_2INT,
455 MPI_MAXLOC, comm), comm);
456
457 // if at least one process has a valid timestep
458 if (data_pairs[TIMESTEP_IDX].len > 0) {
459
460 // broadcast timestep
461 char * timestep_buffer = xmalloc((size_t)data_pairs[TIMESTEP_IDX].len);
462 if (data_pairs[TIMESTEP_IDX].rank == rank)
463 strcpy(timestep_buffer, b->timestep);
465 MPI_Bcast(
466 timestep_buffer, data_pairs[TIMESTEP_IDX].len, MPI_CHAR,
467 data_pairs[TIMESTEP_IDX].rank, comm), comm);
468
469 // check for consistency
471 (b == NULL) || (b->timestep == NULL) ||
472 !strcmp(b->timestep, timestep_buffer),
473 "ERROR(yac_couple_config_field_merge): "
474 "inconsistent timestep definition (\"%s\" != \"%s\")",
475 b->timestep, timestep_buffer);
476
477 // update timestep
478 free((void*)(a->timestep));
479 a->timestep = timestep_buffer;
480 }
481
482 // if at least one process has a valid metadata
483 if (data_pairs[METADATA_IDX].len > 0) {
484
485 // broadcast metadata
486 char * metadata_buffer = xmalloc((size_t)data_pairs[METADATA_IDX].len);
487 if (data_pairs[METADATA_IDX].rank == rank)
488 strcpy(metadata_buffer, b->metadata);
490 MPI_Bcast(
491 metadata_buffer, data_pairs[METADATA_IDX].len, MPI_CHAR,
492 data_pairs[METADATA_IDX].rank, comm), comm);
493
494 // check for consistency
496 (b == NULL) || (b->metadata == NULL) ||
497 !strcmp(b->metadata, metadata_buffer),
498 "ERROR(yac_couple_config_field_merge): "
499 "inconsistent metadata definition (\"%s\" != \"%s\")",
500 b->metadata, metadata_buffer);
501
502 // update metadata
503 free(a->metadata);
504 a->metadata = metadata_buffer;
505 }
506
507 // if at least one process has a valid fractional mask fallback value
508 if (data_pairs[FRAC_MASK_IDX].len != 0) {
509
510 // broadcast fractional mask fallback value
511 double frac_mask_fallback_value;
512 if (data_pairs[FRAC_MASK_IDX].rank == rank)
513 frac_mask_fallback_value = b->frac_mask_fallback_value;
515 MPI_Bcast(
516 &frac_mask_fallback_value, 1, MPI_DOUBLE,
517 data_pairs[FRAC_MASK_IDX].rank, comm), comm);
518
519 // check for consistency
520 // (use memcmp for comparison, because it can be nan)
522 (b == NULL) ||
524 !memcmp(
525 &b->frac_mask_fallback_value, &frac_mask_fallback_value,
526 sizeof(frac_mask_fallback_value)),
527 "ERROR(yac_couple_config_field_merge): "
528 "inconsistent fractional mask fallback value definition "
529 "(%lf != %lf)",
530 b->frac_mask_fallback_value, frac_mask_fallback_value);
531
532 // update fractional mask fallback value
533 a->frac_mask_fallback_value = frac_mask_fallback_value;
534 }
535
536
537 // if at least one process has a valid collection size
538 if (data_pairs[COLLECTION_SIZE_IDX].len > -1) {
539
540 // check for consistency
542 (b == NULL) || (b->collection_size == SIZE_MAX) ||
543 (b->collection_size == (size_t)(data_pairs[COLLECTION_SIZE_IDX].len)),
544 "ERROR(yac_couple_config_field_merge): "
545 "inconsistent collection size definition (\"%zu\" != \"%d\")",
546 b->collection_size, data_pairs[COLLECTION_SIZE_IDX].len);
547
548 // update collection size
549 a->collection_size = (size_t)(data_pairs[COLLECTION_SIZE_IDX].len);
550 }
551}
552
554 void * a_, void * b_, MPI_Comm comm) {
555
556 UNUSED(comm);
557
558 if (b_ == NULL) return;
559
560 struct yac_couple_config_field_couple * a = a_;
561 struct yac_couple_config_field_couple * b = b_;
562
564 (a->source.lag == b->source.lag),
565 "ERROR(yac_couple_config_field_couple_merge): "
566 "inconsistent source lag (%d != %d)", a->source.lag, b->source.lag)
568 (a->target.lag == b->target.lag),
569 "ERROR(yac_couple_config_field_couple_merge): "
570 "inconsistent target lag (%d != %d)", a->target.lag, b->target.lag)
573 "ERROR(yac_couple_config_field_couple_merge): "
574 "inconsistent mapping side (%d != %d)",
578 "ERROR(yac_couple_config_field_couple_merge): "
579 "inconsistent interpolation stack")
582 "ERROR(yac_couple_config_field_couple_merge): "
583 "inconsistent coupling period operation (%d != %d)",
586 !strcmp(a->coupling_period, b->coupling_period),
587 "ERROR(yac_couple_config_field_couple_merge): "
588 "inconsistent coupling period (%s != %s)",
592 "ERROR(yac_couple_config_field_couple_merge): "
593 "inconsistent defintion of enforce_write_weight_file (%d != %d)",
597 !strcmp(a->weight_file_name, b->weight_file_name),
598 "ERROR(yac_couple_config_field_couple_merge): "
599 "inconsistent weight_file_name (%s != %s)",
604 "ERROR(yac_couple_config_field_couple_merge): "
605 "inconsistent weight_file_on_existing (%d != %d)",
608 a->scale_factor == b->scale_factor,
609 "ERROR(yac_couple_config_field_couple_merge): "
610 "inconsistent scale factor (%lf != %lf)",
614 "ERROR(yac_couple_config_field_couple_merge): "
615 "inconsistent scale summand (%lf != %lf)",
619 "ERROR(yac_couple_config_field_couple_merge): "
620 "inconsistent number of source mask names (%zu != %zu)",
623 (a->src_mask_names != NULL) == (b->src_mask_names != NULL),
624 "ERROR(yac_couple_config_field_couple_merge): "
625 "inconsistent availability of source mask names (%s != %s)",
626 (a->src_mask_names != NULL)?"TRUE":"FALSE",
627 (b->src_mask_names != NULL)?"TRUE":"FALSE")
628 for (size_t i = 0; i < a->num_src_mask_names; ++i)
630 !strcmp(a->src_mask_names[i], b->src_mask_names[i]),
631 "ERROR(yac_couple_config_field_couple_merge): "
632 "inconsistent source mask names at index %zu (\"%s\" != \"%s\")",
633 i, a->src_mask_names[i], b->src_mask_names[i])
635 (a->tgt_mask_name != NULL) == (b->tgt_mask_name != NULL),
636 "ERROR(yac_couple_config_field_couple_merge): "
637 "inconsistent availability of target mask name (%s != %s)",
638 (a->tgt_mask_name != NULL)?"TRUE":"FALSE",
639 (b->tgt_mask_name != NULL)?"TRUE":"FALSE")
641 (a->tgt_mask_name == NULL) ||
642 !strcmp(a->tgt_mask_name, b->tgt_mask_name),
643 "ERROR(yac_couple_config_field_couple_merge): "
644 "inconsistent target mask name (\"%s\" != \"%s\")",
647 (a->yaxt_exchanger_name != NULL) == (b->yaxt_exchanger_name != NULL),
648 "ERROR(yac_couple_config_field_couple_merge): "
649 "inconsistent availability of yaxt exchanger name (%s != %s)",
650 (a->yaxt_exchanger_name != NULL)?"TRUE":"FALSE",
651 (b->yaxt_exchanger_name != NULL)?"TRUE":"FALSE")
653 (a->yaxt_exchanger_name == NULL) ||
655 "ERROR(yac_couple_config_field_couple_merge): "
656 "inconsistent yaxt exchanger name (\"%s\" != \"%s\")",
660 "ERROR(yac_couple_config_field_couple_merge): "
661 "inconsistent defintion of use_raw_exchange (%d != %d)",
663}
664
665static void merge_field_couples(
666 size_t * num_field_couples,
667 struct yac_couple_config_field_couple ** field_couples, MPI_Comm comm);
668
670 void * a_, void * b_, MPI_Comm comm) {
671
672 struct yac_couple_config_couple * a = a_;
673 struct yac_couple_config_couple * b = b_;
674
675 if (b) {
678 b->num_field_couples = 0;
679 b->field_couples = NULL;
680 }
681
682 // distribute and merge field couples
684}
685
687 void * a_, void * b_, MPI_Comm comm) {
688
689 struct yac_couple_config_config_output * a = a_;
690 struct yac_couple_config_config_output * b = b_;
691
692 if (b) {
693
695 !strcmp(a->name, b->name),
696 "ERROR(yac_couple_config_config_output_merge): "
697 "inconsistent file names for ref \"%s\" (\"%s\" != \"%s\")",
698 a->ref, a->name, b->name)
700 a->type == b->type,
701 "ERROR(yac_couple_config_config_output_merge): "
702 "inconsistent file types for ref \"%s\" (%d != %d)",
703 a->ref, a->type, b->type)
704
706 }
707
709 "include definitions", &(a->include_definitions), comm);
710}
711
712void yac_couple_config_delete(struct yac_couple_config * couple_config) {
713
714 deallocateDateTime((void*)couple_config->start_datetime);
715 deallocateDateTime((void*)couple_config->end_datetime);
716
717 for (size_t i = 0; i < couple_config->num_config_outputs; ++i)
719 couple_config->config_outputs + i);
720 free((void*)couple_config->config_outputs);
721
722 for (size_t i = 0; i < couple_config->num_grids; ++i){
723 yac_couple_config_grid_free(couple_config->grids + i);
724 }
725 free(couple_config->grids);
726
727 for (size_t i = 0;
728 i < couple_config->num_components; ++i)
730 free(couple_config->components);
731
732 for (size_t couple_idx = 0; couple_idx < couple_config->num_couples;
733 ++couple_idx)
734 yac_couple_config_couple_free(couple_config->couples + couple_idx);
735 free(couple_config->couples);
736 free(couple_config);
737}
738
740 struct yac_couple_config * couple_config, char const * name) {
741
743 name != NULL,
744 "ERROR(yac_couple_config_add_grid_): "
745 "invalid name (NULL is not allowed)")
746
747 for (size_t i = 0; i < couple_config->num_grids; ++i)
748 if (!strcmp(couple_config->grids[i].name, name)) return i;
749
750 size_t grid_idx = couple_config->num_grids;
751 couple_config->num_grids++;
752 couple_config->grids =
753 xrealloc(
754 couple_config->grids,
755 couple_config->num_grids * sizeof(*(couple_config->grids)));
756 couple_config->grids[grid_idx].name = string_dup(name);
757 couple_config->grids[grid_idx].output_filename = NULL;
758 couple_config->grids[grid_idx].metadata = NULL;
759 return grid_idx;
760}
761
763 struct yac_couple_config * couple_config, char const * name) {
764
765 yac_couple_config_add_grid_(couple_config, name);
766}
767
769 struct yac_couple_config * couple_config, char const * name) {
770
772 name != NULL,
773 "ERROR(yac_couple_config_add_component_): "
774 "invalid name (NULL is not allowed)")
775
776 for (size_t i = 0; i < couple_config->num_components; ++i)
777 if (!strcmp(couple_config->components[i].name, name)) return i;
778
779 size_t component_idx = couple_config->num_components;
780 couple_config->num_components++;
781 couple_config->components =
782 xrealloc(
783 couple_config->components,
784 couple_config->num_components * sizeof(*(couple_config->components)));
785 couple_config->components[component_idx].fields = NULL;
786 couple_config->components[component_idx].num_fields = 0;
787 couple_config->components[component_idx].name = strdup(name);
788 couple_config->components[component_idx].metadata = NULL;
789 return component_idx;
790}
791
793 struct yac_couple_config * couple_config, char const * name) {
794
796}
797
799 struct yac_couple_config * couple_config,
800 char const * comp_name, const char* metadata) {
801 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
802 free(couple_config->components[comp_idx].metadata);
803 couple_config->components[comp_idx].metadata
804 = metadata==NULL?NULL:strdup(metadata);
805}
806
808 struct yac_couple_config * couple_config,
809 char const * grid_name, const char* output_filename) {
810 if(!yac_couple_config_contains_grid_name(couple_config, grid_name))
811 yac_couple_config_add_grid(couple_config, grid_name);
812 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
814 output_filename != NULL,
815 "ERROR(yac_couple_config_grid_set_output_filename): invalid output filename "
816 "for grid \"%s\" (NULL is not allowed)",
817 grid_name);
819 (couple_config->grids[grid_idx].output_filename == NULL) ||
820 (!strcmp(couple_config->grids[grid_idx].output_filename, output_filename)),
821 "ERROR(yac_couple_config_grid_set_output_filename): output file name for grid "
822 "\"%s\" has already been set (\"%s\" != \"%s\")",
823 grid_name, couple_config->grids[grid_idx].output_filename, output_filename);
824 if (couple_config->grids[grid_idx].output_filename == NULL)
825 couple_config->grids[grid_idx].output_filename = strdup(output_filename);
826}
827
829 struct yac_couple_config * couple_config,
830 char const * grid_name, const char* metadata) {
831 if(!yac_couple_config_contains_grid_name(couple_config, grid_name))
832 yac_couple_config_add_grid(couple_config, grid_name);
833 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
834 free(couple_config->grids[grid_idx].metadata);
835 couple_config->grids[grid_idx].metadata
836 = metadata==NULL?NULL:strdup(metadata);
837}
838
840 struct yac_couple_config * couple_config,
841 const char* comp_name, const char * grid_name, const char* field_name,
842 const char* metadata) {
843 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
844 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
845 size_t field_idx = yac_couple_config_get_field_idx(couple_config,
846 comp_idx, grid_idx, field_name);
847 free(couple_config->components[comp_idx].fields[field_idx].metadata);
848 couple_config->components[comp_idx].fields[field_idx].metadata
849 = metadata==NULL?NULL:strdup(metadata);
850}
851
853 struct yac_couple_config * couple_config,
854 const char * comp_name) {
855 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
856 return couple_config->components[comp_idx].metadata;
857}
858
860 struct yac_couple_config * couple_config,
861 const char * grid_name) {
862 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
863 return couple_config->grids[grid_idx].output_filename;
864}
865
867 struct yac_couple_config * couple_config,
868 const char * grid_name) {
869 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
870 return couple_config->grids[grid_idx].metadata;
871}
872
874 struct yac_couple_config * couple_config,
875 const char* comp_name, const char * grid_name, const char* field_name) {
876 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
877 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
878 size_t field_idx = yac_couple_config_get_field_idx(couple_config,
879 comp_idx, grid_idx, field_name);
880 return couple_config->components[comp_idx].fields[field_idx].metadata;
881}
882
884 struct yac_couple_config * couple_config, size_t component_idx,
885 char const * routine_name, int line) {
886
888 component_idx < couple_config->num_components,
889 "ERROR(%s:%d:%s): invalid component_idx", __FILE__, line, routine_name)
890}
891
892static void check_grid_idx(
893 struct yac_couple_config * couple_config, size_t grid_idx,
894 char const * routine_name, int line) {
895
897 grid_idx < couple_config->num_grids,
898 "ERROR(%s:%d:%s): invalid grid_idx", __FILE__, line, routine_name)
899}
900
902 struct yac_couple_config * couple_config,
903 size_t comp_idx, size_t grid_idx, char const * name,
904 char const * timestep, size_t collection_size) {
905
907 couple_config, comp_idx,
908 "yac_couple_config_component_add_field_", __LINE__);
910 couple_config, grid_idx,
911 "yac_couple_config_component_add_field_", __LINE__);
912
913 // check whether the field already exists
914 struct yac_couple_config_component * component =
915 couple_config->components + comp_idx;
916 for (size_t i = 0; i < component->num_fields; i++) {
917 if((strcmp(component->fields[i].name, name) == 0) &&
918 (component->fields[i].grid_idx == grid_idx)) {
919 // if no timestep is defined for the field
920 if (!component->fields[i].timestep && timestep)
921 component->fields[i].timestep = strdup(timestep);
922 // if no collection size is defined for the field
923 if (component->fields[i].collection_size == SIZE_MAX)
924 component->fields[i].collection_size = collection_size;
926 !timestep ||
927 !strcmp(timestep, component->fields[i].timestep),
928 "ERROR(yac_couple_config_component_add_field): "
929 "inconsistent timestep definition (\"%s\" != \"%s\")",
930 timestep, component->fields[i].timestep);
932 collection_size == SIZE_MAX ||
933 collection_size == component->fields[i].collection_size,
934 "ERROR(yac_couple_config_component_add_field): "
935 "inconsistent collection_size definition (%zu != %zu)",
936 collection_size, component->fields[i].collection_size);
937 return i;
938 }
939 }
940
941 size_t field_idx = component->num_fields;
942 component->num_fields++;
943
944 component->fields =
945 xrealloc(
946 component->fields,
947 component->num_fields *
948 sizeof(*(component->fields)));
949 struct yac_couple_config_field * field =
950 component->fields + field_idx;
951
952 field->name = strdup(name);
953 field->grid_idx = grid_idx;
954 field->timestep = timestep?strdup(timestep):NULL;
955 field->metadata = NULL;
956 field->frac_mask_fallback_value = YAC_FRAC_MASK_NO_VALUE;
957 field->collection_size = collection_size;
958 return field_idx;
959}
960
962 struct yac_couple_config * couple_config, const char* component_name,
963 const char* grid_name, const char* name, char const * timestep,
964 size_t collection_size) {
965
967 couple_config,
968 yac_couple_config_get_component_idx(couple_config, component_name),
969 yac_couple_config_get_grid_idx(couple_config, grid_name),
971}
972
974 struct yac_couple_config * couple_config) {
975
976 return couple_config->num_couples;
977}
978
980 struct yac_couple_config * couple_config) {
981
982 switch(couple_config->missing_definition_is_fatal) {
983 case(FLAG_FALSE): return 0;
984 case(FLAG_TRUE): return 1;
985 default:
987 }
988}
989
991 struct yac_couple_config * couple_config,
992 int missing_definition_is_fatal) {
993
994 enum flag_value user_value =
995 (missing_definition_is_fatal != 0)?FLAG_TRUE:FLAG_FALSE;
996
998 (couple_config->missing_definition_is_fatal == FLAG_UNSET) ||
999 (couple_config->missing_definition_is_fatal == user_value),
1000 "ERROR(yac_couple_config_set_missing_definition_is_fatal): "
1001 "inconsistent setting of \"missing_definition_is_fatal\"-flag "
1002 "(old: %s new: %s)",
1003 (couple_config->missing_definition_is_fatal == FLAG_TRUE)?"TRUE":"FALSE",
1004 (user_value == FLAG_TRUE)?"TRUE":"FALSE");
1005
1006 couple_config->missing_definition_is_fatal = user_value;
1007}
1008
1010 struct yac_couple_config * couple_config, size_t couple_idx,
1011 char const * routine_name, int line) {
1012
1014 couple_idx < couple_config->num_couples,
1015 "ERROR(%s:%d:%s): invalid couple_idx", __FILE__, line, routine_name);
1016}
1017
1019 struct yac_couple_config * couple_config, size_t couple_idx) {
1020
1022 couple_config, couple_idx, "yac_couple_config_get_num_couple_fields",
1023 __LINE__);
1024
1025 return couple_config->couples[couple_idx].num_field_couples;
1026}
1027
1029 struct yac_couple_config * couple_config, size_t couple_idx,
1030 char const * couple_component_names[2]) {
1031
1033 couple_config, couple_idx, "yac_couple_config_get_couple_component_names",
1034 __LINE__);
1035
1036 for (int i = 0; i < 2; ++i)
1037 couple_component_names[i] =
1038 couple_config->components[
1039 couple_config->couples[couple_idx].component_indices[i]].name;
1040}
1041
1043 struct yac_couple_config * couple_config, char const * component_name) {
1044
1045 YAC_ASSERT(
1046 component_name,
1047 "ERROR(yac_couple_config_component_name_is_valid): component name is NULL")
1048 YAC_ASSERT(
1049 strlen(component_name) <= YAC_MAX_CHARLEN,
1050 "ERROR(yac_couple_config_component_name_is_valid): "
1051 "component name is too long (maximum is YAC_MAX_CHARLEN)")
1052
1053 for (size_t component_idx = 0; component_idx < couple_config->num_components;
1054 ++component_idx)
1055 if (!strcmp(component_name, couple_config->components[component_idx].name))
1056 return 1;
1057 return 0;
1058}
1059
1061 struct yac_couple_config * couple_config) {
1062
1063 return couple_config->num_components;
1064}
1065
1067 struct yac_couple_config * couple_config) {
1068
1069 return couple_config->num_grids;
1070}
1071
1073 struct yac_couple_config * couple_config, size_t component_idx) {
1074 check_component_idx(couple_config, component_idx,
1075 "yac_couple_config_get_num_fields", __LINE__);
1076 return couple_config->components[component_idx].num_fields;
1077}
1078
1080 struct yac_couple_config * couple_config, char const * component_name) {
1081
1082 size_t component_idx = SIZE_MAX;
1083 for (size_t i = 0; (i < couple_config->num_components) &&
1084 (component_idx == SIZE_MAX); ++i)
1085 if (!strcmp(couple_config->components[i].name, component_name))
1086 component_idx = i;
1087
1089 component_idx != SIZE_MAX,
1090 "ERROR(yac_couple_config_get_component_idx): "
1091 "Component \"%s\" not found in coupling configuration",
1092 component_name);
1093
1094 return component_idx;
1095}
1096
1098 struct yac_couple_config * couple_config, char const * grid_name) {
1099
1100 size_t grid_idx = SIZE_MAX;
1101 for (size_t i = 0;
1102 (i < couple_config->num_grids) && (grid_idx == SIZE_MAX); ++i)
1103 if (!strcmp(couple_config->grids[i].name, grid_name))
1104 grid_idx = i;
1105
1107 grid_idx != SIZE_MAX,
1108 "ERROR(yac_couple_config_get_grid_idx): "
1109 "grid name \"%s\" not in list of grids", grid_name)
1110
1111 return grid_idx;
1112}
1113
1115 struct yac_couple_config * couple_config, size_t component_idx,
1116 size_t grid_idx, char const * field_name) {
1118 couple_config, component_idx,
1119 "yac_couple_config_get_component_name", __LINE__);
1120
1121 size_t field_idx = SIZE_MAX;
1122 struct yac_couple_config_component * component =
1123 couple_config->components + component_idx;
1124 size_t nbr_fields = component->num_fields;
1125 for(size_t i=0;
1126 (i<nbr_fields) && (field_idx == SIZE_MAX); ++i)
1127 if((component->fields[i].grid_idx == grid_idx) &&
1128 !strcmp(
1129 field_name,
1130 component->fields[i].name))
1131 field_idx = i;
1132
1134 field_idx != SIZE_MAX,
1135 "ERROR(yac_couple_config_get_field_idx): "
1136 "field not found "
1137 "(component_idx %zu grid_idx %zu field_name \"%s\"",
1138 component_idx, grid_idx, field_name);
1139
1140 return field_idx;
1141}
1142
1144 struct yac_couple_config * couple_config, size_t component_idx) {
1145
1147 couple_config, component_idx,
1148 "yac_couple_config_get_component_name", __LINE__);
1149
1150 return couple_config->components[component_idx].name;
1151}
1152
1154 struct yac_couple_config * couple_config, size_t component_idx,
1155 size_t field_idx, char const * routine_name, int line) {
1156
1158 couple_config, component_idx, routine_name, __LINE__);
1159
1161 field_idx <
1162 couple_config->components[component_idx].num_fields,
1163 "ERROR(%s:%d:%s): invalid field_idx", __FILE__,
1164 line, routine_name)
1165}
1166
1168 struct yac_couple_config * couple_config, size_t component_idx,
1169 size_t field_idx) {
1170
1172 couple_config, component_idx, field_idx,
1173 "yac_couple_config_get_field_grid_name", __LINE__);
1174
1175 return
1176 couple_config->grids[
1177 couple_config->
1178 components[component_idx].
1179 fields[field_idx].grid_idx].name;
1180}
1181
1183 struct yac_couple_config * couple_config, size_t component_idx,
1184 size_t field_idx) {
1185
1187 couple_config, component_idx, field_idx,
1188 "yac_couple_config_get_field_name", __LINE__);
1189
1190 return
1191 couple_config->
1192 components[component_idx].
1193 fields[field_idx].name;
1194}
1195
1197 struct yac_couple_config * couple_config,
1198 char const * component_name, char const * grid_name,
1199 char const * field_name) {
1200
1201 size_t component_idx =
1202 yac_couple_config_get_component_idx(couple_config, component_name);
1203 size_t grid_idx =
1204 yac_couple_config_get_grid_idx(couple_config, grid_name);
1205 size_t field_idx =
1207 couple_config, component_idx, grid_idx, field_name);
1208
1209 struct yac_couple_config_field * field =
1210 couple_config->components[component_idx].fields +
1211 field_idx;
1212
1213 return field->timestep;
1214}
1215
1217 struct yac_couple_config * couple_config,
1218 char const * component_name, char const * grid_name,
1219 char const * field_name) {
1220
1221 size_t component_idx =
1222 yac_couple_config_get_component_idx(couple_config, component_name);
1223 size_t grid_idx =
1224 yac_couple_config_get_grid_idx(couple_config, grid_name);
1225 size_t field_idx =
1227 couple_config, component_idx, grid_idx, field_name);
1228
1229 size_t nbr_couples = couple_config->num_couples;
1230 for(size_t couple_idx = 0; couple_idx<nbr_couples; ++couple_idx){
1231 struct yac_couple_config_couple * couple = couple_config->couples + couple_idx;
1232 if(couple->component_indices[0] != component_idx &&
1233 couple->component_indices[1] != component_idx)
1234 continue;
1235 size_t nbr_trans_couples = couple->num_field_couples;
1236 for(size_t trans_couple_idx = 0; trans_couple_idx < nbr_trans_couples;
1237 ++trans_couple_idx){
1238 struct yac_couple_config_field_couple * transcouple =
1239 couple->field_couples + trans_couple_idx;
1240 if(transcouple->source.component_idx == component_idx &&
1241 transcouple->source.field_idx == field_idx)
1243 if(transcouple->target.component_idx == component_idx &&
1244 transcouple->target.field_idx == field_idx)
1246 }
1247 }
1249}
1250
1252 struct yac_couple_config * couple_config,
1253 size_t component_idx, size_t field_idx) {
1254
1256 couple_config, component_idx,
1257 "yac_couple_config_field_is_valid", __LINE__);
1259 couple_config, component_idx, field_idx,
1260 "yac_couple_config_field_is_valid", __LINE__);
1261
1262 struct yac_couple_config_field * field =
1263 couple_config->components[component_idx].fields +
1264 field_idx;
1265
1266 return (field->collection_size != SIZE_MAX) &&
1267 (field->timestep != NULL);
1268}
1269
1271 struct yac_couple_config * couple_config, size_t couple_idx,
1272 size_t field_couple_idx, char const * routine_name, int line) {
1273
1274 check_couple_idx(couple_config, couple_idx, routine_name, __LINE__);
1275
1277 field_couple_idx <
1278 couple_config->couples[couple_idx].num_field_couples,
1279 "ERROR(%s:%d:%s): invalid field_couple_idx",
1280 __FILE__, line, routine_name)
1281}
1282
1284 struct yac_couple_config * couple_config,
1285 size_t couple_idx, size_t field_couple_idx) {
1286
1288 couple_config, couple_idx, field_couple_idx,
1289 "yac_couple_config_get_interp_stack", __LINE__);
1290
1291 return
1292 couple_config->
1293 couples[couple_idx].
1294 field_couples[field_couple_idx].interp_stack;
1295}
1296
1298 struct yac_couple_config * couple_config,
1299 size_t couple_idx, size_t field_couple_idx,
1300 char const ** src_grid_name, char const ** tgt_grid_name) {
1301
1303 couple_config, couple_idx, field_couple_idx,
1304 "yac_couple_config_get_field_grid_names", __LINE__);
1305
1306 size_t src_component_idx =
1307 couple_config->couples[couple_idx].
1308 field_couples[field_couple_idx].
1309 source.component_idx;
1310 size_t src_field_idx =
1311 couple_config->couples[couple_idx].
1312 field_couples[field_couple_idx].
1313 source.field_idx;
1314
1315 size_t tgt_component_idx =
1316 couple_config->couples[couple_idx].
1317 field_couples[field_couple_idx].
1318 target.component_idx;
1319 size_t tgt_field_idx =
1320 couple_config->couples[couple_idx].
1321 field_couples[field_couple_idx].
1322 target.field_idx;
1323
1324 *src_grid_name =
1325 couple_config->grids[
1326 couple_config->components[src_component_idx].
1327 fields[src_field_idx].grid_idx].name;
1328 *tgt_grid_name =
1329 couple_config->grids[
1330 couple_config->components[tgt_component_idx].
1331 fields[tgt_field_idx].grid_idx].name;
1332}
1333
1335 struct yac_couple_config * couple_config,
1336 char const * comp_name, char const * grid_name, char const * field_name,
1337 double frac_mask_fallback_value) {
1338
1340 YAC_FRAC_MASK_VALUE_IS_VALID(frac_mask_fallback_value),
1341 "ERROR(yac_couple_config_field_enable_frac_mask): "
1342 "\"%lf\" is not a valid fractional mask fallback value "
1343 "(component: \"%s\" grid: \"%s\" field \"%s\")",
1344 frac_mask_fallback_value, comp_name, grid_name, field_name);
1345
1346 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
1347 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
1348 size_t field_idx = yac_couple_config_get_field_idx(couple_config,
1349 comp_idx, grid_idx, field_name);
1350
1351 double old_frac_mask_fallback_value =
1352 couple_config->components[comp_idx].fields[field_idx].
1353 frac_mask_fallback_value;
1354
1355 // (use memcmp for comparison, because it can be nan)
1357 !YAC_FRAC_MASK_VALUE_IS_VALID(old_frac_mask_fallback_value) ||
1358 !memcmp(
1359 &old_frac_mask_fallback_value, &frac_mask_fallback_value,
1360 sizeof(frac_mask_fallback_value)),
1361 "ERROR(yac_couple_config_field_enable_frac_mask): "
1362 "fractional mask fallback value was already set:\n"
1363 "\told value \"%lf\" new value \"%lf\" "
1364 "(component: \"%s\" grid: \"%s\" field \"%s\")",
1365 old_frac_mask_fallback_value, frac_mask_fallback_value,
1366 comp_name, grid_name, field_name);
1367
1368 couple_config->components[comp_idx].fields[field_idx].
1369 frac_mask_fallback_value = 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
1390 YAC_FRAC_MASK_VALUE_IS_SET(field->frac_mask_fallback_value),
1391 "ERROR(yac_couple_config_get_frac_mask_fallback_value): "
1392 "no valid fractional mask fallback value defined "
1393 "(component: \"%s\" grid: \"%s\" field \"%s\")",
1394 couple_config->components[component_idx].name, grid_name, field->name);
1395
1396 return field->frac_mask_fallback_value;
1397}
1398
1400 struct yac_couple_config * couple_config,
1401 char const * component_name, char const * grid_name,
1402 char const * field_name) {
1403
1404 size_t component_idx =
1405 yac_couple_config_get_component_idx(couple_config, component_name);
1406 size_t grid_idx =
1407 yac_couple_config_get_grid_idx(couple_config, grid_name);
1408 size_t field_idx =
1410 couple_config, component_idx, grid_idx, field_name);
1411
1412 struct yac_couple_config_field * field =
1413 couple_config->components[component_idx].fields +
1414 field_idx;
1415
1416 return field->collection_size;
1417}
1418
1420 struct yac_couple_config * couple_config,
1421 size_t couple_idx, size_t field_couple_idx,
1422 char const ** src_component_name, char const ** tgt_component_name) {
1423
1425 couple_config, couple_idx, field_couple_idx,
1426 "yac_couple_config_get_field_couple_component_names", __LINE__);
1427
1428 *src_component_name =
1429 couple_config->components[
1430 couple_config->couples[couple_idx].
1431 field_couples[field_couple_idx].source.component_idx].name;
1432 *tgt_component_name =
1433 couple_config->components[
1434 couple_config->couples[couple_idx].
1435 field_couples[field_couple_idx].target.component_idx].name;
1436}
1437
1439 struct yac_couple_config * couple_config,
1440 size_t couple_idx, size_t field_couple_idx,
1441 char const ** src_field_name, const char ** tgt_field_name) {
1442
1444 couple_config, couple_idx, field_couple_idx,
1445 "yac_couple_config_get_field_names", __LINE__);
1446
1447 size_t src_component_idx =
1448 couple_config->couples[couple_idx].
1449 field_couples[field_couple_idx].source.component_idx;
1450 size_t tgt_component_idx =
1451 couple_config->couples[couple_idx].
1452 field_couples[field_couple_idx].target.component_idx;
1453 size_t src_field_idx =
1454 couple_config->couples[couple_idx].
1455 field_couples[field_couple_idx].source.field_idx;
1456 size_t tgt_field_idx =
1457 couple_config->couples[couple_idx].
1458 field_couples[field_couple_idx].target.field_idx;
1459
1460 *src_field_name =
1461 couple_config->components[src_component_idx].
1462 fields[src_field_idx].name;
1463 *tgt_field_name =
1464 couple_config->components[tgt_component_idx].
1465 fields[tgt_field_idx].name;
1466}
1467
1469 struct yac_couple_config * couple_config,
1470 size_t couple_idx, size_t field_couple_idx) {
1471
1473 couple_config, couple_idx, field_couple_idx,
1474 "yac_couple_config_mapping_on_source", __LINE__);
1475
1476 return
1477 couple_config->
1478 couples[couple_idx].
1479 field_couples[field_couple_idx].
1480 mapping_on_source;
1481}
1482
1484 struct yac_couple_config * couple_config,
1485 size_t couple_idx, size_t field_couple_idx) {
1486
1488 couple_config, couple_idx, field_couple_idx,
1489 "yac_couple_config_get_source_lag", __LINE__);
1490
1491 return
1492 couple_config->
1493 couples[couple_idx].
1494 field_couples[field_couple_idx].
1495 source.lag;
1496}
1497
1499 struct yac_couple_config * couple_config,
1500 size_t couple_idx, size_t field_couple_idx) {
1501
1503 couple_config, couple_idx, field_couple_idx,
1504 "yac_couple_config_get_target_lag", __LINE__);
1505
1506 return
1507 couple_config->
1508 couples[couple_idx].
1509 field_couples[field_couple_idx].
1510 target.lag;
1511}
1512
1514 struct yac_couple_config * couple_config,
1515 size_t couple_idx, size_t field_couple_idx) {
1516
1518 couple_config, couple_idx, field_couple_idx,
1519 "yac_couple_config_get_coupling_period", __LINE__);
1520
1521 return
1522 couple_config->
1523 couples[couple_idx].
1524 field_couples[field_couple_idx].
1525 coupling_period;
1526}
1527
1529 struct yac_couple_config * couple_config,
1530 size_t couple_idx, size_t field_couple_idx) {
1531
1533 couple_config, couple_idx, field_couple_idx,
1534 "yac_couple_config_get_source_timestep", __LINE__);
1535
1536 struct yac_couple_config_field_couple * tcouple =
1537 couple_config->couples[couple_idx].field_couples + field_couple_idx;
1538 char const * timestep =
1539 couple_config->components[tcouple->source.component_idx].
1540 fields[tcouple->source.field_idx].timestep;
1541
1543 timestep,
1544 "ERROR(yac_couple_config_get_source_timestep): "
1545 "no valid timestep defined (component: \"%s\" field \"%s\")",
1546 couple_config->components[tcouple->source.component_idx].name,
1547 couple_config->components[tcouple->source.component_idx].
1548 fields[tcouple->source.field_idx].name);
1549
1550 return timestep;
1551}
1552
1554 struct yac_couple_config * couple_config,
1555 size_t couple_idx, size_t field_couple_idx) {
1556
1558 couple_config, couple_idx, field_couple_idx,
1559 "yac_couple_config_get_target_timestep", __LINE__);
1560
1561 struct yac_couple_config_field_couple * tcouple =
1562 couple_config->couples[couple_idx].field_couples + field_couple_idx;
1563 char const * timestep =
1564 couple_config->components[tcouple->target.component_idx].
1565 fields[tcouple->target.field_idx].timestep;
1566
1567 return timestep;
1568}
1569
1571 struct yac_couple_config * couple_config,
1572 size_t couple_idx, size_t field_couple_idx) {
1573
1575 couple_config, couple_idx, field_couple_idx,
1576 "yac_couple_config_get_coupling_period_operation", __LINE__);
1577
1578 return
1579 couple_config->
1580 couples[couple_idx].
1581 field_couples[field_couple_idx].
1583}
1584
1585static void set_datetime(
1586 char const * type_datetime, struct _datetime ** old, char const * str_new) {
1587
1588 if ((str_new == NULL) || (strlen(str_new) == 0)) return;
1589
1590 YAC_ASSERT(
1592 "ERROR(set_datetime): calendar has not yet been set");
1593
1594 struct _datetime * new = newDateTime(str_new);
1595
1597 new != NULL,
1598 "ERROR(set_datetime): failed to parse datetime \"%s\"", str_new);
1599
1600 char old_datetime_buffer[MAX_DATETIME_STR_LEN],
1601 new_datetime_buffer[MAX_DATETIME_STR_LEN];
1602
1604 (*old == NULL) || (equal_to == compareDatetime(*old, new)),
1605 "ERROR(set_datetime): inconsistent %s datetime "
1606 "(old: \"%s\" new: \"%s\")", type_datetime,
1607 datetimeToString(*old, old_datetime_buffer),
1608 datetimeToString(new, new_datetime_buffer));
1609
1610 deallocateDateTime(*old);
1611
1612 *old = new;
1613}
1614
1616 struct yac_couple_config * couple_config,
1617 char const * start, char const * end) {
1618
1619 set_datetime("start", &(couple_config->start_datetime), start);
1620 set_datetime("end", &(couple_config->end_datetime), end);
1621}
1622
1624 struct yac_couple_config * couple_config) {
1625
1626 YAC_ASSERT(couple_config->start_datetime,
1627 "ERROR(yac_couple_config_get_start_datetime): "
1628 "start_datetime not yet defined");
1629
1630 char datetime_buffer[MAX_DATETIME_STR_LEN];
1631
1632 return
1633 strdup(datetimeToString(couple_config->start_datetime, datetime_buffer));
1634}
1635
1637 struct yac_couple_config * couple_config) {
1638
1639 YAC_ASSERT(couple_config->end_datetime,
1640 "ERROR(yac_couple_config_get_start_datetime): "
1641 "start_datetime not yet defined");
1642
1643 char datetime_buffer[MAX_DATETIME_STR_LEN];
1644
1645 return
1646 strdup(datetimeToString(couple_config->end_datetime, datetime_buffer));
1647}
1648
1650 struct yac_couple_config * couple_config, size_t grid_idx) {
1651
1653 grid_idx < couple_config->num_grids,
1654 "ERROR(yac_couple_config_get_grid_name): "
1655 "Invalid grid idx %zu", grid_idx);
1656
1657 return couple_config->grids[grid_idx].name;
1658}
1659
1661 struct yac_couple_config * couple_config,
1662 size_t couple_idx, size_t field_couple_idx) {
1663
1665 couple_config, couple_idx, field_couple_idx,
1666 "yac_couple_config_enforce_write_weight_file", __LINE__);
1667
1668 return
1669 couple_config->
1670 couples[couple_idx].
1671 field_couples[field_couple_idx].
1672 enforce_write_weight_file;
1673}
1674
1676 struct yac_couple_config * couple_config,
1677 size_t couple_idx, size_t field_couple_idx) {
1678
1680 couple_config, couple_idx, field_couple_idx,
1681 "yac_couple_config_get_weight_file_name", __LINE__);
1682
1683 static char dummy[] = "\0";
1684 char const * weight_file_name =
1685 couple_config->
1686 couples[couple_idx].
1687 field_couples[field_couple_idx].
1688 weight_file_name;
1689
1690 return (weight_file_name != NULL)?weight_file_name:dummy;
1691}
1692
1694 struct yac_couple_config * couple_config,
1695 size_t couple_idx, size_t field_couple_idx) {
1696
1698 couple_config, couple_idx, field_couple_idx,
1699 "yac_couple_config_get_weight_file_on_existing", __LINE__);
1700
1701 return
1702 couple_config->
1703 couples[couple_idx].
1704 field_couples[field_couple_idx].
1705 weight_file_on_existing;
1706}
1707
1709 struct yac_couple_config * couple_config,
1710 size_t couple_idx, size_t field_couple_idx) {
1711
1713 couple_config, couple_idx, field_couple_idx,
1714 "yac_couple_config_get_scale_factor", __LINE__);
1715
1716 return
1717 couple_config->
1718 couples[couple_idx].
1719 field_couples[field_couple_idx].
1720 scale_factor;
1721}
1722
1724 struct yac_couple_config * couple_config,
1725 size_t couple_idx, size_t field_couple_idx) {
1726
1728 couple_config, couple_idx, field_couple_idx,
1729 "yac_couple_config_get_scale_summand", __LINE__);
1730
1731 return
1732 couple_config->
1733 couples[couple_idx].
1734 field_couples[field_couple_idx].
1735 scale_summand;
1736}
1737
1739 struct yac_couple_config * couple_config,
1740 size_t couple_idx, size_t field_couple_idx,
1741 char const * const ** mask_names, size_t * num_mask_names) {
1742
1744 couple_config, couple_idx, field_couple_idx,
1745 "yac_couple_config_get_src_mask_names", __LINE__);
1746
1747 *mask_names =
1748 (char const * const *)(
1749 couple_config->
1750 couples[couple_idx].
1751 field_couples[field_couple_idx].
1752 src_mask_names);
1753 *num_mask_names =
1754 couple_config->
1755 couples[couple_idx].
1756 field_couples[field_couple_idx].
1757 num_src_mask_names;
1758}
1759
1761 struct yac_couple_config * couple_config,
1762 size_t couple_idx, size_t field_couple_idx) {
1763
1765 couple_config, couple_idx, field_couple_idx,
1766 "yac_couple_config_get_tgt_mask_name", __LINE__);
1767
1768 return
1769 couple_config->
1770 couples[couple_idx].
1771 field_couples[field_couple_idx].
1772 tgt_mask_name;
1773}
1774
1776 struct yac_couple_config * couple_config,
1777 size_t couple_idx, size_t field_couple_idx) {
1778
1780 couple_config, couple_idx, field_couple_idx,
1781 "yac_couple_config_get_yaxt_exchanger_name", __LINE__);
1782
1783 return
1784 couple_config->
1785 couples[couple_idx].
1786 field_couples[field_couple_idx].
1787 yaxt_exchanger_name;
1788}
1789
1791 struct yac_couple_config * couple_config,
1792 size_t couple_idx, size_t field_couple_idx) {
1793
1795 couple_config, couple_idx, field_couple_idx,
1796 "yac_couple_config_get_use_raw_exchange", __LINE__);
1797
1798 return
1799 couple_config->
1800 couples[couple_idx].
1801 field_couples[field_couple_idx].
1802 use_raw_exchange;
1803}
1804
1806 struct yac_couple_config * couple_config, char const * grid_name) {
1807
1808 for (size_t grid_idx = 0; grid_idx < couple_config->num_grids;
1809 ++grid_idx)
1810 if (!strcmp(couple_config->grids[grid_idx].name, grid_name))
1811 return 1;
1812 return 0;
1813}
1814
1816 char const * string, MPI_Comm comm) {
1817
1818 int strlen_pack_size, string_pack_size;
1819 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &strlen_pack_size), comm);
1820
1821 if (string != NULL) {
1823 MPI_Pack_size(
1824 (int)(strlen(string)), MPI_CHAR, comm, &string_pack_size), comm);
1825 } else {
1826 string_pack_size = 0;
1827 }
1828
1829 return (size_t)strlen_pack_size + (size_t)string_pack_size;
1830}
1831
1833 void * grid_, MPI_Comm comm) {
1834
1835 struct yac_couple_config_grid * grid = grid_;
1836
1837 return yac_couple_config_get_string_pack_size(grid->name, comm);
1838}
1839
1841 void * field_, MPI_Comm comm) {
1842
1843 struct yac_couple_config_field * field =
1844 (struct yac_couple_config_field *)field_;
1845
1846 YAC_ASSERT(
1847 field->grid_idx <= INT_MAX,
1848 "ERROR(yac_couple_config_get_field_pack_size):"
1849 "grid_idx is too big")
1850
1851 int int_pack_size;
1852 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &int_pack_size), comm);
1853 size_t name_pack_size = yac_couple_config_get_string_pack_size(
1854 field->name, comm);
1855
1856 return int_pack_size + // grid_idx
1857 name_pack_size;
1858}
1859
1861 void * component_, MPI_Comm comm) {
1862
1863 struct yac_couple_config_component * component =
1864 (struct yac_couple_config_component *)component_;
1865
1866 return
1868}
1869
1871 void * field_couple_, MPI_Comm comm) {
1872
1873 struct yac_couple_config_field_couple * field_couple =
1874 (struct yac_couple_config_field_couple *)field_couple_;
1875
1876 int ints_pack_size;
1877 yac_mpi_call(MPI_Pack_size(12, MPI_INT, comm, &ints_pack_size), comm);
1878 int doubles_pack_size;
1879 yac_mpi_call(MPI_Pack_size(2, MPI_DOUBLE, comm, &doubles_pack_size), comm);
1880 int src_mask_names_pack_size = 0;
1881 if (field_couple->num_src_mask_names > 0)
1882 for (size_t i = 0; i < field_couple->num_src_mask_names; ++i)
1883 src_mask_names_pack_size +=
1885 field_couple->src_mask_names[i], comm);
1886
1887 return
1888 (size_t)ints_pack_size + // source.component_idx
1889 // source.field_idx
1890 // source.lag
1891 // target.component_idx
1892 // target.field_idx
1893 // target.lag
1894 // mapping_on_source
1895 // coupling_period_operation
1896 // enforce_write_weight_file
1897 // weight_file_on_existing
1898 // num_src_mask_names
1899 // use_raw_exchange
1901 field_couple->interp_stack, comm) +
1903 field_couple->coupling_period, comm) +
1905 field_couple->weight_file_name, comm) +
1906 doubles_pack_size + // scale_factor
1907 // scale_summand
1908 src_mask_names_pack_size +
1910 field_couple->tgt_mask_name, comm) +
1912 field_couple->yaxt_exchanger_name, comm);
1913}
1914
1916 void * couple_, MPI_Comm comm) {
1917
1918 UNUSED(couple_);
1919
1920 int component_indices_pack_size;
1922 MPI_Pack_size(2, MPI_INT, comm, &component_indices_pack_size), comm);
1923
1924 return (size_t)component_indices_pack_size;
1925}
1926
1928 void * config_output_, MPI_Comm comm) {
1929
1930 struct yac_couple_config_config_output * config_output = config_output_;
1931
1932 int filetype_pack_size;
1934 MPI_Pack_size(1, MPI_INT, comm, &filetype_pack_size), comm);
1935
1936 return
1937 filetype_pack_size +
1938 yac_couple_config_get_string_pack_size(config_output->name, comm) +
1939 yac_couple_config_get_string_pack_size(config_output->ref, comm);
1940}
1941
1943 char const * string, void * buffer, int buffer_size, int * position,
1944 MPI_Comm comm) {
1945
1946 size_t len = (string == NULL)?0:strlen(string);
1947
1948 YAC_ASSERT(
1949 len <= INT_MAX, "ERROR(yac_couple_config_pack_string): string too long")
1950
1951 int len_int = (int)len;
1952
1954 MPI_Pack(
1955 &len_int, 1, MPI_INT, buffer, buffer_size, position, comm), comm);
1956
1957 if (len > 0)
1959 MPI_Pack(
1960 string, len_int, MPI_CHAR, buffer, buffer_size, position, comm),
1961 comm);
1962}
1963
1965 void * grid_, void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1966
1967 struct yac_couple_config_grid * grid =
1968 (struct yac_couple_config_grid *)grid_;
1970 grid->name, buffer, buffer_size, position, comm);
1971}
1972
1974 void * field_, void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1975
1976 struct yac_couple_config_field * field =
1977 (struct yac_couple_config_field *)field_;
1978
1979 YAC_ASSERT(
1980 field->grid_idx <= INT_MAX,
1981 "ERROR(yac_couple_config_pack_field): grid_idx is too big")
1982
1983 int grid_idx = (int)field->grid_idx;
1984
1986 MPI_Pack(
1987 &grid_idx, 1, MPI_INT, buffer, buffer_size, position, comm), comm);
1988 yac_couple_config_pack_string(field->name, buffer,
1989 buffer_size, position, comm);
1990}
1991
1993 void * component_, void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1994
1995 struct yac_couple_config_component * component =
1996 (struct yac_couple_config_component *)component_;
1997
1999 component->name, buffer, buffer_size, position, comm);
2000}
2001
2003 void * field_couple_, void * buffer, int buffer_size, int * position,
2004 MPI_Comm comm) {
2005
2006 struct yac_couple_config_field_couple * field_couple =
2007 (struct yac_couple_config_field_couple *)field_couple_;
2008
2009 YAC_ASSERT(
2010 field_couple->source.component_idx <= INT_MAX,
2011 "ERROR(yac_couple_config_pack_field_couple): "
2012 "source.component_idx bigger than INT_MAX")
2013 YAC_ASSERT(
2014 field_couple->source.field_idx <= INT_MAX,
2015 "ERROR(yac_couple_config_pack_field_couple): "
2016 "source.field_idx bigger than INT_MAX")
2017 YAC_ASSERT(
2018 field_couple->target.component_idx <= INT_MAX,
2019 "ERROR(yac_couple_config_pack_field_couple): "
2020 "target.component_idx bigger than INT_MAX")
2021 YAC_ASSERT(
2022 field_couple->target.field_idx <= INT_MAX,
2023 "ERROR(yac_couple_config_pack_field_couple): "
2024 "target.field_idx bigger than INT_MAX")
2025 YAC_ASSERT(
2026 field_couple->mapping_on_source <= INT_MAX,
2027 "ERROR(yac_couple_config_pack_field_couple): "
2028 "mapping_on_source bigger than INT_MAX")
2029 YAC_ASSERT(
2030 field_couple->coupling_period_operation <= INT_MAX,
2031 "ERROR(yac_couple_config_pack_field_couple): "
2032 "coupling_period_operation bigger than INT_MAX")
2033 YAC_ASSERT(
2034 field_couple->enforce_write_weight_file <= INT_MAX,
2035 "ERROR(yac_couple_config_pack_field_couple): "
2036 "enforce_write_weight_file bigger than INT_MAX")
2037 YAC_ASSERT(
2038 field_couple->weight_file_on_existing <= INT_MAX,
2039 "ERROR(yac_couple_config_pack_field_couple): "
2040 "weight_file_on_existing bigger than INT_MAX")
2041 YAC_ASSERT(
2042 field_couple->num_src_mask_names <= INT_MAX,
2043 "ERROR(yac_couple_config_pack_field_couple): "
2044 "num_src_mask_names bigger than INT_MAX")
2045
2046 int ints[] = {
2047 field_couple->source.component_idx,
2048 field_couple->source.field_idx,
2049 field_couple->source.lag,
2050 field_couple->target.component_idx,
2051 field_couple->target.field_idx,
2052 field_couple->target.lag,
2053 field_couple->mapping_on_source,
2054 (int)(field_couple->coupling_period_operation),
2055 field_couple->enforce_write_weight_file,
2056 (int)(field_couple->weight_file_on_existing),
2057 field_couple->num_src_mask_names,
2058 field_couple->use_raw_exchange};
2059 enum {NUM_INTS = sizeof(ints) / sizeof(ints[0])};
2060
2062 MPI_Pack(
2063 ints, NUM_INTS, MPI_INT, buffer, buffer_size, position, comm), comm);
2064
2066 field_couple->coupling_period, buffer, buffer_size, position, comm);
2068 field_couple->weight_file_name, buffer, buffer_size, position, comm);
2069
2070 double doubles[2] = {
2071 field_couple->scale_factor,
2072 field_couple->scale_summand};
2073
2075 MPI_Pack(doubles, 2, MPI_DOUBLE, buffer, buffer_size, position, comm),
2076 comm);
2077
2079 field_couple->interp_stack, buffer, buffer_size, position, comm);
2080
2081 if (field_couple->num_src_mask_names > 0)
2082 for (size_t i = 0; i < field_couple->num_src_mask_names; ++i)
2084 field_couple->src_mask_names[i], buffer, buffer_size, position, comm);
2085
2087 field_couple->tgt_mask_name, buffer, buffer_size, position, comm);
2088
2090 field_couple->yaxt_exchanger_name, buffer, buffer_size, position, comm);
2091}
2092
2094 void * couple_, void * buffer, int buffer_size, int * position, MPI_Comm comm) {
2095
2096 struct yac_couple_config_couple * couple =
2097 (struct yac_couple_config_couple *)couple_;
2098
2099 YAC_ASSERT(
2100 (couple->component_indices[0] <= INT_MAX) &&
2101 (couple->component_indices[1] <= INT_MAX),
2102 "ERROR(yac_couple_config_pack_couple): "
2103 "component_indices bigger than INT_MAX")
2104
2105 int component_indices[2] = {(int)(couple->component_indices[0]),
2106 (int)(couple->component_indices[1])};
2107
2109 MPI_Pack(
2110 component_indices, 2, MPI_INT, buffer, buffer_size, position, comm),
2111 comm);
2112}
2113
2115 void * config_output_, void * buffer, int buffer_size, int * position,
2116 MPI_Comm comm) {
2117
2118 struct yac_couple_config_config_output * config_output =
2119 (struct yac_couple_config_config_output *)config_output_;
2120
2122 config_output->name, buffer, buffer_size, position, comm);
2123 int filetype_int = (int)config_output->type;
2125 MPI_Pack(
2126 &filetype_int, 1, MPI_INT, buffer, buffer_size, position, comm), comm);
2128 config_output->ref, buffer, buffer_size, position, comm);
2129}
2130
2132 void * buffer, int buffer_size, int * position, MPI_Comm comm) {
2133
2134 int string_len;
2136 MPI_Unpack(
2137 buffer, buffer_size, position, &string_len, 1, MPI_INT, comm), comm);
2138
2139 if (string_len <= 0) return NULL;
2140
2141 char * string = xmalloc(((size_t)string_len + 1) * sizeof(*string));
2143 MPI_Unpack(
2144 buffer, buffer_size, position, string, string_len, MPI_CHAR, comm), comm);
2145 string[string_len] = '\0';
2146 return string;
2147}
2148
2150 void * buffer, int buffer_size, int * position, void * grid_,
2151 MPI_Comm comm) {
2152
2153 struct yac_couple_config_grid * grid =
2154 (struct yac_couple_config_grid *)grid_;
2155
2156 grid->name =
2157 yac_couple_config_unpack_string(buffer, buffer_size, position, comm);
2158 grid->output_filename = NULL;
2159 grid->metadata = NULL;
2160}
2161
2163 void * buffer, int buffer_size, int * position, void * field_,
2164 MPI_Comm comm) {
2165
2166 struct yac_couple_config_field * field =
2167 (struct yac_couple_config_field *)field_;
2168
2169 int grid_idx_int;
2171 MPI_Unpack(
2172 buffer, buffer_size, position, &grid_idx_int, 1, MPI_INT, comm), comm);
2173
2174 YAC_ASSERT(
2175 grid_idx_int >= 0,
2176 "ERROR(yac_couple_config_unpack_field): invalid number of grid_idx_int")
2177
2178 field->grid_idx = (size_t)grid_idx_int;
2179 field->frac_mask_fallback_value = YAC_FRAC_MASK_NO_VALUE;
2180 field->collection_size = SIZE_MAX;
2181 field->name = yac_couple_config_unpack_string(buffer,
2182 buffer_size, position, comm);
2183 field->timestep = NULL;
2184 field->metadata = NULL;
2185}
2186
2188 void * buffer, int buffer_size, int * position, void * component_,
2189 MPI_Comm comm) {
2190
2191 struct yac_couple_config_component * component =
2192 (struct yac_couple_config_component *)component_;
2193
2194 component->name =
2195 yac_couple_config_unpack_string(buffer, buffer_size, position, comm);
2196 component->metadata = NULL;
2197 component->num_fields = 0;
2198 component->fields = NULL;
2199}
2200
2202 void * buffer, int buffer_size, int * position, void * field_couple_,
2203 MPI_Comm comm) {
2204
2205 struct yac_couple_config_field_couple * field_couple =
2206 (struct yac_couple_config_field_couple *)field_couple_;
2207
2208 int ints[12];
2210 MPI_Unpack(
2211 buffer, buffer_size, position, ints, 12, MPI_INT, comm), comm);
2212
2213 YAC_ASSERT(
2214 ints[0] >= 0,
2215 "ERROR(yac_couple_config_unpack_field_couple): "
2216 "invalid source.component_idx")
2217 YAC_ASSERT(
2218 ints[1] >= 0,
2219 "ERROR(yac_couple_config_unpack_field_couple): "
2220 "invalid source.field_idx")
2221 YAC_ASSERT(
2222 ints[3] >= 0,
2223 "ERROR(yac_couple_config_unpack_field_couple): "
2224 "target.component_idx bigger than INT_MAX")
2225 YAC_ASSERT(
2226 ints[4] >= 0,
2227 "ERROR(yac_couple_config_unpack_field_couple): "
2228 "invalid target.field_idx")
2229 YAC_ASSERT(
2230 ints[6] >= 0,
2231 "ERROR(yac_couple_config_unpack_field_couple): "
2232 "invalid mapping_on_source")
2233 YAC_ASSERT(
2234 ints[7] >= 0,
2235 "ERROR(yac_couple_config_unpack_field_couple): "
2236 "invalid coupling_period_operation")
2237 YAC_ASSERT(
2238 ints[8] >= 0,
2239 "ERROR(yac_couple_config_unpack_field_couple): "
2240 "invalid enforce_write_weight_file")
2241 YAC_ASSERT(
2242 ints[9] >= 0,
2243 "ERROR(yac_couple_config_unpack_field_couple): "
2244 "invalid weight_file_on_existing")
2245 YAC_ASSERT(
2246 ints[10] >= 0,
2247 "ERROR(yac_couple_config_unpack_field_couple): "
2248 "invalid num_src_mask_names")
2249 YAC_ASSERT(
2250 (ints[11] == 0) || (ints[11] == 1),
2251 "ERROR(yac_couple_config_unpack_field_couple): "
2252 "invalid use_raw_exchange")
2253
2254 field_couple->source.component_idx = (size_t)(ints[0]);
2255 field_couple->source.field_idx = (size_t)(ints[1]);
2256 field_couple->source.lag = ints[2];
2257 field_couple->target.component_idx = (size_t)(ints[3]);
2258 field_couple->target.field_idx = (size_t)(ints[4]);
2259 field_couple->target.lag = ints[5];
2260 field_couple->mapping_on_source = ints[6];
2261 field_couple->coupling_period_operation =
2262 (enum yac_reduction_type)(ints[7]);
2263 field_couple->enforce_write_weight_file = ints[8];
2264 field_couple->weight_file_on_existing =
2265 (enum yac_weight_file_on_existing)ints[9];
2266 field_couple->num_src_mask_names = (size_t)(ints[10]);
2267 field_couple->use_raw_exchange = (size_t)(ints[11]);
2268
2269 field_couple->coupling_period =
2270 yac_couple_config_unpack_string(buffer, buffer_size, position, comm);
2271 field_couple->weight_file_name =
2272 yac_couple_config_unpack_string(buffer, buffer_size, position, comm);
2273
2274 double doubles[2];
2276 MPI_Unpack(
2277 buffer, buffer_size, position, doubles, 2, MPI_DOUBLE, comm), comm);
2278
2279 field_couple->scale_factor = doubles[0];
2280 field_couple->scale_summand = doubles[1];
2281
2282 field_couple->interp_stack =
2283 yac_interp_stack_config_unpack(buffer, buffer_size, position, comm);
2284
2285 if (field_couple->num_src_mask_names > 0) {
2286 field_couple->src_mask_names =
2287 xmalloc(
2288 field_couple->num_src_mask_names *
2289 sizeof(*(field_couple->src_mask_names)));
2290 for (size_t i = 0; i < field_couple->num_src_mask_names; ++i)
2291 field_couple->src_mask_names[i] =
2293 buffer, buffer_size, position, comm);
2294 } else {
2295 field_couple->src_mask_names = NULL;
2296 }
2297
2298 field_couple->tgt_mask_name =
2300 buffer, buffer_size, position, comm);
2301
2302 field_couple->yaxt_exchanger_name =
2304 buffer, buffer_size, position, comm);
2305}
2306
2308 void * buffer, int buffer_size, int * position, void * couple_,
2309 MPI_Comm comm) {
2310
2311 struct yac_couple_config_couple * couple =
2312 (struct yac_couple_config_couple *)couple_;
2313
2314 int component_indices[2];
2316 MPI_Unpack(
2317 buffer, buffer_size, position, component_indices, 2, MPI_INT, comm),
2318 comm);
2319
2320 YAC_ASSERT(
2321 (component_indices[0] >= 0) && (component_indices[1] >= 0),
2322 "ERROR(yac_couple_config_unpack_couple): invalid component indices")
2323
2324 couple->component_indices[0] = (size_t)(component_indices[0]);
2325 couple->component_indices[1] = (size_t)(component_indices[1]);
2326 couple->num_field_couples = 0;
2327 couple->field_couples = NULL;
2328}
2329
2331 void * buffer, int buffer_size, int * position, void * config_output_,
2332 MPI_Comm comm) {
2333
2334 struct yac_couple_config_config_output * config_output =
2335 (struct yac_couple_config_config_output *)config_output_;
2336
2337 config_output->name =
2338 yac_couple_config_unpack_string(buffer, buffer_size, position, comm);
2339 int filetype_int;
2341 MPI_Unpack(
2342 buffer, buffer_size, position, &filetype_int, 1, MPI_INT, comm),
2343 comm);
2344 config_output->type = (enum yac_text_filetype)filetype_int;
2345 config_output->ref =
2346 yac_couple_config_unpack_string(buffer, buffer_size, position, comm);
2347 config_output->include_definitions = FLAG_UNSET;
2348}
2349
2351 struct yac_couple_config * couple_config,
2352 char const * src_comp_name, char const * src_grid_name, char const * src_field_name,
2353 char const * tgt_comp_name, char const * tgt_grid_name, char const * tgt_field_name,
2354 char const * coupling_period, int time_reduction,
2355 struct yac_interp_stack_config * interp_stack, int src_lag, int tgt_lag,
2356 const char* weight_file_name, int weight_file_on_existing,
2357 int mapping_on_source, double scale_factor, double scale_summand,
2358 size_t num_src_mask_names, char const * const * src_mask_names,
2359 char const * tgt_mask_name, char const * yaxt_exchanger_name,
2360 int use_raw_exchange) {
2361
2362 YAC_ASSERT(src_comp_name && src_comp_name[0] != '\0',
2363 "ERROR(yac_couple_config_def_couple): invalid parameter: src_comp_name");
2364 YAC_ASSERT(src_grid_name && src_grid_name[0] != '\0',
2365 "ERROR(yac_couple_config_def_couple): invalid parameter: src_grid_name");
2366 YAC_ASSERT(src_field_name && src_field_name[0] != '\0',
2367 "ERROR(yac_couple_config_def_couple): invalid parameter: src_field_name");
2368 YAC_ASSERT(tgt_comp_name && tgt_comp_name[0] != '\0',
2369 "ERROR(yac_couple_config_def_couple): invalid parameter: tgt_comp_name");
2370 YAC_ASSERT(tgt_grid_name && tgt_grid_name[0] != '\0',
2371 "ERROR(yac_couple_config_def_couple): invalid parameter: tgt_grid_name");
2372 YAC_ASSERT(tgt_field_name && tgt_field_name[0] != '\0',
2373 "ERROR(yac_couple_config_def_couple): invalid parameter: tgt_field_name");
2374 YAC_ASSERT(coupling_period && coupling_period[0] != '\0',
2375 "ERROR(yac_couple_config_def_couple): invalid parameter: coupling_period");
2376 YAC_ASSERT(
2377 (time_reduction == TIME_NONE) ||
2378 (time_reduction == TIME_ACCUMULATE) ||
2379 (time_reduction == TIME_AVERAGE) ||
2380 (time_reduction == TIME_MINIMUM) ||
2381 (time_reduction == TIME_MAXIMUM),
2382 "ERROR(yac_couple_config_def_couple): invalid parameter: time_reduction");
2383 YAC_ASSERT_F(isnormal(scale_factor),
2384 "ERROR(yac_couple_config_def_couple): \"%lf\" is not a valid scale factor",
2385 scale_factor);
2386 YAC_ASSERT_F(isnormal(scale_summand) || (scale_summand == 0.0),
2387 "ERROR(yac_couple_config_def_couple): \"%lf\" is not a valid scale summand",
2388 scale_summand);
2389 YAC_ASSERT(
2390 (weight_file_on_existing == YAC_WEIGHT_FILE_ERROR) ||
2391 (weight_file_on_existing == YAC_WEIGHT_FILE_KEEP) ||
2392 (weight_file_on_existing == YAC_WEIGHT_FILE_OVERWRITE),
2393 "ERROR(yac_couple_config_def_couple): invalid parameter: weight_file_on_existing");
2394
2395 // get component indices
2396 size_t src_comp_idx =
2397 yac_couple_config_add_component_(couple_config, src_comp_name);
2398 size_t tgt_comp_idx =
2399 yac_couple_config_add_component_(couple_config, tgt_comp_name);
2400 size_t src_grid_idx =
2401 yac_couple_config_add_grid_(couple_config, src_grid_name);
2402 size_t tgt_grid_idx =
2403 yac_couple_config_add_grid_(couple_config, tgt_grid_name);
2404
2405 // check if couple exists
2406 size_t component_indices[2];
2407 if(src_comp_idx < tgt_comp_idx){
2408 component_indices[0] = src_comp_idx;
2409 component_indices[1] = tgt_comp_idx;
2410 }else{
2411 component_indices[0] = tgt_comp_idx;
2412 component_indices[1] = src_comp_idx;
2413 }
2414 struct yac_couple_config_couple * couple = NULL;
2415 for(size_t i = 0; (i < couple_config->num_couples) && !couple; ++i)
2416 if(couple_config->couples[i].component_indices[0] == component_indices[0] &&
2417 couple_config->couples[i].component_indices[1] == component_indices[1])
2418 couple = &couple_config->couples[i];
2419
2420 // create if couple does not exists
2421 if(!couple){
2422 couple_config->couples =
2423 xrealloc(
2424 couple_config->couples,
2425 (couple_config->num_couples + 1) * sizeof(*couple_config->couples));
2426 couple = &couple_config->couples[couple_config->num_couples];
2427 couple_config->num_couples++;
2428 couple->component_indices[0] = component_indices[0];
2429 couple->component_indices[1] = component_indices[1];
2430 couple->num_field_couples = 0;
2431 couple->field_couples = NULL;
2432 }
2433
2434 // get field indices
2435 size_t src_field_idx =
2437 couple_config, src_comp_idx, src_grid_idx,
2438 src_field_name, NULL, SIZE_MAX);
2439 size_t tgt_field_idx =
2441 couple_config, tgt_comp_idx, tgt_grid_idx,
2442 tgt_field_name, NULL, SIZE_MAX);
2443
2444 struct yac_couple_config_field_couple field_couple;
2445 field_couple.source.component_idx = src_comp_idx;
2446 field_couple.source.field_idx = src_field_idx;
2447 field_couple.source.lag = src_lag;
2448 field_couple.target.component_idx = tgt_comp_idx;
2449 field_couple.target.field_idx = tgt_field_idx;
2450 field_couple.target.lag = tgt_lag;
2451 field_couple.coupling_period = strdup(coupling_period);
2452 field_couple.coupling_period_operation =
2453 (enum yac_reduction_type)time_reduction;
2455 field_couple.mapping_on_source = mapping_on_source;
2456 field_couple.weight_file_name =
2458 field_couple.scale_factor = scale_factor;
2459 field_couple.scale_summand = scale_summand;
2460 field_couple.enforce_write_weight_file = weight_file_name != NULL;
2461 field_couple.weight_file_on_existing =
2464 if (num_src_mask_names > 0) {
2465 field_couple.src_mask_names =
2467 for (size_t i = 0; i < num_src_mask_names; ++i)
2468 field_couple.src_mask_names[i] = strdup(src_mask_names[i]);
2469 } else {
2470 field_couple.src_mask_names = NULL;
2471 }
2472 field_couple.tgt_mask_name = string_dup(tgt_mask_name);
2474 field_couple.use_raw_exchange = use_raw_exchange != 0;
2475
2476 // check if field_couple exists
2477 int found_flag = 0;
2478 for(size_t i = 0; (i < couple->num_field_couples) && !found_flag; ++i) {
2480 couple->field_couples + i, &field_couple)) {
2482 couple->field_couples + i, &field_couple, MPI_COMM_SELF);
2484 found_flag = 1;
2485 }
2486 }
2487
2488 if (!found_flag) {
2489 couple->field_couples = xrealloc(couple->field_couples,
2490 (couple->num_field_couples + 1) * sizeof(*couple->field_couples));
2491 couple->field_couples[couple->num_field_couples] = field_couple;
2492 couple->num_field_couples++;
2493 }
2494}
2495
2497 char const * type_datetime, struct _datetime ** datetime, MPI_Comm comm) {
2498
2499 // convert datetime to string
2500 char datetime_buffer[MAX_DATETIME_STR_LEN];
2501 char * str_datetime = datetimeToString(*datetime, datetime_buffer);
2502
2503 // copy from static to dynamic memory
2504 if (str_datetime != NULL) str_datetime = strdup(str_datetime);
2505
2506 // delete old datetime
2507 deallocateDateTime(*datetime);
2508
2509 // synchronize datetime string across processes
2510 couple_config_sync_string(type_datetime, &str_datetime, comm);
2511
2512 // convert datetime string to _datetime struct
2513 *datetime = newDateTime(str_datetime);
2514
2515 free(str_datetime);
2516}
2517
2519 struct yac_couple_config * couple_config, MPI_Comm comm) {
2520
2523 "start_datetime", &(couple_config->start_datetime), comm);
2525 "end_datetime", &(couple_config->end_datetime), comm);
2526}
2527
2571
2572static void merge_grids(
2573 struct yac_couple_config * couple_config, MPI_Comm comm) {
2574
2575 size_t* old_to_new_idx;
2576 void * p_grids = couple_config->grids;
2578 &couple_config->num_grids, &p_grids,
2579 sizeof(couple_config->grids[0]),
2580 comm, &dist_merge_vtable_grid, &old_to_new_idx);
2581 couple_config->grids = p_grids;
2582
2583 // set new grid_idx in fields
2584 for(size_t comp_idx = 0; comp_idx < couple_config->num_components;
2585 ++comp_idx) {
2586 struct yac_couple_config_component * component =
2587 couple_config->components + comp_idx;
2588 for(size_t field_idx = 0; field_idx < component->num_fields; ++field_idx)
2589 component->fields[field_idx].grid_idx =
2590 old_to_new_idx[component->fields[field_idx].grid_idx];
2591 }
2592
2593 free(old_to_new_idx);
2594}
2595
2596static void merge_fields(
2597 struct yac_couple_config * couple_config, size_t comp_idx, MPI_Comm comm) {
2598
2599 struct yac_couple_config_component * component =
2600 couple_config->components + comp_idx;
2601
2602 size_t* old_to_new_idx;
2603 void * p_fields = component->fields;
2605 &component->num_fields, &p_fields,
2606 sizeof(component->fields[0]),
2607 comm, &dist_merge_vtable_field, &old_to_new_idx);
2608 component->fields = p_fields;
2609
2610 // set new field_idx in all field_couples
2611 for(size_t couple_idx = 0; couple_idx < couple_config->num_couples;
2612 ++couple_idx) {
2613 struct yac_couple_config_couple * couple =
2614 couple_config->couples + couple_idx;
2615 for(size_t field_couple_idx = 0;
2616 field_couple_idx < couple->num_field_couples; ++field_couple_idx){
2617 struct yac_couple_config_field_couple * field_couple =
2618 couple->field_couples + field_couple_idx;
2619 if(field_couple->source.component_idx == comp_idx)
2620 field_couple->source.field_idx =
2621 old_to_new_idx[field_couple->source.field_idx];
2622 if(field_couple->target.component_idx == comp_idx)
2623 field_couple->target.field_idx =
2624 old_to_new_idx[field_couple->target.field_idx];
2625 }
2626 }
2627
2628 free(old_to_new_idx);
2629}
2630
2632 struct yac_couple_config * couple_config, MPI_Comm comm) {
2633
2634 // distribute and merge basic component information while keeping the
2635 // individual fields
2636 size_t* old_to_new_idx;
2637 void * p_components = couple_config->components;
2639 &couple_config->num_components, &p_components,
2640 sizeof(couple_config->components[0]),
2641 comm, &dist_merge_vtable_component, &old_to_new_idx);
2642 couple_config->components = p_components;
2643
2644 // set new component_idx in couples
2645 for(size_t couple_idx = 0; couple_idx < couple_config->num_couples;
2646 ++couple_idx) {
2647 struct yac_couple_config_couple * couple =
2648 couple_config->couples + couple_idx;
2649 couple->component_indices[0] = old_to_new_idx[couple->component_indices[0]];
2650 couple->component_indices[1] = old_to_new_idx[couple->component_indices[1]];
2651 if (couple->component_indices[1] < couple->component_indices[0]) {
2652 size_t temp_component_index = couple->component_indices[0];
2653 couple->component_indices[0] = couple->component_indices[1];
2654 couple->component_indices[1] = temp_component_index;
2655 }
2656 for(size_t field_couple_idx = 0;
2657 field_couple_idx < couple->num_field_couples; ++field_couple_idx) {
2658 couple->field_couples[field_couple_idx].source.component_idx =
2659 old_to_new_idx[
2660 couple->field_couples[field_couple_idx].source.component_idx];
2661 couple->field_couples[field_couple_idx].target.component_idx =
2662 old_to_new_idx[
2663 couple->field_couples[field_couple_idx].target.component_idx];
2664 }
2665 }
2666 free(old_to_new_idx);
2667
2668 // merge the fields of each component
2669 for (size_t comp_idx = 0; comp_idx < couple_config->num_components; ++comp_idx)
2670 merge_fields(couple_config, comp_idx, comm);
2671}
2672
2674 size_t * num_field_couples,
2675 struct yac_couple_config_field_couple ** field_couples, MPI_Comm comm) {
2676
2677 void * p_field_couples = *field_couples;
2679 num_field_couples, &p_field_couples, sizeof(**field_couples),
2680 comm, &dist_merge_vtable_field_couple, NULL);
2681 *field_couples = p_field_couples;
2682}
2683
2684static void merge_couples(
2685 struct yac_couple_config * couple_config, MPI_Comm comm) {
2686
2687 // distribute and merge basic couple information while keeping the
2688 // individual field couples
2689 void * p_couples = couple_config->couples;
2691 &couple_config->num_couples, &p_couples,
2692 sizeof(couple_config->couples[0]),
2693 comm, &dist_merge_vtable_couple, NULL);
2694 couple_config->couples = p_couples;
2695}
2696
2698 struct yac_couple_config * couple_config, MPI_Comm comm) {
2699
2700 // distribute and merge basic couple information while keeping the
2701 // individual field couples
2702 void * p_config_outputs = couple_config->config_outputs;
2704 &couple_config->num_config_outputs, &p_config_outputs,
2705 sizeof(couple_config->config_outputs[0]),
2706 comm, &dist_merge_vtable_config_output, NULL);
2707 couple_config->config_outputs = p_config_outputs;
2708}
2709
2711 struct yac_couple_config * couple_config, MPI_Comm comm,
2712 char const * output_ref){
2713
2714 // sync time stuff
2715 couple_config_sync_time(couple_config, comm);
2716
2717 merge_config_output(couple_config, comm);
2718 merge_grids(couple_config, comm);
2719 merge_components(couple_config, comm);
2720 merge_couples(couple_config, comm);
2721
2723 "missing_definition_is_fatal",
2724 &(couple_config->missing_definition_is_fatal), comm);
2725
2726 struct yac_couple_config_config_output * config_output = NULL;
2727 if (output_ref != NULL)
2728 for (size_t i = 0; (i < couple_config->num_config_outputs) &&
2729 (config_output == NULL); ++i)
2730 if (!strcmp(output_ref, couple_config->config_outputs[i].ref))
2731 config_output = couple_config->config_outputs + i;
2732
2733 if (config_output != NULL) {
2734
2735 int rank;
2736 MPI_Comm_rank(comm, &rank);
2737
2738 // rank 0 writes the coupling configuration to file
2739 if (rank == 0) {
2740
2741 FILE * config_file = fopen(config_output->name, "w");
2742
2744 config_file != NULL,
2745 "ERROR(yac_couple_config_sync): "
2746 "failed to create coupling configuration file \"%s\"",
2747 config_output->name);
2748
2750 (config_output->type == YAC_TEXT_FILETYPE_YAML) ||
2751 (config_output->type == YAC_TEXT_FILETYPE_JSON),
2752 "ERROR(yac_couple_config_sync): "
2753 "invalid coupling configuration filetype (type = %d)",
2754 config_output->type);
2755
2756 int emit_flags;
2757 switch(config_output->type) {
2758 default:
2760 emit_flags = YAC_YAML_EMITTER_DEFAULT;
2761 break;
2763 emit_flags = YAC_YAML_EMITTER_JSON;
2764 break;
2765 }
2766
2767 enum flag_value include_definitions = FLAG_FALSE; // default value
2768 if (config_output->include_definitions != FLAG_UNSET)
2770 char * str_couple_config =
2772 couple_config, emit_flags, (int)include_definitions);
2773
2774 fputs(str_couple_config, config_file);
2775 free(str_couple_config);
2776 fclose(config_file);
2777 }
2778 yac_mpi_call(MPI_Barrier(comm), comm);
2779 }
2780}
2781
2783 struct yac_couple_config * couple_config,
2784 char const * filename, enum yac_text_filetype filetype, char const * ref,
2785 int include_definitions) {
2786
2787 YAC_ASSERT(
2788 filename != NULL,
2789 "ERROR(yac_couple_config_set_config_output_filename): filename is NULL");
2790
2792 (filetype == YAC_TEXT_FILETYPE_YAML) ||
2793 (filetype == YAC_TEXT_FILETYPE_JSON),
2794 "ERROR(yac_couple_config_set_config_output_filename): "
2795 "invalid output configuration filetype (type = %d)",
2796 (int)filetype);
2797
2798 YAC_ASSERT(
2799 ref != NULL,
2800 "ERROR(yac_couple_config_set_config_output_filename): ref is NULL");
2801
2802 // check whether there already exists a config output with the same reference
2803 for (size_t i = 0; i < couple_config->num_config_outputs; ++i) {
2804 if (!strcmp(couple_config->config_outputs[i].ref, ref)) {
2806 !strcmp(couple_config->config_outputs[i].name, filename) &&
2807 couple_config->config_outputs[i].type == filetype,
2808 "ERROR(yac_couple_config_set_config_output_filename): "
2809 "an filename has already been set for reference "
2810 "(ref \"%s\" curr filename \"%s\" filetype %d; "
2811 "new filename \"%s\" filetype %d",
2812 ref, couple_config->config_outputs[i].name,
2813 couple_config->config_outputs[i].type, filename, filetype);
2814 return;
2815 }
2816 }
2817
2818 couple_config->config_outputs =
2819 xrealloc(
2820 couple_config->config_outputs,
2821 (couple_config->num_config_outputs + 1) *
2822 sizeof(*(couple_config->config_outputs)));
2823
2824 couple_config->config_outputs[
2825 couple_config->num_config_outputs].name = strdup(filename);
2826 couple_config->config_outputs[
2827 couple_config->num_config_outputs].type = filetype;
2828 couple_config->config_outputs[
2829 couple_config->num_config_outputs].ref = strdup(ref);
2830 couple_config->config_outputs[
2831 couple_config->num_config_outputs].include_definitions =
2832 (enum flag_value)(include_definitions != 0);
2833 couple_config->num_config_outputs++;
2834}
2835
2837 struct yac_couple_config * couple_config,
2838 char const * tgt_component_name, char const * tgt_grid_name,
2839 char const * tgt_field_name, char const ** src_component_name,
2840 char const ** src_grid_name, char const ** src_field_name) {
2841
2842 size_t tgt_comp_idx =
2843 yac_couple_config_get_component_idx(couple_config, tgt_component_name);
2844 size_t tgt_grid_idx =
2845 yac_couple_config_get_grid_idx(couple_config, tgt_grid_name);
2846 size_t tgt_field_idx =
2848 couple_config, tgt_comp_idx, tgt_grid_idx, tgt_field_name);
2849
2850 struct yac_couple_config_field_couple * field_couple = NULL;
2851 for (size_t couple_idx = 0; couple_idx < couple_config->num_couples;
2852 ++couple_idx) {
2853
2854 struct yac_couple_config_couple * couple =
2855 couple_config->couples + couple_idx;
2856
2857 if ((couple->component_indices[0] != tgt_comp_idx) &&
2858 (couple->component_indices[1] != tgt_comp_idx))
2859 continue;
2860
2861 for (size_t temp_field_couple_idx = 0;
2862 temp_field_couple_idx < couple->num_field_couples;
2863 ++temp_field_couple_idx) {
2864
2865 struct yac_couple_config_field_couple * temp_field_couple =
2866 couple->field_couples + temp_field_couple_idx;
2867
2868 if ((temp_field_couple->target.component_idx == tgt_comp_idx) &&
2869 (temp_field_couple->target.field_idx == tgt_field_idx)) {
2870
2872 field_couple == NULL,
2873 "ERROR(yac_couple_config_get_field_source): "
2874 "multiple couples with the same target field is not supported by "
2875 "this routine (target component: \"%s\" target grid: \"%s\""
2876 "target field: \"%s\")", tgt_component_name, tgt_grid_name,
2877 tgt_field_name);
2878
2879 field_couple = temp_field_couple;
2880 }
2881 }
2882 }
2883
2885 field_couple != NULL,
2886 "ERROR(yac_couple_config_get_field_source): "
2887 "provided field is not defined as a target in any coupling "
2888 "(target component: \"%s\" target grid: \"%s\" target field: \"%s\")",
2889 tgt_component_name, tgt_grid_name, tgt_field_name);
2890
2891 struct yac_couple_config_component * src_component =
2892 couple_config->components + field_couple->source.component_idx;
2893 struct yac_couple_config_field * src_field =
2894 src_component->fields + field_couple->source.field_idx;
2895 struct yac_couple_config_grid * src_grid =
2896 couple_config->grids + src_field->grid_idx;
2897
2898 *src_component_name = src_component->name;
2899 *src_grid_name = src_grid->name;
2900 *src_field_name = src_field->name;
2901}
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:73
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)
void yac_couple_config_get_field_source(struct yac_couple_config *couple_config, char const *tgt_component_name, char const *tgt_grid_name, char const *tgt_field_name, char const **src_component_name, char const **src_grid_name, char const **src_field_name)
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_)
char const * yac_couple_config_get_yaxt_exchanger_name(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
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 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)
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 weight_file_on_existing, int mapping_on_source, double scale_factor, double scale_summand, size_t num_src_mask_names, char const *const *src_mask_names, char const *tgt_mask_name, char const *yaxt_exchanger_name, int use_raw_exchange)
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)
enum yac_weight_file_on_existing yac_couple_config_get_weight_file_on_existing(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 char * string_dup(char const *string)
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
int yac_couple_config_get_use_raw_exchange(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
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_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)
yac_weight_file_on_existing
@ YAC_WEIGHT_FILE_KEEP
keep existing weight file
@ YAC_WEIGHT_FILE_OVERWRITE
overwrite existing weight file
@ YAC_WEIGHT_FILE_ERROR
error when weight file existis already
double const YAC_FRAC_MASK_NO_VALUE
#define YAC_FRAC_MASK_VALUE_IS_SET(value)
#define YAC_FRAC_MASK_VALUE_IS_VALID(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::@61 source
enum yac_weight_file_on_existing weight_file_on_existing
struct yac_interp_stack_config * interp_stack
enum yac_reduction_type coupling_period_operation
struct yac_couple_config_field_couple::@61 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:147
size_t num_grids
Definition yac.c:145
static size_t num_components
Definition yac.c:148
int const YAC_EXCHANGE_TYPE_SOURCE
Definition yac.c:34
int const YAC_EXCHANGE_TYPE_NONE
Definition yac.c:33
int const YAC_EXCHANGE_TYPE_TARGET
Definition yac.c:35
void yac_cdef_calendar(int calendar)
Definition yac.c:664
int yac_cget_calendar()
Definition yac.c:681
int const YAC_CALENDAR_NOT_SET
Definition yac.c:62
#define YAC_MAX_CHARLEN
Definition yac.h:95
#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)