YAC 3.13.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 <mpi.h>
15
16#include "couple_config.h"
17#include "yac_mpi_common.h"
18#include "yac.h"
19#include "mtime_calendar.h"
20#include "utils_common.h"
21#include "config_yaml.h"
22#include "dist_merge.h"
23#include "mtime_datetime.h"
26#include "yac_mpi_internal.h"
28
34
36 char const * name; //< name of the file
37 enum yac_text_filetype type; //< type of the file
38 char const * ref; //< name of the synchronization location
39 //< at which this file is to be written
40 //< out
41 enum flag_value include_definitions; //< include user definitions (components,
42 //< grids, and fields)
43};
44
46 char const * name;
47 char* metadata;
48 char const * output_filename;
49};
50
52 char const * name;
53 size_t grid_idx;
54 char const * timestep;
55 char * metadata;
58};
59
61
63 size_t num_fields;
64
65 char const * name;
66 char * metadata;
67};
68
100
108
110
111 struct _datetime * start_datetime;
112 struct _datetime * end_datetime;
113
116
118 size_t num_grids;
119
122
125
126 // this flag indicates whether YAC aborts if for a defined couple at least
127 // one associated field was not defined by the user
129};
130
132
133 struct yac_couple_config * couple_config =
134 xmalloc(1 * sizeof(*couple_config));
135
136 couple_config->start_datetime = NULL;
137 couple_config->end_datetime = NULL;
138
139 couple_config->config_outputs = NULL;
140 couple_config->num_config_outputs = 0;
141
142 couple_config->grids = NULL;
143 couple_config->num_grids = 0;
144
145 couple_config->components = NULL;
146 couple_config->num_components = 0;
147
148 couple_config->couples = NULL;
149 couple_config->num_couples = 0;
150
152
153 return couple_config;
154}
155
156static char * string_dup(char const * string) {
157 return (string != NULL)?strdup(string):NULL;
158}
159
160static void yac_couple_config_field_free(void * field_){
161 struct yac_couple_config_field * field = field_;
162 free((void*)field->name);
163 free((void*)field->timestep);
164 free(field->metadata);
165}
166
167static void yac_couple_config_component_free(void * component_) {
168
169 struct yac_couple_config_component * component = component_;
170
171 for (size_t i = 0; i < component->num_fields; ++i)
172 yac_couple_config_field_free(component->fields + i);
173 free(component->fields);
174 free((void*)(component->name));
175 free(component->metadata);
176}
177
178static void yac_couple_config_field_couple_free(void * field_couple_) {
179
180 struct yac_couple_config_field_couple * field_couple = field_couple_;
182 free((void*)field_couple->coupling_period);
183 free((void*)field_couple->weight_file_name);
184 for (size_t i = 0; i < field_couple->num_src_mask_names; ++i)
185 free((void*)field_couple->src_mask_names[i]);
186 free(field_couple->src_mask_names);
187 free(field_couple->tgt_mask_name);
188 free(field_couple->yaxt_exchanger_name);
190}
191
192static void yac_couple_config_couple_free(void * couple_) {
193
194 struct yac_couple_config_couple * couple = couple_;
195 for (size_t i = 0; i < couple->num_field_couples; ++i)
197 free(couple->field_couples);
198 couple->field_couples = NULL;
199 couple->num_field_couples = 0;
200}
201
202static void yac_couple_config_grid_free(void * grid_) {
203
204 struct yac_couple_config_grid * grid = grid_;
205
206 free((void*)grid->name);
207 free((void*)grid->output_filename);
208 free(grid->metadata);
209}
210
212 void * config_output_) {
213
214 struct yac_couple_config_config_output * config_output = config_output_;
215
216 free((void*)config_output->name);
217 free((void*)config_output->ref);
218}
219
220static int yac_couple_config_grid_compare(void const * a, void const * b) {
221 YAC_ASSERT(((struct yac_couple_config_grid const *)a)->name != NULL &&
222 ((struct yac_couple_config_grid const *)b)->name != NULL,
223 "ERROR(yac_couple_config_grid_compare): "
224 "invalid name (NULL is not allowed)");
225 return strcmp(((struct yac_couple_config_grid const *)a)->name,
226 ((struct yac_couple_config_grid const *)b)->name);
227}
228
229static int yac_couple_config_field_compare(void const * a_, void const * b_) {
230 struct yac_couple_config_field const * a = a_;
231 struct yac_couple_config_field const * b = b_;
232 int ret = (a->grid_idx > b->grid_idx) - (a->grid_idx < b->grid_idx);
233 if (ret) return ret;
235 a->name != NULL && b->name != NULL,
236 "ERROR(yac_couple_config_field_compare): "
237 "invalid name (NULL is not allowed)");
238 return strcmp(a->name, b->name);
239}
240
242 void const * a_, void const * b_) {
243 struct yac_couple_config_component const * a = a_;
244 struct yac_couple_config_component const * b = b_;
245 YAC_ASSERT(a->name != NULL && b->name != NULL,
246 "ERROR(yac_couple_config_component_compare): "
247 "invalid name (NULL is not allowed)");
248 return strcmp(a->name, b->name);
249}
250
252 void const * a_, void const * b_) {
253 struct yac_couple_config_field_couple const * a = a_;
254 struct yac_couple_config_field_couple const * b = b_;
255 int ret;
256 ret = (a->source.component_idx > b->source.component_idx) -
258 if (ret) return ret;
259 ret = (a->target.component_idx > b->target.component_idx) -
261 if (ret) return ret;
262 ret = (a->source.field_idx > b->source.field_idx) -
264 if (ret) return ret;
265 return (a->target.field_idx > b->target.field_idx) -
267}
268
270 void const * a_, void const * b_) {
271 struct yac_couple_config_couple const * a = a_;
272 struct yac_couple_config_couple const * b = b_;
273 int ret;
274 ret = (a->component_indices[0] > b->component_indices[0]) -
275 (a->component_indices[0] < b->component_indices[0]);
276 if (ret) return ret;
277 return (a->component_indices[1] > b->component_indices[1]) -
278 (a->component_indices[1] < b->component_indices[1]);
279}
280
282 void const * a, void const * b) {
284 ((struct yac_couple_config_config_output const *)a)->ref != NULL &&
285 ((struct yac_couple_config_config_output const *)b)->ref != NULL,
286 "ERROR(yac_couple_config_config_output_compare): "
287 "invalid ref (NULL is not allowed)");
288 return strcmp(((struct yac_couple_config_config_output const *)a)->ref,
289 ((struct yac_couple_config_config_output const *)b)->ref);
290}
291
293 char const * string_name, char ** string, MPI_Comm comm) {
294
295 int rank;
296 MPI_Comm_rank(comm, &rank);
297 struct {
298 int len;
299 int rank;
300 } data_pair;
301 size_t len = (*string != NULL)?(strlen(*string) + 1):0;
303 len <= INT_MAX,
304 "ERROR(couple_config_sync_string): \"%s\" too long", string_name);
305 data_pair.len = (int)len;
306 data_pair.rank = rank;
307
308 // determine the broadcaster
310 MPI_Allreduce(
311 MPI_IN_PLACE, &data_pair, 1, MPI_2INT, MPI_MAXLOC, comm), comm);
312 if (data_pair.len == 0) return;
313
314 // broadcast string
315 char const * string_bak = NULL;
316 if (data_pair.rank != rank) {
317 string_bak = *string;
318 *string = xmalloc((size_t)data_pair.len * sizeof(**string));
319 }
321 MPI_Bcast(*string, data_pair.len, MPI_CHAR, data_pair.rank, comm), comm);
322
323 // check for consistency
324 if (data_pair.rank != rank) {
326 (string_bak == NULL) ||
327 !strcmp(string_bak, *string),
328 "ERROR(couple_config_sync_string): inconsistent \"%s\" definition "
329 "(\"%s\" != \"%s\")", string_name, string_bak, *string);
330 free((void*)string_bak);
331 }
332}
333
335 char const * flag_value_name, enum flag_value * flag, MPI_Comm comm) {
336
337 int int_flag = (*flag == FLAG_UNSET)?INT_MAX:((int)*flag);
338
339 // broadcast flag value
341 MPI_Allreduce(
342 MPI_IN_PLACE, &int_flag, 1, MPI_INT, MPI_MIN, comm), comm);
343
344 // if no process has defined a flag value
345 if (int_flag == INT_MAX) return;
346
347 // check for consistency
349 (*flag == FLAG_UNSET) || ((int)(*flag) == int_flag),
350 "ERROR(couple_config_sync_flag_value): inconsistent \"%s\"-flag definition "
351 "(%s != %s)", flag_value_name, ((int_flag == FLAG_TRUE)?"TRUE":"FALSE"),
352 ((*flag == FLAG_TRUE)?"TRUE":"FALSE"));
353
354 // update flag
355 *flag = (enum flag_value)int_flag;
356}
357
358static void couple_config_sync_calendar(MPI_Comm comm) {
359
360 int calendar = (int)getCalendarType();
361 if (calendar == CALENDAR_NOT_SET) calendar = INT_MAX;
362
363 // broadcast calendar
365 MPI_Allreduce(
366 MPI_IN_PLACE, &calendar, 1, MPI_INT, MPI_MIN, comm), comm);
367
368 // if no process has defined a calendar
369 if (calendar == INT_MAX) return;
370
371 // set calendar (if local process has already defined a calendar,
372 // the definition is checked for consistency)
373 yac_cdef_calendar(calendar);
374}
375
377 void * a_, void * b_, MPI_Comm comm) {
378
379 struct yac_couple_config_component * a = a_;
380 struct yac_couple_config_component * b = b_;
381
382 if (b) {
383 a->num_fields = b->num_fields;
384 a->fields = b->fields;
385 b->num_fields = 0;
386 b->fields = NULL;
387 a->metadata = b->metadata;
388 b->metadata = NULL;
389 }
390
392 "component metadata", (char **)&(a->metadata), comm);
393}
394
396 void * a_, void * b_, MPI_Comm comm) {
397
398 struct yac_couple_config_grid * a = a_;
399 struct yac_couple_config_grid * b = b_;
400
401 if (b!= NULL) {
403 b->output_filename = NULL;
404 a->metadata = b->metadata;
405 b->metadata = NULL;
406 }
407
409 "grid output_filename", (char **)&(a->output_filename), comm);
410 couple_config_sync_string("grid metadata", (char **)&(a->metadata), comm);
411}
412
414 void * a_, void * b_, MPI_Comm comm) {
415
416 struct yac_couple_config_field * a = a_;
417 struct yac_couple_config_field * b = b_;
418
419 enum {
420 TIMESTEP_IDX,
421 METADATA_IDX,
422 FRAC_MASK_IDX,
423 COLLECTION_SIZE_IDX,
424 DATA_PAIR_COUNT
425 };
426
427 int rank;
428 MPI_Comm_rank(comm, &rank);
429 struct {
430 int len;
431 int rank;
432 } data_pairs[DATA_PAIR_COUNT];
433 size_t timestep_len =
434 ((b != NULL) && (b->timestep != NULL))?(strlen(b->timestep) + 1):0;
435 size_t metadata_len =
436 ((b != NULL) && (b->metadata != NULL))?(strlen(b->metadata) + 1):0;
438 timestep_len <= INT_MAX,
439 "ERROR(yac_couple_config_field_merge): timestep string too long");
441 metadata_len <= INT_MAX,
442 "ERROR(yac_couple_config_field_merge): metadata string too long");
444 (b == NULL) || (b->collection_size <= INT_MAX) ||
445 (b->collection_size == SIZE_MAX),
446 "ERROR(yac_couple_config_field_merge): invalid collection size \"%zu\"",
447 b->collection_size);
448 data_pairs[TIMESTEP_IDX].len = (int)timestep_len;
449 data_pairs[TIMESTEP_IDX].rank = rank;
450 data_pairs[METADATA_IDX].len = (int)metadata_len;
451 data_pairs[METADATA_IDX].rank = rank;
452 data_pairs[FRAC_MASK_IDX].len =
454 data_pairs[FRAC_MASK_IDX].rank = rank;
455 data_pairs[COLLECTION_SIZE_IDX].len =
456 ((b == NULL) || (b->collection_size == SIZE_MAX))?
457 -1:(int)b->collection_size;
458 data_pairs[COLLECTION_SIZE_IDX].rank = rank;
459
460 // determine the broadcaster
462 MPI_Allreduce(
463 MPI_IN_PLACE, data_pairs, DATA_PAIR_COUNT, MPI_2INT,
464 MPI_MAXLOC, comm), comm);
465
466 // if at least one process has a valid timestep
467 if (data_pairs[TIMESTEP_IDX].len > 0) {
468
469 // broadcast timestep
470 char * timestep_buffer = xmalloc((size_t)data_pairs[TIMESTEP_IDX].len);
471 if (data_pairs[TIMESTEP_IDX].rank == rank)
472 strcpy(timestep_buffer, b->timestep);
474 MPI_Bcast(
475 timestep_buffer, data_pairs[TIMESTEP_IDX].len, MPI_CHAR,
476 data_pairs[TIMESTEP_IDX].rank, comm), comm);
477
478 // check for consistency
480 (b == NULL) || (b->timestep == NULL) ||
481 !strcmp(b->timestep, timestep_buffer),
482 "ERROR(yac_couple_config_field_merge): "
483 "inconsistent timestep definition (\"%s\" != \"%s\")",
484 b->timestep, timestep_buffer);
485
486 // update timestep
487 free((void*)(a->timestep));
488 a->timestep = timestep_buffer;
489 }
490
491 // if at least one process has a valid metadata
492 if (data_pairs[METADATA_IDX].len > 0) {
493
494 // broadcast metadata
495 char * metadata_buffer = xmalloc((size_t)data_pairs[METADATA_IDX].len);
496 if (data_pairs[METADATA_IDX].rank == rank)
497 strcpy(metadata_buffer, b->metadata);
499 MPI_Bcast(
500 metadata_buffer, data_pairs[METADATA_IDX].len, MPI_CHAR,
501 data_pairs[METADATA_IDX].rank, comm), comm);
502
503 // check for consistency
505 (b == NULL) || (b->metadata == NULL) ||
506 !strcmp(b->metadata, metadata_buffer),
507 "ERROR(yac_couple_config_field_merge): "
508 "inconsistent metadata definition (\"%s\" != \"%s\")",
509 b->metadata, metadata_buffer);
510
511 // update metadata
512 free(a->metadata);
513 a->metadata = metadata_buffer;
514 }
515
516 // if at least one process has a valid fractional mask fallback value
517 if (data_pairs[FRAC_MASK_IDX].len != 0) {
518
519 // broadcast fractional mask fallback value
520 double frac_mask_fallback_value;
521 if (data_pairs[FRAC_MASK_IDX].rank == rank)
522 frac_mask_fallback_value = b->frac_mask_fallback_value;
524 MPI_Bcast(
525 &frac_mask_fallback_value, 1, MPI_DOUBLE,
526 data_pairs[FRAC_MASK_IDX].rank, comm), comm);
527
528 // check for consistency
529 // (use memcmp for comparison, because it can be nan)
531 (b == NULL) ||
533 !memcmp(
534 &b->frac_mask_fallback_value, &frac_mask_fallback_value,
535 sizeof(frac_mask_fallback_value)),
536 "ERROR(yac_couple_config_field_merge): "
537 "inconsistent fractional mask fallback value definition "
538 "(%lf != %lf)",
539 b->frac_mask_fallback_value, frac_mask_fallback_value);
540
541 // update fractional mask fallback value
542 a->frac_mask_fallback_value = frac_mask_fallback_value;
543 }
544
545
546 // if at least one process has a valid collection size
547 if (data_pairs[COLLECTION_SIZE_IDX].len > -1) {
548
549 // check for consistency
551 (b == NULL) || (b->collection_size == SIZE_MAX) ||
552 (b->collection_size == (size_t)(data_pairs[COLLECTION_SIZE_IDX].len)),
553 "ERROR(yac_couple_config_field_merge): "
554 "inconsistent collection size definition (\"%zu\" != \"%d\")",
555 b->collection_size, data_pairs[COLLECTION_SIZE_IDX].len);
556
557 // update collection size
558 a->collection_size = (size_t)(data_pairs[COLLECTION_SIZE_IDX].len);
559 }
560}
561
563 void * a_, void * b_, MPI_Comm comm) {
564
565 UNUSED(comm);
566
567 if (b_ == NULL) return;
568
569 struct yac_couple_config_field_couple * a = a_;
570 struct yac_couple_config_field_couple * b = b_;
571
573 (a->source.lag == b->source.lag),
574 "ERROR(yac_couple_config_field_couple_merge): "
575 "inconsistent source lag (%d != %d)", a->source.lag, b->source.lag)
577 (a->target.lag == b->target.lag),
578 "ERROR(yac_couple_config_field_couple_merge): "
579 "inconsistent target lag (%d != %d)", a->target.lag, b->target.lag)
582 "ERROR(yac_couple_config_field_couple_merge): "
583 "inconsistent mapping side (%d != %d)",
587 "ERROR(yac_couple_config_field_couple_merge): "
588 "inconsistent interpolation stack")
591 "ERROR(yac_couple_config_field_couple_merge): "
592 "inconsistent coupling period operation (%d != %d)",
595 !strcmp(a->coupling_period, b->coupling_period),
596 "ERROR(yac_couple_config_field_couple_merge): "
597 "inconsistent coupling period (%s != %s)",
601 "ERROR(yac_couple_config_field_couple_merge): "
602 "inconsistent definition of enforce_write_weight_file (%d != %d)",
606 !strcmp(a->weight_file_name, b->weight_file_name),
607 "ERROR(yac_couple_config_field_couple_merge): "
608 "inconsistent weight_file_name (%s != %s)",
613 "ERROR(yac_couple_config_field_couple_merge): "
614 "inconsistent weight_file_on_existing (%d != %d)",
617 a->scale_factor == b->scale_factor,
618 "ERROR(yac_couple_config_field_couple_merge): "
619 "inconsistent scale factor (%lf != %lf)",
623 "ERROR(yac_couple_config_field_couple_merge): "
624 "inconsistent scale summand (%lf != %lf)",
628 "ERROR(yac_couple_config_field_couple_merge): "
629 "inconsistent number of source mask names (%zu != %zu)",
632 (a->src_mask_names != NULL) == (b->src_mask_names != NULL),
633 "ERROR(yac_couple_config_field_couple_merge): "
634 "inconsistent availability of source mask names (%s != %s)",
635 (a->src_mask_names != NULL)?"TRUE":"FALSE",
636 (b->src_mask_names != NULL)?"TRUE":"FALSE")
637 for (size_t i = 0; i < a->num_src_mask_names; ++i)
639 !strcmp(a->src_mask_names[i], b->src_mask_names[i]),
640 "ERROR(yac_couple_config_field_couple_merge): "
641 "inconsistent source mask names at index %zu (\"%s\" != \"%s\")",
642 i, a->src_mask_names[i], b->src_mask_names[i])
644 (a->tgt_mask_name != NULL) == (b->tgt_mask_name != NULL),
645 "ERROR(yac_couple_config_field_couple_merge): "
646 "inconsistent availability of target mask name (%s != %s)",
647 (a->tgt_mask_name != NULL)?"TRUE":"FALSE",
648 (b->tgt_mask_name != NULL)?"TRUE":"FALSE")
650 (a->tgt_mask_name == NULL) ||
651 !strcmp(a->tgt_mask_name, b->tgt_mask_name),
652 "ERROR(yac_couple_config_field_couple_merge): "
653 "inconsistent target mask name (\"%s\" != \"%s\")",
656 (a->yaxt_exchanger_name != NULL) == (b->yaxt_exchanger_name != NULL),
657 "ERROR(yac_couple_config_field_couple_merge): "
658 "inconsistent availability of yaxt exchanger name (%s != %s)",
659 (a->yaxt_exchanger_name != NULL)?"TRUE":"FALSE",
660 (b->yaxt_exchanger_name != NULL)?"TRUE":"FALSE")
662 (a->yaxt_exchanger_name == NULL) ||
664 "ERROR(yac_couple_config_field_couple_merge): "
665 "inconsistent yaxt exchanger name (\"%s\" != \"%s\")",
670 "ERROR(yac_couple_config_field_couple_merge): "
671 "inconsistent collection selection definition")
674 "ERROR(yac_couple_config_field_couple_merge): "
675 "inconsistent definition of use_raw_exchange (%d != %d)",
677}
678
679static void merge_field_couples(
680 size_t * num_field_couples,
681 struct yac_couple_config_field_couple ** field_couples, MPI_Comm comm);
682
684 void * a_, void * b_, MPI_Comm comm) {
685
686 struct yac_couple_config_couple * a = a_;
687 struct yac_couple_config_couple * b = b_;
688
689 if (b) {
692 b->num_field_couples = 0;
693 b->field_couples = NULL;
694 }
695
696 // distribute and merge field couples
698}
699
701 void * a_, void * b_, MPI_Comm comm) {
702
703 struct yac_couple_config_config_output * a = a_;
704 struct yac_couple_config_config_output * b = b_;
705
706 if (b) {
707
709 !strcmp(a->name, b->name),
710 "ERROR(yac_couple_config_config_output_merge): "
711 "inconsistent file names for ref \"%s\" (\"%s\" != \"%s\")",
712 a->ref, a->name, b->name)
714 a->type == b->type,
715 "ERROR(yac_couple_config_config_output_merge): "
716 "inconsistent file types for ref \"%s\" (%d != %d)",
717 a->ref, a->type, b->type)
718
720 }
721
723 "include definitions", &(a->include_definitions), comm);
724}
725
726void yac_couple_config_delete(struct yac_couple_config * couple_config) {
727
728 deallocateDateTime((void*)couple_config->start_datetime);
729 deallocateDateTime((void*)couple_config->end_datetime);
730
731 for (size_t i = 0; i < couple_config->num_config_outputs; ++i)
733 couple_config->config_outputs + i);
734 free((void*)couple_config->config_outputs);
735
736 for (size_t i = 0; i < couple_config->num_grids; ++i){
737 yac_couple_config_grid_free(couple_config->grids + i);
738 }
739 free(couple_config->grids);
740
741 for (size_t i = 0;
742 i < couple_config->num_components; ++i)
744 free(couple_config->components);
745
746 for (size_t couple_idx = 0; couple_idx < couple_config->num_couples;
747 ++couple_idx)
748 yac_couple_config_couple_free(couple_config->couples + couple_idx);
749 free(couple_config->couples);
750 free(couple_config);
751}
752
754 struct yac_couple_config * couple_config, char const * name) {
755
757 name != NULL,
758 "ERROR(yac_couple_config_add_grid_): "
759 "invalid name (NULL is not allowed)")
760
761 for (size_t i = 0; i < couple_config->num_grids; ++i)
762 if (!strcmp(couple_config->grids[i].name, name)) return i;
763
764 size_t grid_idx = couple_config->num_grids;
765 couple_config->num_grids++;
766 couple_config->grids =
767 xrealloc(
768 couple_config->grids,
769 couple_config->num_grids * sizeof(*(couple_config->grids)));
770 couple_config->grids[grid_idx].name = string_dup(name);
771 couple_config->grids[grid_idx].output_filename = NULL;
772 couple_config->grids[grid_idx].metadata = NULL;
773 return grid_idx;
774}
775
777 struct yac_couple_config * couple_config, char const * name) {
778
779 yac_couple_config_add_grid_(couple_config, name);
780}
781
783 struct yac_couple_config * couple_config, char const * name) {
784
786 name != NULL,
787 "ERROR(yac_couple_config_add_component_): "
788 "invalid name (NULL is not allowed)")
789
790 for (size_t i = 0; i < couple_config->num_components; ++i)
791 if (!strcmp(couple_config->components[i].name, name)) return i;
792
793 size_t component_idx = couple_config->num_components;
794 couple_config->num_components++;
795 couple_config->components =
796 xrealloc(
797 couple_config->components,
798 couple_config->num_components * sizeof(*(couple_config->components)));
799 couple_config->components[component_idx].fields = NULL;
800 couple_config->components[component_idx].num_fields = 0;
801 couple_config->components[component_idx].name = strdup(name);
802 couple_config->components[component_idx].metadata = NULL;
803 return component_idx;
804}
805
807 struct yac_couple_config * couple_config, char const * name) {
808
810}
811
813 struct yac_couple_config * couple_config,
814 char const * comp_name, const char* metadata) {
815 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
816 free(couple_config->components[comp_idx].metadata);
817 couple_config->components[comp_idx].metadata
818 = metadata==NULL?NULL:strdup(metadata);
819}
820
822 struct yac_couple_config * couple_config,
823 char const * grid_name, const char* output_filename) {
824 if(!yac_couple_config_contains_grid_name(couple_config, grid_name))
825 yac_couple_config_add_grid(couple_config, grid_name);
826 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
828 output_filename != NULL,
829 "ERROR(yac_couple_config_grid_set_output_filename): invalid output filename "
830 "for grid \"%s\" (NULL is not allowed)",
831 grid_name);
833 (couple_config->grids[grid_idx].output_filename == NULL) ||
834 (!strcmp(couple_config->grids[grid_idx].output_filename, output_filename)),
835 "ERROR(yac_couple_config_grid_set_output_filename): output file name for grid "
836 "\"%s\" has already been set (\"%s\" != \"%s\")",
837 grid_name, couple_config->grids[grid_idx].output_filename, output_filename);
838 if (couple_config->grids[grid_idx].output_filename == NULL)
839 couple_config->grids[grid_idx].output_filename = strdup(output_filename);
840}
841
843 struct yac_couple_config * couple_config,
844 char const * grid_name, const char* metadata) {
845 if(!yac_couple_config_contains_grid_name(couple_config, grid_name))
846 yac_couple_config_add_grid(couple_config, grid_name);
847 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
848 free(couple_config->grids[grid_idx].metadata);
849 couple_config->grids[grid_idx].metadata
850 = metadata==NULL?NULL:strdup(metadata);
851}
852
854 struct yac_couple_config * couple_config,
855 const char* comp_name, const char * grid_name, const char* field_name,
856 const char* metadata) {
857 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
858 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
859 size_t field_idx = yac_couple_config_get_field_idx(couple_config,
860 comp_idx, grid_idx, field_name);
861 free(couple_config->components[comp_idx].fields[field_idx].metadata);
862 couple_config->components[comp_idx].fields[field_idx].metadata
863 = metadata==NULL?NULL:strdup(metadata);
864}
865
867 struct yac_couple_config * couple_config,
868 const char * comp_name) {
869 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
870 return couple_config->components[comp_idx].metadata;
871}
872
874 struct yac_couple_config * couple_config,
875 const char * grid_name) {
876 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
877 return couple_config->grids[grid_idx].output_filename;
878}
879
881 struct yac_couple_config * couple_config,
882 const char * grid_name) {
883 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
884 return couple_config->grids[grid_idx].metadata;
885}
886
888 struct yac_couple_config * couple_config,
889 const char* comp_name, const char * grid_name, const char* field_name) {
890 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
891 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
892 size_t field_idx = yac_couple_config_get_field_idx(couple_config,
893 comp_idx, grid_idx, field_name);
894 return couple_config->components[comp_idx].fields[field_idx].metadata;
895}
896
898 struct yac_couple_config * couple_config, size_t component_idx,
899 char const * routine_name, int line) {
900
903 "ERROR(%s:%d:%s): invalid component_idx", __FILE__, line, routine_name)
904}
905
906static void check_grid_idx(
907 struct yac_couple_config * couple_config, size_t grid_idx,
908 char const * routine_name, int line) {
909
912 "ERROR(%s:%d:%s): invalid grid_idx", __FILE__, line, routine_name)
913}
914
916 struct yac_couple_config * couple_config,
917 size_t comp_idx, size_t grid_idx, char const * name,
918 char const * timestep, size_t collection_size) {
919
921 couple_config, comp_idx,
922 "yac_couple_config_component_add_field_", __LINE__);
924 couple_config, grid_idx,
925 "yac_couple_config_component_add_field_", __LINE__);
926
927 // check whether the field already exists
928 struct yac_couple_config_component * component =
929 couple_config->components + comp_idx;
930 for (size_t i = 0; i < component->num_fields; i++) {
931 if((strcmp(component->fields[i].name, name) == 0) &&
932 (component->fields[i].grid_idx == grid_idx)) {
933 // if no timestep is defined for the field
934 if (!component->fields[i].timestep && timestep)
935 component->fields[i].timestep = strdup(timestep);
936 // if no collection size is defined for the field
937 if (component->fields[i].collection_size == SIZE_MAX)
938 component->fields[i].collection_size = collection_size;
940 !timestep ||
941 !strcmp(timestep, component->fields[i].timestep),
942 "ERROR(yac_couple_config_component_add_field): "
943 "inconsistent timestep definition (\"%s\" != \"%s\")",
944 timestep, component->fields[i].timestep);
946 collection_size == SIZE_MAX ||
947 collection_size == component->fields[i].collection_size,
948 "ERROR(yac_couple_config_component_add_field): "
949 "inconsistent collection_size definition (%zu != %zu)",
950 collection_size, component->fields[i].collection_size);
951 return i;
952 }
953 }
954
955 size_t field_idx = component->num_fields;
956 component->num_fields++;
957
958 component->fields =
959 xrealloc(
960 component->fields,
961 component->num_fields *
962 sizeof(*(component->fields)));
963 struct yac_couple_config_field * field =
964 component->fields + field_idx;
965
966 field->name = strdup(name);
967 field->grid_idx = grid_idx;
968 field->timestep = timestep?strdup(timestep):NULL;
969 field->metadata = NULL;
970 field->frac_mask_fallback_value = YAC_FRAC_MASK_NO_VALUE;
971 field->collection_size = collection_size;
972 return field_idx;
973}
974
976 struct yac_couple_config * couple_config, const char* component_name,
977 const char* grid_name, const char* name, char const * timestep,
978 size_t collection_size) {
979
981 couple_config,
982 yac_couple_config_get_component_idx(couple_config, component_name),
983 yac_couple_config_get_grid_idx(couple_config, grid_name),
985}
986
988 struct yac_couple_config * couple_config) {
989
990 return couple_config->num_couples;
991}
992
994 struct yac_couple_config * couple_config) {
995
996 switch(couple_config->missing_definition_is_fatal) {
997 case(FLAG_FALSE): return 0;
998 case(FLAG_TRUE): return 1;
999 default:
1001 }
1002}
1003
1005 struct yac_couple_config * couple_config,
1006 int missing_definition_is_fatal) {
1007
1008 enum flag_value user_value =
1009 (missing_definition_is_fatal != 0)?FLAG_TRUE:FLAG_FALSE;
1010
1012 (couple_config->missing_definition_is_fatal == FLAG_UNSET) ||
1013 (couple_config->missing_definition_is_fatal == user_value),
1014 "ERROR(yac_couple_config_set_missing_definition_is_fatal): "
1015 "inconsistent setting of \"missing_definition_is_fatal\"-flag "
1016 "(old: %s new: %s)",
1017 (couple_config->missing_definition_is_fatal == FLAG_TRUE)?"TRUE":"FALSE",
1018 (user_value == FLAG_TRUE)?"TRUE":"FALSE");
1019
1020 couple_config->missing_definition_is_fatal = user_value;
1021}
1022
1024 struct yac_couple_config * couple_config, size_t couple_idx,
1025 char const * routine_name, int line) {
1026
1028 couple_idx < couple_config->num_couples,
1029 "ERROR(%s:%d:%s): invalid couple_idx", __FILE__, line, routine_name);
1030}
1031
1033 struct yac_couple_config * couple_config, size_t couple_idx) {
1034
1036 couple_config, couple_idx, "yac_couple_config_get_num_couple_fields",
1037 __LINE__);
1038
1039 return couple_config->couples[couple_idx].num_field_couples;
1040}
1041
1043 struct yac_couple_config * couple_config, size_t couple_idx,
1044 char const * couple_component_names[2]) {
1045
1047 couple_config, couple_idx, "yac_couple_config_get_couple_component_names",
1048 __LINE__);
1049
1050 for (int i = 0; i < 2; ++i)
1051 couple_component_names[i] =
1052 couple_config->components[
1053 couple_config->couples[couple_idx].component_indices[i]].name;
1054}
1055
1057 struct yac_couple_config * couple_config, char const * component_name) {
1058
1059 YAC_ASSERT(
1060 component_name,
1061 "ERROR(yac_couple_config_component_name_is_valid): component name is NULL")
1062 YAC_ASSERT(
1063 strlen(component_name) <= YAC_MAX_CHARLEN,
1064 "ERROR(yac_couple_config_component_name_is_valid): "
1065 "component name is too long (maximum is YAC_MAX_CHARLEN)")
1066
1067 for (size_t component_idx = 0; component_idx < couple_config->num_components;
1068 ++component_idx)
1069 if (!strcmp(component_name, couple_config->components[component_idx].name))
1070 return 1;
1071 return 0;
1072}
1073
1075 struct yac_couple_config * couple_config) {
1076
1077 return couple_config->num_components;
1078}
1079
1081 struct yac_couple_config * couple_config) {
1082
1083 return couple_config->num_grids;
1084}
1085
1087 struct yac_couple_config * couple_config, size_t component_idx) {
1088 check_component_idx(couple_config, component_idx,
1089 "yac_couple_config_get_num_fields", __LINE__);
1090 return couple_config->components[component_idx].num_fields;
1091}
1092
1094 struct yac_couple_config * couple_config, char const * component_name) {
1095
1096 size_t component_idx = SIZE_MAX;
1097 for (size_t i = 0; (i < couple_config->num_components) &&
1098 (component_idx == SIZE_MAX); ++i)
1099 if (!strcmp(couple_config->components[i].name, component_name))
1100 component_idx = i;
1101
1103 component_idx != SIZE_MAX,
1104 "ERROR(yac_couple_config_get_component_idx): "
1105 "Component \"%s\" not found in coupling configuration",
1106 component_name);
1107
1108 return component_idx;
1109}
1110
1112 struct yac_couple_config * couple_config, char const * grid_name) {
1113
1114 size_t grid_idx = SIZE_MAX;
1115 for (size_t i = 0;
1116 (i < couple_config->num_grids) && (grid_idx == SIZE_MAX); ++i)
1117 if (!strcmp(couple_config->grids[i].name, grid_name))
1118 grid_idx = i;
1119
1121 grid_idx != SIZE_MAX,
1122 "ERROR(yac_couple_config_get_grid_idx): "
1123 "grid name \"%s\" not in list of grids", grid_name)
1124
1125 return grid_idx;
1126}
1127
1129 struct yac_couple_config * couple_config, size_t component_idx,
1130 size_t grid_idx, char const * field_name) {
1132 couple_config, component_idx,
1133 "yac_couple_config_get_component_name", __LINE__);
1134
1135 size_t field_idx = SIZE_MAX;
1136 struct yac_couple_config_component * component =
1137 couple_config->components + component_idx;
1138 size_t nbr_fields = component->num_fields;
1139 for(size_t i=0;
1140 (i<nbr_fields) && (field_idx == SIZE_MAX); ++i)
1141 if((component->fields[i].grid_idx == grid_idx) &&
1142 !strcmp(
1143 field_name,
1144 component->fields[i].name))
1145 field_idx = i;
1146
1148 field_idx != SIZE_MAX,
1149 "ERROR(yac_couple_config_get_field_idx): "
1150 "field not found "
1151 "(component_idx %zu grid_idx %zu field_name \"%s\"",
1152 component_idx, grid_idx, field_name);
1153
1154 return field_idx;
1155}
1156
1158 struct yac_couple_config * couple_config, size_t component_idx) {
1159
1161 couple_config, component_idx,
1162 "yac_couple_config_get_component_name", __LINE__);
1163
1164 return couple_config->components[component_idx].name;
1165}
1166
1168 struct yac_couple_config * couple_config, size_t component_idx,
1169 size_t field_idx, char const * routine_name, int line) {
1170
1172 couple_config, component_idx, routine_name, __LINE__);
1173
1175 field_idx <
1176 couple_config->components[component_idx].num_fields,
1177 "ERROR(%s:%d:%s): invalid field_idx", __FILE__,
1178 line, routine_name)
1179}
1180
1182 struct yac_couple_config * couple_config, size_t component_idx,
1183 size_t field_idx) {
1184
1186 couple_config, component_idx, field_idx,
1187 "yac_couple_config_get_field_grid_name", __LINE__);
1188
1189 return
1190 couple_config->grids[
1191 couple_config->
1193 fields[field_idx].grid_idx].name;
1194}
1195
1197 struct yac_couple_config * couple_config, size_t component_idx,
1198 size_t field_idx) {
1199
1201 couple_config, component_idx, field_idx,
1202 "yac_couple_config_get_field_name", __LINE__);
1203
1204 return
1205 couple_config->
1207 fields[field_idx].name;
1208}
1209
1211 struct yac_couple_config * couple_config,
1212 char const * component_name, char const * grid_name,
1213 char const * field_name) {
1214
1215 size_t component_idx =
1216 yac_couple_config_get_component_idx(couple_config, component_name);
1217 size_t grid_idx =
1218 yac_couple_config_get_grid_idx(couple_config, grid_name);
1219 size_t field_idx =
1221 couple_config, component_idx, grid_idx, field_name);
1222
1223 struct yac_couple_config_field * field =
1224 couple_config->components[component_idx].fields +
1225 field_idx;
1226
1227 return field->timestep;
1228}
1229
1231 struct yac_couple_config * couple_config,
1232 char const * component_name, char const * grid_name,
1233 char const * field_name) {
1234
1235 size_t component_idx =
1236 yac_couple_config_get_component_idx(couple_config, component_name);
1237 size_t grid_idx =
1238 yac_couple_config_get_grid_idx(couple_config, grid_name);
1239 size_t field_idx =
1241 couple_config, component_idx, grid_idx, field_name);
1242
1243 size_t nbr_couples = couple_config->num_couples;
1244 for(size_t couple_idx = 0; couple_idx<nbr_couples; ++couple_idx){
1245 struct yac_couple_config_couple * couple = couple_config->couples + couple_idx;
1246 if(couple->component_indices[0] != component_idx &&
1247 couple->component_indices[1] != component_idx)
1248 continue;
1249 size_t nbr_trans_couples = couple->num_field_couples;
1250 for(size_t trans_couple_idx = 0; trans_couple_idx < nbr_trans_couples;
1251 ++trans_couple_idx){
1252 struct yac_couple_config_field_couple * transcouple =
1253 couple->field_couples + trans_couple_idx;
1254 if(transcouple->source.component_idx == component_idx &&
1255 transcouple->source.field_idx == field_idx)
1257 if(transcouple->target.component_idx == component_idx &&
1258 transcouple->target.field_idx == field_idx)
1260 }
1261 }
1263}
1264
1266 struct yac_couple_config * couple_config,
1267 size_t component_idx, size_t field_idx) {
1268
1270 couple_config, component_idx,
1271 "yac_couple_config_field_is_valid", __LINE__);
1273 couple_config, component_idx, field_idx,
1274 "yac_couple_config_field_is_valid", __LINE__);
1275
1276 struct yac_couple_config_field * field =
1277 couple_config->components[component_idx].fields +
1278 field_idx;
1279
1280 return (field->collection_size != SIZE_MAX) &&
1281 (field->timestep != NULL);
1282}
1283
1285 struct yac_couple_config * couple_config, size_t couple_idx,
1286 size_t field_couple_idx, char const * routine_name, int line) {
1287
1288 check_couple_idx(couple_config, couple_idx, routine_name, __LINE__);
1289
1291 field_couple_idx <
1292 couple_config->couples[couple_idx].num_field_couples,
1293 "ERROR(%s:%d:%s): invalid field_couple_idx",
1294 __FILE__, line, routine_name)
1295}
1296
1298 struct yac_couple_config * couple_config,
1299 size_t couple_idx, size_t field_couple_idx) {
1300
1302 couple_config, couple_idx, field_couple_idx,
1303 "yac_couple_config_get_interp_stack", __LINE__);
1304
1305 return
1306 couple_config->
1307 couples[couple_idx].
1308 field_couples[field_couple_idx].interp_stack;
1309}
1310
1312 struct yac_couple_config * couple_config,
1313 size_t couple_idx, size_t field_couple_idx,
1314 char const ** src_grid_name, char const ** tgt_grid_name) {
1315
1317 couple_config, couple_idx, field_couple_idx,
1318 "yac_couple_config_get_field_grid_names", __LINE__);
1319
1320 size_t src_component_idx =
1321 couple_config->couples[couple_idx].
1322 field_couples[field_couple_idx].
1323 source.component_idx;
1324 size_t src_field_idx =
1325 couple_config->couples[couple_idx].
1326 field_couples[field_couple_idx].
1327 source.field_idx;
1328
1329 size_t tgt_component_idx =
1330 couple_config->couples[couple_idx].
1331 field_couples[field_couple_idx].
1332 target.component_idx;
1333 size_t tgt_field_idx =
1334 couple_config->couples[couple_idx].
1335 field_couples[field_couple_idx].
1336 target.field_idx;
1337
1338 *src_grid_name =
1339 couple_config->grids[
1340 couple_config->components[src_component_idx].
1341 fields[src_field_idx].grid_idx].name;
1342 *tgt_grid_name =
1343 couple_config->grids[
1344 couple_config->components[tgt_component_idx].
1345 fields[tgt_field_idx].grid_idx].name;
1346}
1347
1349 struct yac_couple_config * couple_config,
1350 char const * comp_name, char const * grid_name, char const * field_name,
1351 double frac_mask_fallback_value) {
1352
1354 YAC_FRAC_MASK_VALUE_IS_VALID(frac_mask_fallback_value),
1355 "ERROR(yac_couple_config_field_enable_frac_mask): "
1356 "\"%lf\" is not a valid fractional mask fallback value "
1357 "(component: \"%s\" grid: \"%s\" field \"%s\")",
1358 frac_mask_fallback_value, comp_name, grid_name, field_name);
1359
1360 size_t comp_idx = yac_couple_config_get_component_idx(couple_config, comp_name);
1361 size_t grid_idx = yac_couple_config_get_grid_idx(couple_config, grid_name);
1362 size_t field_idx = yac_couple_config_get_field_idx(couple_config,
1363 comp_idx, grid_idx, field_name);
1364
1365 double old_frac_mask_fallback_value =
1366 couple_config->components[comp_idx].fields[field_idx].
1367 frac_mask_fallback_value;
1368
1369 // (use memcmp for comparison, because it can be nan)
1371 !YAC_FRAC_MASK_VALUE_IS_VALID(old_frac_mask_fallback_value) ||
1372 !memcmp(
1373 &old_frac_mask_fallback_value, &frac_mask_fallback_value,
1374 sizeof(frac_mask_fallback_value)),
1375 "ERROR(yac_couple_config_field_enable_frac_mask): "
1376 "fractional mask fallback value was already set:\n"
1377 "\told value \"%lf\" new value \"%lf\" "
1378 "(component: \"%s\" grid: \"%s\" field \"%s\")",
1379 old_frac_mask_fallback_value, frac_mask_fallback_value,
1380 comp_name, grid_name, field_name);
1381
1382 couple_config->components[comp_idx].fields[field_idx].
1383 frac_mask_fallback_value = frac_mask_fallback_value;
1384}
1385
1387 struct yac_couple_config * couple_config,
1388 char const * component_name, char const * grid_name,
1389 char const * field_name) {
1390
1391 size_t component_idx =
1392 yac_couple_config_get_component_idx(couple_config, component_name);
1393 size_t grid_idx =
1394 yac_couple_config_get_grid_idx(couple_config, grid_name);
1395 size_t field_idx =
1397 couple_config, component_idx, grid_idx, field_name);
1398
1399 struct yac_couple_config_field * field =
1400 couple_config->components[component_idx].fields +
1401 field_idx;
1402
1404 YAC_FRAC_MASK_VALUE_IS_SET(field->frac_mask_fallback_value),
1405 "ERROR(yac_couple_config_get_frac_mask_fallback_value): "
1406 "no valid fractional mask fallback value defined "
1407 "(component: \"%s\" grid: \"%s\" field \"%s\")",
1408 couple_config->components[component_idx].name, grid_name, field->name);
1409
1410 return field->frac_mask_fallback_value;
1411}
1412
1414 struct yac_couple_config * couple_config,
1415 char const * component_name, char const * grid_name,
1416 char const * field_name) {
1417
1418 size_t component_idx =
1419 yac_couple_config_get_component_idx(couple_config, component_name);
1420 size_t grid_idx =
1421 yac_couple_config_get_grid_idx(couple_config, grid_name);
1422 size_t field_idx =
1424 couple_config, component_idx, grid_idx, field_name);
1425
1426 struct yac_couple_config_field * field =
1427 couple_config->components[component_idx].fields +
1428 field_idx;
1429
1430 return field->collection_size;
1431}
1432
1434 struct yac_couple_config * couple_config,
1435 size_t couple_idx, size_t field_couple_idx,
1436 char const ** src_component_name, char const ** tgt_component_name) {
1437
1439 couple_config, couple_idx, field_couple_idx,
1440 "yac_couple_config_get_field_couple_component_names", __LINE__);
1441
1442 *src_component_name =
1443 couple_config->components[
1444 couple_config->couples[couple_idx].
1445 field_couples[field_couple_idx].source.component_idx].name;
1446 *tgt_component_name =
1447 couple_config->components[
1448 couple_config->couples[couple_idx].
1449 field_couples[field_couple_idx].target.component_idx].name;
1450}
1451
1453 struct yac_couple_config * couple_config,
1454 size_t couple_idx, size_t field_couple_idx,
1455 char const ** src_field_name, const char ** tgt_field_name) {
1456
1458 couple_config, couple_idx, field_couple_idx,
1459 "yac_couple_config_get_field_names", __LINE__);
1460
1461 size_t src_component_idx =
1462 couple_config->couples[couple_idx].
1463 field_couples[field_couple_idx].source.component_idx;
1464 size_t tgt_component_idx =
1465 couple_config->couples[couple_idx].
1466 field_couples[field_couple_idx].target.component_idx;
1467 size_t src_field_idx =
1468 couple_config->couples[couple_idx].
1469 field_couples[field_couple_idx].source.field_idx;
1470 size_t tgt_field_idx =
1471 couple_config->couples[couple_idx].
1472 field_couples[field_couple_idx].target.field_idx;
1473
1474 *src_field_name =
1475 couple_config->components[src_component_idx].
1476 fields[src_field_idx].name;
1477 *tgt_field_name =
1478 couple_config->components[tgt_component_idx].
1479 fields[tgt_field_idx].name;
1480}
1481
1483 struct yac_couple_config * couple_config,
1484 size_t couple_idx, size_t field_couple_idx) {
1485
1487 couple_config, couple_idx, field_couple_idx,
1488 "yac_couple_config_mapping_on_source", __LINE__);
1489
1490 return
1491 couple_config->
1492 couples[couple_idx].
1493 field_couples[field_couple_idx].
1494 mapping_on_source;
1495}
1496
1498 struct yac_couple_config * couple_config,
1499 size_t couple_idx, size_t field_couple_idx) {
1500
1502 couple_config, couple_idx, field_couple_idx,
1503 "yac_couple_config_get_source_lag", __LINE__);
1504
1505 return
1506 couple_config->
1507 couples[couple_idx].
1508 field_couples[field_couple_idx].
1509 source.lag;
1510}
1511
1513 struct yac_couple_config * couple_config,
1514 size_t couple_idx, size_t field_couple_idx) {
1515
1517 couple_config, couple_idx, field_couple_idx,
1518 "yac_couple_config_get_target_lag", __LINE__);
1519
1520 return
1521 couple_config->
1522 couples[couple_idx].
1523 field_couples[field_couple_idx].
1524 target.lag;
1525}
1526
1528 struct yac_couple_config * couple_config,
1529 size_t couple_idx, size_t field_couple_idx) {
1530
1532 couple_config, couple_idx, field_couple_idx,
1533 "yac_couple_config_get_coupling_period", __LINE__);
1534
1535 return
1536 couple_config->
1537 couples[couple_idx].
1538 field_couples[field_couple_idx].
1539 coupling_period;
1540}
1541
1543 struct yac_couple_config * couple_config,
1544 size_t couple_idx, size_t field_couple_idx) {
1545
1547 couple_config, couple_idx, field_couple_idx,
1548 "yac_couple_config_get_source_timestep", __LINE__);
1549
1550 struct yac_couple_config_field_couple * tcouple =
1551 couple_config->couples[couple_idx].field_couples + field_couple_idx;
1552 char const * timestep =
1553 couple_config->components[tcouple->source.component_idx].
1554 fields[tcouple->source.field_idx].timestep;
1555
1557 timestep,
1558 "ERROR(yac_couple_config_get_source_timestep): "
1559 "no valid timestep defined (component: \"%s\" field \"%s\")",
1560 couple_config->components[tcouple->source.component_idx].name,
1561 couple_config->components[tcouple->source.component_idx].
1562 fields[tcouple->source.field_idx].name);
1563
1564 return timestep;
1565}
1566
1568 struct yac_couple_config * couple_config,
1569 size_t couple_idx, size_t field_couple_idx) {
1570
1572 couple_config, couple_idx, field_couple_idx,
1573 "yac_couple_config_get_target_timestep", __LINE__);
1574
1575 struct yac_couple_config_field_couple * tcouple =
1576 couple_config->couples[couple_idx].field_couples + field_couple_idx;
1577 char const * timestep =
1578 couple_config->components[tcouple->target.component_idx].
1579 fields[tcouple->target.field_idx].timestep;
1580
1581 return timestep;
1582}
1583
1585 struct yac_couple_config * couple_config,
1586 size_t couple_idx, size_t field_couple_idx) {
1587
1589 couple_config, couple_idx, field_couple_idx,
1590 "yac_couple_config_get_coupling_period_operation", __LINE__);
1591
1592 return
1593 couple_config->
1594 couples[couple_idx].
1595 field_couples[field_couple_idx].
1597}
1598
1599static void set_datetime(
1600 char const * type_datetime, struct _datetime ** old, char const * str_new) {
1601
1602 if ((str_new == NULL) || (strlen(str_new) == 0)) return;
1603
1604 YAC_ASSERT(
1606 "ERROR(set_datetime): calendar has not yet been set");
1607
1608 struct _datetime * new = newDateTime(str_new);
1609
1611 new != NULL,
1612 "ERROR(set_datetime): failed to parse datetime \"%s\"", str_new);
1613
1614 char old_datetime_buffer[MAX_DATETIME_STR_LEN],
1615 new_datetime_buffer[MAX_DATETIME_STR_LEN];
1616
1618 (*old == NULL) || (equal_to == compareDatetime(*old, new)),
1619 "ERROR(set_datetime): inconsistent %s datetime "
1620 "(old: \"%s\" new: \"%s\")", type_datetime,
1621 datetimeToString(*old, old_datetime_buffer),
1622 datetimeToString(new, new_datetime_buffer));
1623
1624 deallocateDateTime(*old);
1625
1626 *old = new;
1627}
1628
1630 struct yac_couple_config * couple_config,
1631 char const * start, char const * end) {
1632
1633 set_datetime("start", &(couple_config->start_datetime), start);
1634 set_datetime("end", &(couple_config->end_datetime), end);
1635}
1636
1638 struct yac_couple_config * couple_config) {
1639
1640 YAC_ASSERT(couple_config->start_datetime,
1641 "ERROR(yac_couple_config_get_start_datetime): "
1642 "start_datetime not yet defined");
1643
1644 char datetime_buffer[MAX_DATETIME_STR_LEN];
1645
1646 return
1647 strdup(datetimeToString(couple_config->start_datetime, datetime_buffer));
1648}
1649
1651 struct yac_couple_config * couple_config) {
1652
1653 YAC_ASSERT(couple_config->end_datetime,
1654 "ERROR(yac_couple_config_get_start_datetime): "
1655 "start_datetime not yet defined");
1656
1657 char datetime_buffer[MAX_DATETIME_STR_LEN];
1658
1659 return
1660 strdup(datetimeToString(couple_config->end_datetime, datetime_buffer));
1661}
1662
1664 struct yac_couple_config * couple_config, size_t grid_idx) {
1665
1668 "ERROR(yac_couple_config_get_grid_name): "
1669 "Invalid grid idx %zu", grid_idx);
1670
1671 return couple_config->grids[grid_idx].name;
1672}
1673
1675 struct yac_couple_config * couple_config,
1676 size_t couple_idx, size_t field_couple_idx) {
1677
1679 couple_config, couple_idx, field_couple_idx,
1680 "yac_couple_config_enforce_write_weight_file", __LINE__);
1681
1682 return
1683 couple_config->
1684 couples[couple_idx].
1685 field_couples[field_couple_idx].
1686 enforce_write_weight_file;
1687}
1688
1690 struct yac_couple_config * couple_config,
1691 size_t couple_idx, size_t field_couple_idx) {
1692
1694 couple_config, couple_idx, field_couple_idx,
1695 "yac_couple_config_get_weight_file_name", __LINE__);
1696
1697 static char dummy[] = "\0";
1698 char const * weight_file_name =
1699 couple_config->
1700 couples[couple_idx].
1701 field_couples[field_couple_idx].
1703
1704 return (weight_file_name != NULL)?weight_file_name:dummy;
1705}
1706
1708 struct yac_couple_config * couple_config,
1709 size_t couple_idx, size_t field_couple_idx) {
1710
1712 couple_config, couple_idx, field_couple_idx,
1713 "yac_couple_config_get_weight_file_on_existing", __LINE__);
1714
1715 return
1716 couple_config->
1717 couples[couple_idx].
1718 field_couples[field_couple_idx].
1719 weight_file_on_existing;
1720}
1721
1723 struct yac_couple_config * couple_config,
1724 size_t couple_idx, size_t field_couple_idx) {
1725
1727 couple_config, couple_idx, field_couple_idx,
1728 "yac_couple_config_get_scale_factor", __LINE__);
1729
1730 return
1731 couple_config->
1732 couples[couple_idx].
1733 field_couples[field_couple_idx].
1734 scale_factor;
1735}
1736
1738 struct yac_couple_config * couple_config,
1739 size_t couple_idx, size_t field_couple_idx) {
1740
1742 couple_config, couple_idx, field_couple_idx,
1743 "yac_couple_config_get_scale_summand", __LINE__);
1744
1745 return
1746 couple_config->
1747 couples[couple_idx].
1748 field_couples[field_couple_idx].
1749 scale_summand;
1750}
1751
1753 struct yac_couple_config * couple_config,
1754 size_t couple_idx, size_t field_couple_idx,
1755 char const * const ** mask_names, size_t * num_mask_names) {
1756
1758 couple_config, couple_idx, field_couple_idx,
1759 "yac_couple_config_get_src_mask_names", __LINE__);
1760
1761 *mask_names =
1762 (char const * const *)(
1763 couple_config->
1764 couples[couple_idx].
1765 field_couples[field_couple_idx].
1766 src_mask_names);
1767 *num_mask_names =
1768 couple_config->
1769 couples[couple_idx].
1770 field_couples[field_couple_idx].
1771 num_src_mask_names;
1772}
1773
1775 struct yac_couple_config * couple_config,
1776 size_t couple_idx, size_t field_couple_idx) {
1777
1779 couple_config, couple_idx, field_couple_idx,
1780 "yac_couple_config_get_tgt_mask_name", __LINE__);
1781
1782 return
1783 couple_config->
1784 couples[couple_idx].
1785 field_couples[field_couple_idx].
1786 tgt_mask_name;
1787}
1788
1790 struct yac_couple_config * couple_config,
1791 size_t couple_idx, size_t field_couple_idx) {
1792
1794 couple_config, couple_idx, field_couple_idx,
1795 "yac_couple_config_get_yaxt_exchanger_name", __LINE__);
1796
1797 return
1798 couple_config->
1799 couples[couple_idx].
1800 field_couples[field_couple_idx].
1801 yaxt_exchanger_name;
1802}
1803
1804struct yac_collection_selection const *
1806 struct yac_couple_config * couple_config,
1807 size_t couple_idx, size_t field_couple_idx) {
1808
1810 couple_config, couple_idx, field_couple_idx,
1811 "yac_couple_config_get_collection_selection", __LINE__);
1812
1813 return
1814 couple_config->
1815 couples[couple_idx].
1816 field_couples[field_couple_idx].
1817 collection_selection;
1818}
1819
1821 struct yac_couple_config * couple_config,
1822 size_t couple_idx, size_t field_couple_idx) {
1823
1825 couple_config, couple_idx, field_couple_idx,
1826 "yac_couple_config_get_use_raw_exchange", __LINE__);
1827
1828 return
1829 couple_config->
1830 couples[couple_idx].
1831 field_couples[field_couple_idx].
1832 use_raw_exchange;
1833}
1834
1836 struct yac_couple_config * couple_config, char const * grid_name) {
1837
1838 for (size_t grid_idx = 0; grid_idx < couple_config->num_grids;
1839 ++grid_idx)
1840 if (!strcmp(couple_config->grids[grid_idx].name, grid_name))
1841 return 1;
1842 return 0;
1843}
1844
1846 void * grid_, MPI_Comm comm) {
1847
1848 struct yac_couple_config_grid * grid = grid_;
1849
1850 return
1852 "yac_couple_config_get_grid_pack_size", grid->name, comm, 1);
1853}
1854
1856 void * field_, MPI_Comm comm) {
1857
1858 struct yac_couple_config_field * field =
1859 (struct yac_couple_config_field *)field_;
1860
1861 YAC_ASSERT(
1862 field->grid_idx <= INT_MAX,
1863 "ERROR(yac_couple_config_get_field_pack_size):"
1864 "grid_idx is too big")
1865
1866 int int_pack_size;
1867 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &int_pack_size), comm);
1868 size_t name_pack_size =
1870 "yac_couple_config_get_field_pack_size", field->name, comm, 1);
1871
1872 return int_pack_size + // grid_idx
1873 name_pack_size;
1874}
1875
1877 void * component_, MPI_Comm comm) {
1878
1879 struct yac_couple_config_component * component =
1880 (struct yac_couple_config_component *)component_;
1881
1882 return
1884 "yac_couple_config_get_component_pack_size",
1885 component->name, comm, 1);
1886}
1887
1889 void * field_couple_, MPI_Comm comm) {
1890
1891 struct yac_couple_config_field_couple * field_couple =
1892 (struct yac_couple_config_field_couple *)field_couple_;
1893
1894 int ints_pack_size;
1895 yac_mpi_call(MPI_Pack_size(12, MPI_INT, comm, &ints_pack_size), comm);
1896 int doubles_pack_size;
1897 yac_mpi_call(MPI_Pack_size(2, MPI_DOUBLE, comm, &doubles_pack_size), comm);
1898 int src_mask_names_pack_size = 0;
1899 if (field_couple->num_src_mask_names > 0)
1900 for (size_t i = 0; i < field_couple->num_src_mask_names; ++i)
1901 src_mask_names_pack_size +=
1903 "yac_couple_config_get_field_couple_pack_size",
1904 field_couple->src_mask_names[i], comm, 1);
1905
1906 return
1907 (size_t)ints_pack_size + // source.component_idx
1908 // source.field_idx
1909 // source.lag
1910 // target.component_idx
1911 // target.field_idx
1912 // target.lag
1913 // mapping_on_source
1914 // coupling_period_operation
1915 // enforce_write_weight_file
1916 // weight_file_on_existing
1917 // num_src_mask_names
1918 // use_raw_exchange
1920 field_couple->interp_stack, comm) +
1922 "yac_couple_config_get_field_couple_pack_size",
1923 field_couple->coupling_period, comm, 1) +
1925 "yac_couple_config_get_field_couple_pack_size",
1926 field_couple->weight_file_name, comm, 1) +
1927 doubles_pack_size + // scale_factor
1928 // scale_summand
1929 src_mask_names_pack_size +
1931 "yac_couple_config_get_field_couple_pack_size",
1932 field_couple->tgt_mask_name, comm, 1) +
1934 "yac_couple_config_get_field_couple_pack_size",
1935 field_couple->yaxt_exchanger_name, comm, 1) +
1937 field_couple->collection_selection, comm);
1938}
1939
1941 void * couple_, MPI_Comm comm) {
1942
1943 UNUSED(couple_);
1944
1945 int component_indices_pack_size;
1947 MPI_Pack_size(2, MPI_INT, comm, &component_indices_pack_size), comm);
1948
1949 return (size_t)component_indices_pack_size;
1950}
1951
1953 void * config_output_, MPI_Comm comm) {
1954
1955 struct yac_couple_config_config_output * config_output = config_output_;
1956
1957 int filetype_pack_size;
1959 MPI_Pack_size(1, MPI_INT, comm, &filetype_pack_size), comm);
1960
1961 return
1962 filetype_pack_size +
1964 "yac_couple_config_get_config_output_pack_size",
1965 config_output->name, comm, 1) +
1967 "yac_couple_config_get_config_output_pack_size",
1968 config_output->ref, comm, 1);
1969}
1970
1972 void * grid_, void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1973
1974 struct yac_couple_config_grid * grid =
1975 (struct yac_couple_config_grid *)grid_;
1977 "yac_couple_config_pack_grid", grid->name, buffer, buffer_size,
1978 position, comm, 1);
1979}
1980
1982 void * field_, void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1983
1984 struct yac_couple_config_field * field =
1985 (struct yac_couple_config_field *)field_;
1986
1987 YAC_ASSERT(
1988 field->grid_idx <= INT_MAX,
1989 "ERROR(yac_couple_config_pack_field): grid_idx is too big")
1990
1991 int grid_idx = (int)field->grid_idx;
1992
1994 MPI_Pack(
1995 &grid_idx, 1, MPI_INT, buffer, buffer_size, position, comm), comm);
1997 "yac_couple_config_pack_field", field->name, buffer,
1998 buffer_size, position, comm, 1);
1999}
2000
2002 void * component_, void * buffer, int buffer_size, int * position, MPI_Comm comm) {
2003
2004 struct yac_couple_config_component * component =
2005 (struct yac_couple_config_component *)component_;
2006
2008 "yac_couple_config_pack_component", component->name,
2009 buffer, buffer_size, position, comm, 1);
2010}
2011
2013 void * field_couple_, void * buffer, int buffer_size, int * position,
2014 MPI_Comm comm) {
2015
2016 struct yac_couple_config_field_couple * field_couple =
2017 (struct yac_couple_config_field_couple *)field_couple_;
2018
2019 YAC_ASSERT(
2020 field_couple->source.component_idx <= INT_MAX,
2021 "ERROR(yac_couple_config_pack_field_couple): "
2022 "source.component_idx bigger than INT_MAX")
2023 YAC_ASSERT(
2024 field_couple->source.field_idx <= INT_MAX,
2025 "ERROR(yac_couple_config_pack_field_couple): "
2026 "source.field_idx bigger than INT_MAX")
2027 YAC_ASSERT(
2028 field_couple->target.component_idx <= INT_MAX,
2029 "ERROR(yac_couple_config_pack_field_couple): "
2030 "target.component_idx bigger than INT_MAX")
2031 YAC_ASSERT(
2032 field_couple->target.field_idx <= INT_MAX,
2033 "ERROR(yac_couple_config_pack_field_couple): "
2034 "target.field_idx bigger than INT_MAX")
2035 YAC_ASSERT(
2036 field_couple->mapping_on_source <= INT_MAX,
2037 "ERROR(yac_couple_config_pack_field_couple): "
2038 "mapping_on_source bigger than INT_MAX")
2039 YAC_ASSERT(
2040 field_couple->coupling_period_operation <= INT_MAX,
2041 "ERROR(yac_couple_config_pack_field_couple): "
2042 "coupling_period_operation bigger than INT_MAX")
2043 YAC_ASSERT(
2044 field_couple->enforce_write_weight_file <= INT_MAX,
2045 "ERROR(yac_couple_config_pack_field_couple): "
2046 "enforce_write_weight_file bigger than INT_MAX")
2047 YAC_ASSERT(
2048 field_couple->weight_file_on_existing <= INT_MAX,
2049 "ERROR(yac_couple_config_pack_field_couple): "
2050 "weight_file_on_existing bigger than INT_MAX")
2051 YAC_ASSERT(
2052 field_couple->num_src_mask_names <= INT_MAX,
2053 "ERROR(yac_couple_config_pack_field_couple): "
2054 "num_src_mask_names bigger than INT_MAX")
2055
2056 int ints[] = {
2057 field_couple->source.component_idx,
2058 field_couple->source.field_idx,
2059 field_couple->source.lag,
2060 field_couple->target.component_idx,
2061 field_couple->target.field_idx,
2062 field_couple->target.lag,
2063 field_couple->mapping_on_source,
2064 (int)(field_couple->coupling_period_operation),
2065 field_couple->enforce_write_weight_file,
2066 (int)(field_couple->weight_file_on_existing),
2067 field_couple->num_src_mask_names,
2068 field_couple->use_raw_exchange};
2069 enum {NUM_INTS = sizeof(ints) / sizeof(ints[0])};
2070
2072 MPI_Pack(
2073 ints, NUM_INTS, MPI_INT, buffer, buffer_size, position, comm), comm);
2074
2076 "yac_couple_config_pack_field_couple",
2077 field_couple->coupling_period, buffer, buffer_size, position, comm, 1);
2078
2080 "yac_couple_config_pack_field_couple",
2081 field_couple->weight_file_name, buffer, buffer_size, position, comm, 1);
2082
2083 double doubles[2] = {
2084 field_couple->scale_factor,
2085 field_couple->scale_summand};
2086
2088 MPI_Pack(doubles, 2, MPI_DOUBLE, buffer, buffer_size, position, comm),
2089 comm);
2090
2092 field_couple->interp_stack, buffer, buffer_size, position, comm);
2093
2094 if (field_couple->num_src_mask_names > 0)
2095 for (size_t i = 0; i < field_couple->num_src_mask_names; ++i)
2097 "yac_couple_config_pack_field_couple", field_couple->src_mask_names[i],
2098 buffer, buffer_size, position, comm, 1);
2099
2101 "yac_couple_config_pack_field_couple",
2102 field_couple->tgt_mask_name, buffer, buffer_size, position, comm, 1);
2103
2105 "yac_couple_config_pack_field_couple",
2106 field_couple->yaxt_exchanger_name, buffer, buffer_size, position, comm, 1);
2107
2109 field_couple->collection_selection, buffer, buffer_size, position, comm);
2110}
2111
2113 void * couple_, void * buffer, int buffer_size, int * position, MPI_Comm comm) {
2114
2115 struct yac_couple_config_couple * couple =
2116 (struct yac_couple_config_couple *)couple_;
2117
2118 YAC_ASSERT(
2119 (couple->component_indices[0] <= INT_MAX) &&
2120 (couple->component_indices[1] <= INT_MAX),
2121 "ERROR(yac_couple_config_pack_couple): "
2122 "component_indices bigger than INT_MAX")
2123
2124 int component_indices[2] = {(int)(couple->component_indices[0]),
2125 (int)(couple->component_indices[1])};
2126
2128 MPI_Pack(
2129 component_indices, 2, MPI_INT, buffer, buffer_size, position, comm),
2130 comm);
2131}
2132
2134 void * config_output_, void * buffer, int buffer_size, int * position,
2135 MPI_Comm comm) {
2136
2137 struct yac_couple_config_config_output * config_output =
2138 (struct yac_couple_config_config_output *)config_output_;
2139
2141 "yac_couple_config_pack_config_output",
2142 config_output->name, buffer, buffer_size, position, comm, 1);
2143 int filetype_int = (int)config_output->type;
2145 MPI_Pack(
2146 &filetype_int, 1, MPI_INT, buffer, buffer_size, position, comm), comm);
2148 "yac_couple_config_pack_config_output",
2149 config_output->ref, buffer, buffer_size, position, comm, 1);
2150}
2151
2153 void * buffer, int buffer_size, int * position, void * grid_,
2154 MPI_Comm comm) {
2155
2156 struct yac_couple_config_grid * grid =
2157 (struct yac_couple_config_grid *)grid_;
2158
2159 grid->name =
2160 yac_string_unpack(buffer, buffer_size, position, comm);
2161 grid->output_filename = NULL;
2162 grid->metadata = NULL;
2163}
2164
2166 void * buffer, int buffer_size, int * position, void * field_,
2167 MPI_Comm comm) {
2168
2169 struct yac_couple_config_field * field =
2170 (struct yac_couple_config_field *)field_;
2171
2172 int grid_idx_int;
2174 MPI_Unpack(
2175 buffer, buffer_size, position, &grid_idx_int, 1, MPI_INT, comm), comm);
2176
2177 YAC_ASSERT(
2178 grid_idx_int >= 0,
2179 "ERROR(yac_couple_config_unpack_field): invalid number of grid_idx_int")
2180
2181 field->grid_idx = (size_t)grid_idx_int;
2182 field->frac_mask_fallback_value = YAC_FRAC_MASK_NO_VALUE;
2183 field->collection_size = SIZE_MAX;
2184 field->name = yac_string_unpack(buffer, buffer_size, position, comm);
2185 field->timestep = NULL;
2186 field->metadata = NULL;
2187}
2188
2190 void * buffer, int buffer_size, int * position, void * component_,
2191 MPI_Comm comm) {
2192
2193 struct yac_couple_config_component * component =
2194 (struct yac_couple_config_component *)component_;
2195
2196 component->name = yac_string_unpack(buffer, buffer_size, position, comm);
2197 component->metadata = NULL;
2198 component->num_fields = 0;
2199 component->fields = NULL;
2200}
2201
2203 void * buffer, int buffer_size, int * position, void * field_couple_,
2204 MPI_Comm comm) {
2205
2206 struct yac_couple_config_field_couple * field_couple =
2207 (struct yac_couple_config_field_couple *)field_couple_;
2208
2209 int ints[12];
2211 MPI_Unpack(
2212 buffer, buffer_size, position, ints, 12, MPI_INT, comm), comm);
2213
2214 YAC_ASSERT(
2215 ints[0] >= 0,
2216 "ERROR(yac_couple_config_unpack_field_couple): "
2217 "invalid source.component_idx")
2218 YAC_ASSERT(
2219 ints[1] >= 0,
2220 "ERROR(yac_couple_config_unpack_field_couple): "
2221 "invalid source.field_idx")
2222 YAC_ASSERT(
2223 ints[3] >= 0,
2224 "ERROR(yac_couple_config_unpack_field_couple): "
2225 "target.component_idx bigger than INT_MAX")
2226 YAC_ASSERT(
2227 ints[4] >= 0,
2228 "ERROR(yac_couple_config_unpack_field_couple): "
2229 "invalid target.field_idx")
2230 YAC_ASSERT(
2231 ints[6] >= 0,
2232 "ERROR(yac_couple_config_unpack_field_couple): "
2233 "invalid mapping_on_source")
2234 YAC_ASSERT(
2235 ints[7] >= 0,
2236 "ERROR(yac_couple_config_unpack_field_couple): "
2237 "invalid coupling_period_operation")
2238 YAC_ASSERT(
2239 ints[8] >= 0,
2240 "ERROR(yac_couple_config_unpack_field_couple): "
2241 "invalid enforce_write_weight_file")
2242 YAC_ASSERT(
2243 ints[9] >= 0,
2244 "ERROR(yac_couple_config_unpack_field_couple): "
2245 "invalid weight_file_on_existing")
2246 YAC_ASSERT(
2247 ints[10] >= 0,
2248 "ERROR(yac_couple_config_unpack_field_couple): "
2249 "invalid num_src_mask_names")
2250 YAC_ASSERT(
2251 (ints[11] == 0) || (ints[11] == 1),
2252 "ERROR(yac_couple_config_unpack_field_couple): "
2253 "invalid use_raw_exchange")
2254
2255 field_couple->source.component_idx = (size_t)(ints[0]);
2256 field_couple->source.field_idx = (size_t)(ints[1]);
2257 field_couple->source.lag = ints[2];
2258 field_couple->target.component_idx = (size_t)(ints[3]);
2259 field_couple->target.field_idx = (size_t)(ints[4]);
2260 field_couple->target.lag = ints[5];
2261 field_couple->mapping_on_source = ints[6];
2262 field_couple->coupling_period_operation =
2263 (enum yac_reduction_type)(ints[7]);
2264 field_couple->enforce_write_weight_file = ints[8];
2265 field_couple->weight_file_on_existing =
2266 (enum yac_weight_file_on_existing)ints[9];
2267 field_couple->num_src_mask_names = (size_t)(ints[10]);
2268 field_couple->use_raw_exchange = (size_t)(ints[11]);
2269
2270 field_couple->coupling_period =
2271 yac_string_unpack(buffer, buffer_size, position, comm);
2272 field_couple->weight_file_name =
2273 yac_string_unpack(buffer, buffer_size, position, comm);
2274
2275 double doubles[2];
2277 MPI_Unpack(
2278 buffer, buffer_size, position, doubles, 2, MPI_DOUBLE, comm), comm);
2279
2280 field_couple->scale_factor = doubles[0];
2281 field_couple->scale_summand = doubles[1];
2282
2283 field_couple->interp_stack =
2284 yac_interp_stack_config_unpack(buffer, buffer_size, position, comm);
2285
2286 if (field_couple->num_src_mask_names > 0) {
2287 field_couple->src_mask_names =
2288 xmalloc(
2289 field_couple->num_src_mask_names *
2290 sizeof(*(field_couple->src_mask_names)));
2291 for (size_t i = 0; i < field_couple->num_src_mask_names; ++i)
2292 field_couple->src_mask_names[i] =
2293 yac_string_unpack(buffer, buffer_size, position, comm);
2294 } else {
2295 field_couple->src_mask_names = NULL;
2296 }
2297
2298 field_couple->tgt_mask_name =
2299 yac_string_unpack(buffer, buffer_size, position, comm);
2300
2301 field_couple->yaxt_exchanger_name =
2302 yac_string_unpack(buffer, buffer_size, position, comm);
2303
2304 field_couple->collection_selection =
2306 buffer, buffer_size, position, comm);
2307}
2308
2310 void * buffer, int buffer_size, int * position, void * couple_,
2311 MPI_Comm comm) {
2312
2313 struct yac_couple_config_couple * couple =
2314 (struct yac_couple_config_couple *)couple_;
2315
2316 int component_indices[2];
2318 MPI_Unpack(
2319 buffer, buffer_size, position, component_indices, 2, MPI_INT, comm),
2320 comm);
2321
2322 YAC_ASSERT(
2323 (component_indices[0] >= 0) && (component_indices[1] >= 0),
2324 "ERROR(yac_couple_config_unpack_couple): invalid component indices")
2325
2326 couple->component_indices[0] = (size_t)(component_indices[0]);
2327 couple->component_indices[1] = (size_t)(component_indices[1]);
2328 couple->num_field_couples = 0;
2329 couple->field_couples = NULL;
2330}
2331
2333 void * buffer, int buffer_size, int * position, void * config_output_,
2334 MPI_Comm comm) {
2335
2336 struct yac_couple_config_config_output * config_output =
2337 (struct yac_couple_config_config_output *)config_output_;
2338
2339 config_output->name =
2340 yac_string_unpack(buffer, buffer_size, position, comm);
2341 int filetype_int;
2343 MPI_Unpack(
2344 buffer, buffer_size, position, &filetype_int, 1, MPI_INT, comm),
2345 comm);
2346 config_output->type = (enum yac_text_filetype)filetype_int;
2347 config_output->ref =
2348 yac_string_unpack(buffer, buffer_size, position, comm);
2349 config_output->include_definitions = FLAG_UNSET;
2350}
2351
2353 struct yac_couple_config * couple_config,
2354 char const * src_comp_name, char const * src_grid_name, char const * src_field_name,
2355 char const * tgt_comp_name, char const * tgt_grid_name, char const * tgt_field_name,
2356 char const * coupling_period, int time_reduction,
2357 struct yac_interp_stack_config * interp_stack, int src_lag, int tgt_lag,
2358 const char* weight_file_name, int weight_file_on_existing,
2359 int mapping_on_source, double scale_factor, double scale_summand,
2360 size_t num_src_mask_names, char const * const * src_mask_names,
2361 char const * tgt_mask_name, char const * yaxt_exchanger_name,
2362 struct yac_collection_selection const * collection_selection,
2363 int use_raw_exchange) {
2364
2365 YAC_ASSERT(src_comp_name && src_comp_name[0] != '\0',
2366 "ERROR(yac_couple_config_def_couple): invalid parameter: src_comp_name");
2368 "ERROR(yac_couple_config_def_couple): invalid parameter: src_grid_name");
2369 YAC_ASSERT(src_field_name && src_field_name[0] != '\0',
2370 "ERROR(yac_couple_config_def_couple): invalid parameter: src_field_name");
2371 YAC_ASSERT(tgt_comp_name && tgt_comp_name[0] != '\0',
2372 "ERROR(yac_couple_config_def_couple): invalid parameter: tgt_comp_name");
2374 "ERROR(yac_couple_config_def_couple): invalid parameter: tgt_grid_name");
2375 YAC_ASSERT(tgt_field_name && tgt_field_name[0] != '\0',
2376 "ERROR(yac_couple_config_def_couple): invalid parameter: tgt_field_name");
2377 YAC_ASSERT(coupling_period && coupling_period[0] != '\0',
2378 "ERROR(yac_couple_config_def_couple): invalid parameter: coupling_period");
2379 YAC_ASSERT(
2380 (time_reduction == TIME_NONE) ||
2381 (time_reduction == TIME_ACCUMULATE) ||
2382 (time_reduction == TIME_AVERAGE) ||
2383 (time_reduction == TIME_MINIMUM) ||
2384 (time_reduction == TIME_MAXIMUM),
2385 "ERROR(yac_couple_config_def_couple): invalid parameter: time_reduction");
2386 YAC_ASSERT_F(isnormal(scale_factor),
2387 "ERROR(yac_couple_config_def_couple): \"%lf\" is not a valid scale factor",
2388 scale_factor);
2389 YAC_ASSERT_F(isnormal(scale_summand) || (scale_summand == 0.0),
2390 "ERROR(yac_couple_config_def_couple): \"%lf\" is not a valid scale summand",
2391 scale_summand);
2392 YAC_ASSERT(
2393 (collection_selection == NULL) ||
2394 (yac_collection_selection_get_collection_size(collection_selection) > 0),
2395 "ERROR(yac_couple_config_def_couple): invalid collection selection "
2396 "(size has to be > 0, if provided)");
2397 YAC_ASSERT(
2398 (weight_file_on_existing == YAC_WEIGHT_FILE_ERROR) ||
2399 (weight_file_on_existing == YAC_WEIGHT_FILE_KEEP) ||
2400 (weight_file_on_existing == YAC_WEIGHT_FILE_OVERWRITE),
2401 "ERROR(yac_couple_config_def_couple): invalid parameter: weight_file_on_existing");
2402
2403 // get component indices
2404 size_t src_comp_idx =
2405 yac_couple_config_add_component_(couple_config, src_comp_name);
2406 size_t tgt_comp_idx =
2407 yac_couple_config_add_component_(couple_config, tgt_comp_name);
2408 size_t src_grid_idx =
2410 size_t tgt_grid_idx =
2412
2413 // check if couple exists
2414 size_t component_indices[2];
2415 if(src_comp_idx < tgt_comp_idx){
2416 component_indices[0] = src_comp_idx;
2417 component_indices[1] = tgt_comp_idx;
2418 }else{
2419 component_indices[0] = tgt_comp_idx;
2420 component_indices[1] = src_comp_idx;
2421 }
2422 struct yac_couple_config_couple * couple = NULL;
2423 for(size_t i = 0; (i < couple_config->num_couples) && !couple; ++i)
2424 if(couple_config->couples[i].component_indices[0] == component_indices[0] &&
2425 couple_config->couples[i].component_indices[1] == component_indices[1])
2426 couple = &couple_config->couples[i];
2427
2428 // create if couple does not exists
2429 if(!couple){
2430 couple_config->couples =
2431 xrealloc(
2432 couple_config->couples,
2433 (couple_config->num_couples + 1) * sizeof(*couple_config->couples));
2434 couple = &couple_config->couples[couple_config->num_couples];
2435 couple_config->num_couples++;
2436 couple->component_indices[0] = component_indices[0];
2437 couple->component_indices[1] = component_indices[1];
2438 couple->num_field_couples = 0;
2439 couple->field_couples = NULL;
2440 }
2441
2442 // get field indices
2443 size_t src_field_idx =
2445 couple_config, src_comp_idx, src_grid_idx,
2446 src_field_name, NULL, SIZE_MAX);
2447 size_t tgt_field_idx =
2449 couple_config, tgt_comp_idx, tgt_grid_idx,
2450 tgt_field_name, NULL, SIZE_MAX);
2451
2452 struct yac_couple_config_field_couple field_couple;
2453 field_couple.source.component_idx = src_comp_idx;
2454 field_couple.source.field_idx = src_field_idx;
2455 field_couple.source.lag = src_lag;
2456 field_couple.target.component_idx = tgt_comp_idx;
2457 field_couple.target.field_idx = tgt_field_idx;
2458 field_couple.target.lag = tgt_lag;
2459 field_couple.coupling_period = strdup(coupling_period);
2460 field_couple.coupling_period_operation =
2461 (enum yac_reduction_type)time_reduction;
2463 field_couple.mapping_on_source = mapping_on_source;
2464 field_couple.weight_file_name =
2466 field_couple.scale_factor = scale_factor;
2467 field_couple.scale_summand = scale_summand;
2468 field_couple.enforce_write_weight_file = weight_file_name != NULL;
2469 field_couple.weight_file_on_existing =
2472 if (num_src_mask_names > 0) {
2473 field_couple.src_mask_names =
2475 for (size_t i = 0; i < num_src_mask_names; ++i)
2476 field_couple.src_mask_names[i] = strdup(src_mask_names[i]);
2477 } else {
2478 field_couple.src_mask_names = NULL;
2479 }
2480 field_couple.tgt_mask_name = string_dup(tgt_mask_name);
2482 field_couple.collection_selection =
2484 field_couple.use_raw_exchange = use_raw_exchange != 0;
2485
2486 // check if field_couple exists
2487 int found_flag = 0;
2488 for(size_t i = 0; (i < couple->num_field_couples) && !found_flag; ++i) {
2490 couple->field_couples + i, &field_couple)) {
2492 couple->field_couples + i, &field_couple, MPI_COMM_SELF);
2494 found_flag = 1;
2495 }
2496 }
2497
2498 if (!found_flag) {
2499 couple->field_couples = xrealloc(couple->field_couples,
2500 (couple->num_field_couples + 1) * sizeof(*couple->field_couples));
2501 couple->field_couples[couple->num_field_couples] = field_couple;
2502 couple->num_field_couples++;
2503 }
2504}
2505
2507 char const * type_datetime, struct _datetime ** datetime, MPI_Comm comm) {
2508
2509 // convert datetime to string
2510 char datetime_buffer[MAX_DATETIME_STR_LEN];
2511 char * str_datetime = datetimeToString(*datetime, datetime_buffer);
2512
2513 // copy from static to dynamic memory
2514 if (str_datetime != NULL) str_datetime = strdup(str_datetime);
2515
2516 // delete old datetime
2517 deallocateDateTime(*datetime);
2518
2519 // synchronize datetime string across processes
2520 couple_config_sync_string(type_datetime, &str_datetime, comm);
2521
2522 // convert datetime string to _datetime struct
2523 *datetime = newDateTime(str_datetime);
2524
2525 free(str_datetime);
2526}
2527
2529 struct yac_couple_config * couple_config, MPI_Comm comm) {
2530
2533 "start_datetime", &(couple_config->start_datetime), comm);
2535 "end_datetime", &(couple_config->end_datetime), comm);
2536}
2537
2581
2582static void merge_grids(
2583 struct yac_couple_config * couple_config, MPI_Comm comm) {
2584
2585 size_t* old_to_new_idx;
2586 void * p_grids = couple_config->grids;
2588 &couple_config->num_grids, &p_grids,
2589 sizeof(couple_config->grids[0]),
2590 comm, &dist_merge_vtable_grid, &old_to_new_idx);
2591 couple_config->grids = p_grids;
2592
2593 // set new grid_idx in fields
2594 for(size_t comp_idx = 0; comp_idx < couple_config->num_components;
2595 ++comp_idx) {
2596 struct yac_couple_config_component * component =
2597 couple_config->components + comp_idx;
2598 for(size_t field_idx = 0; field_idx < component->num_fields; ++field_idx)
2599 component->fields[field_idx].grid_idx =
2600 old_to_new_idx[component->fields[field_idx].grid_idx];
2601 }
2602
2603 free(old_to_new_idx);
2604}
2605
2606static void merge_fields(
2607 struct yac_couple_config * couple_config, size_t comp_idx, MPI_Comm comm) {
2608
2609 struct yac_couple_config_component * component =
2610 couple_config->components + comp_idx;
2611
2612 size_t* old_to_new_idx;
2613 void * p_fields = component->fields;
2615 &component->num_fields, &p_fields,
2616 sizeof(component->fields[0]),
2617 comm, &dist_merge_vtable_field, &old_to_new_idx);
2618 component->fields = p_fields;
2619
2620 // set new field_idx in all field_couples
2621 for(size_t couple_idx = 0; couple_idx < couple_config->num_couples;
2622 ++couple_idx) {
2623 struct yac_couple_config_couple * couple =
2624 couple_config->couples + couple_idx;
2625 for(size_t field_couple_idx = 0;
2626 field_couple_idx < couple->num_field_couples; ++field_couple_idx){
2627 struct yac_couple_config_field_couple * field_couple =
2628 couple->field_couples + field_couple_idx;
2629 if(field_couple->source.component_idx == comp_idx)
2630 field_couple->source.field_idx =
2631 old_to_new_idx[field_couple->source.field_idx];
2632 if(field_couple->target.component_idx == comp_idx)
2633 field_couple->target.field_idx =
2634 old_to_new_idx[field_couple->target.field_idx];
2635 }
2636 }
2637
2638 free(old_to_new_idx);
2639}
2640
2642 struct yac_couple_config * couple_config, MPI_Comm comm) {
2643
2644 // distribute and merge basic component information while keeping the
2645 // individual fields
2646 size_t* old_to_new_idx;
2647 void * p_components = couple_config->components;
2649 &couple_config->num_components, &p_components,
2650 sizeof(couple_config->components[0]),
2651 comm, &dist_merge_vtable_component, &old_to_new_idx);
2652 couple_config->components = p_components;
2653
2654 // set new component_idx in couples
2655 for(size_t couple_idx = 0; couple_idx < couple_config->num_couples;
2656 ++couple_idx) {
2657 struct yac_couple_config_couple * couple =
2658 couple_config->couples + couple_idx;
2659 couple->component_indices[0] = old_to_new_idx[couple->component_indices[0]];
2660 couple->component_indices[1] = old_to_new_idx[couple->component_indices[1]];
2661 if (couple->component_indices[1] < couple->component_indices[0]) {
2662 size_t temp_component_index = couple->component_indices[0];
2663 couple->component_indices[0] = couple->component_indices[1];
2664 couple->component_indices[1] = temp_component_index;
2665 }
2666 for(size_t field_couple_idx = 0;
2667 field_couple_idx < couple->num_field_couples; ++field_couple_idx) {
2668 couple->field_couples[field_couple_idx].source.component_idx =
2669 old_to_new_idx[
2670 couple->field_couples[field_couple_idx].source.component_idx];
2671 couple->field_couples[field_couple_idx].target.component_idx =
2672 old_to_new_idx[
2673 couple->field_couples[field_couple_idx].target.component_idx];
2674 }
2675 }
2676 free(old_to_new_idx);
2677
2678 // merge the fields of each component
2679 for (size_t comp_idx = 0; comp_idx < couple_config->num_components; ++comp_idx)
2680 merge_fields(couple_config, comp_idx, comm);
2681}
2682
2684 size_t * num_field_couples,
2685 struct yac_couple_config_field_couple ** field_couples, MPI_Comm comm) {
2686
2687 void * p_field_couples = *field_couples;
2689 num_field_couples, &p_field_couples, sizeof(**field_couples),
2690 comm, &dist_merge_vtable_field_couple, NULL);
2691 *field_couples = p_field_couples;
2692}
2693
2694static void merge_couples(
2695 struct yac_couple_config * couple_config, MPI_Comm comm) {
2696
2697 // distribute and merge basic couple information while keeping the
2698 // individual field couples
2699 void * p_couples = couple_config->couples;
2701 &couple_config->num_couples, &p_couples,
2702 sizeof(couple_config->couples[0]),
2703 comm, &dist_merge_vtable_couple, NULL);
2704 couple_config->couples = p_couples;
2705}
2706
2708 struct yac_couple_config * couple_config, MPI_Comm comm) {
2709
2710 // distribute and merge basic couple information while keeping the
2711 // individual field couples
2712 void * p_config_outputs = couple_config->config_outputs;
2714 &couple_config->num_config_outputs, &p_config_outputs,
2715 sizeof(couple_config->config_outputs[0]),
2716 comm, &dist_merge_vtable_config_output, NULL);
2717 couple_config->config_outputs = p_config_outputs;
2718}
2719
2721 struct yac_couple_config * couple_config, MPI_Comm comm,
2722 char const * output_ref){
2723
2724 // sync time stuff
2725 couple_config_sync_time(couple_config, comm);
2726
2727 merge_config_output(couple_config, comm);
2728 merge_grids(couple_config, comm);
2729 merge_components(couple_config, comm);
2730 merge_couples(couple_config, comm);
2731
2733 "missing_definition_is_fatal",
2734 &(couple_config->missing_definition_is_fatal), comm);
2735
2736 struct yac_couple_config_config_output * config_output = NULL;
2737 if (output_ref != NULL)
2738 for (size_t i = 0; (i < couple_config->num_config_outputs) &&
2739 (config_output == NULL); ++i)
2740 if (!strcmp(output_ref, couple_config->config_outputs[i].ref))
2741 config_output = couple_config->config_outputs + i;
2742
2743 if (config_output != NULL) {
2744
2745 int rank;
2746 MPI_Comm_rank(comm, &rank);
2747
2748 // rank 0 writes the coupling configuration to file
2749 if (rank == 0) {
2750
2751 FILE * config_file = fopen(config_output->name, "w");
2752
2754 config_file != NULL,
2755 "ERROR(yac_couple_config_sync): "
2756 "failed to create coupling configuration file \"%s\"",
2757 config_output->name);
2758
2760 (config_output->type == YAC_TEXT_FILETYPE_YAML) ||
2761 (config_output->type == YAC_TEXT_FILETYPE_JSON),
2762 "ERROR(yac_couple_config_sync): "
2763 "invalid coupling configuration filetype (type = %d)",
2764 config_output->type);
2765
2766 int emit_flags;
2767 switch(config_output->type) {
2768 default:
2770 emit_flags = YAC_YAML_EMITTER_DEFAULT;
2771 break;
2773 emit_flags = YAC_YAML_EMITTER_JSON;
2774 break;
2775 }
2776
2777 enum flag_value include_definitions = FLAG_FALSE; // default value
2778 if (config_output->include_definitions != FLAG_UNSET)
2780 char * str_couple_config =
2782 couple_config, emit_flags, (int)include_definitions);
2783
2784 fputs(str_couple_config, config_file);
2785 free(str_couple_config);
2786 fclose(config_file);
2787 }
2788 yac_mpi_call(MPI_Barrier(comm), comm);
2789 }
2790}
2791
2793 struct yac_couple_config * couple_config,
2794 char const * filename, enum yac_text_filetype filetype, char const * ref,
2795 int include_definitions) {
2796
2797 YAC_ASSERT(
2798 filename != NULL,
2799 "ERROR(yac_couple_config_set_config_output_filename): filename is NULL");
2800
2802 (filetype == YAC_TEXT_FILETYPE_YAML) ||
2803 (filetype == YAC_TEXT_FILETYPE_JSON),
2804 "ERROR(yac_couple_config_set_config_output_filename): "
2805 "invalid output configuration filetype (type = %d)",
2806 (int)filetype);
2807
2808 YAC_ASSERT(
2809 ref != NULL,
2810 "ERROR(yac_couple_config_set_config_output_filename): ref is NULL");
2811
2812 // check whether there already exists a config output with the same reference
2813 for (size_t i = 0; i < couple_config->num_config_outputs; ++i) {
2814 if (!strcmp(couple_config->config_outputs[i].ref, ref)) {
2816 !strcmp(couple_config->config_outputs[i].name, filename) &&
2817 couple_config->config_outputs[i].type == filetype,
2818 "ERROR(yac_couple_config_set_config_output_filename): "
2819 "an filename has already been set for reference "
2820 "(ref \"%s\" curr filename \"%s\" filetype %d; "
2821 "new filename \"%s\" filetype %d",
2822 ref, couple_config->config_outputs[i].name,
2823 couple_config->config_outputs[i].type, filename, filetype);
2824 return;
2825 }
2826 }
2827
2828 couple_config->config_outputs =
2829 xrealloc(
2830 couple_config->config_outputs,
2831 (couple_config->num_config_outputs + 1) *
2832 sizeof(*(couple_config->config_outputs)));
2833
2834 couple_config->config_outputs[
2835 couple_config->num_config_outputs].name = strdup(filename);
2836 couple_config->config_outputs[
2837 couple_config->num_config_outputs].type = filetype;
2838 couple_config->config_outputs[
2839 couple_config->num_config_outputs].ref = strdup(ref);
2840 couple_config->config_outputs[
2841 couple_config->num_config_outputs].include_definitions =
2842 (enum flag_value)(include_definitions != 0);
2843 couple_config->num_config_outputs++;
2844}
2845
2847 struct yac_couple_config * couple_config,
2848 char const * tgt_component_name, char const * tgt_grid_name,
2849 char const * tgt_field_name, char const ** src_component_name,
2850 char const ** src_grid_name, char const ** src_field_name) {
2851
2852 size_t tgt_comp_idx =
2853 yac_couple_config_get_component_idx(couple_config, tgt_component_name);
2854 size_t tgt_grid_idx =
2856 size_t tgt_field_idx =
2858 couple_config, tgt_comp_idx, tgt_grid_idx, tgt_field_name);
2859
2860 struct yac_couple_config_field_couple * field_couple = NULL;
2861 for (size_t couple_idx = 0; couple_idx < couple_config->num_couples;
2862 ++couple_idx) {
2863
2864 struct yac_couple_config_couple * couple =
2865 couple_config->couples + couple_idx;
2866
2867 if ((couple->component_indices[0] != tgt_comp_idx) &&
2868 (couple->component_indices[1] != tgt_comp_idx))
2869 continue;
2870
2871 for (size_t temp_field_couple_idx = 0;
2872 temp_field_couple_idx < couple->num_field_couples;
2873 ++temp_field_couple_idx) {
2874
2875 struct yac_couple_config_field_couple * temp_field_couple =
2876 couple->field_couples + temp_field_couple_idx;
2877
2878 if ((temp_field_couple->target.component_idx == tgt_comp_idx) &&
2879 (temp_field_couple->target.field_idx == tgt_field_idx)) {
2880
2882 field_couple == NULL,
2883 "ERROR(yac_couple_config_get_field_source): "
2884 "multiple couples with the same target field is not supported by "
2885 "this routine (target component: \"%s\" target grid: \"%s\""
2886 "target field: \"%s\")", tgt_component_name, tgt_grid_name,
2887 tgt_field_name);
2888
2889 field_couple = temp_field_couple;
2890 }
2891 }
2892 }
2893
2895 field_couple != NULL,
2896 "ERROR(yac_couple_config_get_field_source): "
2897 "provided field is not defined as a target in any coupling "
2898 "(target component: \"%s\" target grid: \"%s\" target field: \"%s\")",
2899 tgt_component_name, tgt_grid_name, tgt_field_name);
2900
2901 struct yac_couple_config_component * src_component =
2902 couple_config->components + field_couple->source.component_idx;
2903 struct yac_couple_config_field * src_field =
2904 src_component->fields + field_couple->source.field_idx;
2905 struct yac_couple_config_grid * src_grid =
2906 couple_config->grids + src_field->grid_idx;
2907
2908 *src_component_name = src_component->name;
2909 *src_grid_name = src_grid->name;
2910 *src_field_name = src_field->name;
2911}
2912
2915 struct yac_couple_config * couple_config,
2916 size_t couple_idx, size_t field_couple_idx) {
2917
2919 couple_config, couple_idx, field_couple_idx,
2920 "yac_couple_config_get_interpolation_gen_config", __LINE__);
2921
2922 struct yac_couple_config_couple * couple =
2923 &couple_config->couples[couple_idx];
2924 struct yac_couple_config_field_couple * field_couple =
2925 &couple->field_couples[field_couple_idx];
2926
2927 struct yac_couple_config_component * src_comp =
2928 &couple_config->components[field_couple->source.component_idx];
2929 struct yac_couple_config_field * src_field =
2930 &src_comp->fields[field_couple->source.field_idx];
2931 struct yac_couple_config_grid * src_grid =
2932 &couple_config->grids[src_field->grid_idx];
2933
2934 struct yac_couple_config_component * tgt_comp =
2935 &couple_config->components[field_couple->target.component_idx];
2936 struct yac_couple_config_field * tgt_field =
2937 &tgt_comp->fields[field_couple->target.field_idx];
2938 struct yac_couple_config_grid * tgt_grid =
2939 &couple_config->grids[tgt_field->grid_idx];
2940
2941 // generate new interpolation generation configuration object
2942 struct yac_interpolation_gen_config * interp_gen_config =
2944
2945 // set reorder type
2947 interp_gen_config,
2949
2950 // set fractional masking fallback value
2951 double frac_mask_fallback_value = src_field->frac_mask_fallback_value;
2954 "ERROR(yac_couple_config_get_interpolation_gen_config): "
2955 "no valid fractional mask fallback value defined "
2956 "(component: \"%s\" grid: \"%s\" field \"%s\")",
2957 src_comp->name, src_grid->name, src_field->name);
2958 // if it is not NO_VALUE
2961 interp_gen_config, frac_mask_fallback_value);
2962 }
2963
2964 // set scaling factor, scaling summand, and yaxt exchanger name
2966 interp_gen_config, field_couple->scale_factor);
2968 interp_gen_config, field_couple->scale_summand);
2970 interp_gen_config, field_couple->yaxt_exchanger_name);
2971
2972 // get source and target field collection size
2973 size_t src_collection_size = src_field->collection_size;
2974 size_t tgt_collection_size = tgt_field->collection_size;
2975
2976 // if the user provided a collection selection for the couple
2977 if (field_couple->collection_selection != NULL) {
2978
2981 field_couple->collection_selection) == tgt_field->collection_size,
2982 "ERROR(yac_couple_config_get_interpolation_gen_config): "
2983 "target field collection size does not match size of provided "
2984 "collection selection: \n"
2985 " source:\n"
2986 " component name: \"%s\"\n"
2987 " grid name: \"%s\"\n"
2988 " field name: \"%s\"\n"
2989 " collection_size: %zu\n"
2990 " target:\n"
2991 " component name: \"%s\"\n"
2992 " grid name: \"%s\"\n"
2993 " field name: \"%s\"\n"
2994 " collection_size: %zu\n"
2995 " collection selection:\n"
2996 " size: %zu\n"
2997 " max_index: %zu\n",
2998 src_comp->name, src_grid->name, src_field->name, src_collection_size,
2999 tgt_comp->name, tgt_grid->name, tgt_field->name, tgt_collection_size,
3001 field_couple->collection_selection),
3003 field_couple->collection_selection));
3006 field_couple->collection_selection) < src_field->collection_size,
3007 "ERROR(yac_couple_config_get_interpolation_gen_config): "
3008 "maximum index of provided collection selection exceeds source "
3009 "field collection size: \n"
3010 " source:\n"
3011 " component name: \"%s\"\n"
3012 " grid name: \"%s\"\n"
3013 " field name: \"%s\"\n"
3014 " collection_size: %zu\n"
3015 " target:\n"
3016 " component name: \"%s\"\n"
3017 " grid name: \"%s\"\n"
3018 " field name: \"%s\"\n"
3019 " collection_size: %zu\n"
3020 " collection selection:\n"
3021 " size: %zu\n"
3022 " max_index: %zu\n",
3023 src_comp->name, src_grid->name, src_field->name, src_collection_size,
3024 tgt_comp->name, tgt_grid->name, tgt_field->name, tgt_collection_size,
3026 field_couple->collection_selection),
3028 field_couple->collection_selection));
3029
3031 interp_gen_config, field_couple->collection_selection);
3032
3033 } else { // no collection selection was provided by the user
3035 src_collection_size == tgt_collection_size,
3036 "ERROR(yac_couple_config_get_interpolation_gen_config): "
3037 "collection sizes do not match for coupled fields (%zu != %zu): \n"
3038 " source:\n"
3039 " component name: \"%s\"\n"
3040 " grid name: \"%s\"\n"
3041 " field name: \"%s\"\n"
3042 " target:\n"
3043 " component name: \"%s\"\n"
3044 " grid name: \"%s\"\n"
3045 " field name: \"%s\"\n",
3046 src_collection_size, tgt_collection_size,
3047 src_comp->name, src_grid->name, src_field->name,
3048 tgt_comp->name, tgt_grid->name, tgt_field->name);
3049
3051 interp_gen_config, src_collection_size);
3052 }
3053
3054 return interp_gen_config;
3055}
unsigned component_idx[3]
unsigned num_components
unsigned grid_idx[3]
#define YAC_ASSERT(exp, msg)
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:66
int const YAC_YAML_EMITTER_JSON
emit to JSON format
Definition config_yaml.c:67
#define UNUSED(x)
Definition core.h:72
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)
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)
struct yac_interpolation_gen_config * yac_couple_config_get_interpolation_gen_config(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
char const * yac_couple_config_get_coupling_period(struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
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)
struct yac_collection_selection const * yac_couple_config_get_collection_selection(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 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_)
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)
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, struct yac_collection_selection const *collection_selection, int use_raw_exchange)
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:67
size_t yac_collection_selection_get_collection_size(struct yac_collection_selection const *collection_selection)
Get the size of the collection selection.
struct yac_collection_selection * yac_collection_selection_unpack(void const *buffer, int buffer_size, int *position, MPI_Comm comm)
Unpack a collection selection from a contiguous MPI buffer.
size_t yac_collection_selection_get_pack_size(struct yac_collection_selection const *sel, MPI_Comm comm)
Compute the MPI pack size of a collection selection.
void yac_collection_selection_delete(struct yac_collection_selection *collection_selection)
Delete a collection selection object.
int yac_collection_selection_compare(struct yac_collection_selection const *a, struct yac_collection_selection const *b)
Compare two collection selections.
struct yac_collection_selection * yac_collection_selection_copy(const struct yac_collection_selection *collection_selection)
Selection of indices from a collection.
void yac_collection_selection_pack(struct yac_collection_selection const *sel, void *buffer, int buffer_size, int *position, MPI_Comm comm)
Pack a collection selection into a contiguous MPI buffer.
size_t yac_collection_selection_get_max_index(struct yac_collection_selection const *selection)
Get the maximum index of a collection selection.
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_MAPPING_ON_TGT
weights will be applied at target processes
@ YAC_MAPPING_ON_SRC
weights will be applied at source processes
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
void yac_interpolation_gen_config_set_reorder(struct yac_interpolation_gen_config *config, enum yac_interp_weights_reorder_type reorder)
Set the reordering strategy for interpolation weights.
void yac_interpolation_gen_config_set_collection_size(struct yac_interpolation_gen_config *config, size_t collection_size)
Set the number of contiguous fields (starting at "0") in the field collection.
void yac_interpolation_gen_config_set_collection_selection(struct yac_interpolation_gen_config *config, struct yac_collection_selection const *collection_selection)
Set the collection selection of source field in the source field collection.
void yac_interpolation_gen_config_set_scaling_factor(struct yac_interpolation_gen_config *config, double scaling_factor)
Set the multiplicative scaling factor.
void yac_interpolation_gen_config_set_yaxt_exchanger_name(struct yac_interpolation_gen_config *config, char const *name)
Set the name of the Yaxt exchanger.
void yac_interpolation_gen_config_set_frac_mask_fallback_value(struct yac_interpolation_gen_config *config, double frac_mask_fallback_value)
Set the fractional mask fallback value.
struct yac_interpolation_gen_config * yac_interpolation_gen_config_new(void)
Allocate and initialise an interpolation generation configuration structure.
void yac_interpolation_gen_config_set_scaling_summand(struct yac_interpolation_gen_config *config, double scaling_summand)
Set the additive scaling summand.
Configuration management for interpolation generation.
Defines internal basic interpolation definitions.
#define YAC_FRAC_MASK_VALUE_IS_SET(value)
Test whether a fractional mask value is explicitly set.
#define YAC_FRAC_MASK_VALUE_IS_VALID(value)
Test whether a fractional mask value is valid.
#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::@78 target
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::@78 source
struct yac_collection_selection * collection_selection
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
Configuration structure for interpolation generation.
int collection_size
char const * weight_file_name
char const src_grid_name[]
char const tgt_grid_name[]
double * buffer
int nbr_fields
char const * name
Definition toy_scrip.c:114
static struct user_input_data_component ** components
Definition yac.c:158
size_t num_grids
Definition yac.c:156
int const YAC_EXCHANGE_TYPE_SOURCE
Definition yac.c:39
int const YAC_EXCHANGE_TYPE_NONE
Definition yac.c:38
int const YAC_EXCHANGE_TYPE_TARGET
Definition yac.c:40
void yac_cdef_calendar(int calendar)
Definition yac.c:769
int yac_cget_calendar()
Definition yac.c:786
int const YAC_CALENDAR_NOT_SET
Definition yac.c:67
#define YAC_MAX_CHARLEN
Definition yac.h:97
#define YAC_ASSERT_F(exp, format,...)
Definition yac_assert.h:19
size_t yac_string_get_pack_size(char const *caller, char const *string, MPI_Comm comm, int allow_null)
Compute number of bytes required to pack a string for MPI transport.
Definition yac_mpi.c:646
char * yac_string_unpack(void const *buffer, int buffer_size, int *position, MPI_Comm comm)
Unpack a C string from a buffer packed with yac_string_pack.
Definition yac_mpi.c:697
void yac_string_pack(char const *caller, char const *string, void *buffer, int buffer_size, int *position, MPI_Comm comm, int allow_null)
Pack a C string into a provided buffer using MPI_Pack semantics.
Definition yac_mpi.c:667
#define yac_mpi_call(call, comm)