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