YAC 3.13.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_dummy_coupling8_c.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#include <mpi.h>
6
7#include <stdlib.h>
8#include <stdio.h>
9#include <string.h>
10#include <math.h>
11#include <float.h>
12#include "tests.h"
13#include "test_common.h"
14#include "yac.h"
15
21#define YAC_RAD (0.01745329251994329576923690768489) // M_PI / 180
22
23enum {
29 TGT_DT = 2,
30 SRC_DT = 1,
31};
32
33#define FRAC_MASK_VALUE (1337.0)
34
35static void utest_aggregation();
36static void utest_changing_frac_mask();
37
38int main (void) {
39
40
41 utest_aggregation();
42 utest_changing_frac_mask();
43
45
46 return TEST_EXIT_CODE;
47}
48
50 double ref_recv_field[][COLLECTION_SIZE][NUM_POINTS]) {
51
52 for (int i = 0; i < 3; ++i)
53 for (int j = 0; j < COLLECTION_SIZE; ++j)
54 for (int k = 0; k < NUM_POINTS; ++k)
55 ref_recv_field[i][j][k] = 0.0;
56 for (int j = 0; j < COLLECTION_SIZE; ++j) {
57 for (int k = 0; k < NUM_POINTS; ++k) {
58 ref_recv_field[3][j][k] = DBL_MAX;
59 ref_recv_field[4][j][k] = -DBL_MAX;
60 }
61 }
62}
63
65 double temp_frac_mask[][COLLECTION_SIZE][NUM_POINTSETS][NUM_POINTS]) {
66
67 for (int i = 0; i < NUM_FIELDS; ++i)
68 for (int j = 0; j < COLLECTION_SIZE; ++j)
69 for (int k = 0; k < NUM_POINTS; ++k)
70 temp_frac_mask[i][j][0][k] = 0.0;
71}
72
73static void utest_aggregation() {
74
75 yac_cinit();
77 yac_cdef_datetime("1850-01-01T00:00:00", "1850-01-03T00:00:00");
78
79 int size, rank;
80 MPI_Comm_rank ( MPI_COMM_WORLD, &rank );
81 MPI_Comm_size ( MPI_COMM_WORLD, &size );
82
83 if (size != 2) {
84 fputs("wrong number of processes (has to be 2)\n", stderr);
85 exit(EXIT_FAILURE);
86 }
87
88 int is_target = rank == 1;
89
90 // define local component
91 int comp_id;
92 yac_cdef_comp((is_target)?"target_comp":"source_comp", &comp_id);
93
94 // define grid (both components use an identical grid)
95 int grid_id;
97 (is_target)?"target_grid":"source_grid", (int[2]){3,3}, (int[2]){0,0},
98 (double[]){0*YAC_RAD,1*YAC_RAD,2*YAC_RAD},
99 (double[]){0*YAC_RAD,1*YAC_RAD,2*YAC_RAD}, &grid_id);
100
101 // define points at the vertices of the grid
102 int point_id;
104 grid_id, (int[2]){3,3}, YAC_LOCATION_CORNER,
105 (double[]){0*YAC_RAD,1*YAC_RAD,2*YAC_RAD},
106 (double[]){0*YAC_RAD,1*YAC_RAD,2*YAC_RAD}, &point_id);
107
108 // define fields
109 int field_ids[NUM_FIELDS];
110 const char * fieldName[NUM_FIELDS] =
111 {"time_op_accu_field",
112 "time_op_avg_field",
113 "time_op_none_field",
114 "time_op_min_field",
115 "time_op_max_field"};
116 for (int field_idx = 0; field_idx < NUM_FIELDS; ++field_idx) {
118 fieldName[field_idx], comp_id, &point_id, NUM_POINTSETS,
119 COLLECTION_SIZE, (is_target)?"2":"1", YAC_TIME_UNIT_SECOND,
120 &field_ids[field_idx]);
122 (is_target)?"target_comp":"source_comp",
123 (is_target)?"target_grid":"source_grid",
124 fieldName[field_idx], FRAC_MASK_VALUE);
125 }
126
127 // define interpolation stacks
128 int interp_stack_nnn;
129 yac_cget_interp_stack_config(&interp_stack_nnn);
131 interp_stack_nnn, YAC_NNN_AVG, 1, 0.0, 0.0);
132
133 // define couplings
134 int reduction_type[NUM_FIELDS] =
140 for (int field_idx = 0; field_idx < NUM_FIELDS; ++field_idx)
142 "source_comp", "source_grid", fieldName[field_idx],
143 "target_comp", "target_grid", fieldName[field_idx],
144 "4", YAC_TIME_UNIT_SECOND, reduction_type[field_idx],
145 interp_stack_nnn, 0, 0);
146 yac_cfree_interp_stack_config(interp_stack_nnn);
147
148 yac_cenddef ( );
149
150 double send_field[COLLECTION_SIZE][NUM_POINTSETS][NUM_POINTS] =
151 {{{ 1, 2, 3, 4, 5, 6, 7, 8, 9}},
152 {{10,11,12,13,14,15,16,17,18}},
153 {{19,20,21,22,23,24,25,26,27}}};
155 {{{{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}},
156 {{1.0, 1.0, 0.7, 0.7, 0.5, 0.3, 0.3, 0.0, 0.0}},
157 {{1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0}}},
158 {{{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0}},
159 {{0.7, 0.7, 0.7, 0.7, 0.5, 0.3, 0.3, 0.3, 0.3}},
160 {{1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0}}},
161 {{{0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0}},
162 {{0.3, 0.3, 0.3, 0.3, 0.5, 0.7, 0.7, 0.7, 0.7}},
163 {{1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}},
164 {{{0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}},
165 {{0.0, 0.0, 0.3, 0.3, 0.5, 0.7, 0.7, 1.0, 1.0}},
166 {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}}};
167 double temp_frac_mask[NUM_FIELDS][COLLECTION_SIZE][NUM_POINTSETS][NUM_POINTS];
168 double ref_recv_field[NUM_FIELDS][COLLECTION_SIZE][NUM_POINTS];
169 init_ref_recv_field(ref_recv_field);
170 init_temp_frac_mask(temp_frac_mask);
171
172 // do time steps
173 for (int t = 0; t < 8 * COUPLING_DT; ++t) {
174
175 if (!is_target) {
176
177 for (int field_idx = 0; field_idx < NUM_FIELDS; ++field_idx) {
178
179 int info, ierror;
181 field_ids[field_idx], COLLECTION_SIZE, &send_field[0][0][0],
182 &frac_mask[t%COUPLING_DT][0][0][0], &info, &ierror);
183
184 int ref_send_info =
185 (t%COUPLING_DT)?
186 ((field_idx == 2)?YAC_ACTION_NONE:YAC_ACTION_REDUCTION):
188 if (info != ref_send_info) PUT_ERR("error in yac_cput_: wrong info");
189 if (ierror) PUT_ERR("error in yac_cput_: wrong ierror");
190 }
191 }
192
193 // the first timestep is coupled directly
194 double scale = ((t == 0)?1.0:0.25);
195 for (int i = 0; i < COLLECTION_SIZE; ++i) {
196 for (int j = 0; j < NUM_POINTS; ++j) {
197
198 double frac_mask_value = frac_mask[t%COUPLING_DT][i][0][j];
199 double frac_send_field_value =
200 frac_mask_value * send_field[i][0][j];
201
202 if (frac_mask_value != 0.0) {
203
204 // update ref_recv_field (accu)
205 ref_recv_field[0][i][j] += frac_send_field_value;
206 temp_frac_mask[0][i][0][j] += frac_mask_value * scale;
207
208 // update ref_recv_field (avg)
209 ref_recv_field[1][i][j] += frac_send_field_value * scale;
210 temp_frac_mask[1][i][0][j] += frac_mask_value * scale;
211
212 // update ref_recv_field (minimum)
213 if (ref_recv_field[3][i][j] > frac_send_field_value) {
214 ref_recv_field[3][i][j] = frac_send_field_value;
215 temp_frac_mask[3][i][0][j] = frac_mask_value;
216 }
217
218 // update ref_recv_field (maximum)
219 if (ref_recv_field[4][i][j] < frac_send_field_value) {
220 ref_recv_field[4][i][j] = frac_send_field_value;
221 temp_frac_mask[4][i][0][j] = frac_mask_value;
222 }
223
224 }
225
226 // update ref_recv_field (none)
227 ref_recv_field[2][i][j] = frac_send_field_value;
228 temp_frac_mask[2][i][0][j] = frac_mask_value;
229 }
230 }
231
232 if (is_target) {
233
234 // target calls get every second timestep
235 if ((t % TGT_DT) == 0) {
236 for (int field_idx = 0; field_idx < NUM_FIELDS; ++field_idx) {
237
238 // initialise recv_field
239 double recv_field[COLLECTION_SIZE][NUM_POINTS];
240 for (int j = 0; j < COLLECTION_SIZE; ++j)
241 for (int k = 0; k < NUM_POINTS; ++k)
242 recv_field[j][k] = -1;
243
244 int info, ierror;
245 yac_cget_(
246 field_ids[field_idx], COLLECTION_SIZE, &recv_field[0][0],
247 &info, &ierror);
248
249 int ref_recv_info =
251 if (info != ref_recv_info) PUT_ERR("error in yac_cget_: wrong info");
252 if (ierror) PUT_ERR("error in yac_cget_: wrong ierror");
253
254 if (info == YAC_ACTION_COUPLING) {
255 for (int j = 0; j < COLLECTION_SIZE; ++j) {
256 for (int k = 0; k < NUM_POINTS; ++k) {
257 if (temp_frac_mask[field_idx][j][0][k] != 0.0) {
258 if (fabs(recv_field[j][k] -
259 (ref_recv_field[field_idx][j][k] /
260 temp_frac_mask[field_idx][j][0][k])) > 1e-6)
261 PUT_ERR("error in yac_cget_: wrong recv_field (unmasked)");
262 } else {
263 if (recv_field[j][k] != FRAC_MASK_VALUE)
264 PUT_ERR("error in yac_cget_: wrong recv_field (masked)");
265 }
266 }
267 }
268 } else {
269 for (int j = 0; j < COLLECTION_SIZE; ++j)
270 for (int k = 0; k < NUM_POINTS; ++k)
271 if (recv_field[j][k] != -1)
272 PUT_ERR("error in yac_cget_: wrong recv_field");
273 }
274 }
275 }
276 }
277
278 // update send_field
279 for (int i = 0; i < COLLECTION_SIZE; ++i)
280 for (int j = 0; j < NUM_POINTS; ++j)
281 send_field[i][0][j] += i - 1;
282
283 // clean ref_recv_field at every coupling timestep
284 if ((t % COUPLING_DT) == 0) {
285 init_ref_recv_field(ref_recv_field);
286 init_temp_frac_mask(temp_frac_mask);
287 }
288 }
289
290 yac_ccleanup();
291}
292
293static void utest_changing_frac_mask() {
294
295 yac_cinit();
297 yac_cdef_datetime("1850-01-01T00:00:00", "1850-01-03T00:00:00");
298
299 int size, rank;
300 MPI_Comm_rank ( MPI_COMM_WORLD, &rank );
301 MPI_Comm_size ( MPI_COMM_WORLD, &size );
302
303 if (size != 2) {
304 fputs("wrong number of processes (has to be 2)\n", stderr);
305 exit(EXIT_FAILURE);
306 }
307
308 int is_target = rank == 1;
309
310 // define local component
311 int comp_id;
312 yac_cdef_comp((is_target)?"target_comp":"source_comp", &comp_id);
313
314 // define grid (source has a 2x2 grid, while the target has a 1x1 grid)
315 int grid_id;
316 if (is_target)
318 "target_grid_2", (int[2]){2,2}, (int[2]){0,0},
319 (double[]){0*YAC_RAD,2*YAC_RAD},
320 (double[]){0*YAC_RAD,2*YAC_RAD}, &grid_id);
321 else
323 "source_grid_2", (int[2]){3,3}, (int[2]){0,0},
324 (double[]){0*YAC_RAD,1*YAC_RAD,2*YAC_RAD},
325 (double[]){0*YAC_RAD,1*YAC_RAD,2*YAC_RAD}, &grid_id);
326
327 // define points at the vertices of the grid
328 int point_id;
329 if (is_target)
331 grid_id, (int[2]){1,1}, YAC_LOCATION_CELL,
332 (double[]){1*YAC_RAD}, (double[]){1*YAC_RAD}, &point_id);
333 else
335 grid_id, (int[2]){2,2}, YAC_LOCATION_CELL,
336 (double[]){0.5*YAC_RAD,1.5*YAC_RAD},
337 (double[]){0.5*YAC_RAD,1.5*YAC_RAD}, &point_id);
338
339 // define field
340 int field_id;
342 "field", comp_id, &point_id, 1, 1, "1", YAC_TIME_UNIT_SECOND, &field_id);
344 (is_target)?"target_comp":"source_comp",
345 (is_target)?"target_grid_2":"source_grid_2",
346 "field", FRAC_MASK_VALUE);
347
348 // define interpolation stacks
349 int interp_stack_nnn;
350 yac_cget_interp_stack_config(&interp_stack_nnn);
352 interp_stack_nnn, YAC_NNN_AVG, 4, 0.0, 0.0);
353
354 // define couplings
356 "source_comp", "source_grid_2", "field",
357 "target_comp", "target_grid_2", "field",
359 interp_stack_nnn, 0, 0);
360 yac_cfree_interp_stack_config(interp_stack_nnn);
361
362 yac_cenddef();
363
364 enum {NUM_TIMESTEP = 5, SRC_FIELD_SIZE = 4};
365
366 double send_field[NUM_TIMESTEP][SRC_FIELD_SIZE] =
367 {{ 1, 2, 3, 4}, {10,11,12,13}, {20,21,22,23},
368 {30,31,32,33}, {40,41,42,43}};
369 double frac_mask[NUM_TIMESTEP][SRC_FIELD_SIZE] =
370 {{1.0,1.0,0.0,0.0}, {1.0,0.0,1.0,0.0}, {1.0,1.0,0.0,0.0},
371 {1.0,1.0,1.0,1.0}, {0.0,0.0,0.0,0.0}};
372
373 for (int t = 0; t < NUM_TIMESTEP; ++t) {
374
375 if (!is_target) {
376
377 int info, ierror;
379 field_id, 1, &send_field[t][0], &frac_mask[t][0], &info, &ierror);
380 if (info != YAC_ACTION_COUPLING) PUT_ERR("error in yac_cput_: wrong info");
381 if (ierror) PUT_ERR("error in yac_cput_: wrong ierror");
382 }
383
384 if (is_target) {
385
386 double const weight = 0.25;
387 double ref_recv_field = 0.0;
388 double frac_weight_sum = 0.0;
389 for (int i = 0; i < SRC_FIELD_SIZE; ++i) {
390 ref_recv_field += send_field[t][i] * frac_mask[t][i] * weight;
391 frac_weight_sum += weight * frac_mask[t][i];
392 }
393 ref_recv_field =
394 (frac_weight_sum < 1.e-9)?
395 FRAC_MASK_VALUE:(ref_recv_field/frac_weight_sum);
396
397 double recv_field;
398 int info, ierror;
399 yac_cget_(field_id, 1, &recv_field, &info, &ierror);
400
401 if (info != YAC_ACTION_COUPLING)
402 PUT_ERR("error in yac_cget_: wrong info");
403 if (ierror) PUT_ERR("error in yac_cget_: wrong ierror");
404 if (fabs(recv_field - ref_recv_field) > 1.e-9)
405 PUT_ERR("error in yac_cget_: wrong recv_field");
406 }
407 }
408
409 yac_ccleanup();
410}
const char * fieldName[]
static void init_temp_frac_mask(double temp_frac_mask[][COLLECTION_SIZE][NUM_POINTSETS][NUM_POINTS])
static void init_ref_recv_field(double ref_recv_field[][COLLECTION_SIZE][NUM_POINTS])
#define YAC_RAD
#define FRAC_MASK_VALUE
@ COLLECTION_SIZE
int point_id
#define TEST_EXIT_CODE
Definition tests.h:14
#define PUT_ERR(string)
Definition tests.h:10
int info
int grid_id
int ierror
int * field_id
int comp_id
int const YAC_REDUCTION_TIME_AVERAGE
Definition yac.c:54
void yac_cenddef(void)
Definition yac.c:4400
void yac_cenable_field_frac_mask(const char *comp_name, const char *grid_name, const char *field_name, double frac_mask_fallback_value)
Definition yac.c:1439
void yac_cget_(int const field_id, int const collection_size, double *recv_field, int *info, int *ierr)
Definition yac.c:2741
void yac_cdef_datetime(const char *start_datetime, const char *end_datetime)
Definition yac.c:761
int const YAC_LOCATION_CELL
Definition yac.c:34
int const YAC_REDUCTION_TIME_MINIMUM
Definition yac.c:55
void yac_cput_frac_(int const field_id, int const collection_size, double *send_field, double *send_frac_mask, int *info, int *ierr)
Definition yac.c:3083
void yac_ccleanup()
Clean-up default YAC instance (see Restarting YAC)
Definition yac.c:711
int const YAC_REDUCTION_TIME_MAXIMUM
Definition yac.c:56
void yac_cinit(void)
Definition yac.c:510
void yac_cfinalize()
Finalises YAC.
Definition yac.c:740
int const YAC_LOCATION_CORNER
Definition yac.c:35
int const YAC_REDUCTION_TIME_ACCUMULATE
Definition yac.c:53
void yac_cdef_grid_reg2d(const char *grid_name, int nbr_vertices[2], int cyclic[2], double *x_vertices, double *y_vertices, int *grid_id)
Definition yac.c:4831
void yac_cdef_points_reg2d(int const grid_id, int const *nbr_points, int const located, double const *x_points, double const *y_points, int *point_id)
Definition yac.c:1103
int const YAC_TIME_UNIT_SECOND
Definition yac.c:59
int const YAC_ACTION_NONE
no data exchanges
Definition yac.c:42
void yac_cdef_calendar(int calendar)
Definition yac.c:769
int const YAC_ACTION_REDUCTION
data reduction, but data exchange
Definition yac.c:43
int const YAC_PROLEPTIC_GREGORIAN
Definition yac.c:68
int const YAC_ACTION_COUPLING
data exchange
Definition yac.c:44
void yac_cfree_interp_stack_config(int interp_stack_config_id)
Definition yac.c:5151
int const YAC_NNN_AVG
Definition yac.c:79
void yac_cadd_interp_stack_config_nnn(int interp_stack_config_id, int type, size_t n, double max_search_distance, double scale)
Definition yac.c:5208
void yac_cget_interp_stack_config(int *interp_stack_config_id)
Definition yac.c:5137
void yac_cdef_comp(char const *comp_name, int *comp_id)
Definition yac.c:1013
void yac_cdef_field(char const *name, int const comp_id, int const *point_ids, int const num_pointsets, int collection_size, const char *timestep, int time_unit, int *field_id)
Definition yac.c:1396
void yac_cdef_couple(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_timestep, int time_unit, int time_reduction, int interp_stack_config_id, int src_lag, int tgt_lag)
Definition yac.c:1951
int const YAC_REDUCTION_TIME_NONE
Definition yac.c:52