YAC 3.12.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_point_selection.c
Go to the documentation of this file.
1// Copyright (c) 2025 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <mpi.h>
6#include <math.h>
7#include <string.h>
8
9#include "tests.h"
10#include "test_common.h"
11#include "point_selection.h"
12#include "geometry.h"
13
19#define YAC_RAD (0.01745329251994329576923690768489) // M_PI / 180
20
21static void utest_check_point_selection(
22 struct yac_point_selection * point_selection,
23 yac_const_coordinate_pointer point_coords, size_t * point_indices,
24 size_t num_points, size_t * ref_selected_points,
25 size_t ref_num_selected_points);
26static void utest_check_compare(
27 struct yac_point_selection * a, struct yac_point_selection * b);
28
29int main(void) {
30
31 MPI_Init(NULL, NULL);
32
33 int comm_rank, comm_size;
34 MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
35 MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
36
37 YAC_ASSERT(comm_size == 1, "ERROR wrong number of processes (has to be 1)")
38
39 enum {NLON = 36, NLAT = 19};
40 yac_coordinate_pointer point_coords =
41 malloc(NLON * NLAT * sizeof(*point_coords));
42 for (int i = 0, k = 0; i < NLAT; ++i)
43 for (int j = 0; j < NLON; ++j, ++k)
44 LLtoXYZ_deg((double)(10 * j), (double)(-90 + 10 * i), point_coords[k]);
45
46 { // trivial test with empty point selection
47
48 struct yac_point_selection * point_selection = NULL;
49
50 enum {NUM_POINTS = 100};
51 size_t point_indices[NUM_POINTS];
52 for (size_t i = 0; i < NUM_POINTS; ++i) point_indices[i] = i;
53 enum {REF_NUM_SELECTED_POINTS = 0};
54 size_t * ref_selected_points = NULL;
55
56 utest_check_point_selection(
57 point_selection, (yac_const_coordinate_pointer)point_coords,
58 point_indices, NUM_POINTS, ref_selected_points, REF_NUM_SELECTED_POINTS);
59
60 yac_point_selection_delete(point_selection);
61 }
62
63 { // testing bounding circle point selection
64 // * covers north pole
65
66 double center_lon = 0.0;
67 double center_lat = M_PI_2;
68 double inc_angle = 11.0 * YAC_RAD;
69
70 struct yac_point_selection * point_selection =
72
73 enum {NUM_POINTS = 3 * NLAT};
74 size_t point_indices[NUM_POINTS];
75 for (size_t i = 0, k = 0; i < 3; ++i)
76 for (size_t j = 0; j < NLAT; ++j, ++k)
77 point_indices[k] = i * 10 + j * NLON;
78 enum {REF_NUM_SELECTED_POINTS = 6};
79 size_t ref_selected_points[REF_NUM_SELECTED_POINTS] =
80 {(NLAT - 2) * NLON + 0 * 10, (NLAT - 1) * NLON + 0 * 10,
81 (NLAT - 2) * NLON + 1 * 10, (NLAT - 1) * NLON + 1 * 10,
82 (NLAT - 2) * NLON + 2 * 10, (NLAT - 1) * NLON + 2 * 10};
83
84 utest_check_point_selection(
85 point_selection, (yac_const_coordinate_pointer)point_coords,
86 point_indices, NUM_POINTS, ref_selected_points, REF_NUM_SELECTED_POINTS);
87
88 yac_point_selection_delete(point_selection);
89 }
90
91 { // check yac_point_selection_compare routine
92 struct yac_point_selection * point_selections[] = {
93 NULL,
101 enum {
102 NUM_POINT_SELECTIONS =
103 sizeof(point_selections)/sizeof(point_selections[0])
104 };
105
106 for (size_t i = 0; i < NUM_POINT_SELECTIONS; ++i) {
107 for (size_t j = i + 1; j < NUM_POINT_SELECTIONS; ++j)
108 utest_check_compare(point_selections[i], point_selections[j]);
109 yac_point_selection_delete(point_selections[i]);
110 }
111 }
112
113 free(point_coords);
114
115 MPI_Finalize();
116
117 return TEST_EXIT_CODE;
118}
119
120static inline int compare_size_t(const void * a, const void * b) {
121
122 size_t const * a_ = a, * b_ = b;
123
124 return (*a_ > *b_) - (*b_ > *a_);
125}
126
127static void utest_check_point_selection_(
128 struct yac_point_selection * point_selection,
129 yac_const_coordinate_pointer point_coords, size_t * point_indices,
130 size_t num_points, size_t * ref_sorted_points,
131 size_t * ref_sorted_selected_points, size_t ref_num_selected_points) {
132
133 size_t * point_indices_copy =
134 malloc(num_points * sizeof(*point_indices_copy));
135 memcpy(
136 point_indices_copy, point_indices, num_points * sizeof(*point_indices));
137 yac_coordinate_pointer selected_point_coords =
138 malloc(num_points * sizeof(*selected_point_coords));
139 for (size_t i = 0; i < num_points; ++i)
140 memcpy(
141 selected_point_coords[i], point_coords[point_indices[i]],
142 sizeof(*selected_point_coords));
143
144 size_t num_selected_points;
145
147 point_selection, selected_point_coords, point_indices_copy, num_points,
148 &num_selected_points);
149
150 if (num_selected_points == ref_num_selected_points) {
151
152 // check selected points that were moved to the end of the
153 // original list of points
154 qsort(
155 point_indices_copy + num_points - num_selected_points,
156 num_selected_points, sizeof(*point_indices_copy), compare_size_t);
157 for (size_t i = 0, j = num_points - num_selected_points;
158 i < num_selected_points; ++i, ++j)
159 if (point_indices_copy[j] != ref_sorted_selected_points[i])
160 PUT_ERR("error in selected point within original point list");
161
162 // check original list of points
163 qsort(
164 point_indices_copy, num_points, sizeof(*point_indices_copy),
166 for (size_t i = 0; i < num_points; ++i)
167 if (point_indices_copy[i] != ref_sorted_points[i])
168 PUT_ERR("error in original point list");
169
170 } else {
171 PUT_ERR("wrong number of selected points");
172 }
173
174 free(selected_point_coords);
175 free(point_indices_copy);
176}
177
178static void utest_check_point_selection(
179 struct yac_point_selection * point_selection,
180 yac_const_coordinate_pointer point_coords, size_t * point_indices,
181 size_t num_points, size_t * ref_selected_points,
182 size_t ref_num_selected_points) {
183
184 size_t * sorted_point_indices =
185 malloc(num_points * sizeof(*sorted_point_indices));
186 memcpy(
187 sorted_point_indices, point_indices, num_points * sizeof(*point_indices));
188 qsort(
189 sorted_point_indices, num_points, sizeof(*sorted_point_indices),
191 qsort(
192 ref_selected_points, ref_num_selected_points, sizeof(*ref_selected_points),
194
195 { // check original point selection
196 utest_check_point_selection_(
197 point_selection, point_coords, point_indices, num_points,
198 sorted_point_indices, ref_selected_points, ref_num_selected_points);
199 }
200
201 { // check point selection generated by yac_point_selection_copy
202 struct yac_point_selection * point_selection_copy =
203 yac_point_selection_copy(point_selection);
204 utest_check_point_selection_(
205 point_selection_copy, point_coords, point_indices, num_points,
206 sorted_point_indices, ref_selected_points, ref_num_selected_points);
207 yac_point_selection_delete(point_selection_copy);
208 }
209
210 { // check point selection that was packed and unpacked
211 size_t pack_size =
212 yac_point_selection_get_pack_size(point_selection, MPI_COMM_WORLD);
213 void * pack_buffer = malloc(pack_size);
214 int position = 0;
216 point_selection, pack_buffer, (int)pack_size, &position, MPI_COMM_WORLD);
217 position = 0;
218 struct yac_point_selection * point_selection_copy =
220 pack_buffer, (int)pack_size, &position, MPI_COMM_WORLD);
221 free(pack_buffer);
222 utest_check_point_selection_(
223 point_selection_copy, point_coords, point_indices, num_points,
224 sorted_point_indices, ref_selected_points, ref_num_selected_points);
225 yac_point_selection_delete(point_selection_copy);
226 }
227
228 free(sorted_point_indices);
229}
230
231static void utest_check_compare(
232 struct yac_point_selection * a, struct yac_point_selection * b) {
233
235 PUT_ERR("error in yac_point_selection_compare (a != a)")
238
239 int cmp_a = yac_point_selection_compare(a, b);
240 int cmp_b = yac_point_selection_compare(b, a);
241
242 if (cmp_a != -cmp_b)
243 PUT_ERR("error in yac_point_selection_compare (cmp_a != -cmp_b)")
244 if (!cmp_a) PUT_ERR("error in yac_point_selection_compare (cmp_a == 0)")
245 if (!cmp_b) PUT_ERR("error in yac_point_selection_compare (cmp_b == 0)")
246}
#define YAC_ASSERT(exp, msg)
static void LLtoXYZ_deg(double lon, double lat, double p_out[])
Definition geometry.h:269
int yac_point_selection_compare(struct yac_point_selection const *a, struct yac_point_selection const *b)
struct yac_point_selection * yac_point_selection_bnd_circle_new(double center_lon, double center_lat, double inc_angle)
struct yac_point_selection * yac_point_selection_unpack(void const *buffer, int buffer_size, int *position, MPI_Comm comm)
struct yac_point_selection * yac_point_selection_copy(struct yac_point_selection const *point_select)
void yac_point_selection_apply(struct yac_point_selection const *point_select, yac_coordinate_pointer point_coords, size_t *point_indices, size_t num_points, size_t *num_selected_points)
void yac_point_selection_pack(struct yac_point_selection const *point_select, void *buffer, int buffer_size, int *position, MPI_Comm comm)
size_t yac_point_selection_get_pack_size(struct yac_point_selection const *point_select, MPI_Comm comm)
void yac_point_selection_delete(struct yac_point_selection *point_select)
@ error
Definition test_cxc.c:17
static int compare_size_t(const void *a, const void *b)
#define YAC_RAD
#define TEST_EXIT_CODE
Definition tests.h:14
#define PUT_ERR(string)
Definition tests.h:10
static size_t num_points
Definition yac.c:159
double const (* yac_const_coordinate_pointer)[3]
Definition yac_types.h:20
double(* yac_coordinate_pointer)[3]
Definition yac_types.h:19