YAC 3.21.0
Yet Another Coupler
Loading...
Searching...
No Matches
config_yaml.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// libfyaml is not very clean...so we have to suppress some warnings
10
11#if defined(__NVCOMPILER)
12# pragma diag_suppress unsigned_compare_with_zero
13#elif defined(__GNUC__)
14# pragma GCC diagnostic push
15# pragma GCC diagnostic ignored "-Wpedantic"
16# pragma GCC diagnostic ignored "-Wall"
17# pragma GCC diagnostic ignored "-Wextra"
18#endif
19#include <libfyaml.h>
20#if defined(__NVCOMPILER)
21# pragma diag_default unsigned_compare_with_zero
22#elif defined(__GNUC__)
23# pragma GCC diagnostic pop
24#endif
25
26#include <inttypes.h>
27#include <limits.h>
28#include <stdlib.h>
29#include <string.h>
30#include <stdbool.h>
31#include <errno.h>
32
33#include "yac.h"
34#include "utils_mci.h"
35#include "config_yaml.h"
36#include "mtime_calendar.h"
37#include "geometry.h"
38#include "io_utils.h"
42#include "parameter/param.h"
43#include "instance.h"
44#include "fields.h"
46
47typedef struct fy_document * fy_document_t;
48typedef struct fy_node * fy_node_t;
49typedef struct fy_node_pair * fy_node_pair_t;
50
51enum {
52 EMITTER_DEFAULT = FYECF_DEFAULT,
53 EMITTER_JSON = FYECF_MODE_JSON,
55 PARSER_JSON_AUTO = FYPCF_JSON_AUTO,
56 PARSER_JSON_FORCE = FYPCF_JSON_FORCE,
57};
58
64
65char const * yac_time_to_ISO(
66 char const * time, enum yac_time_unit_type time_unit);
67
69 struct {
70 char const * comp_name;
71 char const * grid_name;
72 int lag;
73 } src;
74 struct {
75 char const * comp_name;
76 struct {
77 char const ** name;
78 size_t count;
80 int lag;
81 } tgt;
82 char const * coupling_period;
85 struct {
86 char const * name;
91
93 char const * src, * tgt;
96
97 char const ** src_mask_names;
99 char const * tgt_mask_name;
100
102
104
106};
107
116
143
152
159
164
169
178
183
184#define OUTPUT_GRIDS_FILE_NAME_STR "file_name"
185
187 yaml_base_keys,
188 DEF_NAME_TYPE_PAIR(start_date, START_DATE),
189 DEF_NAME_TYPE_PAIR(start_datetime, START_DATE),
190 DEF_NAME_TYPE_PAIR(end_date, END_DATE),
191 DEF_NAME_TYPE_PAIR(end_datetime, END_DATE),
192 DEF_NAME_TYPE_PAIR(calendar, CALENDAR),
193 DEF_NAME_TYPE_PAIR(timestep_unit, TIMESTEP_UNIT),
194 DEF_NAME_TYPE_PAIR(coupling, COUPLING),
196
198 yaml_couple_keys,
200 DEF_NAME_TYPE_PAIR(src_component, SOURCE_COMPONENT),
203 DEF_NAME_TYPE_PAIR(tgt_component, TARGET_COMPONENT),
206 DEF_NAME_TYPE_PAIR(coupling_period, COUPLING_PERIOD),
207 DEF_NAME_TYPE_PAIR(time_reduction, TIME_REDUCTION),
212 DEF_NAME_TYPE_PAIR(weight_file_on_existing, WEIGHT_FILE_ON_EXISTING),
213 DEF_NAME_TYPE_PAIR(mapping_side, MAPPING_SIDE),
214 DEF_NAME_TYPE_PAIR(scale_factor, SCALE_FACTOR),
215 DEF_NAME_TYPE_PAIR(scale_summand, SCALE_SUMMAND),
216 DEF_NAME_TYPE_PAIR(interpolation, INTERPOLATION),
217 DEF_NAME_TYPE_PAIR(src_mask_name, SOURCE_MASK_NAME),
218 DEF_NAME_TYPE_PAIR(src_mask_names, SOURCE_MASK_NAMES),
219 DEF_NAME_TYPE_PAIR(tgt_mask_name, TARGET_MASK_NAME),
221 DEF_NAME_TYPE_PAIR(yaxt_exchanger_name, YAXT_EXCHANGER_NAME),
222 DEF_NAME_TYPE_PAIR(collection_selection, COLLECTION_SELECTION),
223 DEF_NAME_TYPE_PAIR(use_raw_exchange, USE_RAW_EXCHANGE))
224
226 yaml_debug_sync_loc_keys,
235
237 yaml_debug_output_grid_keys,
240
242 bool_names,
243 DEF_NAME_TYPE_PAIR(true, true),
244 DEF_NAME_TYPE_PAIR(TRUE, true),
245 DEF_NAME_TYPE_PAIR(yes, true),
246 DEF_NAME_TYPE_PAIR(YES, true),
247 DEF_NAME_TYPE_PAIR(false, false),
248 DEF_NAME_TYPE_PAIR(FALSE, false),
249 DEF_NAME_TYPE_PAIR(no, false),
250 DEF_NAME_TYPE_PAIR(NO, false))
251
253 timestep_units,
254 DEF_NAME_TYPE_PAIR(millisecond, C_MILLISECOND),
261 DEF_NAME_TYPE_PAIR(ISO_format, C_ISO_FORMAT))
262
264 time_operations,
270
272 calendar_types,
273 DEF_NAME_TYPE_PAIR(proleptic-gregorian, PROLEPTIC_GREGORIAN),
274 DEF_NAME_TYPE_PAIR(360d, YEAR_OF_360_DAYS),
275 DEF_NAME_TYPE_PAIR(365d, YEAR_OF_365_DAYS))
276
278 mapping_sides,
279 DEF_NAME_TYPE_PAIR(source, 1),
280 DEF_NAME_TYPE_PAIR(target, 0))
281
283 yaml_debug_keys,
284 DEF_NAME_TYPE_PAIR(global_config, GLOBAL_CONFIG),
285 DEF_NAME_TYPE_PAIR(output_grids, OUTPUT_GRIDS),
286 DEF_NAME_TYPE_PAIR(missing_definition_is_fatal, MISSING_DEF),
287 DEF_NAME_TYPE_PAIR(apply_coordinate_check, APPLY_COORD_CHECK),
288 DEF_NAME_TYPE_PAIR(coordinates_mismatch_is_fatal, COORDS_MISMATCH_FATAL))
289
291 config_filetypes,
296
298 role_types,
299 DEF_NAME_TYPE_PAIR(target, TARGET),
300 DEF_NAME_TYPE_PAIR(source, SOURCE),
301 DEF_NAME_TYPE_PAIR(nothing, NOTHING))
302
304 yaml_comp_grid_names_keys,
305 DEF_NAME_TYPE_PAIR(component, COMP_NAME),
307
309 yaml_weight_file_data_keys,
312
314 weight_file_on_existing_types,
318
319// definition of some assert macros
320#define YAML_ASSERT(CHECK, MSG) \
321 YAC_ASSERT_F( \
322 CHECK, MSG "in YAML configuration file \"%s\"", yaml_filename)
323#define YAML_ASSERT_F(CHECK, MSG, ...) \
324 YAC_ASSERT_F( \
325 CHECK, MSG "in YAML configuration file \"%s\"", __VA_ARGS__, yaml_filename)
326#define YAML_UNREACHABLE_DEFAULT(MSG) \
327 YAC_UNREACHABLE_DEFAULT_F( \
328 MSG "in YAML configuration file \"%s\"", yaml_filename)
329#define YAML_UNREACHABLE_DEFAULT_F(MSG, ...) \
330 YAC_UNREACHABLE_DEFAULT_F( \
331 MSG "in YAML configuration file \"%s\"", __VA_ARGS__, yaml_filename)
332
333static char const * yaml_parse_string_value(
334 fy_node_t value_node, char const * name, char const * yaml_filename) {
335
337 value_node && fy_node_is_scalar(value_node),
338 "unsupported node type for \"%s\" (the node is expected to be scalar)",
339 name);
340
341 return fy_node_get_scalar0(value_node);
342}
343
344static calendarType yaml_parse_calendar_value(
345 fy_node_t value_node, char const * key_name, char const * yaml_filename) {
346
347 char const * calendar_name =
348 yaml_parse_string_value(value_node, key_name, yaml_filename);
349
350 int calendar_type =
352 calendar_types, calendar_types_size, calendar_name);
353
355 calendar_type != INT_MAX,
356 "\"%s\" is not a valid calendar name", calendar_name);
357
358 return (calendarType)calendar_type;
359}
360
361static char const * yaml_parse_timestep_value(
362 fy_node_t value_node, char const * key_name, char const * yaml_filename,
363 enum yac_time_unit_type time_unit) {
364
366 time_unit != TIME_UNIT_UNDEFINED, "time unit is not yet defined");
368 value_node && fy_node_is_scalar(value_node),
369 "unsupported node type for \"%s\" (the node is expected to be scalar)",
370 key_name);
371 char const * timestep =
372 yaml_parse_string_value(value_node, key_name, yaml_filename);
373 char const * timestep_iso =
374 yac_time_to_ISO(timestep, time_unit);
375
377 timestep_iso, "valid to convert timestep \"%s\" to ISO 8601 format",
378 timestep);
379
380 return xstrdup(timestep_iso);
381}
382
384 fy_node_t value_node, char const * key_name, char const * yaml_filename) {
385
386 char const * timestep_unit_str =
387 yaml_parse_string_value(value_node, key_name, yaml_filename);
388
389 int timestep_unit =
391 timestep_units, timestep_units_size, timestep_unit_str);
392
394 timestep_unit != INT_MAX,
395 "\"%s\" is not a valid time step unit", timestep_unit_str);
396
397 return (enum yac_time_unit_type)timestep_unit;
398}
399
401 fy_node_t value_node, char const * key_name, char const * yaml_filename) {
402
403 char const * time_reduction_str =
404 yaml_parse_string_value(value_node, key_name, yaml_filename);
405
406 int time_reduction =
408 time_operations, time_operations_size, time_reduction_str);
409
411 time_reduction != INT_MAX,
412 "\"%s\" is not a valid time reduction type in", time_reduction_str);
413
414 return (enum yac_reduction_type)time_reduction;
415}
416
418 fy_node_t value_node, char const * key_name, char const * yaml_filename) {
419
420 char const * integer_str =
421 yaml_parse_string_value(value_node, key_name, yaml_filename);
422
423 char * endptr;
424 long int long_value = strtol(integer_str, &endptr, 10);
425
427 (endptr != integer_str) && (*endptr == '\0') &&
428 (long_value >= INT_MIN) && (long_value <= INT_MAX),
429 "\"%s\" is not a valid integer value", integer_str);
430
431 return (int)long_value;
432}
433
435 fy_node_t value_node, char const * key_name, char const * yaml_filename) {
436
437 char const * size_t_str =
438 yaml_parse_string_value(value_node, key_name, yaml_filename);
439
440 errno = 0;
441 char *endptr = NULL;
442 uintmax_t temp = strtoumax(size_t_str, &endptr, 10);
443
445 (errno == 0) && (endptr != size_t_str) && (*endptr == '\0') &&
446 (temp <= SIZE_MAX),
447 "\"%s\" is not a valid size_t value", size_t_str);
448
449 return (size_t)temp;
450}
451
453 fy_node_t value_node, char const * key_name, char const * yaml_filename) {
454
455 char const * double_str =
456 yaml_parse_string_value(value_node, key_name, yaml_filename);
457
458 char * endptr;
459 double dble_value = strtod(double_str, &endptr);
460
462 (endptr != double_str) && (*endptr == '\0'),
463 "\"%s\" is not a valid double value for \"%s\"", double_str, key_name);
464
465 return dble_value;
466}
467
469 struct yac_name_type_pair const * valid_values, size_t num_valid_values,
470 fy_node_t value_node, char const * key_name, char const * yaml_filename) {
471
472 char const * value_str =
473 yaml_parse_string_value(value_node, key_name, yaml_filename);
474
475 int value =
477 valid_values, num_valid_values, value_str);
478
480 value != INT_MAX,
481 "\"%s\" is not a valid enum value for \"%s\" ", value_str, key_name);
482
483 return value;
484}
485
496 char const ** interpolation_type_str, fy_node_t * parameter_node,
497 fy_node_t interp_method_node, char const * yaml_filename) {
498
499 fy_node_t interpolation_name_node;
500
501 // determine type of interpolation node
502 switch(fy_node_get_type(interp_method_node)) {
504 "unsupported interpolation method node type "
505 "(interpolation methods are expected to be defined as either scalar "
506 "or maps)");
507
508 // interpolation node only contains the name and not parameters
509 case (FYNT_SCALAR):
510 interpolation_name_node = interp_method_node;
511 *parameter_node = NULL;
512 break;
513
514 // interpolation node contains name and parameters
515 case (FYNT_MAPPING):
516
518 fy_node_mapping_item_count(interp_method_node) == 1,
519 "base interpolation method node is only allowed to have one pair ");
520
521 fy_node_pair_t base_interp_method_pair =
522 fy_node_mapping_get_by_index(interp_method_node, 0);
523
524 interpolation_name_node = fy_node_pair_key(base_interp_method_pair);
525
526 fy_node_t base_interp_method_value_node =
527 fy_node_pair_value(base_interp_method_pair);
528
530 fy_node_is_mapping(base_interp_method_value_node),
531 "unsupported base interpolation method value node type "
532 "for interpolation method \"%s\" "
533 "(interpolation method parameters are expected to be "
534 "defined as maps)",
535 yaml_parse_string_value(
536 interpolation_name_node, "interpolation method name", yaml_filename));
537
538 *parameter_node = base_interp_method_value_node;
539 break;
540 }
541
542 *interpolation_type_str =
543 yaml_parse_string_value(
544 interpolation_name_node, "interpolation method name", yaml_filename);
545}
546
548 struct yac_param * param,
549 fy_node_t value_node,
550 char const * interpolation_name,
551 char const * yaml_filename) {
552
553 char const * param_name = yac_param_get_name(param);
554 enum yac_param_type type =
555 yac_param_get_type(param);
556
557 // if no node is provided, keep the default value for all param types
558 if (fy_node_is_null(value_node)) return;
559
560 switch (type) {
562 "unsupported parameter type for parameter \"%s\" of interpolation "
563 "method \"%s\"",
564 param_name, interpolation_name);
565 // case (YAC_PARAM_TYPE_EMPTY):
566 // YAML_ASSERT_F(
567 // fy_node_is_null(value_node),
568 // "invalid null parameter value for parameter \"%s\" of interpolation "
569 // "method \"%s\"",
570 // param_name, interpolation_name);
571 // break;
572 case (YAC_PARAM_TYPE_SCALAR): {
574 fy_node_is_scalar(value_node),
575 "invalid scalar parameter value for parameter \"%s\" of interpolation "
576 "method \"%s\"",
577 param_name, interpolation_name);
578
579 int ierr =
580 yac_param_set_scalar(param, fy_node_get_scalar0(value_node));
582 ierr == 0,
583 "failed to set parameter \"%s\" of interpolation method \"%s\": %s",
584 param_name, interpolation_name,
586 break;
587 }
588 case (YAC_PARAM_TYPE_STRUCT): {
590 fy_node_is_scalar(value_node) || fy_node_is_mapping(value_node),
591 "invalid parameter value for parameter \"%s\" of interpolation "
592 "method \"%s\" (expected scalar sub-parameter name or map)",
593 param_name, interpolation_name);
594
595 if (fy_node_is_scalar(value_node)) {
596
597 // scalar value is the name of a sub-parameter to activate with defaults
598 char const * sub_parameter_name =
599 yaml_parse_string_value(
600 value_node, "interpolation method parameter name", yaml_filename);
601
602 struct yac_param * sub_param = NULL;
603 int ierr =
605 param, sub_parameter_name, &sub_param);
607 ierr == 0,
608 "\"%s\" is not a valid sub-parameter of \"%s\" for interpolation "
609 "method \"%s\": %s",
610 sub_parameter_name, param_name, interpolation_name,
612
613 } else {
614
615 void * iter = NULL;
616 fy_node_pair_t parameter_pair;
617 while ((parameter_pair = fy_node_mapping_iterate(value_node, &iter))) {
618
619 char const * sub_parameter_name =
620 yaml_parse_string_value(
621 fy_node_pair_key(parameter_pair),
622 "interpolation method parameter name", yaml_filename);
623
624 struct yac_param * sub_param = NULL;
625 int ierr =
627 param, sub_parameter_name, &sub_param);
629 ierr == 0,
630 "\"%s\" is not a valid sub-parameter of \"%s\" for interpolation "
631 "method \"%s\": %s",
632 sub_parameter_name, param_name, interpolation_name,
634
636 sub_param, fy_node_pair_value(parameter_pair),
637 interpolation_name, yaml_filename);
638 }
639 }
640 break;
641 }
642 case (YAC_PARAM_TYPE_LIST): {
644 fy_node_is_scalar(value_node) || fy_node_is_sequence(value_node),
645 "invalid parameter value for parameter \"%s\" of "
646 "interpolation method \"%s\" (expected scalar or sequence)",
647 param_name, interpolation_name);
648
649 size_t count = fy_node_is_scalar(value_node)?1:
650 (size_t)fy_node_sequence_item_count(value_node);
651 for (size_t i = 0; i < count; ++i) {
652 struct yac_param * sub_param = NULL;
653 int ierr = yac_param_append(param, &sub_param);
655 ierr == 0,
656 "failed to append to parameter \"%s\" of interpolation method "
657 "\"%s\": %s",
658 param_name, interpolation_name,
660
662 sub_param,
663 fy_node_is_scalar(value_node)?value_node:
664 fy_node_sequence_get_by_index(value_node, (int)i),
665 interpolation_name, yaml_filename);
666 }
667 break;
668 }
669 }
670}
671
673 struct yac_interp_stack_config * interp_stack,
674 fy_node_t interp_method_node, char const * yaml_filename) {
675
676 char const * interpolation_type_str;
677 fy_node_t parameter_node;
678
679 // get name of interpolations
681 &interpolation_type_str, &parameter_node,
682 interp_method_node, yaml_filename);
683
684 // generate interpolation method configuration with default values based
685 // on the interpolation name
686 struct yac_interp_method_config * method_config =
688
689 // get the root parameter of the interpolation method configuration and set
690 // the user-provided parameter values from the YAML node
691 struct yac_param * root_param =
694 root_param, parameter_node, interpolation_type_str, yaml_filename);
695
696
697 // add the interpolation method configuration to the interpolation stack
698 yac_interp_stack_config_add(interp_stack, method_config);
699}
700
702 struct yac_interp_stack_config * interp_stack,
703 fy_node_t interp_stack_node, char const * yaml_filename) {
704
706 fy_node_is_sequence(interp_stack_node),
707 "unsupported interpolation stack node type"
708 "(interpolation stacks are expected to be defined as a sequence)");
709
710 // parse couplings
711 void * iter = NULL;
712 fy_node_t interp_stack_item;
713 while ((interp_stack_item =
714 fy_node_sequence_iterate(interp_stack_node, &iter)))
716 interp_stack, interp_stack_item, yaml_filename);
717}
718
719static struct field_couple_field_names yaml_parse_field_name(
720 fy_node_t field_node, const char * yaml_filename) {
721
722 struct field_couple_field_names field_name;
723
724 switch(fy_node_get_type(field_node)) {
725
727 "unsupported field name node type "
728 "(field name is either scalars or a map)");
729
730 // the node contains one name for both source and target field
731 case (FYNT_SCALAR): {
732
733 field_name.src =
734 ((field_name.tgt =
735 yaml_parse_string_value(field_node, "field name", yaml_filename)));
736
737 break;
738 }
739
740 // the node contains different names for the source and target field
741 case (FYNT_MAPPING): {
742
743 field_name.src =
744 fy_node_mapping_lookup_scalar0_by_simple_key(
745 field_node, "src", (size_t)-1);
746 field_name.tgt =
747 fy_node_mapping_lookup_scalar0_by_simple_key(
748 field_node, "tgt", (size_t)-1);
749
751 field_name.src && field_name.tgt &&
752 (fy_node_mapping_item_count(field_node) == 2),
753 "invalid field name mapping node "
754 "(field name mapping node has to contain two maps "
755 "with the keys \"src\" and \"tgt\")")
756
757 break;
758 }
759 }
760
761 return field_name;
762}
763
765 size_t ** values, size_t * num_values,
766 fy_node_t values_node, char const * sequence_name,
767 const char * yaml_filename) {
768
770 (*values == NULL) && (*num_values == 0),
771 "values have already been set for sequence \"%s\"",
772 sequence_name);
773
774 // handle sequence node
775 if (fy_node_is_sequence(values_node)) {
776
777 *num_values = (size_t)fy_node_sequence_item_count(values_node);
778 *values = xmalloc(*num_values * sizeof(**values));
779
780 for (size_t value_idx = 0; value_idx < *num_values; ++value_idx)
781 (*values)[value_idx] =
783 fy_node_sequence_get_by_index(values_node, value_idx),
784 sequence_name, yaml_filename);
785 } else {
786 // single scalar node
787 *num_values = 1;
788 *values = xmalloc(sizeof(**values));
789 **values=
790 yaml_parse_size_t_value(values_node, sequence_name, yaml_filename);
791 }
792}
793
795 struct yac_collection_selection ** collection_selection,
796 fy_node_t values_node, char const * sequence_name,
797 const char * yaml_filename) {
798
800 *collection_selection == NULL,
801 "values have already been set for sequence \"%s\"",
802 sequence_name);
803
804 size_t collection_size = 0;
805 size_t * indices = NULL;
806
808 &indices, &collection_size, values_node, sequence_name, yaml_filename);
809
810 *collection_selection =
812
813 free(indices);
814}
815
817 char const *** values, size_t * num_values,
818 fy_node_t values_node, char const * sequence_name,
819 const char * yaml_filename) {
820
822 (*values == NULL) && (*num_values == 0),
823 "values have already been set for sequence \"%s\"",
824 sequence_name);
825
826 // if the field node contains multiple fields
827 if (fy_node_is_sequence(values_node)) {
828
829 *num_values = (size_t)fy_node_sequence_item_count(values_node);
830 *values = xmalloc(*num_values * sizeof(**values));
831 for (size_t value_idx = 0; value_idx < *num_values; ++value_idx)
832 (*values)[value_idx] =
833 yaml_parse_string_value(
834 fy_node_sequence_get_by_index(values_node, value_idx),
835 sequence_name, yaml_filename);
836 } else {
837 *num_values = 1;
838 *values = xmalloc(sizeof(**values));
839 **values =
840 yaml_parse_string_value(
841 values_node, sequence_name, yaml_filename);
842 }
843}
844
846 struct field_couple_field_names ** field_names,
847 size_t * num_field_names, fy_node_t fields_node,
848 const char * yaml_filename) {
849
850 // if the field node contains multiple fields
851 if (fy_node_is_sequence(fields_node)) {
852
853 size_t start_idx = *num_field_names;
854 *num_field_names += (size_t)fy_node_sequence_item_count(fields_node);
855 *field_names =
856 xrealloc(*field_names, *num_field_names * sizeof(**field_names));
857 for (size_t i = start_idx; i < *num_field_names; ++i)
858 (*field_names)[i] =
860 fy_node_sequence_get_by_index(fields_node, i), yaml_filename);
861 } else {
862 ++*num_field_names;
863 *field_names =
864 xrealloc(*field_names, *num_field_names * sizeof(**field_names));
865 (*field_names)[*num_field_names-1] =
867 }
868}
869
871 char const ** comp_name, char const *** grid_names, size_t * num_grid_names,
872 fy_node_t values_node, char const * type_name, const char * yaml_filename,
873 int allow_multiple_grids) {
874
876 *comp_name == NULL, "%s component name already set", type_name);
878 (*grid_names == NULL) && (*num_grid_names == 0),
879 "%s grid names already set", type_name);
880
882 fy_node_is_mapping(values_node),
883 "unsupported component/grid names node type (has to be a map)");
884
885 // parse component/grid names
886 void * iter = NULL;
887 fy_node_pair_t pair;
888 while((pair = fy_node_mapping_iterate(values_node, &iter))) {
889
890 enum yaml_comp_grid_names_key_types comp_grid_names_key_type =
893 yaml_comp_grid_names_keys, yaml_comp_grid_names_keys_size,
894 fy_node_pair_key(pair),
895 "component/grid names parameter name", yaml_filename);
896 char const * comp_grid_names_key_name =
898 yaml_comp_grid_names_keys, yaml_comp_grid_names_keys_size,
899 comp_grid_names_key_type);
900
901 fy_node_t name_node = fy_node_pair_value(pair);
902
903 switch(comp_grid_names_key_type) {
904 YAML_UNREACHABLE_DEFAULT("invalid component/grid name key type");
905 case(COMP_NAME):
906 *comp_name =
907 yaml_parse_string_value(
908 name_node, comp_grid_names_key_name, yaml_filename);
909 break;
910 case(GRID_NAMES):
911 if (allow_multiple_grids) {
913 grid_names, num_grid_names,
914 name_node, comp_grid_names_key_name, yaml_filename);
915 } else {
916 *num_grid_names = 1;
917 *grid_names = xmalloc(sizeof(**grid_names));
918 **grid_names =
919 yaml_parse_string_value(
920 name_node, comp_grid_names_key_name, yaml_filename);
921 }
922 break;
923 }
924 }
925}
926
928 char const ** weight_file_name,
929 enum yac_weight_file_on_existing * on_existing,
930 fy_node_t values_node, char const * type_name, const char * yaml_filename) {
931
933 *weight_file_name == NULL, "%s weight file name already set", type_name);
935 *on_existing == YAC_WEIGHT_FILE_UNDEFINED,
936 "%s \"on existing\" already set ", type_name);
937
939 fy_node_is_mapping(values_node),
940 "unsupported weight file data node type (has to be a map)");
941
942 // parse component/grid names
943 void * iter = NULL;
944 fy_node_pair_t pair;
945 while((pair = fy_node_mapping_iterate(values_node, &iter))) {
946
947 enum yaml_weight_file_data_key_types weight_file_data_key_type =
950 yaml_weight_file_data_keys, yaml_weight_file_data_keys_size,
951 fy_node_pair_key(pair),
952 "weight file data parameter name", yaml_filename);
953 char const * weight_file_data_key_name =
955 yaml_weight_file_data_keys, yaml_weight_file_data_keys_size,
956 weight_file_data_key_type);
957
958 fy_node_t weight_file_data_node = fy_node_pair_value(pair);
959
960 switch(weight_file_data_key_type) {
961 YAML_UNREACHABLE_DEFAULT("invalid weight file data key type");
964 yaml_parse_string_value(
965 weight_file_data_node, weight_file_data_key_name, yaml_filename);
966 break;
968 *on_existing =
971 weight_file_on_existing_types,
972 weight_file_on_existing_types_size,
973 weight_file_data_node, weight_file_data_key_name,
975 break;
976 }
977 }
978}
979
981 struct field_couple_buffer * field_buffer,
982 fy_node_pair_t couple_pair, const char * yaml_filename,
983 enum yac_time_unit_type time_unit) {
984
985 enum yaml_couple_key_types couple_key_type =
988 yaml_couple_keys, yaml_couple_keys_size,
989 fy_node_pair_key(couple_pair),
990 "couple configuration parameter name", yaml_filename);
991 char const * couple_key_name =
993 yaml_couple_keys, yaml_couple_keys_size, couple_key_type);
994
995 fy_node_t value_node = fy_node_pair_value(couple_pair);
996
997 switch (couple_key_type) {
998 YAML_UNREACHABLE_DEFAULT("invalid couple key type");
999 case (SOURCE_NAME): {
1000 char const ** src_grid_names = NULL;
1001 size_t num_src_grid_names = 0;
1002 int const allow_multiple_grids = 0;
1004 &(field_buffer->src.comp_name),
1005 &src_grid_names,
1006 &num_src_grid_names,
1007 value_node, couple_key_name, yaml_filename, allow_multiple_grids);
1008 field_buffer->src.grid_name = src_grid_names[0];
1009 free((void*)src_grid_names);
1010 break;
1011 }
1012 case (SOURCE_COMPONENT):
1013 field_buffer->src.comp_name =
1014 yaml_parse_string_value(value_node, couple_key_name, yaml_filename);
1015 break;
1016 case (SOURCE_GRID):
1018 field_buffer->src.grid_name == NULL,
1019 "%s has already been set", couple_key_name);
1020 field_buffer->src.grid_name =
1021 yaml_parse_string_value(value_node, couple_key_name, yaml_filename);
1022 break;
1023 case (TARGET_NAMES): {
1024 int const allow_multiple_grids = 1;
1026 &(field_buffer->tgt.comp_name),
1027 &(field_buffer->tgt.grid.name),
1028 &(field_buffer->tgt.grid.count),
1029 value_node, couple_key_name, yaml_filename, allow_multiple_grids);
1030 break;
1031 }
1032 case (TARGET_COMPONENT):
1033 field_buffer->tgt.comp_name =
1034 yaml_parse_string_value(value_node, couple_key_name, yaml_filename);
1035 break;
1036 case (TARGET_GRID):
1038 &field_buffer->tgt.grid.name, &field_buffer->tgt.grid.count,
1039 value_node, couple_key_name, yaml_filename);
1040 break;
1041 case (FIELD):
1043 &(field_buffer->field_names),
1044 &(field_buffer->num_field_names),
1045 value_node, yaml_filename);
1046 break;
1047 case (COUPLING_PERIOD):
1048 field_buffer->coupling_period =
1050 value_node, couple_key_name, yaml_filename, time_unit);
1051 break;
1052 case (TIME_REDUCTION):
1053 field_buffer->time_reduction =
1055 value_node, couple_key_name, yaml_filename);
1056 break;
1057 case (SOURCE_LAG):
1058 field_buffer->src.lag =
1060 value_node, couple_key_name, yaml_filename);
1061 break;
1062 case (TARGET_LAG):
1063 field_buffer->tgt.lag =
1065 value_node, couple_key_name, yaml_filename);
1066 break;
1067 case (WEIGHT_FILE_NAME):
1068 field_buffer->weight_file.name =
1069 yaml_parse_string_value(
1070 value_node, couple_key_name, yaml_filename);
1071 break;
1073 field_buffer->weight_file.on_existing =
1076 weight_file_on_existing_types,
1077 weight_file_on_existing_types_size,
1078 value_node, couple_key_name, yaml_filename);
1079 break;
1080 case (WEIGHT_FILE_DATA):
1082 &(field_buffer->weight_file.name),
1083 &(field_buffer->weight_file.on_existing),
1084 value_node, couple_key_name, yaml_filename);
1085 break;
1086 case (MAPPING_SIDE):
1087 field_buffer->mapping_on_source =
1089 mapping_sides, mapping_sides_size,
1090 value_node, couple_key_name, yaml_filename);
1091 break;
1092 case (SCALE_FACTOR):
1093 field_buffer->scale_factor =
1095 value_node, couple_key_name, yaml_filename);
1096 break;
1097 case (SCALE_SUMMAND):
1098 field_buffer->scale_summand =
1100 value_node, couple_key_name, yaml_filename);
1101 break;
1102 case (INTERPOLATION):
1104 field_buffer->interp_stack, value_node, yaml_filename);
1105 break;
1106 case (SOURCE_MASK_NAME):
1107 case (SOURCE_MASK_NAMES):
1109 &(field_buffer->src_mask_names),
1110 &(field_buffer->num_src_mask_names),
1111 value_node, couple_key_name, yaml_filename);
1112 break;
1113 case (TARGET_MASK_NAME):
1114 field_buffer->tgt_mask_name =
1115 yaml_parse_string_value(
1116 value_node, couple_key_name, yaml_filename);
1117 break;
1118 case (YAXT_EXCHANGER_NAME):
1119 field_buffer->yaxt_exchanger_name =
1120 yaml_parse_string_value(
1121 value_node, couple_key_name, yaml_filename);
1122 break;
1123 case (COLLECTION_SELECTION):
1125 &field_buffer->collection_selection,
1126 value_node, couple_key_name, yaml_filename);
1127 break;
1128 case (USE_RAW_EXCHANGE):
1129 field_buffer->use_raw_exchange =
1131 bool_names, bool_names_size,
1132 value_node, couple_key_name, yaml_filename);
1133 break;
1134 }
1135}
1136
1138 struct yac_couple_config * couple_config, fy_node_t couple_node,
1139 char const * yaml_filename, enum yac_time_unit_type time_unit) {
1140
1142 fy_node_is_mapping(couple_node),
1143 "unsupported couple node type "
1144 "(couples are expected to be defined as a mapping)");
1145
1146 // initialise field configuration buffer with default values
1147 struct field_couple_buffer field_buffer = {
1148 .src.comp_name = NULL,
1149 .src.grid_name = NULL,
1150 .tgt.comp_name = NULL,
1151 .tgt.grid.name = NULL,
1152 .tgt.grid.count = 0,
1153 .field_names = NULL,
1154 .num_field_names = 0,
1155 .coupling_period = NULL,
1156 .time_reduction = TIME_NONE,
1157 .interp_stack = yac_interp_stack_config_new(),
1158 .src.lag = 0,
1159 .tgt.lag = 0,
1160 .weight_file.name = NULL,
1161 .weight_file.on_existing = YAC_WEIGHT_FILE_UNDEFINED,
1162 .mapping_on_source = 1,
1163 .scale_factor = 1.0,
1164 .scale_summand = 0.0,
1165 .src_mask_names = NULL,
1166 .num_src_mask_names = 0,
1167 .tgt_mask_name = NULL,
1168 .yaxt_exchanger_name = NULL,
1169 .collection_selection = NULL,
1170 .use_raw_exchange = 0};
1171
1172 // parse couple
1173 void * iter = NULL;
1174 fy_node_pair_t pair;
1175 while ((pair = fy_node_mapping_iterate(couple_node, &iter)))
1177 &field_buffer, pair, yaml_filename, time_unit);
1178
1180 field_buffer.src.comp_name, "missing source component name");
1182 field_buffer.src.grid_name != NULL,
1183 "missing source grid name (component \"%s\")",
1184 field_buffer.src.comp_name);
1186 field_buffer.src.grid_name[0] != '\0',
1187 "invalid source grid name (component \"%s\")",
1188 field_buffer.src.comp_name);
1190 field_buffer.tgt.comp_name,
1191 "missing target component name");
1193 field_buffer.tgt.grid.count > 0,
1194 "missing target grid name (component \"%s\")",
1195 field_buffer.tgt.comp_name);
1196 for (size_t i = 0; i < field_buffer.tgt.grid.count; ++i)
1198 (field_buffer.tgt.grid.name[i] != NULL) &&
1199 (field_buffer.tgt.grid.name[i][0] != '\0'),
1200 "invalid target grid name (component \"%s\" grid idx %zu)",
1201 field_buffer.tgt.comp_name, i);
1203 field_buffer.num_field_names > 0,
1204 "missing field names "
1205 "(source component \"%s\" source grid \"%s\" "
1206 "target component \"%s\" target grid \"%s\")",
1207 field_buffer.src.comp_name, field_buffer.src.grid_name,
1208 field_buffer.tgt.comp_name, field_buffer.tgt.grid.name[0]);
1210 field_buffer.coupling_period,
1211 "missing coupling period "
1212 "(source component \"%s\" source grid \"%s\" "
1213 "target component \"%s\" target grid \"%s\")",
1214 field_buffer.src.comp_name, field_buffer.src.grid_name,
1215 field_buffer.tgt.comp_name, field_buffer.tgt.grid.name[0]);
1216
1217 for (size_t i = 0; i < field_buffer.num_field_names; ++i)
1218 for (size_t k = 0; k < field_buffer.tgt.grid.count; ++k)
1220 couple_config,
1221 field_buffer.src.comp_name,
1222 field_buffer.src.grid_name,
1223 field_buffer.field_names[i].src,
1224 field_buffer.tgt.comp_name,
1225 field_buffer.tgt.grid.name[k],
1226 field_buffer.field_names[i].tgt,
1227 field_buffer.coupling_period,
1228 field_buffer.time_reduction,
1229 field_buffer.interp_stack,
1230 field_buffer.src.lag,
1231 field_buffer.tgt.lag,
1232 field_buffer.weight_file.name,
1235 field_buffer.weight_file.on_existing,
1236 field_buffer.mapping_on_source,
1237 field_buffer.scale_factor,
1238 field_buffer.scale_summand,
1239 field_buffer.num_src_mask_names,
1240 field_buffer.src_mask_names,
1241 field_buffer.tgt_mask_name,
1242 field_buffer.yaxt_exchanger_name,
1243 field_buffer.collection_selection,
1244 field_buffer.use_raw_exchange);
1245
1246 // cleanup
1248 free((void*)field_buffer.tgt.grid.name);
1249 free((void*)field_buffer.field_names);
1250 free((void*)field_buffer.coupling_period);
1252 free((void*)field_buffer.src_mask_names);
1253}
1254
1256 struct yac_couple_config * couple_config,
1257 fy_node_t coupling_node, char const * yaml_filename,
1258 enum yac_time_unit_type time_unit) {
1259
1260 // check if the coupling node is empty -> nothing to be read
1261 if (!coupling_node) return;
1262
1264 fy_node_is_sequence(coupling_node),
1265 "unsupported coupling node type "
1266 "(couplings are expected to be defined as a sequence)");
1267
1268 // parse couplings
1269 void * iter = NULL;
1270 fy_node_t couple_node;
1271 while ((couple_node = fy_node_sequence_iterate(coupling_node, &iter)))
1272 yaml_parse_couple(couple_config, couple_node, yaml_filename, time_unit);
1273}
1274
1275static struct debug_config_file yaml_parse_config_file_value(
1276 fy_node_t config_file_node, char const * file_type_name,
1277 const char * yaml_filename) {
1278
1279 struct debug_config_file config_file =
1280 {.name = NULL, .type = YAC_TEXT_FILETYPE_YAML, .include_definitions = 0};
1281
1282 char * str_buffer = xmalloc(strlen(file_type_name) + 32);
1283
1284 switch(fy_node_get_type(config_file_node)) {
1285
1287 "unsupported config file node type "
1288 "(%s is either scalar or a map)", file_type_name);
1289
1290 // the node contains only the filename
1291 case (FYNT_SCALAR): {
1292
1293 config_file.name =
1294 yaml_parse_string_value(
1295 config_file_node,
1296 strcat(strcpy(str_buffer, file_type_name), " name"),
1298
1299 break;
1300 }
1301
1302 // the node contains the name and the type
1303 case (FYNT_MAPPING): {
1304
1305 fy_node_t filename_node =
1306 fy_node_mapping_lookup_by_string(
1307 config_file_node, "filename", (size_t)-1);
1308 fy_node_t filetype_node =
1309 fy_node_mapping_lookup_by_string(
1310 config_file_node, "filetype", (size_t)-1);
1311 fy_node_t include_definitions_node =
1312 fy_node_mapping_lookup_by_string(
1313 config_file_node, "include_definitions", (size_t)-1);
1314
1316 filename_node,
1317 "invalid %s mapping node "
1318 "(global config file mapping node has to include a map "
1319 "with the keys \"filename\")", file_type_name)
1320
1321 config_file.name =
1322 yaml_parse_string_value(
1323 filename_node, strcat(strcpy(str_buffer, file_type_name), " name"),
1325 config_file.type =
1326 (filetype_node)?
1327 (enum yac_text_filetype)
1329 config_filetypes, config_filetypes_size,
1330 filetype_node, strcat(strcpy(str_buffer, file_type_name), " type"),
1332 config_file.include_definitions =
1333 (include_definitions_node)?
1335 bool_names, bool_names_size,
1336 include_definitions_node,
1337 strcat(strcpy(str_buffer, file_type_name), " include definitions"),
1338 yaml_filename):0;
1339 break;
1340 }
1341 }
1342
1344 config_file.name, "missing filename for %s", file_type_name);
1345
1346 free(str_buffer);
1347
1348 return config_file;
1349}
1350
1352 struct debug_config_file_buffer * config_file_buffer,
1353 fy_node_pair_t config_file_pair, char const * config_file_type_name,
1354 const char * yaml_filename) {
1355
1357 debug_sync_loc_key_type =
1360 yaml_debug_sync_loc_keys,
1361 yaml_debug_sync_loc_keys_size,
1362 fy_node_pair_key(config_file_pair),
1363 "config synchronisation location parameter name",
1365 char const * debug_sync_loc_key_name =
1367 yaml_debug_sync_loc_keys, yaml_debug_sync_loc_keys_size,
1368 debug_sync_loc_key_type);
1369
1370 fy_node_t value_node = fy_node_pair_value(config_file_pair);
1371
1372 char config_file_type_name_sync[
1373 strlen(config_file_type_name) + strlen(debug_sync_loc_key_name) + 8];
1374 sprintf(
1375 config_file_type_name_sync, "%s (%s)",
1376 config_file_type_name, debug_sync_loc_key_name);
1377
1378 config_file_buffer->config_file[debug_sync_loc_key_type] =
1380 value_node, config_file_type_name_sync, yaml_filename);
1381}
1382
1384 fy_node_t config_file_node, char const * config_file_type_name,
1385 char const * yaml_filename) {
1386
1388 fy_node_is_mapping(config_file_node),
1389 "unsupported %s node type "
1390 "(%s is expected to be defined as a mapping)",
1391 config_file_type_name, config_file_type_name);
1392
1393 struct debug_config_file_buffer config_file_buffer;
1394 config_file_buffer.sync_loc_ref[SYNC_LOC_DEF_COMP] =
1396 config_file_buffer.sync_loc_ref[SYNC_LOC_SYNC_DEF] =
1398 config_file_buffer.sync_loc_ref[SYNC_LOC_ENDDEF] =
1400 for (int i = 0; i < SYNC_LOC_COUNT; ++i) {
1401 config_file_buffer.config_file[i].name = NULL;
1402 config_file_buffer.config_file[i].type = YAC_TEXT_FILETYPE_YAML;
1403 config_file_buffer.config_file[i].include_definitions = 0;
1405 config_file_buffer.sync_loc_ref[i] != NULL,
1406 "invalid unsupported synchronisation location (%d) for %s",
1407 i, config_file_type_name);
1408 }
1409
1410 // parse couplings
1411 void * iter = NULL;
1412 fy_node_pair_t pair;
1413 while ((pair = fy_node_mapping_iterate(config_file_node, &iter)))
1415 &config_file_buffer, pair, config_file_type_name, yaml_filename);
1416
1417 return config_file_buffer;
1418}
1419
1421 struct yac_couple_config * couple_config, fy_node_t global_config_node,
1422 char const * yaml_filename) {
1423
1424 char const * config_file_type_name = "debug global config file";
1425
1427 fy_node_is_mapping(global_config_node),
1428 "unsupported %s node type "
1429 "(%s is expected to be defined as a mapping)",
1430 config_file_type_name, config_file_type_name);
1431
1432 struct debug_config_file_buffer global_config_buffer =
1434 global_config_node, config_file_type_name, yaml_filename);
1435
1436 for (int i = 0; i < SYNC_LOC_COUNT; ++i)
1437 if (global_config_buffer.config_file[i].name != NULL)
1439 couple_config, global_config_buffer.config_file[i].name,
1440 global_config_buffer.config_file[i].type,
1441 global_config_buffer.sync_loc_ref[i],
1442 global_config_buffer.config_file[i].include_definitions);
1443}
1444
1446 char const ** grid_name, char const ** file_name,
1447 fy_node_pair_t output_grid_pair, char const * yaml_filename) {
1448
1449 enum yaml_debug_output_grid_key_types output_grid_key_type =
1452 yaml_debug_output_grid_keys, yaml_debug_output_grid_keys_size,
1453 fy_node_pair_key(output_grid_pair),
1454 "output grid parameter name", yaml_filename);
1455 char const * debug_output_key_name =
1457 yaml_debug_output_grid_keys, yaml_debug_output_grid_keys_size,
1458 output_grid_key_type);
1459
1460 fy_node_t value_node = fy_node_pair_value(output_grid_pair);
1461
1462 switch(output_grid_key_type) {
1463 YAML_UNREACHABLE_DEFAULT("invalid output grid key type");
1464 case(OUTPUT_GRID_GRID_NAME): {
1465 *grid_name =
1466 yaml_parse_string_value(value_node, debug_output_key_name, yaml_filename);
1467 break;
1468 }
1469 case(OUTPUT_GRID_FILE_NAME): {
1470 *file_name =
1471 yaml_parse_string_value(value_node, debug_output_key_name, yaml_filename);
1472 break;
1473 }
1474 };
1475}
1476
1478 struct yac_couple_config * couple_config, fy_node_t output_grid_node,
1479 char const * yaml_filename) {
1480
1482 fy_node_is_mapping(output_grid_node),
1483 "unsupported output grid node type "
1484 "(output grids are expected to be defined as a mapping)");
1485
1486 char const * grid_name = NULL;
1487 char const * file_name = NULL;
1488
1489 // parse output grid
1490 void * iter = NULL;
1491 fy_node_pair_t pair;
1492 while ((pair = fy_node_mapping_iterate(output_grid_node, &iter)))
1494
1496 grid_name && file_name,
1497 "output grid mapping has to contain both \"grid_name\" and \"file_name\" "
1498 "parameters (grid name: \"%s\", file name: \"%s\")",
1499 (grid_name)?grid_name:"<missing>", (file_name)?file_name:"<missing>");
1500
1501 yac_couple_config_add_grid(couple_config, grid_name);
1503 couple_config, grid_name, file_name);
1504}
1505
1511 struct yac_couple_config * couple_config, fy_node_t output_grids_node,
1512 char const * yaml_filename) {
1513
1515 fy_node_mapping_item_count(output_grids_node) == 1,
1516 "debug output grids mapping is only allowed to have one pair ");
1517
1518 fy_node_pair_t output_grids_pair =
1519 fy_node_mapping_get_by_index(output_grids_node, 0);
1520
1522 !strcmp(
1524 yaml_parse_string_value(
1525 fy_node_pair_key(output_grids_pair),
1526 "output grid parameter name", yaml_filename)),
1527 "unsupported output grid parameter name \"%s\" "
1528 "(only \"%s\" is supported if debug output grids is defined as a "
1529 "mapping, because it applies to all grids) ",
1530 yaml_parse_string_value(
1531 fy_node_pair_key(output_grids_pair),
1532 "output grid parameter name", yaml_filename),
1534
1536 couple_config,
1537 yaml_parse_string_value(
1538 fy_node_pair_value(output_grids_pair),
1540}
1541
1543 struct yac_couple_config * couple_config, fy_node_t output_grids_node,
1544 char const * yaml_filename) {
1545
1547 fy_node_is_sequence(output_grids_node) ||
1548 fy_node_is_mapping(output_grids_node),
1549 "unsupported debug output grids node type "
1550 "(debug output grids is expected to be defined as a mapping or as a "
1551 "sequence of mappings)");
1552
1553 // a mapping applies to all grids
1554 if (fy_node_is_mapping(output_grids_node)) {
1556 couple_config, output_grids_node, yaml_filename);
1557 return;
1558 }
1559
1560 // parse output grids
1561 void * iter = NULL;
1562 fy_node_t output_grid_node;
1563 while ((output_grid_node =
1564 fy_node_sequence_iterate(output_grids_node, &iter)))
1566 couple_config, output_grid_node, yaml_filename);
1567}
1568
1570 struct yac_couple_config * couple_config, fy_node_pair_t debug_pair,
1571 const char * yaml_filename) {
1572
1573 enum yaml_debug_key_types debug_key_type =
1576 yaml_debug_keys, yaml_debug_keys_size,
1577 fy_node_pair_key(debug_pair),
1578 "debug configuration parameter name", yaml_filename);
1579
1580 fy_node_t value_node = fy_node_pair_value(debug_pair);
1581
1582 switch (debug_key_type) {
1583 YAML_UNREACHABLE_DEFAULT("invalid debug_key_type");
1584 case(GLOBAL_CONFIG):
1586 couple_config, value_node, yaml_filename);
1587 break;
1588 case(OUTPUT_GRIDS):
1590 couple_config, value_node, yaml_filename);
1591 break;
1592 case(MISSING_DEF):
1594 couple_config,
1596 bool_names, bool_names_size, value_node,
1597 "\"missing definition is fatal\" bool value", yaml_filename));
1598 break;
1599 case(APPLY_COORD_CHECK):
1601 couple_config,
1603 bool_names, bool_names_size, value_node,
1604 "\"apply coordinate check\" bool value", yaml_filename));
1605 break;
1608 couple_config,
1610 bool_names, bool_names_size, value_node,
1611 "\"coordinates mismatch is fatal\" bool value",
1612 yaml_filename));
1613 break;
1614 };
1615}
1616
1618 struct yac_couple_config * couple_config,
1619 fy_node_t debug_node, char const * yaml_filename) {
1620
1621 // check if the debug node is empty -> nothing to be read
1622 if (!debug_node) return;
1623
1625 fy_node_is_mapping(debug_node),
1626 "unsupported debug node type "
1627 "(debug is expected to be defined as a mapping)");
1628
1629 // parse couplings
1630 void * iter = NULL;
1631 fy_node_pair_t pair;
1632 while ((pair = fy_node_mapping_iterate(debug_node, &iter)))
1633 yaml_parse_debug_map_pair(couple_config, pair, yaml_filename);
1634}
1635
1636// computes the Levenshtein edit distance between two strings (i.e. the
1637// minimum number of single-character insertions, deletions, or
1638// substitutions required to turn one string into the other)
1639static size_t yaml_edit_distance(char const * a, char const * b) {
1640
1641 size_t len_a = strlen(a);
1642 size_t len_b = strlen(b);
1643
1644 size_t * prev_row = xmalloc((len_b + 1) * sizeof(*prev_row));
1645 size_t * curr_row = xmalloc((len_b + 1) * sizeof(*curr_row));
1646
1647 for (size_t j = 0; j <= len_b; ++j) prev_row[j] = j;
1648
1649 for (size_t i = 1; i <= len_a; ++i) {
1650 curr_row[0] = i;
1651 for (size_t j = 1; j <= len_b; ++j) {
1652 size_t substitution_cost = prev_row[j-1] + (a[i-1] != b[j-1]);
1653 size_t deletion_cost = prev_row[j] + 1;
1654 size_t insertion_cost = curr_row[j-1] + 1;
1655 size_t cost = MIN(substitution_cost, MIN(deletion_cost, insertion_cost));
1656 curr_row[j] = cost;
1657 }
1658 size_t * tmp = prev_row;
1659 prev_row = curr_row;
1660 curr_row = tmp;
1661 }
1662
1663 size_t distance = prev_row[len_b];
1664
1665 free(prev_row);
1666 free(curr_row);
1667
1668 return distance;
1669}
1670
1671// root keys are silently ignored by design, so that other tools sharing
1672// the same YAML file can define their own additional root keys; however,
1673// a root key that is a close (but not exact) match of a valid root key is
1674// most likely a typo and is therefore reported as a fatal error
1676 char const * unknown_key, char const * yaml_filename) {
1677
1678 char const * closest_key_name = NULL;
1679 size_t closest_distance = SIZE_MAX;
1680
1681 for (size_t i = 0; i < yaml_base_keys_size; ++i) {
1682 size_t distance =
1683 yaml_edit_distance(unknown_key, yaml_base_keys[i].name);
1684 if (distance < closest_distance) {
1685 closest_distance = distance;
1686 closest_key_name = yaml_base_keys[i].name;
1687 }
1688 }
1689
1690 // tolerate a larger edit distance for longer keys, but always require an
1691 // exact match for very short ones
1692 size_t key_len = strlen(unknown_key);
1693 size_t max_typo_distance = MIN(key_len / 4 + 1, (size_t)2);
1694
1696 (closest_key_name == NULL) || (closest_distance > max_typo_distance),
1697 "unknown root key \"%s\" (did you mean \"%s\"?) ",
1698 unknown_key, closest_key_name);
1699}
1700
1702 struct yac_couple_config * couple_config, fy_node_pair_t base_pair,
1703 const char * yaml_filename, enum yac_time_unit_type * time_unit,
1704 char const ** start_datetime, char const ** end_datetime) {
1705
1706 fy_node_t key_node = fy_node_pair_key(base_pair);
1707
1709 fy_node_is_scalar(key_node),
1710 "unsupported key node type "
1711 "(key nodes are expected to be scalar nodes)");
1712
1713 char const * base_key_name = fy_node_get_scalar0(key_node);
1714 int base_key_type =
1716 yaml_base_keys, yaml_base_keys_size, base_key_name);
1717
1718 fy_node_t value_node = fy_node_pair_value(base_pair);
1719
1720 switch (base_key_type) {
1721 case (START_DATE):
1722 *start_datetime =
1723 yaml_parse_string_value(
1724 value_node, base_key_name, yaml_filename);
1725 break;
1726 case (END_DATE):
1727 *end_datetime =
1728 yaml_parse_string_value(
1729 value_node, base_key_name, yaml_filename);
1730 break;
1731 case (CALENDAR):
1734 value_node, base_key_name, yaml_filename),
1735 "YAML coupling configuration file");
1736 break;
1737 case (TIMESTEP_UNIT): {
1738 enum yac_time_unit_type time_unit_ =
1740 value_node, base_key_name, yaml_filename);
1742 (*time_unit == TIME_UNIT_UNDEFINED) || (*time_unit == time_unit_),
1743 "inconsistent redefinition of time unit")
1744 *time_unit = time_unit_;
1745 break;
1746 }
1747 case (COUPLING):
1749 (*time_unit != TIME_UNIT_UNDEFINED),
1750 "time unit has to be defined before the couplings")
1752 couple_config, value_node, yaml_filename, *time_unit);
1753 break;
1754 case (DEBUG):
1756 couple_config, value_node, yaml_filename);
1757 break;
1758 default:
1759 // Unknown root key is silently ignored by design, so that other tools
1760 // sharing the same YAML file can define their own additional root keys;
1761 // however, a root key that is a close (but not exact) match of a valid
1762 // root key is most likely a typo and is therefore reported as a
1763 // fatal error.
1765 break;
1766 }
1767}
1768
1770 struct yac_couple_config * couple_config, fy_document_t document,
1771 const char * yaml_filename) {
1772
1773 // get root node of document
1774 fy_node_t root_node = fy_document_root(document);
1775
1776 // if the configuration file is empty
1777 if (!root_node) return;
1778
1780 fy_node_is_mapping(root_node),
1781 "unsupported root node type (root node is expected to be a mapping node)");
1782
1783 char const * start_datetime = NULL;
1784 char const * end_datetime = NULL;
1785
1786 // parse base root mappings
1787 enum yac_time_unit_type time_unit = TIME_UNIT_UNDEFINED;
1788 void * iter = NULL;
1789 fy_node_pair_t pair;
1790 while ((pair = fy_node_mapping_iterate(root_node, &iter)))
1792 couple_config, pair, yaml_filename, &time_unit,
1793 &start_datetime, &end_datetime);
1794
1795 if ((start_datetime != NULL) || (end_datetime != NULL)) {
1796
1797 YAC_ASSERT(
1799 "cannot set start/end datetime because calendar has not yet been set");
1800
1802 couple_config, start_datetime, end_datetime);
1803 }
1804}
1805
1807 struct yac_couple_config * couple_config, const char * yaml_filename,
1808 int parse_flags) {
1809
1810 // check whether the yaml configuration file exists
1813 "YAML configuration file could not be found \"%s\"", yaml_filename);
1814
1815 // open yaml configuration file
1816 FILE * config_file = xfopen(yaml_filename, "r");
1818 config_file, "could not open YAML configuration file \"%s\"", yaml_filename);
1819
1820 // parse yaml configuration file into document
1821 struct fy_parse_cfg parse_config =
1822 {.search_path = ".",
1823 .userdata = NULL,
1824 .diag = NULL};
1825 parse_config.flags =
1826 (enum fy_parse_cfg_flags)parse_flags;
1827
1828 fy_document_t document =
1829 fy_document_build_from_fp(&parse_config, config_file);
1831 document, "could not parse YAML configuration file \"%s\"", yaml_filename);
1832
1833 // resolve anchors and merge keys
1835 !fy_document_resolve(document),
1836 "could not resolve anchors and merge keys");
1837
1838 // parse document into couple configuration
1839 yaml_parse_document(couple_config, document, yaml_filename);
1840
1841 // cleanup
1842 fy_document_destroy(document);
1843 xfclose(config_file);
1844
1845 return;
1846}
1847
1850 char const * str_interp_stack_config, int parse_flags) {
1851 char const * yaml_filename =
1852 "user-provided interp stack config string";
1853
1855 str_interp_stack_config != NULL, "interpolation stack string is NULL");
1856
1857 // parse string into document
1858 struct fy_parse_cfg parse_config =
1859 {.search_path = ".",
1860 .userdata = NULL,
1861 .diag = NULL};
1862 parse_config.flags =
1863 (enum fy_parse_cfg_flags)parse_flags;
1864
1865 fy_document_t document =
1866 fy_document_build_from_string(
1867 &parse_config, str_interp_stack_config, (size_t)-1);
1868 YAML_ASSERT(document, "failed parsing");
1869
1870 // resolve anchors and merge keys
1872 !fy_document_resolve(document),
1873 "could not resolve anchors and merge keys");
1874
1875 fy_node_t interp_stack_config_node = fy_document_root(document);
1876 YAML_ASSERT(interp_stack_config_node, "invalid root node");
1877
1878 struct yac_interp_stack_config * interp_stack_config =
1880
1882 interp_stack_config, interp_stack_config_node,
1884
1885 // cleanup
1886 fy_document_destroy(document);
1887
1888 return interp_stack_config;
1889}
1890
1892 fy_document_t document, char const * value) {
1893
1894 // return NULL if value is empty
1895 if (!value) return (fy_node_t)NULL;
1896
1897 fy_node_t scalar_node =
1898 fy_node_create_scalar_copy(document, value, strlen(value));
1899 YAC_ASSERT(scalar_node, "failed to create scalar node");
1900
1901 return scalar_node;
1902}
1903
1905 fy_document_t document, int value) {
1906
1907 char str_value[16];
1908 int value_size = snprintf(str_value, sizeof(str_value), "%d", value);
1910 (value_size >= 0) && ((size_t)value_size < sizeof(str_value)),
1911 "could not write \"%d\" to string buffer of size %zu",
1912 value, sizeof(str_value));
1913
1914 return yac_yaml_create_scalar(document, str_value);
1915}
1916
1918 fy_document_t document, size_t value) {
1919
1920 char str_value[32];
1921 int value_size = snprintf(str_value, sizeof(str_value), "%zu", value);
1923 (value_size >= 0) && ((size_t)value_size < sizeof(str_value)),
1924 "could not write \"%zu\" to string buffer of size %zu",
1925 value, sizeof(str_value));
1926
1927 return yac_yaml_create_scalar(document, str_value);
1928}
1929
1931 fy_document_t document, double value) {
1932
1933 char str_value[32];
1934 int value_size = snprintf(str_value, sizeof(str_value), "%g", value);
1936 (value_size >= 0) && ((size_t)value_size < sizeof(str_value)),
1937 "could not write \"%g\" to string buffer of size %zu",
1938 value, sizeof(str_value));
1939
1940 return yac_yaml_create_scalar(document, str_value);
1941}
1942
1944 fy_document_t document, char const * const * values, size_t num_values) {
1945
1946 // return NULL if sequence is empty
1947 if (num_values == 0) return (fy_node_t)NULL;
1948
1949 YAC_ASSERT(values, "no values provided");
1950
1951 // create sequence node
1952 fy_node_t sequence_node = fy_node_create_sequence(document);
1953 YAC_ASSERT(sequence_node, "failed to create sequence node");
1954
1955 for (size_t value_idx = 0; value_idx < num_values; ++value_idx) {
1956 char const * value = values[value_idx];
1957 YAC_ASSERT_F(value, "invalid value at idx %zu", value_idx);
1958 int appending_failed =
1959 fy_node_sequence_append(
1960 sequence_node, yac_yaml_create_scalar(document, value));
1961 YAC_ASSERT(!appending_failed, "failed to append interpolation node");
1962 }
1963
1964 return sequence_node;
1965}
1966
1968 fy_document_t document, size_t const * values, size_t num_values) {
1969
1970 // return NULL if sequence is empty
1971 if (num_values == 0) return (fy_node_t)NULL;
1972
1973 YAC_ASSERT(values, "no values provided");
1974
1975 // create sequence node
1976 fy_node_t sequence_node = fy_node_create_sequence(document);
1977 YAC_ASSERT(sequence_node, "failed to create sequence node");
1978
1979 char str_value[32]; // enough for any size_t
1980 for (size_t value_idx = 0; value_idx < num_values; ++value_idx) {
1981 int value_size =
1982 snprintf(str_value, sizeof(str_value), "%zu", values[value_idx]);
1984 (value_size >= 0) && ((size_t)value_size < sizeof(str_value)),
1985 "could not write \"%zu\" to string buffer of size %zu",
1986 values[value_idx], sizeof(str_value));
1987 fy_node_t scalar_node = yac_yaml_create_scalar(document, str_value);
1988 YAC_ASSERT_F(scalar_node, "failed to create scalar at idx %zu", value_idx);
1989 int appending_failed = fy_node_sequence_append(sequence_node, scalar_node);
1990 YAC_ASSERT(!appending_failed, "failed to append sequence element");
1991 }
1992
1993 return sequence_node;
1994}
1995
1996
1998 fy_node_t map, char const * key, fy_node_t value) {
1999
2000 // if the value node is empty, return
2001 if (!value) return;
2002
2003 YAC_ASSERT(key, "NULL key is not supported");
2004
2005 fy_document_t document = fy_node_document(map);
2006 YAC_ASSERT(document, "failed to get document from node");
2007
2008 // set key and value for root node
2009 int appending_failed =
2010 fy_node_mapping_append(
2011 map, yac_yaml_create_scalar(document, key), value);
2012 YAC_ASSERT(!appending_failed, "failed to append mapping node pair");
2013}
2014
2016 fy_node_t map, char const * key, char const * value) {
2017
2018 fy_document_t document = fy_node_document(map);
2019 YAC_ASSERT(document, "failed to get document from node");
2020
2022}
2023
2025 fy_node_t map, char const * key, int value) {
2026
2027 fy_document_t document = fy_node_document(map);
2028 YAC_ASSERT(document, "failed to get document from node");
2029
2031 map, key, yac_yaml_create_scalar_int(document, value));
2032}
2033
2035 fy_node_t map, char const * key, size_t value) {
2036
2037 fy_document_t document = fy_node_document(map);
2038 YAC_ASSERT(document, "failed to get document from node");
2039
2041 map, key, yac_yaml_create_scalar_size_t(document, value));
2042}
2043
2045 fy_node_t map, char const * key, double value) {
2046
2047 fy_document_t document = fy_node_document(map);
2048 YAC_ASSERT(document, "failed to get document from node");
2049
2051 map, key, yac_yaml_create_scalar_dble(document, value));
2052}
2053
2055 fy_document_t document, struct yac_couple_config * couple_config,
2056 size_t couple_idx, size_t field_couple_idx) {
2057
2058 const char * src_field_name;
2059 const char * tgt_field_name;
2061 couple_config, couple_idx, field_couple_idx,
2062 &src_field_name, &tgt_field_name);
2063
2064 // if both names are identical
2065 if (!strcmp(src_field_name, tgt_field_name))
2066 return yac_yaml_create_scalar(document, src_field_name);
2067
2068 // create field name node
2069 fy_node_t field_name_node = fy_node_create_mapping(document);
2070 YAC_ASSERT(field_name_node, "failed to create mapping node");
2071
2072 // add source field name
2073 yac_yaml_map_append_scalar(field_name_node, "src", src_field_name);
2074
2075 // add target field name
2076 yac_yaml_map_append_scalar(field_name_node, "tgt", tgt_field_name);
2077
2078 return field_name_node;
2079}
2080
2082 fy_document_t document, struct yac_param * param);
2083
2085 fy_document_t document, struct yac_param const * param) {
2086
2087 // if the value is default, skip it in YAML output
2088 if (yac_param_is_default(param)) return NULL;
2089
2090 size_t buflen = 32;
2091 char * value_str = xmalloc(buflen);
2092
2093 while (1) {
2094 int ierr = yac_param_get_scalar(param, value_str, buflen);
2095 if (ierr == 0) break;
2096 YAC_ASSERT_F(buflen < (1u << 20), "%s", yac_param_get_last_error());
2097 buflen *= 2;
2098 value_str = xrealloc(value_str, buflen);
2099 }
2100
2101 fy_node_t scalar_node = yac_yaml_create_scalar(document, value_str);
2102 free(value_str);
2103
2104 return scalar_node;
2105}
2106
2108 fy_document_t document, struct yac_param * param) {
2109
2110 if (yac_param_is_default(param)) return NULL;
2111
2112 size_t sub_count;
2113 int ierr = yac_param_get_sub_count(param, &sub_count);
2114 YAC_ASSERT_F(ierr == 0, "%s", yac_param_get_last_error());
2115
2116 fy_node_t map_node = fy_node_create_mapping(document);
2117 YAC_ASSERT(map_node, "failed to create mapping node");
2118
2119 int contains_non_default_values = 0;
2120 for (size_t i = 0; i < sub_count; ++i) {
2121 struct yac_param * sub_param = NULL;
2122 ierr = yac_param_get_sub_by_index(param, i, &sub_param);
2123 YAC_ASSERT_F(ierr == 0, "%s", yac_param_get_last_error());
2124
2125 fy_node_t sub_node =
2126 yac_yaml_create_non_default_param_node(document, sub_param);
2127 if (!sub_node) continue;
2128
2129 char const * sub_name = yac_param_get_name(sub_param);
2130 YAC_ASSERT(sub_name, "encountered unnamed sub-parameter");
2131
2132 yac_yaml_map_append(map_node, sub_name, sub_node);
2133 contains_non_default_values = 1;
2134 }
2135
2136 if (contains_non_default_values) return map_node;
2137
2138 fy_node_t node = NULL;
2139
2140 // One-of selection changed while active branch remained at defaults.
2141 if (sub_count == 1) {
2142 struct yac_param * active_sub_param = NULL;
2143 ierr = yac_param_get_sub_by_index(param, 0,
2144 &active_sub_param);
2145 YAC_ASSERT_F(ierr == 0, "%s", yac_param_get_last_error());
2146
2147 char const * sub_name = yac_param_get_name(active_sub_param);
2148 YAC_ASSERT(sub_name, "active sub-parameter has no name");
2149
2150 node = yac_yaml_create_scalar(document, sub_name);
2151 }
2152
2153 fy_node_free(map_node);
2154
2155 return node;
2156}
2157
2159 fy_document_t document, struct yac_param * param) {
2160
2161 if (yac_param_is_default(param)) return NULL;
2162
2163 size_t sub_count;
2164 int ierr = yac_param_get_sub_count(param, &sub_count);
2165 YAC_ASSERT_F(ierr == 0, "%s", yac_param_get_last_error());
2166
2167 fy_node_t sequence_node = fy_node_create_sequence(document);
2168 YAC_ASSERT(sequence_node, "failed to create sequence node");
2169
2170 for (size_t i = 0; i < sub_count; ++i) {
2171 struct yac_param * sub_param = NULL;
2172 ierr = yac_param_get_sub_by_index(param, i, &sub_param);
2173 YAC_ASSERT_F(ierr == 0, "%s", yac_param_get_last_error());
2174
2175 fy_node_t sub_node =
2176 yac_yaml_create_non_default_param_node(document, sub_param);
2177 int appending_failed = fy_node_sequence_append(sequence_node, sub_node);
2178 YAC_ASSERT(!appending_failed, "failed to append sequence element");
2179 }
2180
2181 return sequence_node;
2182}
2183
2185 fy_document_t document, struct yac_param * param) {
2186
2188
2189 fy_node_t node = NULL;
2190
2191 switch (type) {
2192 YAC_UNREACHABLE_DEFAULT("unsupported parameter type");
2193 case (YAC_PARAM_TYPE_SCALAR):
2194 node = yac_yaml_create_non_default_scalar_param_node(document, param);
2195 break;
2196 case (YAC_PARAM_TYPE_STRUCT):
2197 node = yac_yaml_create_non_default_struct_param_node(document, param);
2198 break;
2199 case (YAC_PARAM_TYPE_LIST):
2200 node = yac_yaml_create_non_default_list_param_node(document, param);
2201 break;
2202 }
2203
2204 return node;
2205}
2206
2208 fy_document_t document,
2209 struct yac_interp_method_config const * method_config) {
2210
2211 struct yac_param * root_param =
2213 char const * interpolation_name =
2214 yac_param_get_name(root_param);
2215 YAC_ASSERT(interpolation_name, "failed to get interpolation method name");
2216
2217 fy_node_t parameter_node =
2218 yac_yaml_create_non_default_param_node(document, root_param);
2219
2220 fy_node_t interpolation_node;
2221
2222 // if the interpolation contains non-default parameter values
2223 if (parameter_node) {
2224
2225 // create interpolation node
2226 interpolation_node = fy_node_create_mapping(document);
2227 YAC_ASSERT(interpolation_node, "failed to create mapping node");
2229 interpolation_node, interpolation_name, parameter_node);
2230 } else {
2231
2232 interpolation_node =
2233 yac_yaml_create_scalar(document, interpolation_name);
2234 }
2235
2236
2237 return interpolation_node;
2238}
2239
2241 fy_document_t document, struct yac_couple_config * couple_config,
2242 size_t couple_idx, size_t field_couple_idx) {
2243
2244 struct yac_interp_stack_config * interp_stack =
2246 couple_config, couple_idx, field_couple_idx);
2247
2248 YAC_ASSERT(interp_stack, "invalid interpolation stack");
2249
2250 // create interpolation stack node
2251 fy_node_t interp_stack_node = fy_node_create_sequence(document);
2252 YAC_ASSERT(interp_stack_node, "failed to create sequence node");
2253
2254 size_t interp_stack_size =
2256 YAC_ASSERT(interp_stack_size, "invalid interpolation stack size");
2257
2258 for (size_t interp_stack_idx = 0; interp_stack_idx < interp_stack_size;
2259 ++interp_stack_idx) {
2260 int appending_failed =
2261 fy_node_sequence_append(
2262 interp_stack_node,
2264 document,
2265 yac_interp_stack_config_get(interp_stack, interp_stack_idx)));
2266 YAC_ASSERT(!appending_failed, "failed to append interpolation node");
2267 }
2268
2269 return interp_stack_node;
2270}
2271
2273 fy_node_t coupling_node, struct yac_couple_config * couple_config,
2274 size_t couple_idx, size_t field_couple_idx) {
2275
2276 fy_document_t document = fy_node_document(coupling_node);
2277 YAC_ASSERT(document, "failed to get document from node");
2278
2279 // create couple node
2280 fy_node_t field_couple_node = fy_node_create_mapping(document);
2281 YAC_ASSERT(coupling_node, "failed to create mapping node");
2282
2283 // get component names
2284 char const * src_component_name;
2285 char const * tgt_component_name;
2287 couple_config, couple_idx, field_couple_idx,
2288 &src_component_name, &tgt_component_name);
2289
2290 // add source component name
2292 field_couple_node,
2294 yaml_couple_keys, yaml_couple_keys_size, SOURCE_COMPONENT),
2295 src_component_name);
2296
2297 // add target component name
2299 field_couple_node,
2301 yaml_couple_keys, yaml_couple_keys_size, TARGET_COMPONENT),
2302 tgt_component_name);
2303
2304 // get grid names
2305 char const * src_grid_name;
2306 char const * tgt_grid_name;
2308 couple_config, couple_idx, field_couple_idx,
2310
2311 // add source grid name
2313 field_couple_node,
2315 yaml_couple_keys, yaml_couple_keys_size, SOURCE_GRID),
2317
2318 // add target grid name
2320 field_couple_node,
2322 yaml_couple_keys, yaml_couple_keys_size, TARGET_GRID),
2324
2325 // add field names
2327 field_couple_node,
2329 yaml_couple_keys, yaml_couple_keys_size, FIELD),
2331 document, couple_config, couple_idx, field_couple_idx));
2332
2333 // add coupling period
2335 field_couple_node,
2337 yaml_couple_keys, yaml_couple_keys_size, COUPLING_PERIOD),
2339 couple_config, couple_idx, field_couple_idx));
2340
2341 // add time reduction
2343 field_couple_node,
2345 yaml_couple_keys, yaml_couple_keys_size, TIME_REDUCTION),
2347 time_operations, time_operations_size,
2349 couple_config, couple_idx, field_couple_idx)));
2350
2351 // add source lag
2353 field_couple_node,
2355 yaml_couple_keys, yaml_couple_keys_size, SOURCE_LAG),
2357 couple_config, couple_idx, field_couple_idx));
2358
2359 // add target lag
2361 field_couple_node,
2363 yaml_couple_keys, yaml_couple_keys_size, TARGET_LAG),
2365 couple_config, couple_idx, field_couple_idx));
2366
2367 // add weight file name
2369 couple_config, couple_idx, field_couple_idx)) {
2371 field_couple_node,
2373 yaml_couple_keys, yaml_couple_keys_size, WEIGHT_FILE_NAME),
2375 couple_config, couple_idx, field_couple_idx));
2377 field_couple_node,
2379 yaml_couple_keys, yaml_couple_keys_size, WEIGHT_FILE_ON_EXISTING),
2381 weight_file_on_existing_types, weight_file_on_existing_types_size,
2383 couple_config, couple_idx, field_couple_idx)));
2384 }
2385
2386 // add mapping side
2388 field_couple_node,
2390 yaml_couple_keys, yaml_couple_keys_size, MAPPING_SIDE),
2392 mapping_sides, mapping_sides_size,
2394 couple_config, couple_idx, field_couple_idx)));
2395
2396 // add scale factor
2398 field_couple_node,
2400 yaml_couple_keys, yaml_couple_keys_size, SCALE_FACTOR),
2402 couple_config, couple_idx, field_couple_idx));
2403
2404 // add scale summand
2406 field_couple_node,
2408 yaml_couple_keys, yaml_couple_keys_size, SCALE_SUMMAND),
2410 couple_config, couple_idx, field_couple_idx));
2411
2412 // add interpolation
2414 field_couple_node,
2416 yaml_couple_keys, yaml_couple_keys_size, INTERPOLATION),
2418 document, couple_config, couple_idx, field_couple_idx));
2419
2420 // add source mask names
2421 char const * const * src_mask_names;
2422 size_t num_src_mask_names;
2424 couple_config, couple_idx, field_couple_idx,
2425 &src_mask_names, &num_src_mask_names);
2426 if (num_src_mask_names == 1)
2428 field_couple_node,
2430 yaml_couple_keys, yaml_couple_keys_size, SOURCE_MASK_NAME),
2431 src_mask_names[0]);
2432 else if (num_src_mask_names > 1)
2434 field_couple_node,
2436 yaml_couple_keys, yaml_couple_keys_size, SOURCE_MASK_NAMES),
2438 document, src_mask_names, num_src_mask_names));
2439
2440 // add target mask name
2441 char const * tgt_mask_name =
2443 couple_config, couple_idx, field_couple_idx);
2444 if (tgt_mask_name)
2446 field_couple_node,
2448 yaml_couple_keys, yaml_couple_keys_size, TARGET_MASK_NAME),
2449 tgt_mask_name);
2450
2451 // add yaxt exchanger name
2452 char const * yaxt_exchanger_name =
2454 couple_config, couple_idx, field_couple_idx);
2455 if (yaxt_exchanger_name)
2457 field_couple_node,
2459 yaml_couple_keys, yaml_couple_keys_size, YAXT_EXCHANGER_NAME),
2460 yaxt_exchanger_name);
2461
2462 // add collection selection
2463 struct yac_collection_selection const * collection_selection =
2465 couple_config, couple_idx, field_couple_idx);
2466 if (collection_selection) {
2467 size_t collection_size =
2469 size_t const * indices =
2470 yac_collection_selection_get_indices(collection_selection);
2471 size_t * continous_indices = NULL;
2472 if (indices == NULL) {
2473 continous_indices =
2474 xmalloc(collection_size * sizeof(*continous_indices));
2475 for (size_t i = 0; i < collection_size; ++i) continous_indices[i] = i;
2476 indices = continous_indices;
2477 }
2478 if (collection_size == 1) {
2480 field_couple_node,
2482 yaml_couple_keys, yaml_couple_keys_size, COLLECTION_SELECTION),
2483 indices[0]);
2484 } else if (collection_size > 1) {
2486 field_couple_node,
2488 yaml_couple_keys, yaml_couple_keys_size, COLLECTION_SELECTION),
2490 document, indices, collection_size));
2491 }
2492 free(continous_indices);
2493 }
2494
2495 // add use raw exchange
2497 field_couple_node,
2499 yaml_couple_keys, yaml_couple_keys_size, USE_RAW_EXCHANGE),
2501 bool_names, bool_names_size,
2503 couple_config, couple_idx, field_couple_idx)));
2504
2505 int appending_failed =
2506 fy_node_sequence_append(coupling_node, field_couple_node);
2507 YAC_ASSERT(!appending_failed, "failed to append field couple node");
2508}
2509
2511 fy_node_t coupling_node, struct yac_couple_config * couple_config,
2512 size_t couple_idx) {
2513
2514 size_t num_couple_fields =
2515 yac_couple_config_get_num_couple_fields(couple_config, couple_idx);
2516
2517 for (size_t field_couple_idx = 0;
2518 field_couple_idx < num_couple_fields; ++field_couple_idx)
2520 coupling_node, couple_config, couple_idx, field_couple_idx);
2521}
2522
2524 fy_document_t document, char const * grid_name, char const * file_name) {
2525
2526 fy_node_t output_grid_node = fy_node_create_mapping(document);
2527 YAC_ASSERT(output_grid_node, "failed to create mapping node");
2528
2530 output_grid_node,
2532 yaml_debug_output_grid_keys, yaml_debug_output_grid_keys_size,
2534 grid_name);
2536 output_grid_node,
2538 yaml_debug_output_grid_keys, yaml_debug_output_grid_keys_size,
2540 file_name);
2541
2542 return output_grid_node;
2543}
2544
2546 fy_document_t document, struct yac_couple_config * couple_config) {
2547
2548 // count the number of output grids
2549 // (the effective file names are used here, hence an output file name that
2550 // applies to all grids is emitted as one entry per grid)
2551 size_t num_output_grids = 0;
2552 size_t num_grids =
2553 yac_couple_config_get_num_grids(couple_config);
2554 for (size_t grid_idx = 0; grid_idx < num_grids; ++grid_idx)
2556 couple_config,
2557 yac_couple_config_get_grid_name(couple_config, grid_idx)) != NULL)
2558 ++num_output_grids;
2559
2560 fy_node_t output_grids_node = NULL;
2561
2562 if (num_output_grids > 0) {
2563
2564 // create output grids node
2565 output_grids_node = fy_node_create_sequence(document);
2566 YAC_ASSERT(output_grids_node, "failed to create sequence node");
2567
2568 // for all output grids
2569 for (size_t grid_idx = 0; grid_idx < num_grids; ++grid_idx) {
2570
2571 char const * grid_name =
2573 char const * file_name =
2574 yac_couple_config_get_grid_output_filename(couple_config, grid_name);
2575
2576 if (file_name != NULL) {
2577 int appending_failed =
2578 fy_node_sequence_append(
2579 output_grids_node,
2580 yac_yaml_create_output_grid_node(document, grid_name, file_name));
2581 YAC_ASSERT(!appending_failed, "failed to append output grid node");
2582 }
2583 }
2584 }
2585
2586 return output_grids_node;
2587}
2588
2590 fy_document_t document, struct yac_couple_config * couple_config) {
2591
2592 // create debug node
2593 fy_node_t debug_node = fy_node_create_mapping(document);
2594 YAC_ASSERT(debug_node, "failed to create mapping node");
2595
2596 // add output grids node
2598 debug_node,
2600 yaml_debug_keys, yaml_debug_keys_size, OUTPUT_GRIDS),
2601 yac_yaml_create_output_grids_node(document, couple_config));
2602
2603 // add "missing_definition_is_fatal" node
2605 debug_node,
2607 yaml_debug_keys, yaml_debug_keys_size, MISSING_DEF),
2609 bool_names, bool_names_size,
2611
2612 // add "apply_coordinate_checks" node
2614 debug_node,
2616 yaml_debug_keys, yaml_debug_keys_size, APPLY_COORD_CHECK),
2618 bool_names, bool_names_size,
2620
2621 // add "coordinates_mismatch_is_fatal" node
2623 debug_node,
2625 yaml_debug_keys, yaml_debug_keys_size, COORDS_MISMATCH_FATAL),
2627 bool_names, bool_names_size,
2629
2630 return debug_node;
2631}
2632
2634 fy_document_t document, struct yac_couple_config * couple_config) {
2635
2636 size_t num_couples =
2637 yac_couple_config_get_num_couples(couple_config);
2638
2639 if (!num_couples) return NULL;
2640
2641 // create coupling node
2642 fy_node_t coupling_node = fy_node_create_sequence(document);
2643 YAC_ASSERT(coupling_node, "failed to create sequence node");
2644
2645 // for all couples
2646 for (size_t couple_idx = 0; couple_idx < num_couples; ++couple_idx)
2648 coupling_node, couple_config, couple_idx);
2649
2650 return coupling_node;
2651}
2652
2654 fy_document_t document, struct yac_couple_config * couple_config,
2655 size_t component_idx, size_t field_idx) {
2656
2657 fy_node_t field_node = fy_node_create_mapping(document);
2658 YAC_ASSERT(field_node, "failed to create mapping node");
2659
2660 // get field parameters
2661 char const * component_name =
2663 couple_config, component_idx);
2664 char const * field_name =
2666 couple_config, component_idx, field_idx);
2667 char const * grid_name =
2669 couple_config, component_idx, field_idx);
2670 char const * metadata =
2672 couple_config, component_name, grid_name, field_name);
2673 size_t collection_size =
2675 couple_config, component_name, grid_name, field_name);
2676 char const * timestep =
2678 couple_config, component_name, grid_name, field_name);
2679 int role =
2681 couple_config, component_name, grid_name, field_name);
2682 double frac_mask_fallback_value =
2684 couple_config, component_name, grid_name, field_name);
2685
2686 // add field name
2687 yac_yaml_map_append_scalar(field_node, "name", field_name);
2688
2689 // add grid name
2690 yac_yaml_map_append_scalar(field_node, "grid_name", grid_name);
2691
2692 // add metadata
2693 if (metadata)
2694 yac_yaml_map_append_scalar(field_node, "metadata", metadata);
2695
2696 // add collection_size
2697 if (collection_size != SIZE_MAX)
2699 field_node, "collection_size", (int)collection_size);
2700
2701 // add timestep
2702 if (timestep)
2703 yac_yaml_map_append_scalar(field_node, "timestep", timestep);
2704
2705 // add role
2707 field_node, "role",
2709 role_types, role_types_size, (enum yac_field_exchange_type)role));
2710
2711 // add fractional fallback value
2712 if (YAC_FRAC_MASK_VALUE_IS_VALID(frac_mask_fallback_value))
2714 field_node, "frac_mask_fallback_value", frac_mask_fallback_value);
2715
2716 return field_node;
2717}
2718
2720 fy_document_t document, struct yac_couple_config * couple_config,
2721 size_t component_idx) {
2722
2723 size_t num_fields =
2725
2726 if (num_fields == 0) return (fy_node_t)NULL;
2727
2728 fy_node_t fields_node = fy_node_create_sequence(document);
2729 YAC_ASSERT(fields_node, "failed to create sequence node");
2730
2731 for (size_t field_idx = 0; field_idx < num_fields; ++field_idx) {
2732
2733 int appending_failed =
2734 fy_node_sequence_append(
2735 fields_node,
2737 document, couple_config, component_idx, field_idx));
2738 YAC_ASSERT(!appending_failed, "failed to append field node");
2739 }
2740
2741 return fields_node;
2742}
2743
2745 fy_document_t document, struct yac_couple_config * couple_config,
2746 size_t component_idx) {
2747
2748 fy_node_t component_node = fy_node_create_mapping(document);
2749 YAC_ASSERT(component_node, "failed to create mapping node");
2750
2751 // get component name, component metadata, and fields
2752 char const * component_name =
2754 char const * metadata =
2755 yac_couple_config_get_component_metadata(couple_config, component_name);
2756 fy_node_t fields_node =
2758 document, couple_config, component_idx);
2759
2760 // add component name
2761 yac_yaml_map_append_scalar(component_node, "name", component_name);
2762
2763 // add metadata
2764 if (metadata)
2765 yac_yaml_map_append_scalar(component_node, "metadata", metadata);
2766
2767 // add fields
2768 yac_yaml_map_append(component_node, "fields", fields_node);
2769
2770 return component_node;
2771}
2772
2774 fy_document_t document, struct yac_couple_config * couple_config) {
2775
2776 // get number of components in coupling configuration
2778
2779 if (num_components == 0) return (fy_node_t)NULL;
2780
2781 // create sequence node
2782 fy_node_t components_node = fy_node_create_sequence(document);
2783 YAC_ASSERT(components_node, "failed to create sequence node");
2784
2785 for (size_t component_idx = 0; component_idx < num_components;
2786 ++component_idx) {
2787
2788 int appending_failed =
2789 fy_node_sequence_append(
2790 components_node,
2791 yac_yaml_create_component_node(document, couple_config, component_idx));
2792 YAC_ASSERT(!appending_failed, "failed to append component node");
2793 }
2794
2795 return components_node;
2796}
2797
2799 fy_document_t document, struct yac_couple_config * couple_config,
2800 size_t grid_idx) {
2801
2802 fy_node_t grid_node = fy_node_create_mapping(document);
2803 YAC_ASSERT(grid_node, "failed to create mapping node");
2804
2805 // get grid name and metadata
2806 char const * grid_name =
2808 char const * metadata =
2809 yac_couple_config_get_grid_metadata(couple_config, grid_name);
2810
2811 // add grid name
2812 yac_yaml_map_append_scalar(grid_node, "name", grid_name);
2813
2814 // add metadata
2815 if (metadata)
2816 yac_yaml_map_append_scalar(grid_node, "metadata", metadata);
2817
2818 return grid_node;
2819}
2820
2822 fy_document_t document, struct yac_couple_config * couple_config) {
2823
2824 // get number of grids in coupling configuration
2825 size_t num_grids = yac_couple_config_get_num_grids(couple_config);
2826
2827 if (num_grids == 0) return (fy_node_t)NULL;
2828
2829 // create sequence node
2830 fy_node_t grids_node = fy_node_create_sequence(document);
2831 YAC_ASSERT(grids_node, "failed to create sequence node");
2832
2833 for (size_t grids_idx = 0; grids_idx < num_grids; ++grids_idx) {
2834
2835 int appending_failed =
2836 fy_node_sequence_append(
2837 grids_node,
2838 yac_yaml_create_grid_node(document, couple_config, grids_idx));
2839 YAC_ASSERT(!appending_failed, "failed to append grid node");
2840 }
2841
2842 return grids_node;
2843}
2844
2846 fy_document_t document, struct yac_couple_config * couple_config) {
2847
2848 // create definition
2849 fy_node_t definition_node = fy_node_create_mapping(document);
2850 YAC_ASSERT(definition_node, "failed to create mapping node");
2851
2852 // add components
2854 definition_node,
2855 "components", yac_yaml_create_components_node(document, couple_config));
2856
2857 // add grids
2859 definition_node, "grids", yac_yaml_create_grids_node(document, couple_config));
2860
2861 return definition_node;
2862}
2863
2865 fy_document_t document, struct yac_couple_config * couple_config,
2866 int include_definitions) {
2867
2868 // create root node
2869 fy_node_t root_node = fy_node_create_mapping(document);
2870 YAC_ASSERT(root_node, "failed to create mapping node");
2871
2872 // add debug
2874 root_node,
2876 yaml_base_keys, yaml_base_keys_size, DEBUG),
2877 yac_yaml_create_debug_node(document, couple_config));
2878
2879 // add debug definitions (components, grids, and fields)
2880 if (include_definitions)
2882 root_node, "debug_definitions",
2883 yac_yaml_create_definitions_node(document, couple_config));
2884
2885 // add start datetime
2886 char * start_datetime = yac_couple_config_get_start_datetime(couple_config);
2888 root_node,
2890 yaml_base_keys, yaml_base_keys_size, START_DATE), start_datetime);
2891 free(start_datetime);
2892
2893 // add end datetime
2894 char * end_datetime = yac_couple_config_get_end_datetime(couple_config);
2896 root_node,
2898 yaml_base_keys, yaml_base_keys_size, END_DATE), end_datetime);
2899 free(end_datetime);
2900
2901 // add calendar
2903 root_node,
2905 yaml_base_keys, yaml_base_keys_size, CALENDAR),
2907 calendar_types, calendar_types_size, getCalendarType()));
2908
2909 // add timestep unit
2911 root_node,
2913 yaml_base_keys, yaml_base_keys_size, TIMESTEP_UNIT),
2915 timestep_units, timestep_units_size, C_ISO_FORMAT));
2916
2917 // add couplings
2919 root_node,
2921 yaml_base_keys, yaml_base_keys_size, COUPLING),
2922 yac_yaml_create_coupling_node(document, couple_config));
2923
2924 return root_node;
2925}
2926
2928 struct yac_couple_config * couple_config, int emit_flags,
2929 int include_definitions) {
2930
2931 // create an empty document
2932 fy_document_t document = fy_document_create(NULL);
2933 YAC_ASSERT(document, "failed to create document");
2934
2935 // create nodes from coupling configuration
2936 fy_node_t root_node =
2938 document, couple_config, include_definitions);
2939
2940 // set root node of the document
2941 int setting_root_failed =
2942 fy_document_set_root(document, root_node);
2943 YAC_ASSERT(!setting_root_failed, "failed to add root node to document");
2944
2945 // emit document to string
2946 char * str_document =
2947 fy_emit_document_to_string(
2948 document, (enum fy_emitter_cfg_flags)emit_flags);
2949
2950 YAC_ASSERT(str_document, "failed to emit document to string");
2951
2952 // destroy document
2953 fy_document_destroy(document);
2954
2955 return str_document;
2956}
char const * grid_names[]
unsigned component_idx[3]
unsigned num_fields
unsigned num_components
char const * field_names[8]
char const * file_name
unsigned grid_idx[3]
#define YAC_ASSERT(exp, msg)
static double yaml_parse_double_value(fy_node_t value_node, char const *key_name, char const *yaml_filename)
yaml_debug_sync_loc_key_types
@ SYNC_LOC_COUNT
@ SYNC_LOC_ENDDEF
@ SYNC_LOC_DEF_COMP
@ SYNC_LOC_SYNC_DEF
static fy_node_t yac_yaml_create_interpolation_node(fy_document_t document, struct yac_interp_method_config const *method_config)
static void yaml_parse_couple(struct yac_couple_config *couple_config, fy_node_t couple_node, char const *yaml_filename, enum yac_time_unit_type time_unit)
struct yac_interp_stack_config * yac_yaml_parse_interp_stack_config_string(char const *str_interp_stack_config, int parse_flags)
static void yaml_parse_field_names(struct field_couple_field_names **field_names, size_t *num_field_names, fy_node_t fields_node, const char *yaml_filename)
static void yac_yaml_append_couple_nodes(fy_node_t coupling_node, struct yac_couple_config *couple_config, size_t couple_idx)
static void yaml_check_base_key_typo(char const *unknown_key, char const *yaml_filename)
static fy_node_t yac_yaml_create_scalar_dble(fy_document_t document, double value)
#define YAML_UNREACHABLE_DEFAULT_F(MSG,...)
static void yaml_set_interp_method_config_param_from_node(struct yac_param *param, fy_node_t value_node, char const *interpolation_name, char const *yaml_filename)
struct fy_node_pair * fy_node_pair_t
Definition config_yaml.c:49
static fy_node_t yac_yaml_create_non_default_param_node(fy_document_t document, struct yac_param *param)
static fy_node_t yac_yaml_create_field_node(fy_document_t document, struct yac_couple_config *couple_config, size_t component_idx, size_t field_idx)
static calendarType yaml_parse_calendar_value(fy_node_t value_node, char const *key_name, char const *yaml_filename)
static fy_node_t yac_yaml_create_grids_node(fy_document_t document, struct yac_couple_config *couple_config)
static void yaml_parse_base_map_pair(struct yac_couple_config *couple_config, fy_node_pair_t base_pair, const char *yaml_filename, enum yac_time_unit_type *time_unit, char const **start_datetime, char const **end_datetime)
static void yaml_parse_string_sequence(char const ***values, size_t *num_values, fy_node_t values_node, char const *sequence_name, const char *yaml_filename)
static fy_node_t yac_yaml_create_output_grids_node(fy_document_t document, struct yac_couple_config *couple_config)
static fy_node_t yac_yaml_create_sequence_scalar_size_t(fy_document_t document, size_t const *values, size_t num_values)
int const YAC_YAML_PARSER_JSON_AUTO
Definition config_yaml.c:62
yaml_debug_key_types
@ GLOBAL_CONFIG
@ APPLY_COORD_CHECK
@ GLOBAL_DEFS
@ COORDS_MISMATCH_FATAL
@ OUTPUT_GRIDS
@ MISSING_DEF
static void yaml_parse_size_t_sequence(size_t **values, size_t *num_values, fy_node_t values_node, char const *sequence_name, const char *yaml_filename)
#define YAML_UNREACHABLE_DEFAULT(MSG)
char * yac_yaml_emit_coupling(struct yac_couple_config *couple_config, int emit_flags, int include_definitions)
static size_t yaml_parse_size_t_value(fy_node_t value_node, char const *key_name, char const *yaml_filename)
static fy_node_t yac_yaml_create_components_node(fy_document_t document, struct yac_couple_config *couple_config)
static fy_node_t yac_yaml_create_couple_config_nodes(fy_document_t document, struct yac_couple_config *couple_config, int include_definitions)
static fy_node_t yac_yaml_create_grid_node(fy_document_t document, struct yac_couple_config *couple_config, size_t grid_idx)
static void yac_yaml_map_append_scalar_dble(fy_node_t map, char const *key, double value)
static void yaml_parse_document(struct yac_couple_config *couple_config, fy_document_t document, const char *yaml_filename)
static int yaml_parse_enum_value(struct yac_name_type_pair const *valid_values, size_t num_valid_values, fy_node_t value_node, char const *key_name, char const *yaml_filename)
int const YAC_YAML_EMITTER_DEFAULT
emit to YAML format
Definition config_yaml.c:59
void yac_yaml_read_coupling(struct yac_couple_config *couple_config, const char *yaml_filename, int parse_flags)
static fy_node_t yac_yaml_create_non_default_scalar_param_node(fy_document_t document, struct yac_param const *param)
yaml_couple_key_types
@ WEIGHT_FILE_NAME
@ SCALE_SUMMAND
@ TARGET_COMPONENT
@ SOURCE_GRID
@ SOURCE_MASK_NAME
@ INTERPOLATION
@ SOURCE_MASK_NAMES
@ YAXT_EXCHANGER_NAME
@ MAPPING_SIDE
@ TIME_REDUCTION
@ SOURCE_LAG
@ WEIGHT_FILE_ON_EXISTING
@ COLLECTION_SELECTION
@ SOURCE_NAME
@ FIELD
@ TARGET_GRID
@ COUPLING_PERIOD
@ TARGET_NAMES
@ WEIGHT_FILE_DATA
@ SOURCE_COMPONENT
@ SCALE_FACTOR
@ TARGET_LAG
@ TARGET_MASK_NAME
@ USE_RAW_EXCHANGE
static int yaml_parse_integer_value(fy_node_t value_node, char const *key_name, char const *yaml_filename)
static void yaml_parse_debug_output_grids(struct yac_couple_config *couple_config, fy_node_t output_grids_node, char const *yaml_filename)
static void yaml_parse_comp_grid_names(char const **comp_name, char const ***grid_names, size_t *num_grid_names, fy_node_t values_node, char const *type_name, const char *yaml_filename, int allow_multiple_grids)
#define OUTPUT_GRIDS_FILE_NAME_STR
int const YAC_YAML_EMITTER_JSON
emit to JSON format
Definition config_yaml.c:60
static enum yac_time_unit_type yaml_parse_timestep_unit_value(fy_node_t value_node, char const *key_name, char const *yaml_filename)
static void yac_yaml_map_append_scalar(fy_node_t map, char const *key, char const *value)
struct fy_document * fy_document_t
Definition config_yaml.c:47
int const YAC_YAML_PARSER_DEFAULT
default parse flags (YAML format)
Definition config_yaml.c:61
static fy_node_t yac_yaml_create_output_grid_node(fy_document_t document, char const *grid_name, char const *file_name)
static fy_node_t yac_yaml_create_non_default_struct_param_node(fy_document_t document, struct yac_param *param)
static struct field_couple_field_names yaml_parse_field_name(fy_node_t field_node, const char *yaml_filename)
static void yaml_parse_base_interp_method_node(char const **interpolation_type_str, fy_node_t *parameter_node, fy_node_t interp_method_node, char const *yaml_filename)
reads interpolation name and user-provided parameters from YAML node
static void yaml_parse_weight_file_data(char const **weight_file_name, enum yac_weight_file_on_existing *on_existing, fy_node_t values_node, char const *type_name, const char *yaml_filename)
yaml_weight_file_data_key_types
@ WEIGHT_FILE_DATA_ON_EXISTING
@ WEIGHT_FILE_DATA_NAME
static fy_node_t yac_yaml_create_field_name_node(fy_document_t document, struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
static char const * yaml_parse_timestep_value(fy_node_t value_node, char const *key_name, char const *yaml_filename, enum yac_time_unit_type time_unit)
static struct debug_config_file_buffer yaml_parse_debug_config_file_buffer(fy_node_t config_file_node, char const *config_file_type_name, char const *yaml_filename)
#define YAML_ASSERT_F(CHECK, MSG,...)
static fy_node_t yac_yaml_create_component_node(fy_document_t document, struct yac_couple_config *couple_config, size_t component_idx)
static size_t yaml_edit_distance(char const *a, char const *b)
yaml_debug_output_grid_key_types
@ OUTPUT_GRID_FILE_NAME
@ OUTPUT_GRID_GRID_NAME
static void yaml_parse_coupling(struct yac_couple_config *couple_config, fy_node_t coupling_node, char const *yaml_filename, enum yac_time_unit_type time_unit)
static fy_node_t yac_yaml_create_coupling_node(fy_document_t document, struct yac_couple_config *couple_config)
static void yaml_parse_output_grid_pair(char const **grid_name, char const **file_name, fy_node_pair_t output_grid_pair, char const *yaml_filename)
static fy_node_t yac_yaml_create_interpolation_stack_node(fy_document_t document, struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
static enum yac_reduction_type yaml_parse_time_reduction_value(fy_node_t value_node, char const *key_name, char const *yaml_filename)
static void yaml_parse_debug_global_config(struct yac_couple_config *couple_config, fy_node_t global_config_node, char const *yaml_filename)
static void yac_yaml_map_append_scalar_size_t(fy_node_t map, char const *key, size_t value)
static fy_node_t yac_yaml_create_scalar_size_t(fy_document_t document, size_t value)
char const * yac_time_to_ISO(char const *time, enum yac_time_unit_type time_unit)
Definition event.c:353
int const YAC_YAML_PARSER_JSON_FORCE
assume JSON format
Definition config_yaml.c:63
static void yac_yaml_append_couple_field_nodes(fy_node_t coupling_node, struct yac_couple_config *couple_config, size_t couple_idx, size_t field_couple_idx)
static void yaml_parse_interp_stack_value(struct yac_interp_stack_config *interp_stack, fy_node_t interp_stack_node, char const *yaml_filename)
static fy_node_t yac_yaml_create_debug_node(fy_document_t document, struct yac_couple_config *couple_config)
struct fy_node * fy_node_t
Definition config_yaml.c:48
static void yaml_parse_debug(struct yac_couple_config *couple_config, fy_node_t debug_node, char const *yaml_filename)
static void yac_yaml_map_append(fy_node_t map, char const *key, fy_node_t value)
static fy_node_t yac_yaml_create_sequence_scalar(fy_document_t document, char const *const *values, size_t num_values)
static void yaml_parse_debug_map_pair(struct yac_couple_config *couple_config, fy_node_pair_t debug_pair, const char *yaml_filename)
static void yac_yaml_map_append_scalar_int(fy_node_t map, char const *key, int value)
#define YAML_ASSERT(CHECK, MSG)
static fy_node_t yac_yaml_create_fields_node(fy_document_t document, struct yac_couple_config *couple_config, size_t component_idx)
static void yaml_parse_debug_config_file_map_pair(struct debug_config_file_buffer *config_file_buffer, fy_node_pair_t config_file_pair, char const *config_file_type_name, const char *yaml_filename)
yaml_base_key_types
@ DEBUG
@ TIMESTEP_UNIT
@ START_DATE
@ COUPLING
@ CALENDAR
@ END_DATE
static void yaml_parse_interp_method(struct yac_interp_stack_config *interp_stack, fy_node_t interp_method_node, char const *yaml_filename)
yaml_comp_grid_names_key_types
@ COMP_NAME
@ GRID_NAMES
static fy_node_t yac_yaml_create_scalar(fy_document_t document, char const *value)
static void yaml_parse_output_grid(struct yac_couple_config *couple_config, fy_node_t output_grid_node, char const *yaml_filename)
static fy_node_t yac_yaml_create_scalar_int(fy_document_t document, int value)
static void yaml_parse_collection_selection_sequence(struct yac_collection_selection **collection_selection, fy_node_t values_node, char const *sequence_name, const char *yaml_filename)
static struct debug_config_file yaml_parse_config_file_value(fy_node_t config_file_node, char const *file_type_name, const char *yaml_filename)
static fy_node_t yac_yaml_create_non_default_list_param_node(fy_document_t document, struct yac_param *param)
static void yaml_parse_couple_map_pair(struct field_couple_buffer *field_buffer, fy_node_pair_t couple_pair, const char *yaml_filename, enum yac_time_unit_type time_unit)
@ EMITTER_DEFAULT
Definition config_yaml.c:52
@ PARSER_JSON_AUTO
Definition config_yaml.c:55
@ EMITTER_JSON
Definition config_yaml.c:53
@ PARSER_JSON_FORCE
Definition config_yaml.c:56
@ PARSER_DEFAULT
Definition config_yaml.c:54
static void yaml_parse_all_output_grids(struct yac_couple_config *couple_config, fy_node_t output_grids_node, char const *yaml_filename)
static fy_node_t yac_yaml_create_definitions_node(fy_document_t document, struct yac_couple_config *couple_config)
int yac_couple_config_get_enforce_write_weight_file(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
double yac_couple_config_get_scale_summand(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
void yac_couple_config_get_field_couple_component_names(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx, char const **src_component_name, char const **tgt_component_name)
struct yac_interp_stack_config * yac_couple_config_get_interp_stack(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
int yac_couple_config_get_missing_definition_is_fatal(struct yac_couple_config const *couple_config)
int yac_couple_config_get_use_raw_exchange(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
void yac_couple_config_get_field_names(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx, char const **src_field_name, const char **tgt_field_name)
char * yac_couple_config_get_end_datetime(struct yac_couple_config const *couple_config)
void yac_couple_config_set_grid_output_filename(struct yac_couple_config *couple_config, char const *grid_name, const char *output_filename)
const char * yac_couple_config_get_grid_output_filename(struct yac_couple_config const *couple_config, const char *grid_name)
const char * yac_couple_config_get_component_metadata(struct yac_couple_config const *couple_config, const char *comp_name)
char const * yac_couple_config_get_yaxt_exchanger_name(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
char const * yac_couple_config_get_field_grid_name(struct yac_couple_config const *couple_config, size_t component_idx, size_t field_idx)
char const * yac_couple_config_get_field_timestep(struct yac_couple_config const *couple_config, char const *component_name, char const *grid_name, char const *field_name)
double yac_couple_config_get_scale_factor(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
void yac_couple_config_set_datetime(struct yac_couple_config *couple_config, char const *start, char const *end)
size_t yac_couple_config_get_num_grids(struct yac_couple_config const *couple_config)
void yac_couple_config_set_apply_coordinate_check(struct yac_couple_config *couple_config, int apply_coordinate_check)
char const * yac_couple_config_get_weight_file_name(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
void yac_couple_config_get_src_mask_names(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx, char const *const **mask_names, size_t *num_mask_names)
char const * yac_couple_config_get_grid_name(struct yac_couple_config const *couple_config, size_t grid_idx)
double yac_couple_config_get_frac_mask_fallback_value(struct yac_couple_config const *couple_config, char const *component_name, char const *grid_name, char const *field_name)
size_t yac_couple_config_get_num_couples(struct yac_couple_config const *couple_config)
struct yac_collection_selection const * yac_couple_config_get_collection_selection(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
char const * yac_couple_config_get_tgt_mask_name(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
int yac_couple_config_get_source_lag(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
size_t yac_couple_config_get_field_collection_size(struct yac_couple_config const *couple_config, char const *component_name, char const *grid_name, char const *field_name)
char * yac_couple_config_get_start_datetime(struct yac_couple_config const *couple_config)
int yac_couple_config_get_field_role(struct yac_couple_config const *couple_config, char const *component_name, char const *grid_name, char const *field_name)
size_t yac_couple_config_get_num_components(struct yac_couple_config const *couple_config)
void yac_couple_config_set_coordinates_mismatch_is_fatal(struct yac_couple_config *couple_config, int coordinates_mismatch_is_fatal)
char const * yac_couple_config_get_field_name(struct yac_couple_config const *couple_config, size_t component_idx, size_t field_idx)
size_t yac_couple_config_get_num_couple_fields(struct yac_couple_config const *couple_config, size_t couple_idx)
size_t yac_couple_config_get_num_fields(struct yac_couple_config const *couple_config, size_t component_idx)
void yac_couple_config_add_grid(struct yac_couple_config *couple_config, char const *name)
int yac_couple_config_get_target_lag(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
const char * yac_couple_config_get_grid_metadata(struct yac_couple_config const *couple_config, const char *grid_name)
enum yac_weight_file_on_existing yac_couple_config_get_weight_file_on_existing(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
int yac_couple_config_get_coordinates_mismatch_is_fatal(struct yac_couple_config const *couple_config)
int yac_couple_config_get_mapping_on_source(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
void yac_couple_config_get_field_grid_names(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx, char const **src_grid_name, char const **tgt_grid_name)
char const * yac_couple_config_get_component_name(struct yac_couple_config const *couple_config, size_t component_idx)
int yac_couple_config_get_apply_coordinate_check(struct yac_couple_config const *couple_config)
void yac_couple_config_set_all_grids_output_filename(struct yac_couple_config *couple_config, char const *output_filename)
void yac_couple_config_set_missing_definition_is_fatal(struct yac_couple_config *couple_config, int missing_definition_is_fatal)
char const * yac_couple_config_get_coupling_period(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_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)
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)
enum yac_reduction_type yac_couple_config_get_coupling_period_operation(struct yac_couple_config const *couple_config, size_t couple_idx, size_t field_couple_idx)
const char * yac_couple_config_get_field_metadata(struct yac_couple_config const *couple_config, const char *comp_name, const char *grid_name, const char *field_name)
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
yac_time_unit_type
@ C_SECOND
@ TIME_UNIT_UNDEFINED
@ C_HOUR
@ C_DAY
@ C_MILLISECOND
@ C_MINUTE
@ C_MONTH
@ C_ISO_FORMAT
@ C_YEAR
yac_field_exchange_type
Definition fields.h:12
@ SOURCE
Definition fields.h:15
@ TARGET
Definition fields.h:16
@ NOTHING
Definition fields.h:14
size_t yac_collection_selection_get_collection_size(struct yac_collection_selection const *collection_selection)
Get the size of the collection selection.
size_t const * yac_collection_selection_get_indices(struct yac_collection_selection const *collection_selection)
Get explicit selection indices if non-contiguous.
void yac_collection_selection_delete(struct yac_collection_selection *collection_selection)
Delete a collection selection object.
struct yac_collection_selection * yac_collection_selection_new(size_t collection_size, size_t const *selection_indices)
Create a new collection selection.
int yac_name_type_pair_get_type(struct yac_name_type_pair const *pairs, size_t count, char const *name)
Definition utils_core.c:23
#define DEF_NAME_TYPE_PAIR(NAME, TYPE)
char const * yac_name_type_pair_get_name(struct yac_name_type_pair const *pairs, size_t count, int type)
Definition utils_core.c:14
#define DEF_NAME_TYPE_PAIRS(NAME,...)
void yac_instance_def_calendar(int calendar_type, char const *source)
Definition instance.c:1557
#define YAC_INSTANCE_CONFIG_OUTPUT_REF_ENDDEF
Definition instance.h:15
#define YAC_INSTANCE_CONFIG_OUTPUT_REF_COMP
Definition instance.h:13
#define YAC_INSTANCE_CONFIG_OUTPUT_REF_SYNC
Definition instance.h:14
char * key
enum callback_type type
struct @23::@24 value
struct yac_param * yac_interp_method_config_get_param(struct yac_interp_method_config const *config)
struct yac_interp_method_config * yac_interp_method_config_default_from_name_new(char const *method_name)
Defines the interface for interpolation method configuration "base class" in YAC.
size_t yac_interp_stack_config_get_size(struct yac_interp_stack_config *interp_stack)
Get the number of interpolation methods in the stack.
struct yac_interp_method_config const * yac_interp_stack_config_get(struct yac_interp_stack_config *interp_stack, size_t interp_stack_idx)
Get a method configuration from the stack by index.
void yac_interp_stack_config_delete(struct yac_interp_stack_config *interp_stack_config)
Free an interpolation stack configuration object.
void yac_interp_stack_config_add(struct yac_interp_stack_config *interp_stack_config, struct yac_interp_method_config *method_config)
Add an interpolation method configuration to the end of the stack.
struct yac_interp_stack_config * yac_interp_stack_config_new()
Allocate a new empty interpolation stack configuration object.
#define YAC_WEIGHT_FILE_ON_EXISTING_DEFAULT_VALUE
yac_weight_file_on_existing
@ YAC_WEIGHT_FILE_KEEP
keep existing weight file
@ YAC_WEIGHT_FILE_UNDEFINED
@ YAC_WEIGHT_FILE_OVERWRITE
overwrite existing weight file
@ YAC_WEIGHT_FILE_ERROR
error when weight file existis already
Defines internal basic interpolation definitions.
#define YAC_FRAC_MASK_VALUE_IS_VALID(value)
Test whether a fractional mask value is valid.
int yac_file_exists(const char *filename)
Check whether a file exists.
Definition io_utils.c:394
int yac_param_get_sub_by_index(struct yac_param *param, size_t idx, struct yac_param **sub_param)
Get a handle to a subparameter by index.
Definition param.c:89
int yac_param_is_default(const struct yac_param *param)
Check whether a parameter is at its default value.
Definition param.c:37
int yac_param_get_scalar(const struct yac_param *param, char *buf, size_t buflen)
Get the value of a scalar parameter as a string.
Definition param.c:123
int yac_param_set_scalar(struct yac_param *param, const char *value_str)
Set the value of a scalar parameter from a string.
Definition param.c:113
enum yac_param_type yac_param_get_type(const struct yac_param *param)
Get the type of a parameter.
Definition param.c:24
int yac_param_append(struct yac_param *param, struct yac_param **sub_param)
Append a new default subparameter to a list parameter and return a handle to it.
Definition param.c:102
int yac_param_get_sub_count(const struct yac_param *param, size_t *count)
Get the number of subparameters.
Definition param.c:61
const char * yac_param_get_last_error(void)
Retrieve the last error message for the calling thread.
Definition param.c:298
const char * yac_param_get_name(const struct yac_param *param)
Get the name of the current parameter.
Definition param.c:50
int yac_param_get_sub_by_name(struct yac_param *param, const char *name, struct yac_param **sub_param)
Get a handle to a subparameter by name.
Definition param.c:75
Public interface for YAC parameters.
yac_param_type
Parameter type for generic configuration interface.
Definition param.h:171
@ YAC_PARAM_TYPE_SCALAR
Single typed value (e.g., int, double, string, enum)
Definition param.h:177
@ YAC_PARAM_TYPE_LIST
Ordered, growable list of subparameters.
Definition param.h:181
@ YAC_PARAM_TYPE_STRUCT
Named, fixed set of subparameters.
Definition param.h:179
#define xstrdup(s)
Definition ppm_xfuncs.h:84
#define xrealloc(ptr, size)
Definition ppm_xfuncs.h:67
#define xmalloc(size)
Definition ppm_xfuncs.h:66
#define xfclose(fp)
Definition ppm_xfuncs.h:79
#define xfopen(path, mode)
Definition ppm_xfuncs.h:74
struct debug_config_file_buffer::debug_config_file config_file[SYNC_LOC_COUNT]
char const * sync_loc_ref[SYNC_LOC_COUNT]
char const ** src_mask_names
Definition config_yaml.c:97
char const * yaxt_exchanger_name
char const * coupling_period
Definition config_yaml.c:82
enum yac_weight_file_on_existing on_existing
Definition config_yaml.c:87
char const * name
Definition config_yaml.c:86
struct field_couple_buffer::@58 src
char const * tgt_mask_name
Definition config_yaml.c:99
struct field_couple_buffer::@60 weight_file
struct field_couple_buffer::@59 tgt
char const * comp_name
Definition config_yaml.c:70
struct yac_interp_stack_config * interp_stack
Definition config_yaml.c:84
char const * grid_name
Definition config_yaml.c:71
struct yac_collection_selection * collection_selection
struct field_couple_buffer::field_couple_field_names * field_names
struct field_couple_buffer::@59::@61 grid
char const ** name
Definition config_yaml.c:77
enum yac_reduction_type time_reduction
Definition config_yaml.c:83
@ error
Definition test_cxc.c:17
int collection_size
char * yaml_filename
char const * weight_file_name
char const src_grid_name[]
char const tgt_grid_name[]
#define MIN(a, b)
Definition toy_common.h:29
char const * name
Definition toy_scrip.c:114
int yac_cget_calendar()
Definition yac.c:1041
int const YAC_CALENDAR_NOT_SET
Definition yac.c:72
#define YAC_ASSERT_F(exp, format,...)
Definition yac_assert.h:39
#define YAC_UNREACHABLE_DEFAULT(msg)
Definition yac_assert.h:56