YAC 3.12.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_common.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 <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include <stdlib.h>
9
10#include "test_common.h"
11#include "geometry.h"
12#include "tests.h"
13
20 double * lon, double * lat, enum yac_edge_type * edge_type,
21 size_t num_corners, void (*fun_LLtoXYZ)(double,double,double[])) {
22
23 struct yac_grid_cell cell;
24
25 cell.coordinates_xyz = xmalloc(num_corners * sizeof(*(cell.coordinates_xyz)));
26 cell.edge_type = xmalloc(num_corners * sizeof(*(cell.edge_type)));
29 for (size_t i = 0; i < num_corners; ++i)
30 (*fun_LLtoXYZ)(lon[i], lat[i], cell.coordinates_xyz[i]);
31 memcpy(cell.edge_type, edge_type, num_corners * sizeof(*edge_type));
32
33 return cell;
34}
35
37 double * lon, double * lat, enum yac_edge_type * edge_type,
38 size_t num_corners) {
40}
41
43 double * lon, double * lat, enum yac_edge_type * edge_type,
44 size_t num_corners) {
46}
47
50 size_t num_corners) {
51
52 struct yac_grid_cell cell;
53
54 cell.coordinates_xyz = xmalloc(num_corners * sizeof(*(cell.coordinates_xyz)));
55 cell.edge_type = xmalloc(num_corners * sizeof(*(cell.edge_type)));
58 memcpy(cell.coordinates_xyz, coords, num_corners * sizeof(*coords));
59 memcpy(cell.edge_type, edge_type, num_corners * sizeof(*edge_type));
60
61 return cell;
62}
63
64int intersect(enum yac_edge_type edge_type_a,
65 double lon_a, double lat_a, double lon_b, double lat_b,
66 enum yac_edge_type edge_type_b,
67 double lon_c, double lat_c, double lon_d, double lat_d,
68 double * intersection) {
69
70// Intel ICX with O3 seems to use some vector operation for copying q to
71// intersection in the code below. However, this causes a segmentation vault
72// due to the alignment of q. By increasing the size of p to 4, the alignment
73// of q is correct.
74#define INTEL_ICX_BUG
75#ifdef INTEL_ICX_BUG
76 double a[3], b[3], c[3], d[3], p[4], q[3];
77#else
78 double a[3], b[3], c[3], d[3], p[3], q[3];
79#endif
80
81 LLtoXYZ_deg(lon_a, lat_a, a);
82 LLtoXYZ_deg(lon_b, lat_b, b);
83 LLtoXYZ_deg(lon_c, lat_c, c);
84 LLtoXYZ_deg(lon_d, lat_d, d);
85
86 int ret = yac_intersect_vec(edge_type_a, a, b, edge_type_b, c, d, p, q);
87
88 switch (ret) {
89 case ((1 << 0) | (1 << 2)):
90 case ((1 << 0) | (1 << 1) | (1 << 2)):
91 case ((1 << 0) | (1 << 2) | (1 << 3)):
92 case ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)):
93 intersection[0] = p[0];
94 intersection[1] = p[1];
95 intersection[2] = p[2];
96 return 1;
97 case ( (1 << 1) | (1 << 3)):
98 case ((1 << 0) | (1 << 1) | (1 << 3)):
99 case ( (1 << 1) | (1 << 2) | (1 << 3)):
100 intersection[0] = q[0];
101 intersection[1] = q[1];
102 intersection[2] = q[2];
103 return 1;
104 default:
105 return 0;
106 }
107}
108
109void * to_pointer(void * data, size_t size_data) {
110
111 void * ret_value = xmalloc(size_data);
112 memcpy(ret_value, data, size_data);
113 return ret_value;
114}
115
116int double_are_equal(double a, double b) {
117
118 return (a > b) == (a < b);
119}
120
121int double_are_unequal(double a, double b) {
122
123 return (a > b) != (a < b);
124}
125
126void set_even_io_rank_list(MPI_Comm comm) {
127
128 int comm_size;
129 MPI_Comm_size(comm, &comm_size);
130
131 char * io_rank_list = xmalloc(16 * comm_size);
132 io_rank_list[0] = '\0';
133 for (int i = 0; i < comm_size; i += 2) {
134 char rank[16];
135 snprintf(rank, sizeof(rank), "%d,", i);
136 strcat(io_rank_list, rank);
137 }
138 char comm_size_str[16];
139 snprintf(comm_size_str, sizeof(comm_size_str), "%d", comm_size);
140 setenv("YAC_IO_RANK_LIST", io_rank_list, 1);
141 setenv("YAC_IO_MAX_NUM_RANKS_PER_NODE", comm_size_str, 1);
142 free(io_rank_list);
143}
144
146 unsetenv("YAC_IO_RANK_LIST");
147 unsetenv("YAC_IO_MAX_NUM_RANKS");
148 unsetenv("YAC_IO_RANK_EXCLUDE_LIST");
149 unsetenv("YAC_IO_MAX_NUM_RANKS_PER_NODE");
150}
151
152static int check_indices(
153 size_t const * indices_a, size_t const * indices_b, size_t count) {
154
155 if (count == 0) return 1;
156
157 if (count == 1) return *indices_a == *indices_b;
158
159 size_t i;
160 for (i = 0; i < count; ++i) if (indices_a[i] == indices_b[0]) break;
161 if (i == count) return 0;
162
163 if (indices_a[(i+1)%count] == indices_b[1]) {
164
165 for (size_t j = 2; j < count; ++j)
166 if (indices_a[(i+j)%count] !=indices_b[j])
167 return 0;
168
169 } else if (indices_a[(i+1)%count] == indices_b[count - 1]) {
170
171 for (size_t j = 2; j < count; ++j)
172 if (indices_a[(i+j)%count] != indices_b[count - j])
173 return 0;
174
175 } else return 0;
176
177 return 1;
178}
179
181 struct yac_basic_grid_data grid_a, struct yac_basic_grid_data grid_b,
182 char const * grid_name) {
183
184 printf("testing grid: %s\n", grid_name);
185
186 if ((grid_a.num_cells != grid_b.num_cells) ||
187 (grid_a.num_total_cells != grid_b.num_total_cells))
188 PUT_ERR("error in grid.num_cells or grid.num_total_cells\n")
189 if ((grid_a.num_vertices != grid_b.num_vertices) ||
190 (grid_a.num_total_vertices != grid_b.num_total_vertices))
191 PUT_ERR("error in grid.num_vertices or grid.num_total_vertices\n")
192 if ((grid_a.num_edges != grid_b.num_edges) ||
193 (grid_a.num_total_edges != grid_b.num_total_edges))
194 PUT_ERR("error in grid.num_edges or grid.num_total_edges\n")
195
196 for (size_t i = 0; i < grid_a.num_cells; ++i)
197 if (grid_a.num_vertices_per_cell[i] != grid_b.num_vertices_per_cell[i])
198 PUT_ERR("error in grid.num_vertices_per_cell\n")
199
200 for (size_t i = 0; i < grid_a.num_vertices; ++i) {
201 if (grid_a.num_cells_per_vertex[i] != grid_b.num_cells_per_vertex[i])
202 PUT_ERR("error in grid.num_cells_per_vertex\n")
203
205 grid_a.vertex_coordinates[i],
207 PUT_ERR("error in grid.coordinates_xyz\n")
208 }
209
210 for (size_t i = 0, offset = 0; i < grid_a.num_cells; ++i) {
211
212 size_t num_vertices = grid_a.num_vertices_per_cell[i];
213
214 if ((grid_a.cell_to_vertex_offsets[i] !=
215 grid_b.cell_to_vertex_offsets[i]) ||
216 (grid_a.cell_to_vertex_offsets[i] != offset))
217 PUT_ERR("error in grid.cell_to_vertex_offsets\n")
218
219 if (!check_indices(grid_a.cell_to_vertex + offset,
220 grid_b.cell_to_vertex + offset, num_vertices))
221 PUT_ERR("error in grid.cell_to_vertex\n")
222
223 if ((grid_a.cell_to_edge_offsets[i] !=
224 grid_b.cell_to_edge_offsets[i]) ||
225 (grid_a.cell_to_edge_offsets[i] != offset))
226 PUT_ERR("error in grid.cell_to_edge_offsets\n")
227
228 if (!check_indices(grid_a.cell_to_edge + offset,
229 grid_b.cell_to_edge + offset, num_vertices))
230 PUT_ERR("error in grid.cell_to_edge\n")
231
232 offset += num_vertices;
233 }
234
235 for (size_t i = 0, offset = 0; i < grid_a.num_vertices; ++i) {
236
237 size_t num_cells = grid_a.num_cells_per_vertex[i];
238
239 if ((grid_a.vertex_to_cell_offsets[i] !=
240 grid_b.vertex_to_cell_offsets[i]) ||
241 (grid_a.vertex_to_cell_offsets[i] != offset))
242 PUT_ERR("error in grid.vertex_to_cell_offsets\n")
243
244 if (!check_indices(grid_a.vertex_to_cell + offset,
245 grid_b.vertex_to_cell + offset, num_cells))
246 PUT_ERR("error in grid.vertex_to_cell\n")
247
248 offset += num_cells;
249 }
250
251 for (size_t i = 0; i < grid_a.num_edges; ++i) {
252 if (!check_indices(grid_a.edge_to_vertex[i], grid_b.edge_to_vertex[i], 2))
253 PUT_ERR("error in grid.vertex_to_cell\n")
254 if (grid_a.edge_type[i] != grid_b.edge_type[i])
255 PUT_ERR("error in grid.edge_type");
256 }
257}
static void LLtoXYZ_deg(double lon, double lat, double p_out[])
Definition geometry.h:269
int yac_intersect_vec(enum yac_edge_type edge_type_a, double const a[3], double const b[3], enum yac_edge_type edge_type_b, double const c[3], double const d[3], double p[3], double q[3])
#define yac_angle_tol
Definition geometry.h:26
static double get_vector_angle(double const a[3], double const b[3])
Definition geometry.h:340
yac_edge_type
Definition grid_cell.h:12
#define xmalloc(size)
Definition ppm_xfuncs.h:66
yac_coordinate_pointer vertex_coordinates
size_t * vertex_to_cell_offsets
yac_size_t_2_pointer edge_to_vertex
enum yac_edge_type * edge_type
size_t * cell_to_vertex_offsets
size_t num_corners
Definition grid_cell.h:21
enum yac_edge_type * edge_type
Definition grid_cell.h:20
size_t array_size
Definition grid_cell.h:22
double(* coordinates_xyz)[3]
Definition grid_cell.h:19
struct yac_grid_cell generate_cell_rad(double *lon, double *lat, enum yac_edge_type *edge_type, size_t num_corners)
Definition test_common.c:42
void * to_pointer(void *data, size_t size_data)
static int check_indices(size_t const *indices_a, size_t const *indices_b, size_t count)
int double_are_unequal(double a, double b)
struct yac_grid_cell generate_cell_3d(yac_coordinate_pointer coords, enum yac_edge_type *edge_type, size_t num_corners)
Definition test_common.c:48
void clear_yac_io_env()
struct yac_grid_cell generate_cell_deg(double *lon, double *lat, enum yac_edge_type *edge_type, size_t num_corners)
Definition test_common.c:36
int intersect(enum yac_edge_type edge_type_a, double lon_a, double lat_a, double lon_b, double lat_b, enum yac_edge_type edge_type_b, double lon_c, double lat_c, double lon_d, double lat_d, double *intersection)
Definition test_common.c:64
void set_even_io_rank_list(MPI_Comm comm)
static struct yac_grid_cell generate_cell_func(double *lon, double *lat, enum yac_edge_type *edge_type, size_t num_corners, void(*fun_LLtoXYZ)(double, double, double[]))
Definition test_common.c:19
int double_are_equal(double a, double b)
void check_basic_grid_data(struct yac_basic_grid_data grid_a, struct yac_basic_grid_data grid_b, char const *grid_name)
double * data
size_t num_cells[2]
#define PUT_ERR(string)
Definition tests.h:10
double(* p)(double lon, double lat)
Definition toy_scrip.c:119
static void LLtoXYZ(double lon, double lat, double p_out[])
Definition toy_scrip.c:587
double(* yac_coordinate_pointer)[3]
Definition yac_types.h:19