20#define ARGS(...) __VA_ARGS__
21#define _GET_NTH_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, N, ...) N
23#define FOREACH(name, ...) \
25 enum {NUM_ ## name = sizeof( name ) / sizeof( name [0])}; \
26 int name ## _idx[2]; \
27 for (name ## _idx[0] = 0; name ## _idx[0] < NUM_ ## name; \
28 ++ name ## _idx[0]) { \
29 for (name ## _idx[1] = 0; name ## _idx[1] < NUM_ ## name; \
30 ++ name ## _idx[1]) { \
31 configs_differ += (name ## _idx[0]) != (name ## _idx[1]); \
33 configs_differ -= (name ## _idx[0]) != (name ## _idx[1]); \
37#define FOREACH_ENUM(name, values, ...) \
39 enum yac_ ## name name [] = {values}; \
40 FOREACH(name, __VA_ARGS__) \
42#define FOREACH_TYPE(name, type, values, ...) \
44 type name[] = {values}; \
45 FOREACH(name, __VA_ARGS__) \
47#define FOREACH_INT(name, values, ...) \
48 FOREACH_TYPE(name, int, ARGS(values), __VA_ARGS__)
49#define FOREACH_DBLE(name, values, ...) \
50 FOREACH_TYPE(name, double, ARGS(values), __VA_ARGS__)
51#define FOREACH_BOOL(name, ...) FOREACH_INT(name, ARGS(0, 1), __VA_ARGS__)
52#define FOREACH_STRING(name, values, ...) \
53 FOREACH_TYPE(name, ARGS(char const *), ARGS(values), __VA_ARGS__)
54#define FOREACH_STRUCT(name, struct_name, values, ...) \
55 FOREACH_TYPE(name, ARGS(struct struct_name), ARGS(values), __VA_ARGS__)
56#define _CHECK_STACKS(interp_name, config) \
59 struct yac_interp_stack_config * a = yac_interp_stack_config_new(); \
60 struct yac_interp_stack_config * b = yac_interp_stack_config_new(); \
61 config_idx = 0, yac_interp_stack_config_add_ ## interp_name ( a, config ); \
62 config_idx = 1, yac_interp_stack_config_add_ ## interp_name ( b, config ); \
63 utest_check_compare_stacks(a, b, configs_differ); \
65#define _CONFIG_ARGS1(arg_name) arg_name[arg_name ## _idx[config_idx]]
66#define _CONFIG_ARGS2(arg_name, ...) \
67 _CONFIG_ARGS1(arg_name), _CONFIG_ARGS1(__VA_ARGS__)
68#define _CONFIG_ARGS3(arg_name, ...) \
69 _CONFIG_ARGS1(arg_name), _CONFIG_ARGS2(__VA_ARGS__)
70#define _CONFIG_ARGS4(arg_name, ...) \
71 _CONFIG_ARGS1(arg_name), _CONFIG_ARGS3(__VA_ARGS__)
72#define _CONFIG_ARGS5(arg_name, ...) \
73 _CONFIG_ARGS1(arg_name), _CONFIG_ARGS4(__VA_ARGS__)
74#define _CONFIG_ARGS6(arg_name, ...) \
75 _CONFIG_ARGS1(arg_name), _CONFIG_ARGS5(__VA_ARGS__)
76#define _CONFIG_ARGS7(arg_name, ...) \
77 _CONFIG_ARGS1(arg_name), _CONFIG_ARGS6(__VA_ARGS__)
78#define _CONFIG_ARGS8(arg_name, ...) \
79 _CONFIG_ARGS1(arg_name), _CONFIG_ARGS7(__VA_ARGS__)
80#define _CONFIG_ARGS9(arg_name, ...) \
81 _CONFIG_ARGS1(arg_name), _CONFIG_ARGS8(__VA_ARGS__)
82#define _CONFIG_ARGS10(arg_name, ...) \
83 _CONFIG_ARGS1(arg_name), _CONFIG_ARGS9(__VA_ARGS__)
84#define _CONFIG_ARGS11(arg_name, ...) \
85 _CONFIG_ARGS1(arg_name), _CONFIG_ARGS10(__VA_ARGS__)
86#define _CONFIG_ARGS12(arg_name, ...) \
87 _CONFIG_ARGS1(arg_name), _CONFIG_ARGS11(__VA_ARGS__)
88#define CHECK_STACKS(interp_name, ... ) \
89 _CHECK_STACKS(interp_name, \
90 EXPAND(_GET_NTH_ARG(__VA_ARGS__, _CONFIG_ARGS12, \
101 _CONFIG_ARGS1)(__VA_ARGS__)))
103static void utest_check_compare_stacks(
109 double spread_distance,
double max_search_distance,
122 MPI_Init(NULL, NULL);
123 xt_initialize(MPI_COMM_WORLD);
125 int configs_differ = 0;
133 utest_check_compare_stacks(a, b, 1);
139 utest_check_compare_stacks(a, b, 0);
144 interp_avg_weight_type,
148 CHECK_STACKS(average, interp_avg_weight_type, partial_coverage)))
152 interp_ncc_weight_type,
156 CHECK_STACKS(ncc, interp_ncc_weight_type, partial_coverage)))
162 interp_nnn_weight_type,
167 max_search_distance,
ARGS(0.0, M_PI_2),
171 nnn, interp_nnn_weight_type, counts,
172 max_search_distance, scales)))))
178 interp_nnn_weight_type,
183 max_search_distance,
ARGS(0.0, M_PI_2),
185 scales,
ARGS(0.5, 1.0),
187 nnn, interp_nnn_weight_type, counts,
188 max_search_distance, scales)))))
198 interp_method_conserv_normalisation,
201 order, enforced_conserv, partial_coverage,
202 interp_method_conserv_normalisation)))))
216 NUM_CELL_AREA_CONFIGS =
217 sizeof(cell_area_configs) /
sizeof(cell_area_configs[0])};
222 cell_area_configs[0], cell_area_configs[1], cell_area_configs[2],
223 cell_area_configs[3], cell_area_configs[4], cell_area_configs[5],
224 cell_area_configs[6]),
228 cell_area_configs[0], cell_area_configs[1], cell_area_configs[2],
229 cell_area_configs[3], cell_area_configs[4], cell_area_configs[5],
230 cell_area_configs[6]),
232 spread_distance,
ARGS(0.0, 0.1),
234 max_search_distance,
ARGS(0.0, 0.4),
236 interp_spmap_weight_type,
239 interp_spmap_scale_type,
244 spread_distance, max_search_distance,
245 interp_spmap_weight_type, interp_spmap_scale_type,
246 src_cell_area_config, tgt_cell_area_config)))))))
248 for (
size_t i = 0;
i < NUM_CELL_AREA_CONFIGS; ++
i)
277 scale_config_custom),
280 NUM_DEFAULT_CONFIGS =
281 sizeof(default_configs)/
sizeof(default_configs[0])};
305 bnd_point_selection_b, spmap_config_custom),
309 bnd_point_selection_a, NULL),
311 bnd_point_selection_b, NULL),
316 bnd_point_selection_b, spmap_config_custom),
318 enum {NUM_OVERWRITE_CONFIGS = 6};
323 default_configs[0], default_configs[1],
324 default_configs[2], default_configs[3]),
328 overwrite_configs[0], overwrite_configs[1], overwrite_configs[2],
329 overwrite_configs[3], overwrite_configs[4], overwrite_configs[5]),
330 CHECK_STACKS(spmap_ext_, default_config, overwrite_config)))
332 for (
size_t i = 0;
i < NUM_OVERWRITE_CONFIGS; ++
i)
334 (overwrite_configs[
i] != NULL) && (overwrite_configs[i][j] != NULL);
340 for (
size_t i = 0;
i < NUM_DEFAULT_CONFIGS; ++
i)
348 "test_interp_stack_config_file_a.nc",
349 "test_interp_stack_config_file_b.nc"),
351 interp_file_on_missing_file,
354 interp_file_on_success,
357 user_file, filename, interp_file_on_missing_file,
358 interp_file_on_success))))
362 fixed_value,
ARGS(-1.0, 0.0, 1.0, NAN),
367 constructor_key,
ARGS(NULL,
"constructor_a",
"constructor_b"),
369 do_search_key,
ARGS(NULL,
"do_search_key_a",
"do_search_key_b"),
374 creep_distance,
ARGS(-1, 0, 1),
379 compute_weights_key,
ARGS(
"compute_weights_a",
"compute_weights_b"),
385 double *
coords = (
double[]){0.0,0.1,0.2};
388 coords, coords, (
size_t[]){2,2},
389 (
size_t[]){0,0}, (
size_t[]){2,2}, 1),
391 coords, coords, (
size_t[]){2,2},
392 (
size_t[]){0,0}, (
size_t[]){2,2}, 1)};
394 malloc(4 *
sizeof(*cell_center_coords));
395 for (
int i = 0, k = 0;
i < 2; ++
i)
396 for (
int j = 0; j < 2; ++j, ++k)
398 (coords[j] + coords[j+1])*0.5, (coords[i] + coords[i+1])*0.5,
399 cell_center_coords[k]);
405 size_t src_cell_coord_idx =
408 size_t tgt_cell_coord_idx =
411 free(cell_center_coords);
418 size_t num_src_fields =
sizeof(src_fields) /
sizeof(src_fields[0]);
422 tgt_field.coordinates_idx = tgt_cell_coord_idx;
428 enum {OVERWRITE_CONFIG_COUNT = 1};
430 overwrite_configs[OVERWRITE_CONFIG_COUNT+1];
431 overwrite_configs[OVERWRITE_CONFIG_COUNT] = NULL;
442 overwrite_configs[0] =
468 double *
src_field = (
double[]){1.0,2.0,3.0,4.0};
470 double *
tgt_field = (
double[]){0.0,0.0,0.0,0.0};
471 double const * ref_tgt_field =
472 (
double[]){1.0/3.0, 2.0+1.0/3.0, 3.0+1.0/3.0, 4.0};
476 for (
int i = 0;
i < 4; ++
i)
477 if (fabs(tgt_field[i] - ref_tgt_field[i]) > 1e-6)
478 PUT_ERR(
"ERROR in yac_interp_stack_config_add_spmap_ext");
485 for (
size_t i = 0;
i < OVERWRITE_CONFIG_COUNT; ++
i)
499static void utest_check_compare_stacks_(
501 int configs_differ) {
503 configs_differ = configs_differ != 0;
506 PUT_ERR(
"error in yac_interp_stack_config_compare (a != a)")
513 if ((cmp_a != cmp_b) ^ configs_differ)
515 if ((cmp_a != 0) ^ configs_differ)
517 if ((cmp_b != 0) ^ configs_differ)
524static
void utest_check_compare_stacks(
526 int configs_differ) {
528 utest_check_compare_stacks_(
531 utest_check_compare_stacks_(a, b, configs_differ);
536 double spread_distance,
double max_search_distance,
544 double src_sphere_radius =
547 char const * src_filename =
550 char const * src_varname =
559 double tgt_sphere_radius =
562 char const * tgt_filename =
565 char const * tgt_varname =
574 spread_distance, max_search_distance,
weight_type, scale_type,
589 double spread_distance_;
590 double max_search_distance_;
593 double src_sphere_radius_;
594 char const * src_filename_;
595 char const * src_varname_;
596 int src_min_global_id_;
597 double tgt_sphere_radius_;
598 char const * tgt_filename_;
599 char const * tgt_varname_;
600 int tgt_min_global_id_;
603 &spread_distance_, &max_search_distance_, &weight_type_, &scale_type_,
604 &src_sphere_radius_, &src_filename_, &src_varname_, &src_min_global_id_,
605 &tgt_sphere_radius_, &tgt_filename_, &tgt_varname_, &tgt_min_global_id_);
607 if (spread_distance_ != spread_distance)
608 PUT_ERR(
"ERROR in yac_interp_stack_config_entry_get_spmap");
609 if (max_search_distance_ != max_search_distance)
610 PUT_ERR(
"ERROR in yac_interp_stack_config_entry_get_spmap");
612 PUT_ERR(
"ERROR in yac_interp_stack_config_entry_get_spmap");
613 if (scale_type_ != scale_type)
614 PUT_ERR(
"ERROR in yac_interp_stack_config_entry_get_spmap");
struct yac_basic_grid * yac_basic_grid_new(char const *name, struct yac_basic_grid_data grid_data)
size_t yac_basic_grid_add_coordinates(struct yac_basic_grid *grid, enum yac_location location, yac_coordinate_pointer coordinates, size_t count)
void yac_basic_grid_delete(struct yac_basic_grid *grid)
void yac_dist_grid_pair_delete(struct yac_dist_grid_pair *grid_pair)
struct yac_dist_grid_pair * yac_dist_grid_pair_new(struct yac_basic_grid *grid_a, struct yac_basic_grid *grid_b, MPI_Comm comm)
struct yac_basic_grid_data yac_generate_basic_grid_data_reg2d(double const *global_coords_x, double const *global_coords_y, size_t const num_global_cells_[2], size_t const local_start[2], size_t const local_count[2], int with_halo)
void yac_interp_grid_delete(struct yac_interp_grid *interp_grid)
struct yac_interp_grid * yac_interp_grid_new(struct yac_dist_grid_pair *grid_pair, char const *src_grid_name, char const *tgt_grid_name, size_t num_src_fields, struct yac_interp_field const *src_fields, struct yac_interp_field const tgt_field)
void yac_interp_method_delete(struct interp_method **method)
struct yac_interp_weights * yac_interp_method_do_search(struct interp_method **method, struct yac_interp_grid *interp_grid)
@ YAC_INTERP_AVG_ARITHMETIC
@ YAC_INTERP_CONSERV_DESTAREA
@ YAC_INTERP_CONSERV_FRACAREA
@ YAC_INTERP_FILE_MISSING_CONT
continue on missing file
@ YAC_INTERP_FILE_MISSING_ERROR
abort on missing file
@ YAC_INTERP_FILE_SUCCESS_CONT
@ YAC_INTERP_FILE_SUCCESS_STOP
@ YAC_INTERP_NCC_DIST
distance weighted average of n source points
@ YAC_INTERP_NCC_AVG
average of n source points
@ YAC_INTERP_NNN_GAUSS
distance with Gauss weights of n source points
@ YAC_INTERP_NNN_RBF
radial basis functions
@ YAC_INTERP_NNN_AVG
average of n source points
@ YAC_INTERP_NNN_DIST
distance weighted average of n source points
@ YAC_INTERP_NNN_ZERO
all weights are set to zero
char const * yac_spmap_cell_area_config_get_filename(struct yac_spmap_cell_area_config const *cell_area_config)
double yac_spmap_cell_area_config_get_sphere_radius(struct yac_spmap_cell_area_config const *cell_area_config)
struct yac_spmap_cell_area_config * yac_spmap_cell_area_config_file_new(char const *filename, char const *varname, yac_int min_global_id)
struct yac_spmap_overwrite_config * yac_spmap_overwrite_config_new(struct yac_point_selection const *src_point_selection, struct yac_interp_spmap_config const *config)
yac_int yac_spmap_cell_area_config_get_min_global_id(struct yac_spmap_cell_area_config const *cell_area_config)
enum yac_interp_spmap_cell_area_provider yac_spmap_cell_area_config_get_type(struct yac_spmap_cell_area_config const *cell_area_config)
char const * yac_spmap_cell_area_config_get_varname(struct yac_spmap_cell_area_config const *cell_area_config)
struct yac_interp_spmap_config * yac_interp_spmap_config_new(double spread_distance, double max_search_distance, enum yac_interp_spmap_weight_type weight_type, struct yac_spmap_scale_config const *scale_config)
void yac_spmap_scale_config_delete(struct yac_spmap_scale_config *scale_config)
void yac_interp_spmap_config_delete(struct yac_interp_spmap_config *config)
void yac_spmap_cell_area_config_delete(struct yac_spmap_cell_area_config *cell_area_config)
struct yac_spmap_cell_area_config * yac_spmap_cell_area_config_yac_new(double sphere_radius)
void yac_spmap_overwrite_config_delete(struct yac_spmap_overwrite_config *overwrite_config)
struct yac_spmap_scale_config * yac_spmap_scale_config_new(enum yac_interp_spmap_scale_type scale_type, struct yac_spmap_cell_area_config const *source_cell_area_config, struct yac_spmap_cell_area_config const *target_cell_area_config)
#define YAC_INTERP_SPMAP_MAX_SEARCH_DISTANCE_DEFAULT
yac_interp_spmap_scale_type
@ YAC_INTERP_SPMAP_NONE
weights are not scaled
@ YAC_INTERP_SPMAP_INVTGTAREA
@ YAC_INTERP_SPMAP_SRCAREA
@ YAC_INTERP_SPMAP_FRACAREA
#define YAC_INTERP_SPMAP_SCALE_CONFIG_DEFAULT
#define YAC_INTERP_SPMAP_WEIGHTED_DEFAULT
#define YAC_INTERP_SPMAP_SPREAD_DISTANCE_DEFAULT
yac_interp_spmap_cell_area_provider
@ YAC_INTERP_SPMAP_CELL_AREA_FILE
@ YAC_INTERP_SPMAP_CELL_AREA_YAC
yac_interp_spmap_weight_type
#define YAC_INTERP_SPMAP_DEFAULT_CONFIG
size_t yac_interp_stack_config_get_size(struct yac_interp_stack_config *interp_stack)
int yac_interp_stack_config_compare(void const *a_, void const *b_)
union yac_interp_stack_config_entry const * yac_interp_stack_config_get_entry(struct yac_interp_stack_config *interp_stack, size_t interp_stack_idx)
void yac_interp_stack_config_add_spmap(struct yac_interp_stack_config *interp_stack_config, double spread_distance, double max_search_distance, enum yac_interp_spmap_weight_type weight_type, enum yac_interp_spmap_scale_type scale_type, double src_sphere_radius, char const *src_filename, char const *src_varname, int src_min_global_id, double tgt_sphere_radius, char const *tgt_filename, char const *tgt_varname, int tgt_min_global_id)
void yac_interp_stack_config_add_fixed(struct yac_interp_stack_config *interp_stack_config, double value)
void yac_interp_stack_config_add_average(struct yac_interp_stack_config *interp_stack_config, enum yac_interp_avg_weight_type reduction_type, int partial_coverage)
void yac_interp_stack_config_delete(struct yac_interp_stack_config *interp_stack_config)
struct yac_interp_stack_config * yac_interp_stack_config_copy(struct yac_interp_stack_config *interp_stack)
struct interp_method ** yac_interp_stack_config_generate(struct yac_interp_stack_config *interp_stack)
struct yac_interp_stack_config * yac_interp_stack_config_new()
void yac_interp_stack_config_add_spmap_ext(struct yac_interp_stack_config *interp_stack_config, struct yac_interp_spmap_config *default_config, struct yac_spmap_overwrite_config **overwrite_configs)
void yac_interp_stack_config_entry_get_spmap(union yac_interp_stack_config_entry const *interp_stack_entry, double *spread_distance, double *max_search_distance, enum yac_interp_spmap_weight_type *weight_type, enum yac_interp_spmap_scale_type *scale_type, double *src_sphere_radius, char const **src_filename, char const **src_varname, int *src_min_global_id, double *tgt_sphere_radius, char const **tgt_filename, char const **tgt_varname, int *tgt_min_global_id)
struct yac_interpolation * yac_interp_weights_get_interpolation(struct yac_interp_weights *weights, enum yac_interp_weights_reorder_type reorder, size_t collection_size, double frac_mask_fallback_value, double scaling_factor, double scaling_summand, char const *yaxt_exchanger_name, int is_source, int is_target)
void yac_interp_weights_delete(struct yac_interp_weights *weights)
@ YAC_MAPPING_ON_SRC
weights will be applied at source processes
void yac_interpolation_execute(struct yac_interpolation *interp, double ***src_fields, double **tgt_field)
Execute interpolation synchronously and write results to the target field.
void yac_interpolation_delete(struct yac_interpolation *interp)
Free an interpolation object and release all resources.
double const YAC_FRAC_MASK_NO_VALUE
struct yac_point_selection * yac_point_selection_bnd_circle_new(double center_lon, double center_lat, double inc_angle)
void yac_point_selection_delete(struct yac_point_selection *point_select)
enum yac_location location
struct yac_interp_field tgt_field
struct yac_dist_grid_pair * grid_pair
struct yac_interp_field src_fields[]
#define FOREACH_TYPE(name, type, values,...)
#define FOREACH_STRING(name, values,...)
static void yac_interp_stack_config_add_spmap_(struct yac_interp_stack_config *interp_stack_config, double spread_distance, double max_search_distance, enum yac_interp_spmap_weight_type weight_type, enum yac_interp_spmap_scale_type scale_type, struct yac_spmap_cell_area_config *src_cell_area_config, struct yac_spmap_cell_area_config *tgt_cell_area_config)
static void yac_interp_stack_config_add_spmap_ext_(struct yac_interp_stack_config *interp_stack_config, struct yac_interp_spmap_config *default_config, struct yac_spmap_overwrite_config **overwrite_configs)
#define CHECK_STACKS(interp_name,...)
#define FOREACH_DBLE(name, values,...)
#define FOREACH_ENUM(name, values,...)
#define FOREACH_INT(name, values,...)
#define FOREACH_BOOL(name,...)
static void LLtoXYZ(double lon, double lat, double p_out[])
struct yac_spmap_overwrite_config ** overwrite_configs
struct yac_interp_spmap_config * default_config
struct yac_basic_grid ** grids
double(* yac_coordinate_pointer)[3]