YAC 3.13.0
Yet Another Coupler
Loading...
Searching...
No Matches
toy_icon_callback.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#include <stdlib.h>
8#include <stdio.h>
9#include <unistd.h>
10#include <math.h>
11#include "yac.h"
12#include "yac_utils.h"
13
14/* ------------------------------------------------- */
15
16const char fieldName[] = "icon_to_cube";
17
26
27static void compute_weights_callback(
28 double const tgt_coords[3], int src_cell_id, size_t src_cell_idx,
29 int const ** global_results_points, double ** result_weights,
30 size_t * result_count, void * user_data);
31static inline void LLtoXYZ(double lon, double lat, double p_out[]);
32static inline void XYZtoLL (double const p_in[], double * lon, double * lat);
33
34#define STR_USAGE "Usage: %s -c configFilename -g gridFilename\n"
35#define YAC_ASSERT_ARGS(exp, msg) \
36 { \
37 if(!((exp))) { \
38 fprintf(stderr, "ERROR: %s\n" STR_USAGE, msg, argv[0]); \
39 exit(EXIT_FAILURE); \
40 } \
41 }
42
43static void parse_arguments(
44 int argc, char ** argv,
45 char const ** configFilename, char const ** gridFilename);
46
47int main (int argc, char *argv[]) {
48
49 // Initialisation of MPI
50
51 MPI_Init(0, NULL);
52 xt_initialize(MPI_COMM_WORLD);
53
54 char const * configFilename = "toy_callback.yaml"; // default configuration file
55 char const * gridFilename = "icon_grid_0043_R02B04_G.nc"; // default grid file
56 parse_arguments(argc, argv, &configFilename, &gridFilename);
57 yac_cinit ();
58 yac_cread_config_yaml(configFilename);
59
60 int comp_id;
61 char * comp_name = "ICON";
62
63 yac_cdef_comp ( comp_name, &comp_id );
64
65 MPI_Comm local_comm;
66 yac_cget_comp_comm(comp_id, &local_comm);
67
68 int rank, size;
69 MPI_Comm_rank(local_comm,&rank);
70 MPI_Comm_size(local_comm,&size);
71
72 MPI_Comm_free(&local_comm);
73
74
75 int cell_point_id;
76 int corner_point_id;
77
78 int field_id;
79 int grid_id;
80
81 /* Grid definition for the first component (ICON) */
82
83 int num_vertices;
84 int num_cells;
85 int * num_vertices_per_cell;
86 int * cell_to_vertex;
87 int * cell_to_vertex_offset;
88 double * x_vertices;
89 double * y_vertices;
90 double * x_cells;
91 double * y_cells;
92
93 int * cell_mask;
94 int * global_cell_id;
95 int * cell_core_mask;
96 int * global_corner_id;
97 int * corner_core_mask;
98
99 yac_read_part_icon_grid_information(gridFilename, &num_vertices, &num_cells,
100 &num_vertices_per_cell, &cell_to_vertex,
101 &x_vertices, &y_vertices, &x_cells,
102 &y_cells, &global_cell_id,
103 &cell_mask,
104 &cell_core_mask, &global_corner_id,
105 &corner_core_mask, rank, size);
106
107 cell_to_vertex_offset = malloc(num_cells * sizeof(*cell_to_vertex_offset));
108 for (int i = 0, accu = 0; i < num_cells; ++i) {
109 cell_to_vertex_offset[i] = accu;
110 accu += num_vertices_per_cell[i];
111 }
112
113 double * x_points, * y_points;
114
115 x_points = x_vertices;
116 y_points = y_vertices;
117
118 double * x_center, * y_center;
119
120 x_center = x_cells;
121 y_center = y_cells;
122
124 "icon_grid", num_vertices, num_cells, num_vertices_per_cell,
125 x_vertices, y_vertices, cell_to_vertex, &grid_id);
126
131
133 grid_id, num_cells, YAC_LOCATION_CELL, x_center, y_center, &cell_point_id );
135 grid_id, num_vertices, YAC_LOCATION_CORNER, x_points, y_points, &corner_point_id );
136
137 /* Field definition for the first component (ICON-atmosphere) */
138 int point_ids[2] = {cell_point_id, corner_point_id};
139 int num_points = 2;
141 fieldName, comp_id, point_ids, num_points, 1, "2", YAC_TIME_UNIT_SECOND,
142 &field_id);
143
144 // register callback routine
145 struct grid_info grid_info;
153 compute_weights_callback, (void*)&grid_info, "compute_weights_callback");
154
155 /* Search. */
156 yac_cenddef( );
157
158 double * cell_out = malloc(num_cells * sizeof(*cell_out));
159 double * corner_out = malloc(num_vertices * sizeof(*corner_out));
160
161 int err, info;
162
163 for (int i = 0; i < num_cells; ++i) {
164
165 double middle_point[3] = {0, 0, 0};
166
167 for (int j = 0; j < num_vertices_per_cell[i]; ++j) {
168
169 double curr_point[3];
170
171 LLtoXYZ(x_vertices[cell_to_vertex[cell_to_vertex_offset[i] + j]],
172 y_vertices[cell_to_vertex[cell_to_vertex_offset[i] + j]],
173 curr_point);
174
175 middle_point[0] += curr_point[0];
176 middle_point[1] += curr_point[1];
177 middle_point[2] += curr_point[2];
178 }
179
180 double scale = 1.0 / sqrt(middle_point[0] * middle_point[0] +
181 middle_point[1] * middle_point[1] +
182 middle_point[2] * middle_point[2]);
183
184 middle_point[0] *= scale;
185 middle_point[1] *= scale;
186 middle_point[2] *= scale;
187
188 double lon, lat;
189
190 XYZtoLL(middle_point, &lon, &lat);
191
192 cell_out[i] = yac_test_func(lon, lat);
193 }
194 for (int i = 0; i < num_vertices; ++i)
195 corner_out[i] = yac_test_func(x_vertices[i], y_vertices[i]);
196
197 {
198 double *point_set_data[2];
199 double **collection_data[1] = {point_set_data};
200
201 point_set_data[0] = cell_out;
202 point_set_data[1] = corner_out;
203 yac_cput(field_id, 1, collection_data, &info, &err);
204 }
205
206#ifdef VTK_OUTPUT
207 //----------------------------------------------------------
208 // write field to vtk output file
209 //----------------------------------------------------------
210
211 char vtk_filename[32];
212
213 sprintf(vtk_filename, "toy_icon_callback_%d.vtk", rank);
214
215 YAC_VTK_FILE *vtk_file = yac_vtk_open(vtk_filename, "unstruct_out");
217 vtk_file, x_vertices, y_vertices, num_vertices);
218 yac_vtk_write_cell_data(vtk_file, (unsigned *)cell_to_vertex,
219 (unsigned*)num_vertices_per_cell, num_cells);
221 vtk_file, corner_core_mask, num_vertices, "corner_core_mask");
223 vtk_file, global_corner_id, num_vertices, "global_corner_id");
225 vtk_file, cell_core_mask, num_cells, "cell_core_mask");
227 vtk_file, global_cell_id, num_cells, "global_cell_id");
228
229 yac_vtk_write_cell_scalars_double(vtk_file, cell_out, num_cells, "cell_out");
231 vtk_file, corner_out, num_vertices, "corner_out");
232
233 yac_vtk_close(vtk_file);
234
235#endif // VTK_OUTPUT
236
238
239 xt_finalize();
240
241 MPI_Finalize();
242
244 free(cell_to_vertex);
246 free(x_cells);
247 free(y_cells);
248 free(x_vertices);
249 free(y_vertices);
250 free(cell_mask);
251 free(global_cell_id);
252 free(cell_core_mask);
253 free(global_corner_id);
254 free(corner_core_mask);
255 free(cell_out);
256 free(corner_out);
257
258 return EXIT_SUCCESS;
259}
260
262 double const tgt_coords[3], int src_cell_id, size_t src_cell_idx,
263 int const ** global_results_points, double ** result_weights,
264 size_t * result_count, void * user_data) {
265
266 (void)(tgt_coords);
267
268 struct grid_info * info = (struct grid_info*)user_data;
269
270 for (size_t i = 0; i < 2; ++i) {
271 global_results_points[i] = NULL;
272 result_weights[i] = NULL;
273 result_count[i] = 0;
274 }
275
276 // consistency check
277 if ((info->global_cell_id[src_cell_idx] != src_cell_id) ||
278 (!info->cell_core_mask[src_cell_idx])) {
279 fputs("ERROR(compute_weights_callback): inconsistent data\n", stderr);
280 exit(EXIT_FAILURE);
281 }
282
283 static double cell_weight[1] = {0.5};
284 static double vertex_weights[4] = {0.125, 0.125, 0.125, 0.125};
285
286 static int cell_result_points[1];
287 static int vertex_result_points[4];
288
289 for (int i = 0; i < info->num_vertices_per_cell[src_cell_idx]; ++i)
290 vertex_result_points[i] =
291 (int)(info->global_corner_id[
292 info->cell_to_vertex[
293 info->cell_to_vertex_offset[src_cell_idx] + i]]);
294 cell_result_points[0] = (int)src_cell_id;
295
296 global_results_points[0] = cell_result_points;
297 global_results_points[1] = vertex_result_points;
298 result_weights[0] = cell_weight;
299 result_weights[1] = vertex_weights;
300 result_count[0] = 1;
301 result_count[1] = 4;
302}
303
304static void parse_arguments(
305 int argc, char ** argv,
306 char const ** configFilename, char const ** gridFilename) {
307
308 int opt;
309 while ((opt = getopt(argc, argv, "c:g:")) != -1) {
310 YAC_ASSERT_ARGS((opt == 'c') || (opt == 'g'), "invalid command argument")
311 switch (opt) {
312 default:
313 case 'c':
314 *configFilename = optarg;
315 break;
316 case 'g':
317 *gridFilename = optarg;
318 break;
319 }
320 }
321}
322
323static inline void LLtoXYZ(double lon, double lat, double p_out[]) {
324
325 while (lon < -M_PI) lon += 2.0 * M_PI;
326 while (lon >= M_PI) lon -= 2.0 * M_PI;
327
328 double cos_lat = cos(lat);
329 p_out[0] = cos_lat * cos(lon);
330 p_out[1] = cos_lat * sin(lon);
331 p_out[2] = sin(lat);
332}
333
334static inline void XYZtoLL (double const p_in[], double * lon, double * lat) {
335
336 *lon = atan2(p_in[1] , p_in[0]);
337 *lat = M_PI_2 - acos(p_in[2]);
338}
void * user_data
void yac_read_part_icon_grid_information(const char *filename, int *nbr_vertices, int *nbr_cells, int **num_vertices_per_cell, int **cell_to_vertex, double **x_vertices, double **y_vertices, double **x_cells, double **y_cells, int **global_cell_id, int **cell_mask, int **cell_core_mask, int **global_corner_id, int **corner_core_mask, int rank, int size)
int * global_corner_id
int * num_vertices_per_cell
int * cell_to_vertex_offset
int * cell_to_vertex
int * cell_mask
double yac_test_func(double lon, double lat)
size_t num_cells[2]
int info
int * cell_core_mask
int grid_id
int cell_point_id
int * field_id
int comp_id
const char fieldName[]
static void parse_arguments(int argc, char **argv, char const **configFilename, char const **gridFilename)
#define YAC_ASSERT_ARGS(exp, msg)
static void compute_weights_callback(double const tgt_coords[3], int src_cell_id, size_t src_cell_idx, int const **global_results_points, double **result_weights, size_t *result_count, void *user_data)
static void LLtoXYZ(double lon, double lat, double p_out[])
static void XYZtoLL(double const p_in[], double *lon, double *lat)
void yac_vtk_write_cell_scalars_double(YAC_VTK_FILE *vtk_file, double *scalars, unsigned num_cells, char *name)
Definition vtk_output.c:264
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_ll(YAC_VTK_FILE *vtk_file, double *point_data_lon, double *point_data_lat, unsigned num_points)
Definition vtk_output.c:149
void yac_vtk_write_point_scalars_double(YAC_VTK_FILE *vtk_file, double *scalars, unsigned num_points, char *name)
Definition vtk_output.c:292
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_close(YAC_VTK_FILE *vtk_file)
Definition vtk_output.c:403
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_cenddef(void)
Definition yac.c:4400
void yac_cset_global_index(int const *global_index, int location, int grid_id)
Definition yac.c:5049
int const YAC_LOCATION_CELL
Definition yac.c:34
void yac_cadd_compute_weights_callback(yac_func_compute_weights compute_weights_callback, void *user_data, char const *key)
Definition yac.c:5867
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_cget_comp_comm(int comp_id, MPI_Comm *comp_comm)
Definition yac.c:856
int const YAC_TIME_UNIT_SECOND
Definition yac.c:59
void yac_cdef_grid_unstruct(const char *grid_name, int nbr_vertices, int nbr_cells, int *num_vertices_per_cell, double *x_vertices, double *y_vertices, int *cell_to_vertex, int *grid_id)
Definition yac.c:4867
void yac_cdef_points_unstruct(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:1181
void yac_cput(int const field_id, int const collection_size, double ***const send_field, int *info, int *ierr)
Definition yac.c:3721
void yac_cread_config_yaml(const char *yaml_filename)
Definition yac.c:595
void yac_cset_core_mask(int const *is_core, int location, int grid_id)
Definition yac.c:5065
static size_t num_points
Definition yac.c:162
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