YAC 3.13.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_dummy_coupling5_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// if this is included in the wrong order SNAN is not defined
8#include "feenableexcept.h"
9
10#include <stdlib.h>
11#include <stdio.h>
12#include <string.h>
13#include <math.h>
14#include "tests.h"
15#include "test_common.h"
16#include "yac.h"
17
22#define YAC_RAD (0.01745329251994329576923690768489) // M_PI / 180
23
24int main(int argc, char** argv) {
25
26 MPI_Init(NULL, NULL);
27
28 if (argc != 2) {
29 PUT_ERR("ERROR: missing config file directory");
30 MPI_Finalize();
31 return TEST_EXIT_CODE;
32 }
33
34 feenableexcept(FE_INVALID);
35
36 for (int with_core_mask = 0; with_core_mask < 2; ++with_core_mask) {
37 for (int with_field_mask = 0; with_field_mask < 2; ++with_field_mask) {
38
39 int instance_id;
40 yac_cinit_instance(&instance_id);
42
43 char * yaml_filename =
44 strcat(
45 strcpy(
46 malloc(strlen(argv[1]) + 32), argv[1]), "coupling_test5.yaml");
48 free(yaml_filename);
49
50 int size, rank;
51 MPI_Comm_rank ( MPI_COMM_WORLD, &rank );
52 MPI_Comm_size ( MPI_COMM_WORLD, &size );
53
54 if (size != 3) {
55 fputs("wrong number of processes (has to be 3)\n", stderr);
56 exit(EXIT_FAILURE);
57 }
58
59 int is_target = rank < 2;
60 int is_source = rank > 0;
61 YAC_ASSERT((is_target || is_source), "internal error")
62
63 // define local component
64 int comp_id;
65 char const * comp_name = "main_comp";
66 yac_cdef_comps_instance(instance_id, &comp_name, 1, &comp_id);
67
68 // define grid (both components use an identical grids)
69 int grid_ids[2];
70 double x_vertices[2][3] = {{0.0*YAC_RAD,1.0*YAC_RAD,2.0*YAC_RAD},
71 {1.0*YAC_RAD,2.0*YAC_RAD,3.0*YAC_RAD}};
72 double y_vertices[3] = {0.0*YAC_RAD,1.0*YAC_RAD,2.0*YAC_RAD};
73 if (is_target)
75 "target_grid", (int[2]){3,3}, (int[2]){0,0},
76 x_vertices[rank], y_vertices, &grid_ids[0]);
77 if (is_source)
79 "source_grid", (int[2]){3,3}, (int[2]){0,0},
80 x_vertices[rank-1], y_vertices, &grid_ids[1]);
81
82 yac_int cell_global_index[2][4] = {{0,1,3,4}, {1,2,4,5}};
83 yac_int corner_global_index[2][9] =
84 {{0,1,2, 4,5,6, 8,9,10}, {1,2,3, 5,6,7, 9,10,11}};
85 yac_int edge_global_index[2][12] =
86 {{0,1,2,3,5, 7,8,9,10,12, 14,15}, {2,3,4,5,6, 9,10,11,12,13, 15,16}};
87 int cell_core_mask[2][4] = {{1,1,1,0}, {0,1,1,1}};
88 int corner_core_mask[2][9] = {{1,1,1, 1,1,1, 1,1,0}, {0,1,1, 1,1,1, 1,1,1}};
89 int edge_core_mask[2][12] = {{1,1,1,1,1, 1,1,1,1,0, 1,0},
90 {0,0,1,1,1, 1,1,1,1,1, 1,1}};
91 int corner_field_mask[2][9] = {{1,1,1, 0,1,1, 1,1,1}, {1,1,1, 1,1,1, 1,1,1}};
92 if (is_target) {
94 cell_global_index[rank], YAC_LOCATION_CELL, grid_ids[0]);
96 corner_global_index[rank], YAC_LOCATION_CORNER, grid_ids[0]);
98 edge_global_index[rank], YAC_LOCATION_EDGE, grid_ids[0]);
99 if (with_core_mask) {
101 cell_core_mask[rank], YAC_LOCATION_CELL, grid_ids[0]);
103 corner_core_mask[rank], YAC_LOCATION_CORNER, grid_ids[0]);
105 edge_core_mask[rank], YAC_LOCATION_EDGE, grid_ids[0]);
106 }
107 }
108 if (is_source) {
110 cell_global_index[rank-1], YAC_LOCATION_CELL, grid_ids[1]);
112 corner_global_index[rank-1], YAC_LOCATION_CORNER, grid_ids[1]);
114 edge_global_index[rank-1], YAC_LOCATION_EDGE, grid_ids[1]);
115 if (with_core_mask) {
117 cell_core_mask[rank-1], YAC_LOCATION_CELL, grid_ids[1]);
119 corner_core_mask[rank-1], YAC_LOCATION_CORNER, grid_ids[1]);
121 edge_core_mask[rank-1], YAC_LOCATION_EDGE, grid_ids[1]);
122 }
123 }
124
125 // define points at the vertices of the grid
126 int point_ids[2];
127 if (is_target) {
129 grid_ids[0], (int[2]){3,3}, YAC_LOCATION_CORNER,
130 x_vertices[rank], y_vertices, &point_ids[0]);
131 if (with_field_mask)
132 yac_cset_mask(corner_field_mask[rank], point_ids[0]);
133 }
134 if (is_source) {
136 grid_ids[1], (int[2]){3,3}, YAC_LOCATION_CORNER,
137 x_vertices[rank-1], y_vertices, &point_ids[1]);
138 if (with_field_mask)
139 yac_cset_mask(corner_field_mask[rank-1], point_ids[1]);
140 }
141
142 // define fields
143 int field_ids[2][2];
144 int dummy_field_ids[2];
145 if (is_target) {
147 "field_a", comp_id, &point_ids[0], 1, 1, "3", YAC_TIME_UNIT_SECOND,
148 &field_ids[0][0]);
150 "field_b", comp_id, &point_ids[0], 1, 1, "3", YAC_TIME_UNIT_SECOND,
151 &field_ids[1][0]);
153 "dummy_field", comp_id, &point_ids[0], 1, 1, "3", YAC_TIME_UNIT_SECOND,
154 &dummy_field_ids[0]);
155 }
156 if (is_source) {
158 "field_a", comp_id, &point_ids[1], 1, 1, "2", YAC_TIME_UNIT_SECOND,
159 &field_ids[0][1]);
161 "field_b", comp_id, &point_ids[1], 1, 1, "2", YAC_TIME_UNIT_SECOND,
162 &field_ids[1][1]);
164 "dummy_field", comp_id, &point_ids[1], 1, 1, "2", YAC_TIME_UNIT_SECOND,
165 &dummy_field_ids[1]);
166 }
167
168 yac_cenddef_instance ( instance_id );
169
170 double source_data[10][2][9] = // [put_idx][rank][field_idx]
171 {{{ 0, 1, 2, 4, 5, 6, 8, 9,10}, { 1, 2, 3, 5, 6, 7, 9,10,11}}, // t = 0
172 {{ 1, 2, 3, 5, 6, 7, 9,10,11}, { 2, 3, 4, 6, 7, 8,10,11,12}}, // t = 2
173 {{ 2, 3, 4, 6, 7, 8,10,11,12}, { 3, 4, 5, 7, 8, 9,11,12,13}}, // t = 4
174 {{ 3, 4, 5, 7, 8, 9,11,12,13}, { 4, 5, 6, 8, 9,10,12,13,14}}, // t = 6
175 {{ 4, 5, 6, 8, 9,10,12,13,14}, { 5, 6, 7, 9,10,11,13,14,15}}, // t = 8
176 {{ 5, 6, 7, 9,10,11,13,14,15}, { 6, 7, 8,10,11,12,14,15,16}}, // t = 10
177 {{ 6, 7, 8,10,11,12,14,15,16}, { 7, 8, 9,11,12,13,15,16,17}}, // t = 12
178 {{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}, // t = 14
179 {{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}, // t = 16
180 {{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}};// t = 18
181 double ref_recv_field[2][7][2][9] = // [reduction_idx][get_idx][rank][field_idx]
182 {{{{ 0, 1, 2, 4, 5, 6, 8, 9,10}, { 1, 2, 3, 5, 6, 7, 9,10,11}}, // t = 0
183 {{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}, // t = 3
184 {{ 6, 9,12,18,21,24,30,33,36}, { 9,12,15,21,24,27,33,36,39}}, // t = 6
185 {{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}, // t = 9
186 {{15,18,21,27,30,33,39,42,45}, {18,21,24,30,33,36,42,45,48}}, // t = 12
187 {{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}, // t = 15
188 {{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}},// t = 18
189 {{{ 0, 1, 2, 4, 5, 6, 8, 9,10}, { 1, 2, 3, 5, 6, 7, 9,10,11}}, // t = 0
190 {{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}, // t = 3
191 {{ 3, 4, 5, 7, 8, 9,11,12,13}, { 4, 5, 6, 8, 9,10,12,13,14}}, // t = 6
192 {{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}, // t = 9
193 {{ 6, 7, 8,10,11,12,14,15,16}, { 7, 8, 9,11,12,13,15,16,17}}, // t = 12
194 {{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}, // t = 15
195 {{-1,-1,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,-1}}}};// t = 18
196
197#ifdef SNAN
198 if (is_source)
199 for (size_t i = 0; i < 10; ++i)
200 for (size_t j = 0; j < 2; ++j)
201 for (size_t k = 0; k < 9; ++k)
202 if ((with_core_mask && !corner_core_mask[rank-1][k]) ||
203 (with_field_mask && !corner_field_mask[rank-1][k]))
204 source_data[i][j][k] = SNAN;
205#endif
206 if (is_target)
207 for (size_t i = 0; i < 2; ++i)
208 for (size_t j = 0; j < 7; ++j)
209 for (size_t k = 0; k < 2; ++k)
210 for (size_t l = 0; l < 9; ++l)
211 if ((with_core_mask && !corner_core_mask[rank][l]) ||
212 (with_field_mask && !corner_field_mask[rank][l]))
213 ref_recv_field[i][j][k][l] = -1;
214
215 int ref_send_info[2][10] =
216 {{YAC_ACTION_COUPLING, // t = 0
217 YAC_ACTION_REDUCTION, // t = 2
218 YAC_ACTION_REDUCTION, // t = 4
219 YAC_ACTION_COUPLING, // t = 6
220 YAC_ACTION_REDUCTION, // t = 8
221 YAC_ACTION_REDUCTION, // t = 10
223 YAC_ACTION_OUT_OF_BOUND, // t = 14
224 YAC_ACTION_OUT_OF_BOUND, // t = 16
225 YAC_ACTION_OUT_OF_BOUND}, // t = 18
226 {YAC_ACTION_COUPLING, // t = 0
227 YAC_ACTION_NONE, // t = 2
228 YAC_ACTION_NONE, // t = 4
229 YAC_ACTION_COUPLING, // t = 6
230 YAC_ACTION_NONE, // t = 8
231 YAC_ACTION_NONE, // t = 10
233 YAC_ACTION_OUT_OF_BOUND, // t = 14
234 YAC_ACTION_OUT_OF_BOUND, // t = 16
235 YAC_ACTION_OUT_OF_BOUND}}; // t = 18
236 int ref_recv_info[7] =
237 {YAC_ACTION_COUPLING, // t = 0
238 YAC_ACTION_NONE, // t = 3
239 YAC_ACTION_COUPLING, // t = 6
240 YAC_ACTION_NONE, // t = 9
242 YAC_ACTION_OUT_OF_BOUND, // t = 15
243 YAC_ACTION_OUT_OF_BOUND}; // t = 18
244
245 int const source_period = 2;
246 int const target_period = 3;
247 int const test_time = 18;
248
249 // do time steps
250 for (int t = 0, put_idx = 0, get_idx = 0; t <= test_time; ++t) {
251
252 int is_even_timestep = !(t%2);
253 int is_source_timestep = is_source && (!(t%source_period));
254 int is_target_timestep = is_target && (!(t%target_period));
255
256 int const collection_size = 1;
257 double * send_field_vertex =
258 (is_source_timestep)?(source_data[put_idx][rank-1]):NULL;
259 double * send_fields[1] = {send_field_vertex};
260 double ** send_field_collection_data[1] = {send_fields};
261 double recv_field_data[9] = {-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0};
262 double * recv_field_vertex =
263 (is_target_timestep)?recv_field_data:NULL;
264 double * recv_field_collection_data[1] = {recv_field_vertex};
265
266 int send_info, recv_info, send_action, recv_action;
267 int dummy_send_ierr, dummy_recv_ierr;
268
269 if (is_source) {
270 yac_cget_action(dummy_field_ids[1], &send_action);
271 if (send_action != YAC_ACTION_NONE) PUT_ERR("ERROR in dummy_send_action");
272 if (is_even_timestep) {
273 yac_cput(
274 dummy_field_ids[1], collection_size, send_field_collection_data,
275 &send_info, &dummy_send_ierr);
276 if (dummy_send_ierr != 0) PUT_ERR("ERROR in dummy_send_ierr");
277 if (send_info != YAC_ACTION_NONE) PUT_ERR("ERROR in dummy_send_info");
278 } else {
279 yac_cupdate(dummy_field_ids[1]);
280 }
281 }
282 if (is_target) {
283 yac_cget_action(dummy_field_ids[0], &recv_action);
284 if (recv_action != YAC_ACTION_NONE) PUT_ERR("ERROR in dummy_recv_action");
285 if (is_even_timestep) {
286 yac_cget(
287 dummy_field_ids[0], collection_size, recv_field_collection_data,
288 &recv_info, &dummy_recv_ierr);
289 if (dummy_recv_ierr != 0) PUT_ERR("ERROR in dummy_recv_ierr");
290 if (recv_info != YAC_ACTION_NONE) PUT_ERR("ERROR in dummy_recv_info");
291 } else {
292 yac_cupdate(dummy_field_ids[0]);
293 }
294 }
295
296 for (int i = 0; i < 2; ++i) {
297 int ierr = 0;
298 if (is_source_timestep && !is_target_timestep) {
299 yac_cget_action(field_ids[i][1], &send_action);
300 if (is_even_timestep && (send_action == YAC_ACTION_NONE)) {
301 yac_cupdate(field_ids[i][1]);
302 send_info = YAC_ACTION_NONE;
303 } else {
304 yac_cput(
305 field_ids[i][1], collection_size, send_field_collection_data,
306 &send_info, &ierr);
307 }
308 } else if (!is_source_timestep && is_target_timestep) {
309 yac_cget_action(field_ids[i][0], &recv_action);
310 if (is_even_timestep && (recv_action == YAC_ACTION_NONE)) {
311 yac_cupdate(field_ids[i][0]);
312 recv_info = YAC_ACTION_NONE;
313 } else {
314 yac_cget(
315 field_ids[i][0], collection_size, recv_field_collection_data,
316 &recv_info, &ierr);
317 }
318 } else if (is_source_timestep && is_target_timestep) {
319 yac_cget_action(field_ids[i][1], &send_action);
320 yac_cget_action(field_ids[i][0], &recv_action);
322 field_ids[i][1], field_ids[i][0], collection_size,
323 send_field_collection_data, recv_field_collection_data,
324 &send_info, &recv_info, &ierr);
325 }
326
327 if (ierr != 0) PUT_ERR("ERROR in ierr");
328 if (is_source_timestep) {
329 if (send_info != ref_send_info[i][put_idx])
330 PUT_ERR("ERROR in send_info");
331 if (send_action != ref_send_info[i][put_idx])
332 PUT_ERR("ERROR in send_action");
333 }
334 if (is_target_timestep) {
335 if (recv_info != ref_recv_info[get_idx])
336 PUT_ERR("ERROR in recv_info");
337 if (recv_action != ref_recv_info[get_idx])
338 PUT_ERR("ERROR in recv_action");
339 for (int j = 0; j < 9; ++j)
340 if (fabs(recv_field_data[j] -
341 ref_recv_field[i][get_idx][rank][j]) > 1e-9)
342 PUT_ERR("ERROR in recv_field_data");
343 }
344 }
345
346 if (is_source_timestep) ++put_idx;
347 if (is_target_timestep) ++get_idx;
348 }
349
350 yac_cfinalize_instance(instance_id);
351 } // with field mask
352 } // with core mask
353
354 MPI_Finalize();
355
356 return TEST_EXIT_CODE;
357}
#define YAC_ASSERT(exp, msg)
#define YAC_RAD
int collection_size
char * yaml_filename
#define TEST_EXIT_CODE
Definition tests.h:14
#define PUT_ERR(string)
Definition tests.h:10
int * cell_core_mask
int comp_id
void yac_cset_global_index_yac_int(yac_int const *global_index, int location, int grid_id)
Definition yac.c:5036
int const YAC_ACTION_OUT_OF_BOUND
put/get is outside of the valid range
Definition yac.c:50
int const YAC_LOCATION_CELL
Definition yac.c:34
void yac_cfinalize_instance(int yac_instance_id)
Finalises YAC.
Definition yac.c:731
void yac_cenddef_instance(int yac_instance_id)
Definition yac.c:4393
void yac_cread_config_yaml_instance(int yac_instance_id, const char *yaml_filename)
Definition yac.c:586
int const YAC_LOCATION_CORNER
Definition yac.c:35
void yac_cget(int const field_id, int collection_size, double **recv_field, int *info, int *ierr)
Definition yac.c:2759
void yac_cupdate(int field_id)
Definition yac.c:2446
void yac_cget_action(int field_id, int *action)
Definition yac.c:2380
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
void yac_cexchange(int const send_field_id, int const recv_field_id, int const collection_size, double ***const send_field, double **recv_field, int *send_info, int *recv_info, int *ierr)
Definition yac.c:4345
int const YAC_LOCATION_EDGE
Definition yac.c:36
void yac_cput(int const field_id, int const collection_size, double ***const send_field, int *info, int *ierr)
Definition yac.c:3721
int const YAC_ACTION_NONE
no data exchanges
Definition yac.c:42
void yac_cdef_calendar(int calendar)
Definition yac.c:769
void yac_cset_core_mask(int const *is_core, int location, int grid_id)
Definition yac.c:5065
int const YAC_ACTION_REDUCTION
data reduction, but data exchange
Definition yac.c:43
int const YAC_ACTION_GET_FOR_RESTART
last valid get
Definition yac.c:46
int const YAC_PROLEPTIC_GREGORIAN
Definition yac.c:68
void yac_cset_mask(int const *is_valid, int points_id)
Definition yac.c:1304
int const YAC_ACTION_COUPLING
data exchange
Definition yac.c:44
void yac_cinit_instance(int *yac_instance_id)
Definition yac.c:498
int const YAC_ACTION_PUT_FOR_RESTART
last valid put
Definition yac.c:47
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_comps_instance(int yac_instance_id, char const **comp_names, int num_comps, int *comp_ids)
Definition yac.c:974
YAC_INT yac_int
Definition yac_types.h:15