YAC 3.13.2
Yet Another Coupler
Loading...
Searching...
No Matches
toy_multi_reg2d.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// #define VERBOSE
6
7#include <mpi.h>
8#include <stdlib.h>
9#include <stdio.h>
10#include <unistd.h>
11#include "yac.h"
12#include "yac_utils.h"
13
14#include "toy_multi_common.h"
15
16// redefine YAC assert macros
17#undef YAC_ASSERT
18#define STR_USAGE "Usage: %s -x num_cells_x -y num_cells_y\n"
19#define YAC_ASSERT(exp, msg) \
20 { \
21 if(!((exp))) { \
22 fprintf(stderr, "ERROR: %s\n" STR_USAGE, msg, argv[0]); \
23 exit(EXIT_FAILURE); \
24 } \
25 }
26
27static void parse_arguments(
28 int argc, char ** argv, size_t * num_cells_x, size_t * num_cells_y);
29
30int main (int argc, char *argv[]) {
31
32 double tic;
33
34 // Initialisation of MPI
35
36 MPI_Init (0, NULL);
37
38 MPI_Barrier(MPI_COMM_WORLD);
39 tic=MPI_Wtime();
40
41 size_t num_cells_x = 256; // default horizontal resolution
42 size_t num_cells_y = 128; // default vertical resolution
43 parse_arguments(argc, argv, &num_cells_x, &num_cells_y);
44 yac_cinit ();
46 yac_cdef_datetime("2008-03-09T16:05:07", "2008-03-10T16:05:07");
47
48 int comp_id;
49 char * comp_name = "ECHAM";
50
51 yac_cdef_comp(comp_name, &comp_id);
52
53 MPI_Comm comp_comm;
54
55 yac_cget_comp_comm(comp_id, &comp_comm);
56
57 int rank, comp_rank, comp_size;
58 MPI_Comm_rank(MPI_COMM_WORLD,&rank);
59 MPI_Comm_rank(comp_comm,&comp_rank);
60 MPI_Comm_size(comp_comm,&comp_size);
61 MPI_Comm_free(&comp_comm);
62
63 int total_nbr_cells[2] = {num_cells_x, num_cells_y};
64 int num_procs[2];
65
66 yac_generate_reg2d_decomp(total_nbr_cells, comp_size, num_procs);
67
68 int block_pos[2];
69 int block_size[2];
70 int nbr_cells[2];
71 int cyclic[2];
72 int nbr_points[2];
73 block_pos[0] = comp_rank%num_procs[0];
74 block_pos[1] = comp_rank/num_procs[0];
75 block_size[0] = (num_cells_x + num_procs[0] - 1)/num_procs[0];
76 block_size[1] = (num_cells_y + num_procs[1] - 1)/num_procs[1];
77 nbr_cells[0] = MIN(block_size[0], (int)num_cells_x - block_size[0] * block_pos[0]);
78 nbr_cells[1] = MIN(block_size[1], (int)num_cells_y - block_size[1] * block_pos[1]);
79 cyclic[0] = num_procs[0] == 1;
80 cyclic[1] = 0;
81
82 // halo
83 if (!cyclic[0])
84 nbr_cells[0] += 2;
85 if (num_procs[1] > 1) {
86
87 nbr_cells[1] += 1;
88
89 if ((block_pos[1] != 0) && (block_pos[1] != num_procs[1]-1))
90 nbr_cells[1] += 1;
91 }
92
93 if (cyclic[0])
94 nbr_points[0] = nbr_cells[0];
95 else
96 nbr_points[0] = nbr_cells[0]+1;
97
98 nbr_points[1] = nbr_cells[1] + 1;
99
100 double * global_x_vertices = malloc((num_cells_x+3) * sizeof(*global_x_vertices));
101 double * global_y_vertices = malloc((num_cells_y+1) * sizeof(*global_y_vertices));
102 double * x_vertices;
103 double * y_vertices;
104 double * x_corner_points;
105 double * y_corner_points;
106
107 for (size_t i = 0; i < num_cells_x+3; ++i)
108 global_x_vertices[i] =
109 0.0 + (2.0 * M_PI / ((double)num_cells_x)) * ((double)i-1.0);
110 for (size_t i = 0; i < num_cells_y; ++i)
111 global_y_vertices[i] =
112 -M_PI_2 + (M_PI / ((double)num_cells_y)) * (double)i;
113 global_y_vertices[num_cells_y] = M_PI_2;
114
115 if (cyclic[0])
116 x_vertices = x_corner_points = global_x_vertices + 1;
117 else
118 x_vertices = x_corner_points = global_x_vertices + block_size[0] * block_pos[0];
119
120 y_vertices = y_corner_points = global_y_vertices + block_size[1] * block_pos[1];
121
122 if (block_pos[1] != 0) {
123 y_vertices -= 1;
124 y_corner_points -= 1;
125 }
126
127 double * x_cell_points = malloc(nbr_cells[0] * sizeof(*x_cell_points));
128 double * y_cell_points = malloc(nbr_cells[1] * sizeof(*y_cell_points));
129
130 for (int i = 0; i < nbr_cells[0]; ++i)
131 x_cell_points[i] = (x_corner_points[i] + x_corner_points[i + 1]) * 0.5;
132 for (int i = 0; i < nbr_cells[1]; ++i)
133 y_cell_points[i] = (y_corner_points[i] + y_corner_points[i + 1]) * 0.5;
134
135 int grid_id;
136 char grid_name[256];
137 sprintf(grid_name, "%s_grid", comp_name);
138
140 grid_name, nbr_points, cyclic, x_vertices, y_vertices, &grid_id);
141
142 int * global_global_cell_id =
143 malloc(num_cells_y * (num_cells_x + 2) * sizeof(*global_global_cell_id));
144 int * global_global_corner_id =
145 malloc((num_cells_y + 1) * (num_cells_x + 3) * sizeof(*global_global_corner_id));
146
147 for (size_t j = 0, id = 0; j < num_cells_y; ++j)
148 for (size_t i = 1; i <= num_cells_x; ++i)
149 global_global_cell_id[j * (num_cells_x + 2) + i] = id++;
150 for (size_t i = 0; i < num_cells_y; ++i) {
151 global_global_cell_id[i * (num_cells_x + 2) + 0] =
152 global_global_cell_id[i * (num_cells_x + 2) + num_cells_x];
153 global_global_cell_id[i * (num_cells_x + 2) + num_cells_x+1] =
154 global_global_cell_id[i * (num_cells_x + 2) + 1];
155 }
156
157 if (num_procs[0] == 1) {
158
159 for (size_t j = 0, id = 0; j < num_cells_y + 1; ++j)
160 for (size_t i = 1; i <= num_cells_x; ++i)
161 global_global_corner_id[j * (num_cells_x + 3) + i] = id++;
162
163 } else {
164
165 for (size_t j = 0, id = 0; j < num_cells_y + 1; ++j)
166 for (size_t i = 0; i < num_cells_x; ++i)
167 global_global_corner_id[j * (num_cells_x + 3) + (i + 1)] = id++;
168
169 for (size_t i = 0; i < num_cells_y + 1; ++i) {
170
171 global_global_corner_id[i * (num_cells_x + 3) + 0] =
172 global_global_corner_id[i * (num_cells_x + 3) + num_cells_x];
173 global_global_corner_id[i * (num_cells_x + 3) + num_cells_x + 1] =
174 global_global_corner_id[i * (num_cells_x + 3) + 1];
175 global_global_corner_id[i * (num_cells_x + 3) + num_cells_x + 2] =
176 global_global_corner_id[i * (num_cells_x + 3) + 2];
177 }
178 }
179
180 int * local_global_cell_id = malloc(nbr_cells[1] * nbr_cells[0] * sizeof(*local_global_cell_id));
181 int * cell_core_mask = malloc(nbr_cells[1] * nbr_cells[0] * sizeof(*cell_core_mask));
182 int * local_global_corner_id = malloc(nbr_points[1] * nbr_points[0] * sizeof(*local_global_corner_id));
183 int * corner_core_mask = malloc(nbr_points[1] * nbr_points[0] * sizeof(*corner_core_mask));
184
185 int offset_x, offset_y;
186
187 if (cyclic[0])
188 offset_x = 1;
189 else
190 offset_x = block_size[0] * block_pos[0];
191 offset_y = block_size[1] * block_pos[1] - (block_pos[1] != 0);
192
193 for (int j = 0; j < nbr_cells[1]; ++j)
194 for (int i = 0; i < nbr_cells[0]; ++i)
195 local_global_cell_id[j * nbr_cells[0] + i] =
196 global_global_cell_id[(j+offset_y) * (num_cells_x + 2) + i+offset_x];
197
198 free(global_global_cell_id);
199
200 for (int j = 0; j < nbr_points[1]; ++j)
201 for (int i = 0; i < nbr_points[0]; ++i)
202 local_global_corner_id[j * nbr_points[0] + i] =
203 global_global_corner_id[(j+offset_y) * (num_cells_x + 3) +i+offset_x];
204
205 free(global_global_corner_id);
206
207 for (int j = 0; j < nbr_cells[1]; ++j)
208 for (int i = 0; i < nbr_cells[0]; ++i)
209 cell_core_mask[j * nbr_cells[0] + i] = 1;
210 if (num_procs[1] > 1) {
211 if (block_pos[1] > 0)
212 for (int i = 0; i < nbr_cells[0]; ++i)
213 cell_core_mask[i] = 0;
214 if (block_pos[1] < num_procs[1] - 1)
215 for (int i = 0; i < nbr_cells[0]; ++i)
216 cell_core_mask[(nbr_cells[1] - 1) * nbr_cells[0] + i] = 0;
217 }
218 if (num_procs[0] > 1) {
219 for (int j = 0; j < nbr_cells[1]; ++j) {
220 cell_core_mask[j * nbr_cells[0]] = 0;
221 cell_core_mask[j * nbr_cells[0] + nbr_cells[0] - 1] = 0;
222 }
223 }
224
225 for (int j = 0; j < nbr_points[1]; ++j)
226 for (int i = 0; i < nbr_points[0]; ++i)
227 corner_core_mask[j * nbr_points[0] + i] = 1;
228 if (num_procs[1] > 1) {
229 if (block_pos[1] > 0)
230 for (int i = 0; i < nbr_points[0]; ++i)
231 corner_core_mask[i] = 0;
232 if (block_pos[1] < num_procs[1] - 1)
233 for (int i = 0; i < nbr_points[0]; ++i)
234 corner_core_mask[(nbr_points[1] - 1) * nbr_points[0] + i] = 0;
235 }
236 if (num_procs[0] > 1) {
237 for (int j = 0; j < nbr_points[1]; ++j) {
238 corner_core_mask[j * nbr_points[0]] = 0;
239 corner_core_mask[j * nbr_points[0] + nbr_points[0] - 1] = 0;
240 }
241 }
242
243 yac_cset_global_index(local_global_cell_id, YAC_LOCATION_CELL, grid_id);
245 yac_cset_global_index(local_global_corner_id, YAC_LOCATION_CORNER, grid_id);
247
248 int cell_point_id, corner_point_id;
249
251 grid_id, nbr_cells, YAC_LOCATION_CELL, x_cell_points, y_cell_points,
254 grid_id, nbr_points, YAC_LOCATION_CORNER, x_corner_points, y_corner_points,
255 &corner_point_id);
256
257 unsigned num_cells = nbr_cells[0] * nbr_cells[1];
258 unsigned num_corners = nbr_points[0] * nbr_points[1];
259
260 double * cell_point_data = malloc(num_cells * sizeof(*cell_point_data));
261 double * corner_point_data = malloc(num_corners * sizeof(*corner_point_data));
262
263 unsigned * cell_corners = malloc(num_cells * 4 * sizeof(*cell_corners));
264 unsigned * num_points_per_cell = malloc(num_cells * sizeof(*num_points_per_cell));
265 for (unsigned i = 0; i < num_cells; ++i) {
266
267 {
268 unsigned x_index, y_index;
269
270 y_index = i / nbr_cells[0];
271 x_index = i - y_index * nbr_cells[0];
272
273 if (!cyclic[0]) {
274
275 cell_corners[i*4+0] = y_index * (nbr_cells[0] + 1) + x_index;
276 cell_corners[i*4+1] = y_index * (nbr_cells[0] + 1) + x_index + 1;
277 cell_corners[i*4+2] = (y_index + 1) * (nbr_cells[0] + 1) + x_index + 1;
278 cell_corners[i*4+3] = (y_index + 1) * (nbr_cells[0] + 1) + x_index;
279
280 } else {
281
282 cell_corners[i*4+0] = y_index * nbr_cells[0] + x_index;
283 if (x_index + 1 != (unsigned)(nbr_cells[0])) {
284 cell_corners[i*4+1] = y_index * nbr_cells[0] + x_index + 1;
285 cell_corners[i*4+2] = (y_index + 1) * nbr_cells[0] + x_index + 1;
286 } else {
287 cell_corners[i*4+1] = y_index * nbr_cells[0];
288 cell_corners[i*4+2] = (y_index + 1) * nbr_cells[0];
289 }
290 cell_corners[i*4+3] = (y_index + 1) * nbr_cells[0] + x_index;
291 }
292 }
293 num_points_per_cell[i] = 4;
294 }
295
296 for (unsigned i = 0; i < num_cells; ++i) {
297
298 double curr_x, curr_y;
299
300 curr_x = (x_vertices[cell_corners[i*4+0]%nbr_points[0]] +
301 x_vertices[cell_corners[i*4+1]%nbr_points[0]]) * 0.5;
302 curr_y = (y_vertices[cell_corners[i*4+1]/nbr_points[0]] +
303 y_vertices[cell_corners[i*4+2]/nbr_points[0]]) * 0.5;
304
305 cell_point_data[i] = yac_test_func(curr_x, curr_y);
306 }
307
308 for (unsigned i = 0; i < num_corners; ++i)
309 corner_point_data[i] = yac_test_func(x_corner_points[i%nbr_points[0]],
310 y_corner_points[i/nbr_points[0]]);
311
312 MPI_Barrier(MPI_COMM_WORLD);
313 if (rank == 0)
314 printf(
315 "toy_multi_common(%s): Time for initialisation %f\n",
316 comp_name, MPI_Wtime()-tic);
317
318 // initialize VTK file
319 double * point_data =
320 malloc(nbr_points[0] * nbr_points[1] * 3 * sizeof(*point_data));
321 for (int i = 0; i < nbr_points[1]; ++i)
322 for (int j = 0; j < nbr_points[0]; ++j)
323 LLtoXYZ(
324 x_vertices[j], y_vertices[i], &point_data[3*(i * nbr_points[0] + j)]);
325
326 char vtk_filename[32];
327
328 sprintf(vtk_filename, "%s_out_%d.vtk", comp_name, comp_rank);
329
330 YAC_VTK_FILE *vtk_file = yac_vtk_open(vtk_filename, comp_name);
332 vtk_file, point_data, nbr_points[0]*nbr_points[1]);
334 vtk_file, cell_corners, num_points_per_cell, num_cells);
336 vtk_file, corner_core_mask, nbr_points[0]*nbr_points[1],
337 "corner_core_mask");
339 vtk_file, local_global_corner_id, nbr_points[0]*nbr_points[1],
340 "global_corner_id");
342 vtk_file, cell_core_mask, num_cells, "cell_core_mask");
344 vtk_file, local_global_cell_id, num_cells, "global_cell_id");
345
346 int ret =
348 comp_name, comp_id, grid_id, cell_point_id, corner_point_id,
349 cell_point_data, corner_point_data, vtk_file);
350
351 free(num_points_per_cell);
352 free(cell_corners);
353 free(point_data);
354 free(corner_point_data);
355 free(cell_point_data);
356 free(corner_core_mask);
357 free(local_global_corner_id);
358 free(cell_core_mask);
359 free(local_global_cell_id);
360 free(x_cell_points);
361 free(y_cell_points);
362 free(global_x_vertices);
363 free(global_y_vertices);
364
365 return ret;
366}
367
368static void parse_arguments(
369 int argc, char ** argv, size_t * num_cells_x, size_t * num_cells_y) {
370
371 int opt;
372 while ((opt = getopt(argc, argv, "x:y:")) != -1) {
373 YAC_ASSERT((opt == 'c') || (opt == 'x') || (opt == 'y'), "invalid command argument")
374 switch (opt) {
375 default:
376 case 'x':
377 *num_cells_x = atoi(optarg);
378 YAC_ASSERT(*num_cells_x > 0, "invalid horizontal resolution");
379 break;
380 case 'y':
381 *num_cells_y = atoi(optarg);
382 YAC_ASSERT(*num_cells_y > 0, "invalid vertical resolution");
383 break;
384 }
385 }
386}
void yac_generate_reg2d_decomp(int num_points[2], int total_num_procs, int *num_procs)
double yac_test_func(double lon, double lat)
size_t num_cells[2]
unsigned cyclic[2]
#define MIN(a, b)
Definition toy_common.h:29
int * cell_core_mask
int grid_id
int cell_point_id
int comp_id
int run_toy_multi_common(char const *comp_name, int comp_id, int grid_id, int cell_point_id, int corner_point_id, double *cell_point_data, double *corner_point_data, YAC_VTK_FILE *vtk_file)
static void parse_arguments(int argc, char **argv, size_t *num_cells_x, size_t *num_cells_y)
#define YAC_ASSERT(exp, msg)
static void LLtoXYZ(double lon, double lat, double p_out[])
Definition toy_scrip.c:587
void yac_vtk_write_cell_scalars_int(YAC_VTK_FILE *vtk_file, int *scalars, unsigned num_cells, char *name)
Definition vtk_output.c:250
void yac_vtk_write_point_data(YAC_VTK_FILE *vtk_file, double *point_data, unsigned num_points)
Definition vtk_output.c:69
void yac_vtk_write_point_scalars_int(YAC_VTK_FILE *vtk_file, int *scalars, unsigned num_points, char *name)
Definition vtk_output.c:278
void yac_vtk_write_cell_data(YAC_VTK_FILE *vtk_file, unsigned *cell_corners, unsigned *num_points_per_cell, unsigned num_cells)
Definition vtk_output.c:88
YAC_VTK_FILE * yac_vtk_open(const char *filename, const char *title)
Definition vtk_output.c:45
void yac_cset_global_index(int const *global_index, int location, int grid_id)
Definition yac.c:5049
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
void yac_cinit(void)
Definition yac.c:514
int const YAC_LOCATION_CORNER
Definition yac.c:35
void yac_cget_comp_comm(int comp_id, MPI_Comm *comp_comm)
Definition yac.c:856
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
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_PROLEPTIC_GREGORIAN
Definition yac.c:68
void yac_cdef_comp(char const *comp_name, int *comp_id)
Definition yac.c:1013