YAC 3.13.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_dummy_coupling4_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#include <yaxt.h>
7
8#include <stdlib.h>
9#include <stdio.h>
10#include <string.h>
11#include <math.h>
12#include <float.h>
13#include "tests.h"
14#include "test_common.h"
15#include "yac.h"
16
22#define YAC_RAD (0.01745329251994329576923690768489) // M_PI / 180
23
24enum {
28 NUM_POINTS = 9
29};
30
31static void utest_init_ref_recv_field(
32 double ref_recv_field[][COLLECTION_SIZE][NUM_POINTS]) {
33
34 for (int i = 0; i < 3; ++i)
35 for (int j = 0; j < COLLECTION_SIZE; ++j)
36 for (int k = 0; k < NUM_POINTS; ++k)
37 ref_recv_field[i][j][k] = 0.0;
38 for (int j = 0; j < COLLECTION_SIZE; ++j) {
39 for (int k = 0; k < NUM_POINTS; ++k) {
40 ref_recv_field[3][j][k] = DBL_MAX;
41 ref_recv_field[4][j][k] = -DBL_MAX;
42 }
43 }
44}
45
46int main(int argc, char** argv) {
47
48 yac_cinit();
50
51 int size, rank;
52 MPI_Comm_rank ( MPI_COMM_WORLD, &rank );
53 MPI_Comm_size ( MPI_COMM_WORLD, &size );
54
55 if (size != 2) {
56 fputs("wrong number of processes (has to be 2)\n", stderr);
57 exit(EXIT_FAILURE);
58 }
59
60 if (argc != 2) {
61 PUT_ERR("ERROR: missing config file directory");
62 xt_finalize();
63 MPI_Finalize();
64 return TEST_EXIT_CODE;
65 }
66
67 char * yaml_filename =
68 strcat(
69 strcpy(
70 malloc(strlen(argv[1]) + 32), argv[1]), "coupling_test4.yaml");
72 free(yaml_filename);
73
74 int is_target = rank == 1;
75
76 // define local component
77 int comp_id;
78 yac_cdef_comp((is_target)?"target_comp":"source_comp", &comp_id);
79
80 // define grid (both components use an identical grid
81 int grid_id;
83 (is_target)?"target_grid":"source_grid", (int[2]){3,3}, (int[2]){0,0},
84 (double[]){0*YAC_RAD,1*YAC_RAD,2*YAC_RAD},
85 (double[]){0*YAC_RAD,1*YAC_RAD,2*YAC_RAD}, &grid_id);
86
87 // define points at the vertices of the grid
88 int point_id;
90 grid_id, (int[2]){3,3}, YAC_LOCATION_CORNER,
91 (double[]){0*YAC_RAD,1*YAC_RAD,2*YAC_RAD},
92 (double[]){0*YAC_RAD,1*YAC_RAD,2*YAC_RAD}, &point_id);
93
94 // define fields
95 int field_ids[NUM_FIELDS];
96 const char * fieldName[NUM_FIELDS] =
97 {"time_op_accu_field",
98 "time_op_avg_field",
99 "time_op_none_field",
100 "time_op_min_field",
101 "time_op_max_field"};
102 for (int i = 0; i < NUM_FIELDS; ++i )
104 fieldName[i], comp_id, &point_id, 1, 3,
105 (is_target)?"2":"1", YAC_TIME_UNIT_SECOND,
106 &field_ids[i]);
107
108 yac_cenddef ( );
109
110 double send_field[COLLECTION_SIZE][NUM_POINTSETS][NUM_POINTS] =
111 {{{ 1, 2, 3, 4, 5, 6, 7, 8, 9}},
112 {{10,11,12,13,14,15,16,17,18}},
113 {{19,20,21,22,23,24,25,26,27}}};
114 double ref_recv_field[NUM_FIELDS][COLLECTION_SIZE][NUM_POINTS];
115 utest_init_ref_recv_field(ref_recv_field);
116
117 // do time steps
118 for (int t = 0; t < 32; ++t) {
119
120 if (!is_target) {
121
122 for (int i = 0; i < NUM_FIELDS; ++i) {
123
124 int info, ierror;
125 yac_cput_(
126 field_ids[i], COLLECTION_SIZE, &send_field[0][0][0], &info, &ierror);
127
128 int ref_send_info =
129 (t%4)?
132 if (info != ref_send_info) PUT_ERR("error in yac_cput_: wrong info");
133 if (ierror) PUT_ERR("error in yac_cput_: wrong ierror");
134 }
135 }
136
137 double scale = ((t == 0)?1.0:0.25);
138 for (int i = 0; i < COLLECTION_SIZE; ++i)
139 for (int j = 0; j < NUM_POINTS; ++j) {
140
141 // update ref_recv_field (accu)
142 ref_recv_field[0][i][j] += send_field[i][0][j];
143
144 // update ref_recv_field (avg)
145 ref_recv_field[1][i][j] += send_field[i][0][j] * scale;
146
147 // update ref_recv_field (none)
148 ref_recv_field[2][i][j] = send_field[i][0][j];
149
150 // update ref_recv_field (minimum)
151 ref_recv_field[3][i][j] =
152 MIN(ref_recv_field[3][i][j], send_field[i][0][j]);
153
154 // update ref_recv_field (maximum)
155 ref_recv_field[4][i][j] =
156 MAX(ref_recv_field[4][i][j], send_field[i][0][j]);
157 }
158
159 if (is_target) {
160
161 // target calls get every second timestep
162 if ((t % 2) == 0) {
163 for (int i = 0; i < NUM_FIELDS; ++i) {
164
165 // initialise recv_field
166 double recv_field[COLLECTION_SIZE][NUM_POINTS];
167 for (int j = 0; j < COLLECTION_SIZE; ++j)
168 for (int k = 0; k < NUM_POINTS; ++k)
169 recv_field[j][k] = -1;
170
171 int info, ierror;
172 yac_cget_(
173 field_ids[i], COLLECTION_SIZE, &recv_field[0][0], &info, &ierror);
174
175 int ref_recv_info = (t%4)?YAC_ACTION_NONE:YAC_ACTION_COUPLING;
176 if (info != ref_recv_info) PUT_ERR("error in yac_cget_: wrong info");
177 if (ierror) PUT_ERR("error in yac_cget_: wrong ierror");
178
179 if (info == YAC_ACTION_COUPLING) {
180 for (int j = 0; j < COLLECTION_SIZE; ++j)
181 for (int k = 0; k < NUM_POINTS; ++k)
182 if (fabs(recv_field[j][k] - ref_recv_field[i][j][k]) > 1e-6)
183 PUT_ERR("error in yac_cget_: wrong recv_field");
184 } else {
185 for (int j = 0; j < COLLECTION_SIZE; ++j)
186 for (int k = 0; k < NUM_POINTS; ++k)
187 if (recv_field[j][k] != -1)
188 PUT_ERR("error in yac_cget_: wrong recv_field");
189 }
190 }
191 }
192 }
193
194 // update send_field
195 for (int i = 0; i < 3; ++i)
196 for (int j = 0; j < NUM_POINTS; ++j)
197 send_field[i][0][j] += i - 1;
198
199 // clean ref_recv_field at every coupling timestep
200 if ((t % 4) == 0) utest_init_ref_recv_field(ref_recv_field);
201 }
202
203 yac_cfinalize ();
204
205 return TEST_EXIT_CODE;
206}
const char * fieldName[]
@ COLLECTION_SIZE
#define YAC_RAD
char * yaml_filename
int point_id
#define TEST_EXIT_CODE
Definition tests.h:14
#define PUT_ERR(string)
Definition tests.h:10
#define MIN(a, b)
Definition toy_common.h:29
int info
int grid_id
int ierror
int comp_id
#define MAX(a, b)
void yac_cenddef(void)
Definition yac.c:4400
void yac_cget_(int const field_id, int const collection_size, double *recv_field, int *info, int *ierr)
Definition yac.c:2741
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
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_cread_config_yaml(const char *yaml_filename)
Definition yac.c:595
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
void yac_cput_(int const field_id, int const collection_size, double *send_field, int *info, int *ierr)
Definition yac.c:3063
int const YAC_PROLEPTIC_GREGORIAN
Definition yac.c:68
int const YAC_ACTION_COUPLING
data exchange
Definition yac.c:44
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