YAC 3.12.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_bnd_sphere_part.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 <stdlib.h>
6#include <stdio.h>
7#include <float.h>
8
9#include "tests.h"
10#include "test_common.h"
11#include "grids/basic_grid.h"
12#include "sphere_part.h"
13#include "geometry.h"
14
20static void utest_random_test(size_t count);
21static void utest_random_test_big(size_t count);
22static void utest_empty_test();
23static void utest_zero_balance_point();
24static void utest_mean_point_test();
25
26int main(void) {
27
28 srand(1365441);
29
30 for (size_t i = 0; i < 10; ++i) {
31 utest_random_test(1);
32 utest_random_test(10);
33 utest_random_test(100);
34 utest_random_test(650);
35 utest_random_test_big(50);
36 }
37 utest_empty_test();
38 utest_zero_balance_point();
39 utest_mean_point_test();
40
41 return TEST_EXIT_CODE;
42}
43
44static void gen_random_point(double * point) {
45
46 double x_coordinate = 2.0 * M_PI * (((double)rand()) / ((double)RAND_MAX));
47 double y_coordinate = M_PI * (((double)rand()) / ((double)RAND_MAX)) - M_PI_2;
48 LLtoXYZ(x_coordinate, y_coordinate, point);
49}
50
51static void gen_random_bnd_circle(struct bounding_circle * circle) {
52
54 double angle = M_PI_2 * (((double)rand()) / ((double)RAND_MAX));
55 circle->inc_angle = sin_cos_angle_new(sin(angle), cos(angle));
56 circle->sq_crd = DBL_MAX;
57}
58
59static void gen_random_bnd_circle_big(struct bounding_circle * circle) {
60
62 double angle = 3.0 * M_PI_2 * (((double)rand()) / ((double)RAND_MAX));
63 circle->inc_angle = sin_cos_angle_new(sin(angle), cos(angle));
64 circle->sq_crd = DBL_MAX;
65}
66
67static int compare_size_t(void const * a, void const * b) {
68 return
69 (*(size_t const *)a > *(size_t const *)b) -
70 (*(size_t const *)a < *(size_t const *)b);
71}
72
73static int check_results(
74 size_t * list, size_t list_size, size_t * sorted_indices, size_t count) {
75
76 qsort(list, list_size, sizeof(size_t), compare_size_t);
77
78 size_t match_count = 0;
79 for (size_t i = 0, j = 0; i < count; ++i) {
80 while ((j < list_size) && (list[j] < sorted_indices[i])) ++j;
81 if ((j < list_size) && (list[j] == sorted_indices[i])) ++match_count;
82 }
83 return match_count != count;
84}
85
86static void utest_random_test(size_t count) {
87
88 struct bounding_circle * bnd_circles =
89 xmalloc(2 * count * sizeof(*bnd_circles));
90 struct bounding_circle * bnd_circles_a = bnd_circles;
91 struct bounding_circle * bnd_circles_b = bnd_circles + count;
92 double (*point_coords)[3] = xmalloc(count * sizeof(*point_coords));
93
94 for (size_t i = 0; i < count; ++i) {
95
96 gen_random_bnd_circle(bnd_circles_a + i);
97 gen_random_bnd_circle(bnd_circles_b + i);
98 gen_random_point(point_coords[i]);
99 }
100
101 struct bnd_sphere_part_search * search =
102 yac_bnd_sphere_part_search_new(bnd_circles_a, count);
103
104 { // check yac_bnd_sphere_part_search_do_point_search
105 size_t * results;
106 size_t * num_results = xmalloc(count * sizeof(*num_results));
108 search, point_coords, count, &results, num_results);
109
110 size_t * ref_results = xmalloc(count * sizeof(*ref_results));
111 for (size_t i = 0, offset = 0; i < count; ++i) {
112 size_t ref_num_results = 0;
113 for (size_t j = 0; j < count; ++j)
115 point_coords[i], bnd_circles_a + j))
116 ref_results[ref_num_results++] = j;
117
118 if ((ref_num_results > num_results[i]) ||
120 results + offset, num_results[i], ref_results, ref_num_results))
121 PUT_ERR("ERROR in yac_bnd_sphere_part_search_do_point_search");
122
123 offset += num_results[i];
124 }
125 free(ref_results);
126 free(results);
127 free(num_results);
128 }
129
130 { // yac_bnd_sphere_part_search_do_bnd_circle_search
131 size_t * results;
132 size_t * num_results = xmalloc(count * sizeof(*num_results));
134 search, bnd_circles_b, count, &results, num_results);
135
136 size_t * ref_results = xmalloc(count * sizeof(*ref_results));
137 for (size_t i = 0, offset = 0; i < count; ++i) {
138 size_t ref_num_results = 0;
139 for (size_t j = 0; j < count; ++j)
141 bnd_circles_b + i, bnd_circles_a + j))
142 ref_results[ref_num_results++] = j;
143
144 if ((ref_num_results > num_results[i]) ||
146 results + offset, num_results[i], ref_results, ref_num_results))
147 PUT_ERR("ERROR in yac_bnd_sphere_part_search_do_bnd_circle_search");
148
149 offset += num_results[i];
150 }
151 free(ref_results);
152 free(results);
153 free(num_results);
154 }
155
157 free(point_coords);
158 free(bnd_circles);
159}
160
161static void utest_random_test_big(size_t count) {
162
163 struct bounding_circle * bnd_circles =
164 xmalloc(2 * count * sizeof(*bnd_circles));
165 struct bounding_circle * bnd_circles_a = bnd_circles;
166 struct bounding_circle * bnd_circles_b = bnd_circles + count;
167 double (*point_coords)[3] = xmalloc(count * sizeof(*point_coords));
168
169 for (size_t i = 0; i < count; ++i) {
170
171 gen_random_bnd_circle(bnd_circles_a + i);
172 gen_random_bnd_circle_big(bnd_circles_b + i);
173 gen_random_point(point_coords[i]);
174 }
175
176 struct bnd_sphere_part_search * search =
177 yac_bnd_sphere_part_search_new(bnd_circles_a, count);
178
179 { // yac_bnd_sphere_part_search_do_bnd_circle_search
180 size_t * results;
181 size_t * num_results = xmalloc(count * sizeof(*num_results));
183 search, bnd_circles_b, count, &results, num_results);
184
185 size_t * ref_results = xmalloc(count * sizeof(*ref_results));
186 for (size_t i = 0, offset = 0; i < count; ++i) {
187 size_t ref_num_results = 0;
188 for (size_t j = 0; j < count; ++j)
190 bnd_circles_b + i, bnd_circles_a + j))
191 ref_results[ref_num_results++] = j;
192
193 if ((ref_num_results > num_results[i]) ||
195 results + offset, num_results[i], ref_results, ref_num_results))
196 PUT_ERR("ERROR in yac_bnd_sphere_part_search_do_bnd_circle_search");
197
198 offset += num_results[i];
199 }
200 free(ref_results);
201 free(results);
202 free(num_results);
203 }
204
206 free(point_coords);
207 free(bnd_circles);
208}
209
210static void utest_empty_test() {
211
212 size_t count = 32;
213 struct bounding_circle * bnd_circles =
214 xmalloc(count * sizeof(*bnd_circles));
215 double (*point_coords)[3] = xmalloc(count * sizeof(*point_coords));
216
217 for (size_t i = 0; i < count; ++i) {
218
219 gen_random_bnd_circle(bnd_circles + i);
220 gen_random_point(point_coords[i]);
221 }
222
223 struct bnd_sphere_part_search * search =
225
226 { // check yac_bnd_sphere_part_search_do_point_search
227 size_t * results;
228 size_t * num_results = xmalloc(count * sizeof(*num_results));
230 search, point_coords, count, &results, num_results);
231
232 for (size_t i = 0; i < count; ++i)
233 if (num_results[i] != 0)
234 PUT_ERR("ERROR in yac_bnd_sphere_part_search_do_point_search");
235
236 free(results);
237 free(num_results);
238 }
239
240 { // yac_bnd_sphere_part_search_do_bnd_circle_search
241 size_t * results;
242 size_t * num_results = xmalloc(count * sizeof(*num_results));
244 search, bnd_circles, count, &results, num_results);
245
246 for (size_t i = 0; i < count; ++i)
247 if (num_results[i] != 0)
248 PUT_ERR("ERROR in yac_bnd_sphere_part_search_do_bnd_circle_search");
249
250 free(results);
251 free(num_results);
252 }
253
255 free(point_coords);
256 free(bnd_circles);
257}
258
259static void utest_zero_balance_point() {
260
261 struct bounding_circle utest_zero_balance_point_bnd_circles[6] =
262 {{.base_vector = {1,0,0}, .inc_angle = SIN_COS_ZERO, .sq_crd = DBL_MAX},
263 {.base_vector = {-1,0,0}, .inc_angle = SIN_COS_ZERO, .sq_crd = DBL_MAX},
264 {.base_vector = {0,1,0}, .inc_angle = SIN_COS_ZERO, .sq_crd = DBL_MAX},
265 {.base_vector = {0,-1,0}, .inc_angle = SIN_COS_ZERO, .sq_crd = DBL_MAX},
266 {.base_vector = {0,0,1}, .inc_angle = SIN_COS_ZERO, .sq_crd = DBL_MAX},
267 {.base_vector = {0,0,-1}, .inc_angle = SIN_COS_ZERO, .sq_crd = DBL_MAX}};
268
269 struct bnd_sphere_part_search * search =
271 utest_zero_balance_point_bnd_circles,
272 sizeof(utest_zero_balance_point_bnd_circles)/
273 sizeof(utest_zero_balance_point_bnd_circles[0]));
274
276}
277
278static void utest_mean_point_test() {
279
280 struct bounding_circle pole_balance_point_bnd_circles[5] =
281 {{.base_vector = {1,0,0}, .inc_angle = SIN_COS_M_PI_2, .sq_crd = DBL_MAX},
282 {.base_vector = {-1,0,0}, .inc_angle = SIN_COS_M_PI_2, .sq_crd = DBL_MAX},
283 {.base_vector = {0,1,0}, .inc_angle = SIN_COS_M_PI_2, .sq_crd = DBL_MAX},
284 {.base_vector = {0,-1,0}, .inc_angle = SIN_COS_M_PI_2, .sq_crd = DBL_MAX},
285 {.base_vector = {0,0,1}, .inc_angle = SIN_COS_M_PI_2, .sq_crd = DBL_MAX}};
286
287 double search_points[6][3] =
288 {{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};
289
290 struct bnd_sphere_part_search * search =
292 pole_balance_point_bnd_circles,
293 sizeof(pole_balance_point_bnd_circles)/
294 sizeof(pole_balance_point_bnd_circles[0]));
295
296 size_t num_points = sizeof(search_points)/sizeof(search_points[0]);
297 size_t * results;
298 size_t num_results[num_points];
300 search, search_points, num_points, &results, num_results);
301
302 size_t ref_results[6][5] =
303 {{0,2,3,4},{1,2,3,4},{0,1,3,4},{0,1,2,4},{0,1,2,3,4},{0,1,2,3}};
304 size_t ref_num_results[6] = {4,4,4,4,5,4};
305
306 for (size_t i = 0, offset = 0; i < num_points; offset += num_results[i++])
307 if ((ref_num_results[i] > num_results[i]) ||
309 results + offset, num_results[i], ref_results[i], ref_num_results[i]))
310 PUT_ERR("ERROR in yac_bnd_sphere_part_search_do_point_search");
311
312 free(results);
314}
int yac_extents_overlap(struct bounding_circle *extent_a, struct bounding_circle *extent_b)
Definition bnd_circle.c:533
static const struct sin_cos_angle SIN_COS_ZERO
Definition geometry.h:36
static int yac_point_in_bounding_circle_vec(double point_vector[3], struct bounding_circle *bnd_circle)
Definition geometry.h:197
static const struct sin_cos_angle SIN_COS_M_PI_2
Definition geometry.h:40
static struct sin_cos_angle sin_cos_angle_new(double sin, double cos)
Definition geometry.h:351
#define xmalloc(size)
Definition ppm_xfuncs.h:66
void yac_bnd_sphere_part_search_do_bnd_circle_search(struct bnd_sphere_part_search *search, struct bounding_circle *bnd_circles, size_t count, size_t **cells, size_t *num_cells_per_bnd_circle)
struct bnd_sphere_part_search * yac_bnd_sphere_part_search_new(struct bounding_circle *circles, size_t num_circles)
void yac_bnd_sphere_part_search_delete(struct bnd_sphere_part_search *search)
void yac_bnd_sphere_part_search_do_point_search(struct bnd_sphere_part_search *search, yac_coordinate_pointer coordinates_xyz, size_t count, size_t **cells, size_t *num_cells_per_coordinate)
algorithm for searching cells and points on a grid
struct sin_cos_angle inc_angle
angle between the middle point and the boundary of the spherical cap
Definition geometry.h:53
double base_vector[3]
Definition geometry.h:51
double sq_crd
Definition geometry.h:56
static int compare_size_t(void const *a, void const *b)
static void gen_random_bnd_circle(struct bounding_circle *circle)
static void gen_random_point(double *point)
static int check_results(size_t *list, size_t list_size, size_t *sorted_indices, size_t count)
static void gen_random_bnd_circle_big(struct bounding_circle *circle)
#define TEST_EXIT_CODE
Definition tests.h:14
#define PUT_ERR(string)
Definition tests.h:10
static void LLtoXYZ(double lon, double lat, double p_out[])
Definition toy_scrip.c:587
static size_t num_points
Definition yac.c:159