21#define TEST_GROUP_START() \
22 {++test_major_idx; test_minor_idx = 0;}
23#define TEST_START(DESC) \
26 printf("%d.%d) %s\n", test_major_idx, test_minor_idx, (DESC)); \
31 unsigned num_ref_cells);
35static void utest_check_weight_correction(
36 double * weights,
size_t count,
double *
ref_weights);
51 int test_major_idx = 0, test_minor_idx;
54 TEST_START(
"clipping with an empty source cell");
60 (
double[]){-0.5, 0.0, 0.7, 0.0},
gc_edges, 4);
62 if (utest_compare_cells(overlap_cell[0], SourceCells[0]))
63 PUT_ERR(
"ERROR: wrong clipping cell\n");
70 TEST_START(
"Simple test case with two quadrangle");
99 double intersection[3], intersection_lon, intersection_lat;
104 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
112 (
double[]){-0.5, 0.0, 0.7, 0.0},
gc_edges, 4),
114 (
double[]){0.6, 0.0, -0.6, 0.0},
gc_edges, 4)},
117 generate_cell_deg((
double[]){0.0, intersection_lon, 0.5, 0.0, -0.5, -intersection_lon},
118 (
double[]){0.6, intersection_lat, 0.0, -0.5, 0.0, intersection_lat},
gc_edges, 6)},
124 TEST_START(
"Simple test case with one quadrangle and one triangle");
151 double intersection[3], intersection_lon, intersection_lat;
155 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
163 (
double[]){-0.5,0.0,0.7,0.0},
gc_edges, 4),
165 (
double[]){0.0,0.6,0.0},
gc_edges, 3)},
169 (
double[]){0.6,intersection_lat,0.0,0.0,intersection_lat},
gc_edges, 5)},
174 TEST_START(
"Simple test case with one quadrangle and one triangle");
201 double intersection[2][3], intersection_lon[2], intersection_lat[2];
209 for (
int i = 0;
i < 2; ++
i) {
210 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
219 (
double[]){-0.5,0.0,0.7,0.0},
gc_edges, 4),
221 (
double[]){0.1,0.6,0.1},
gc_edges, 3)},
225 (
double[]){0.1,intersection_lat[0],intersection_lat[1]},
gc_edges, 3)},
230 TEST_START(
"Simple test case with one quadrangle and one triangle");
257 double intersection[2][3], intersection_lon[2], intersection_lat[2];
265 for (
int i = 0;
i < 2; ++
i) {
266 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
275 (
double[]){-0.5,0.0,0.7,0.0},
gc_edges, 4),
277 (
double[]){0.1,0.6,0.1},
gc_edges, 3)},
280 generate_cell_deg((
double[]){0.0,intersection_lon[0],intersection_lon[1],-intersection_lon[1],-intersection_lon[0]},
281 (
double[]){0.6,intersection_lat[0],intersection_lat[1],intersection_lat[1],intersection_lat[0]},
gc_edges, 5)},
287 TEST_START(
"Two source cells overlapping one target cell");
323 double intersection[3], intersection_lon, intersection_lat;
327 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
333 (
double[]){0.5,intersection_lat,0.0,0.0,intersection_lat},
336 (
double[]){-0.5,-intersection_lat,0.0,0.0,-intersection_lat},
339 for (
int src_order_a = -1; src_order_a <= 1; src_order_a += 2) {
340 for (
int src_order_b = -1; src_order_b <= 1; src_order_b += 2) {
341 for (
int tgt_order = -1; tgt_order <= 1; tgt_order += 2) {
342 for (
int src_start_a = 0; src_start_a < 3; ++src_start_a) {
343 for (
int src_start_b = 0; src_start_b < 3; ++src_start_b) {
344 for (
int tgt_start = 0; tgt_start < 4; ++tgt_start) {
348 (
double[]){0.0,0.5,0.0},
gc_edges, 3),
350 (
double[]){0.0,0.0,-0.5},
gc_edges, 3)};
353 (
double[]){0.0,0.7,0.0,-0.7},
gc_edges, 4);
356 if (utest_compare_cells(overlap_cell[0], ref_cells[0]) ||
357 utest_compare_cells(overlap_cell[1], ref_cells[1]))
358 PUT_ERR(
"ERROR: wrong clipping cell\n");
410 (
double[]){0.5,0.0,0.0},
gc_edges, 3),
412 (
double[]){-0.5,0.0,0.0},
gc_edges, 3)};
414 for (
int src_order_a = -1; src_order_a <= 1; src_order_a += 2) {
415 for (
int src_order_b = -1; src_order_b <= 1; src_order_b += 2) {
416 for (
int tgt_order = -1; tgt_order <= 1; tgt_order += 2) {
417 for (
int src_start_a = 0; src_start_a < 3; ++src_start_a) {
418 for (
int src_start_b = 0; src_start_b < 3; ++src_start_b) {
419 for (
int tgt_start = 0; tgt_start < 4; ++tgt_start) {
423 (
double[]){0.0,0.5,0.0},
gc_edges, 3),
425 (
double[]){0.0,0.0,-0.5},
gc_edges, 3)};
428 (
double[]){0.5,0.0,-0.5,0.0},
gc_edges, 4);
431 if (utest_compare_cells(overlap_cell[0], ref_cells[0]) ||
432 utest_compare_cells(overlap_cell[1], ref_cells[1]))
433 PUT_ERR(
"ERROR: wrong clipping cell\n");
484 (
double[]){0.5,0.0,-0.5,0.0},
gc_edges, 4),
486 (
double[]){0.5,0.0,-0.5,0.0},
gc_edges, 4)},
490 (
double[]){0.5,0.0,-0.5,0.0},
gc_edges, 4)},
495 TEST_START(
"Simple cases: source inside target cell");
530 (
double[]){0.4,0.0,-0.4,0.0},
gc_edges, 4),
532 (
double[]){0.5,0.0,-0.5,0.0},
gc_edges, 4)},
536 (
double[]){0.4,0.0,-0.4,0.0},
gc_edges, 4)},
541 TEST_START(
"Simple cases: target inside source cell");
576 (
double[]){0.6,0.0,-0.6,0.0},
gc_edges, 4),
578 (
double[]){0.5,0.0,-0.5,0.0},
gc_edges, 4)},
582 (
double[]){0.5,0.0,-0.5,0.0},
gc_edges, 4)},
621 (
double[]){0.5,0.0,0.0,0.5},
gc_edges, 4),
623 (
double[]){0.5,0.0,-0.5,0.0},
gc_edges, 4)},
655 double intersection[4][3], intersection_lon[4], intersection_lat[4];
669 for (
int i = 0;
i < 4; ++
i) {
670 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
679 (
double[]){-22.5,-22.5,0.0,0.0},
gc_edges, 4),
681 (
double[]){-7.2167,-19.2921,-26.5650},
gc_edges, 3)},
688 intersection_lon[3]},
693 intersection_lat[3]},
gc_edges, 5)},
721 double intersection[4][3], intersection_lon[4], intersection_lat[4];
735 for (
int i = 0;
i < 4; ++
i) {
736 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
745 (
double[]){-0.5,-0.5,0.5,0.5},
gc_edges, 4),
747 (
double[]){0.0,0.0,-0.75},
gc_edges, 3)},
754 intersection_lon[3]},
759 intersection_lat[3]},
gc_edges, 5)},
765 TEST_START(
"Special case in which no corner on any square is within the other");
790 double intersection[3], intersection_lon[8], intersection_lat[8];
791 double src_data[2][4] = {{-0.5,-0.5, 0.5, 0.5},
792 { 0.5,-0.5,-0.5, 0.5}};
793 double tgt_data[2][4] = {{ 0.0,-0.7, 0.0, 0.7},
794 { 0.7, 0.0,-0.7, 0.0}};
796 for (
int i = 0;
i < 8; ++
i) {
799 src_data[0][(i/2+1)%4],
800 src_data[1][(i/2+1)%4],
802 tgt_data[1][((i+1)/2)%4],
803 tgt_data[0][((i+1)/2+1)%4],
804 tgt_data[1][((i+1)/2+1)%4], intersection))
806 XYZtoLL(intersection, &intersection_lon[i], &intersection_lat[i]);
815 (
double[]){-0.5,-0.5,0.5,0.5},
gc_edges, 4),
817 (
double[]){-0.7,0.0,0.7,0.0},
gc_edges, 4)},
852 (
double[]){0.0,0.0,1.0,1.0},
gc_edges, 4),
854 (
double[]){0.0,0.0,1.0,1.0},
gc_edges, 4)},
887 (
double[]){0.0,0.0,1.0,1.0},
gc_edges, 4),
889 (
double[]){2.0,2.0,3.0,3.0},
gc_edges, 4)},
919 double intersection[2][3], intersection_lon[2], intersection_lat[2];
927 for (
int i = 0;
i < 2; ++
i) {
928 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
937 (
double[]){0.5,0.5,-0.5},
gc_edges, 3),
939 (
double[]){-1.0,-1.0,1.0,1.0},
gc_edges, 4)},
945 -intersection_lon[1],
946 -intersection_lon[0]},
951 intersection_lat[0]},
gc_edges, 5)},
957 TEST_START(
"touching edges of two triangles");
982 (
double[]){0.0,0.0,1.0},
gc_edges, 3),
984 (
double[]){0.0,0.0,-0.5},
gc_edges, 3)},
998 (
double[]){ 65.0, 65.0, 90.0},
gc_edges, 3),
1000 (
double[]){ 70.0, 70.0, 90.0},
gc_edges, 3)},
1009 TEST_START(
"test from test_interpolation_method_conserv.x");
1030 utest_test_clipping(
1045 TEST_START(
"test from test_interpolation_method_conserv.x");
1066 utest_test_clipping(
1104 double intersection[3], intersection_lon, intersection_lat;
1108 return EXIT_FAILURE;
1109 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1113 utest_test_clipping(
1119 (
double[]){ 39.0,22.0,39.0},
gc_edges, 3)},
1123 (
double[]){intersection_lat,intersection_lat},
1127 (
double[]){intersection_lat,intersection_lat},
1156 double intersection[3], intersection_lon, intersection_lat;
1160 return EXIT_FAILURE;
1161 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1165 utest_test_clipping(
1171 (
double[]){ 40.0,22.0,39.0},
gc_edges, 3)},
1175 (
double[]){ 40.0,intersection_lat},
1179 (
double[]){ 40.0,intersection_lat},
1208 double intersection[2][3], intersection_lon[2], intersection_lat[2];
1212 return EXIT_FAILURE;
1215 return EXIT_FAILURE;
1216 for (
int i = 0;
i < 2; ++
i) {
1217 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1222 utest_test_clipping(
1228 (
double[]){ 59.0,80.0,59.0},
gc_edges, 3)},
1232 fabs(intersection_lon[1]),
1233 -fabs(intersection_lon[1]),
1234 -intersection_lon[0],-19.0},
1235 (
double[]){59.0,60.0,60.0,60.0,60.0,59.0},
1239 generate_cell_deg((
double[]){19.0,intersection_lon[0],-intersection_lon[0],-19.0,-fabs(intersection_lon[1]),fabs(intersection_lon[1])},
1240 (
double[]){59.0,60.0,60.0,59.0,60.0,60.0},
1271 double intersection[2][3], intersection_lon[2], intersection_lat[2];
1275 return EXIT_FAILURE;
1278 return EXIT_FAILURE;
1279 for (
int i = 0;
i < 2; ++
i) {
1280 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1285 utest_test_clipping(
1291 (
double[]){ 60.0,80.0,59.0},
gc_edges, 3)},
1295 (
double[]){60.0,intersection_lat[0],intersection_lat[1]},
1298 generate_cell_deg((
double[]){20.0,intersection_lon[0],-20.0,intersection_lon[1]},
1299 (
double[]){60.0,intersection_lat[0], 60.0,intersection_lat[1]},
1330 double intersection[3][3], intersection_lon[3], intersection_lat[3];
1334 return EXIT_FAILURE;
1337 return EXIT_FAILURE;
1340 return EXIT_FAILURE;
1341 for (
int i = 0;
i < 3; ++
i) {
1342 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1347 utest_test_clipping(
1353 (
double[]){ 60.0,40.0,59.0},
gc_edges, 3)},
1356 generate_cell_deg((
double[]){intersection_lon[0],intersection_lon[1],intersection_lon[2],-20.0},
1357 (
double[]){intersection_lat[0],intersection_lat[1],intersection_lat[2], 60.0},
1386 double intersection[3], intersection_lon, intersection_lat;
1390 return EXIT_FAILURE;
1391 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1395 utest_test_clipping(
1399 intersection_lon+40.0,intersection_lon},
1402 (
double[]){ 39.0,39.0,20.0},
gc_edges, 3)},
1406 (
double[]){40.0,40.0},
1410 (
double[]){40.0,40.0},
1439 double intersection[3][3], intersection_lon[3], intersection_lat[3];
1443 return EXIT_FAILURE;
1446 return EXIT_FAILURE;
1447 for (
int i = 0;
i < 2; ++
i) {
1448 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1454 intersection_lon[0],60.0, intersection[2]))
1455 return EXIT_FAILURE;
1456 XYZtoLL(intersection[2], &intersection_lon[2], &intersection_lat[2]);
1457 intersection_lon[2] /=
YAC_RAD;
1458 intersection_lat[2] /=
YAC_RAD;
1460 utest_test_clipping(
1464 intersection_lon[0]+40.0,
1465 intersection_lon[0]+40.0,
1466 intersection_lon[0]},
1469 (
double[]){ 39.0,39.0, 50.0},
gc_edges, 3)},
1473 intersection_lon[1],intersection_lon[2]},
1474 (
double[]){40.0,40.0,40.0,intersection_lat[2]},
1504 utest_test_clipping(
1510 (
double[]){ 40.0,20.0,40.0},
gc_edges, 3)},
1514 (
double[]){ 40.0,40.0},
1518 (
double[]){ 40.0,40.0},
1547 utest_test_clipping(
1553 (
double[]){ 40.0,50.0,40.0},
gc_edges, 3)},
1557 (
double[]){40.0,40.0,50.0},
1586 utest_test_clipping(
1592 (
double[]){ 60.0,50.0,60.0},
gc_edges, 3)},
1596 (
double[]){60.0,60.0,50.0},
1625 utest_test_clipping(
1631 (
double[]){ 60.0,70.0,60.0},
gc_edges, 3)},
1635 (
double[]){60.0,60.0},
1639 (
double[]){60.0,60.0},
1668 utest_test_clipping(
1674 (
double[]){-40.0,-50.0,-40.0},
gc_edges, 3)},
1678 (
double[]){-40.0,-40.0,-50.0},
gc_edges, 3)},
1705 double intersection[3], intersection_lon, intersection_lat;
1709 return EXIT_FAILURE;
1710 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1714 utest_test_clipping(
1720 (
double[]){59.0,45.0,60.0},
gc_edges, 3)},
1724 (
double[]){intersection_lat,60.0,45.0,59.0},
1751 double intersection[2][3], intersection_lon[2], intersection_lat[2];
1755 return EXIT_FAILURE;
1758 return EXIT_FAILURE;
1759 for (
int i = 0;
i < 2; ++
i) {
1760 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1765 utest_test_clipping(
1771 (
double[]){58.5,40.0,58.5},
gc_edges, 3)},
1775 intersection_lon[1],
1776 -intersection_lon[1],
1777 -intersection_lon[0]},
1778 (
double[]){59.0,60.0,60.0,59.0},
1808 double intersection[2][3], intersection_lon[2], intersection_lat[2];
1812 return EXIT_FAILURE;
1815 return EXIT_FAILURE;
1816 for (
int i = 0;
i < 2; ++
i) {
1817 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1822 utest_test_clipping(
1828 (
double[]){59.0,80.0,59.0},
gc_edges, 3)},
1832 fabs(intersection_lon[1]),
1833 -fabs(intersection_lon[1]),
1834 -intersection_lon[0],-20.0},
1835 (
double[]){59.0,60.0,60.0,60.0,60.0,59.0},
1840 -intersection_lon[0],-20.0,
1841 -fabs(intersection_lon[1]),
1842 fabs(intersection_lon[1])},
1843 (
double[]){59.0,60.0,60.0,59.0,60.0,60.0},
1873 double intersection[3], intersection_lon, intersection_lat;
1877 return EXIT_FAILURE;
1878 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1882 utest_test_clipping(
1888 (
double[]){59.0,50.0,59.0},
gc_edges, 3)},
1893 (
double[]){60.0,60.0,59.0,50.0,59.0},
1923 double intersection[3], intersection_lon, intersection_lat;
1927 return EXIT_FAILURE;
1928 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1932 utest_test_clipping(
1938 (
double[]){ 19.0,-19.0,-19.0,19.0},
gc_edges, 4)},
1942 -intersection_lon,19.0,19.0,
1943 -intersection_lon,intersection_lon,-19.0},
1944 (
double[]){19.0,20.0,20.0,19.0,
1945 -19.0,-20.0,-20.0,-19.0},
1976 double intersection[3], intersection_lon, intersection_lat;
1980 return EXIT_FAILURE;
1981 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1985 utest_test_clipping(
1991 (
double[]){ 45.0,45.0,55.0},
gc_edges, 3)},
1995 (
double[]){intersection_lat,55.0,45.0},
2025 utest_test_clipping(
2031 (
double[]){ 40.0,30.0,50.0},
gc_edges, 3)},
2035 (
double[]){40.0,50.0,40.0},
2065 double intersection[2][3], intersection_lon[2], intersection_lat[2];
2069 return EXIT_FAILURE;
2072 return EXIT_FAILURE;
2073 for (
int i = 0;
i < 2; ++
i) {
2074 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2079 utest_test_clipping(
2085 (
double[]){61.0,80.0,59.0},
gc_edges, 3)},
2089 intersection_lon[1]},
2090 (
double[]){60.0,intersection_lat[0],
2091 intersection_lat[1]},
2120 double intersection[2][3], intersection_lon[2], intersection_lat[2];
2124 return EXIT_FAILURE;
2125 XYZtoLL(intersection[0], &intersection_lon[0], &intersection_lat[0]);
2126 intersection_lon[0] /=
YAC_RAD;
2127 intersection_lat[0] /=
YAC_RAD;
2130 return EXIT_FAILURE;
2131 XYZtoLL(intersection[1], &intersection_lon[1], &intersection_lat[1]);
2132 intersection_lon[1] /=
YAC_RAD;
2133 intersection_lat[1] /=
YAC_RAD;
2135 utest_test_clipping(
2141 (
double[]){30.0,30.0,intersection_lat[0]},
2146 -intersection_lon[1]},
2147 (
double[]){intersection_lat[0],40.0,40.0},
2176 double intersection[4][3], intersection_lon[4], intersection_lat[4];
2180 return EXIT_FAILURE;
2183 return EXIT_FAILURE;
2186 return EXIT_FAILURE;
2189 return EXIT_FAILURE;
2190 for (
int i = 0;
i < 4; ++
i) {
2191 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2196 utest_test_clipping(
2202 (
double[]){59.0,70.0,59.0},
gc_edges, 3)},
2206 intersection_lon[3],-intersection_lon[3],
2207 -intersection_lon[2],-20.0,-20.0},
2208 (
double[]){intersection_lat[0],intersection_lat[1],
2209 60.0,60.0,60.0,60.0,intersection_lat[1],
2210 intersection_lat[0]},
2216 intersection_lon[3],-intersection_lon[3],
2217 -intersection_lon[2],-20.0,-20.0,
2218 -intersection_lon[3],intersection_lon[3]},
2219 (
double[]){intersection_lat[0],intersection_lat[1],
2220 60.0,60.0,60.0,60.0,intersection_lat[1],
2221 intersection_lat[0],60.0,60.0},
2228 -intersection_lon[2],-20.0,-20.0,
2229 -intersection_lon[3],intersection_lon[3]},
2230 (
double[]){intersection_lat[0],intersection_lat[1],
2231 60.0,60.0,intersection_lat[1],
2232 intersection_lat[0],60.0,60.0},
2264 double intersection[3][3], intersection_lon[3], intersection_lat[3];
2268 return EXIT_FAILURE;
2271 return EXIT_FAILURE;
2272 for (
int i = 0;
i < 2; ++
i) {
2273 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2279 40.0, intersection[2]))
2280 return EXIT_FAILURE;
2281 XYZtoLL(intersection[2], &intersection_lon[2], &intersection_lat[2]);
2282 intersection_lon[2] /=
YAC_RAD;
2283 intersection_lat[2] /=
YAC_RAD;
2285 utest_test_clipping(
2289 intersection_lon[0],-intersection_lon[0]},
2292 (
double[]){59.0,70.0,59.0},
gc_edges, 3)},
2296 intersection_lon[1],-intersection_lon[1],
2297 -intersection_lon[0],-intersection_lon[2]},
2298 (
double[]){intersection_lat[2],60.0,60.0,60.0,60.0,
2299 intersection_lat[2]},
2304 intersection_lon[1],-intersection_lon[1],
2305 -intersection_lon[0],-intersection_lon[2],
2306 -intersection_lon[1],intersection_lon[1]},
2307 (
double[]){intersection_lat[2],60.0,60.0,60.0,60.0,
2308 intersection_lat[2],60.0,60.0},
2314 -intersection_lon[0],-intersection_lon[2],
2315 -intersection_lon[1],intersection_lon[1]},
2316 (
double[]){intersection_lat[2],60.0,60.0,
2317 intersection_lat[2],60.0,60.0},
2347 double intersection[3][3], intersection_lon[3], intersection_lat[3];
2351 return EXIT_FAILURE;
2354 return EXIT_FAILURE;
2358 return EXIT_FAILURE;
2359 for (
int i = 0;
i < 3; ++
i) {
2360 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2365 utest_test_clipping(
2371 (
double[]){59.0,50.0,59.0},
gc_edges, 3)},
2375 -20.0,-intersection_lon[0]},
2376 (
double[]){60.0,intersection_lat[1],
2377 intersection_lat[2],50.0,
2378 intersection_lat[2],intersection_lat[1],
2408 utest_test_clipping(
2412 (
double[]){ 85.0,85.0,85.0,85.0,85.0},
2417 (
double[]){ 80.0,80.0,80.0,80.0,80.0},
2424 (
double[]){ 85.0,85.0,85.0,85.0,85.0},
2453 utest_test_clipping(
2457 (
double[]){ 85.0,85.0,85.0,85.0,85.0},
2462 (
double[]){ 85.0,85.0,85.0,85.0,85.0},
2469 (
double[]){ 85.0,85.0,85.0,85.0,85.0},
2498 utest_test_clipping(
2502 (
double[]){ 85.0,85.0,85.0,85.0,85.0},
2507 (
double[]){-85.0,-85.0,-85.0,-85.0,-85.0},
2541 utest_test_clipping(
2545 (
double[]){ 85.0,85.0,85.0,85.0,85.0},
2550 (
double[]){ 85.0,85.0,85.0,85.0,85.0,85.0},
2557 (
double[]){ 85.0,85.0,85.0,85.0,85.0,85.0},
2588 double intersection[2][3], intersection_lon[2], intersection_lat[2];
2592 return EXIT_FAILURE;
2595 return EXIT_FAILURE;
2596 for (
int i = 0;
i < 2; ++
i) {
2597 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2602 utest_test_clipping(
2606 (
double[]){ 85.5,85.5,85.5,85.5,85.5},
2611 (
double[]){ 85.0,85.0,85.0,85.0,85.0,85.0},
2619 intersection_lon[1]+60.0*0.0,
2620 intersection_lon[0]+60.0*1.0,
2621 intersection_lon[1]+60.0*1.0,
2622 intersection_lon[0]+60.0*2.0,
2623 intersection_lon[1]+60.0*2.0,
2624 intersection_lon[0]+60.0*3.0,
2625 intersection_lon[1]+60.0*3.0,
2626 intersection_lon[0]+60.0*4.0,
2627 intersection_lon[1]+60.0*4.0,
2628 intersection_lon[0]+60.0*5.0,
2629 intersection_lon[1]+60.0*5.0},
2630 (
double[]){85.5,85.5,85.5,85.5,85.5,85.5,85.5,85.5,
2631 85.5,85.5,85.5,85.5},
2645 TEST_START(
"example taken from bug report by Uwe");
2668 utest_test_clipping(
2672 (
double[]){ 0.0, 0.0, 5.0, 5.0},
gc_edges, 4),
2674 (
double[]){-10.0,-10.0, 0.0, 0.0},
gc_edges, 4)},
2706 utest_test_clipping(
2710 (
double[]){-1.0,1.0,1.0},
gc_edges, 3),
2723 double intersection[3], intersection_lon, intersection_lat;
2727 return EXIT_FAILURE;
2728 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
2732 utest_test_clipping(
2736 (
double[]){85.0,90.0,85.0},
gc_edges, 3),
2742 (
double[]){intersection_lat,85.0,90.0},
2753 double intersection[4][3], intersection_lon[4], intersection_lat[4];
2756 0.49087385212340517437,-0.88357293382212931387,
2758 0.46519399935013672209,-0.88122392525212978054,
2760 return EXIT_FAILURE;
2762 0.46633015951723494341,-0.85902924121595902740,
2764 0.46519399935013672209,-0.88122392525212978054,
2766 return EXIT_FAILURE;
2768 0.46633015951723494341,-0.85902924121595902740,
2770 0.46519399935013672209,-0.88122392525212978054,
2772 return EXIT_FAILURE;
2774 0.49087385212340517437,-0.85902924121595902740,
2776 0.46519399935013672209,-0.88122392525212978054,
2778 return EXIT_FAILURE;
2779 for (
int i = 0;
i < 4; ++
i) {
2780 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2785 utest_test_clipping(
2789 0.49087385212340517437,
2790 0.49087385212340517437,
2791 0.46633015951723494341},
2792 (
double[]){-0.88357293382212931387,
2793 -0.88357293382212931387,
2794 -0.85902924121595902740,
2797 0.50100250912415544846,
2798 0.46519399935013672209},
2799 (
double[]){-0.90109638077934106626,
2800 -0.88440597750634275531,
2801 -0.88122392525212978054},
gc_edges, 3)},
2805 intersection_lon[0],
2806 0.46633015951723494341,
2807 0.46633015951723494341,
2808 0.49087385212340517437},
2809 (
double[]){-0.88357293382212931387,
2810 intersection_lat[0],
2811 intersection_lat[1],
2812 intersection_lat[2],
2813 intersection_lat[3]},
2825 double intersection[4][3], intersection_lon[4], intersection_lat[4];
2829 return EXIT_FAILURE;
2832 return EXIT_FAILURE;
2835 return EXIT_FAILURE;
2838 return EXIT_FAILURE;
2839 for (
int i = 0;
i < 4; ++
i) {
2840 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2845 utest_test_clipping(
2849 (
double[]){-89.6,-89.6,-89.5,-89.5},
gc_edges, 4),
2851 (
double[]){-89.75,-89.75,-89.50,-89.50},
gc_edges, 4)},
2855 intersection_lon[2],180.20},
2856 (
double[]){-89.6,intersection_lat[0],
2857 intersection_lat[1],intersection_lat[2],
2858 intersection_lat[3]},
gc_edges, 5)},
2866 double intersection[2][3], intersection_lon[2], intersection_lat[2];
2875 -0.76075226373764/
YAC_RAD, intersection[0]))
2876 return EXIT_FAILURE;
2884 -0.82925269516665/
YAC_RAD, intersection[1]))
2885 return EXIT_FAILURE;
2886 for (
int i = 0;
i < 2; ++
i) {
2887 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2892 utest_test_clipping(
2900 (
double[]){-0.76085447079128/
YAC_RAD,
2908 (
double[]){-0.76075226373764/
YAC_RAD,
2914 intersection_lon[0], intersection_lon[1]},
2915 (
double[]){-0.76075226373764/
YAC_RAD,
2916 intersection_lat[0], intersection_lat[1]},
2920 intersection_lon[0],
2922 intersection_lon[1]},
2923 (
double[]){-0.76075226373764/
YAC_RAD,
2924 intersection_lat[0],
2926 intersection_lat[1]},
2934 TEST_START(
"example in which all coordinates are 0 (occurred in a test"
2935 " of Uwe due to erroneous input data)")
2937 utest_test_clipping(
2944 (
double[]){0, 0, 0},
gc_edges, 3)},
2952 TEST_START(
"example example take from ICON_toy");
2954 utest_test_clipping(
2961 (
double[]){-1.5418135425481947/
YAC_RAD,
2969 (
double[]){-1.5707963267948966/
YAC_RAD,
2983 double intersection[2][3], intersection_lon[2], intersection_lat[2];
2994 return EXIT_FAILURE;
3004 return EXIT_FAILURE;
3005 for (
int i = 0;
i < 2; ++
i) {
3006 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3011 utest_test_clipping(
3018 (
double[]){-1.5418135425481947/
YAC_RAD,
3025 (
double[]){-1.5462526341887264/
YAC_RAD,
3033 intersection_lon[0],
3035 intersection_lon[1]},
3036 (
double[]){-1.5462526341887264/
YAC_RAD,
3037 intersection_lat[0],
3039 intersection_lat[1]},
3048 TEST_START(
"example example take from ICON_toy");
3050 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3061 return EXIT_FAILURE;
3071 return EXIT_FAILURE;
3072 for (
int i = 0;
i < 2; ++
i) {
3073 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3078 utest_test_clipping(
3084 (
double[]){ 1.5418206553283160/
YAC_RAD,
3091 (
double[]){ 1.5462526341887264/
YAC_RAD,
3099 (
double[]){90.0,intersection_lat[0],
3100 intersection_lat[1]},
3107 TEST_START(
"example example take from ICON_toy");
3109 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3120 return EXIT_FAILURE;
3130 return EXIT_FAILURE;
3131 for (
int i = 0;
i < 2; ++
i) {
3132 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3137 utest_test_clipping(
3144 (
double[]){-0.0311624518327736/
YAC_RAD,
3152 (
double[]){ 0.0000000000000000/
YAC_RAD,
3160 intersection_lon[0],
3161 intersection_lon[1]},
3162 (
double[]){0.0000000043633749/
YAC_RAD,
3171 TEST_START(
"example example take from ICON_toy");
3173 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3184 return EXIT_FAILURE;
3194 return EXIT_FAILURE;
3195 for (
int i = 0;
i < 2; ++
i) {
3196 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3201 utest_test_clipping(
3208 (
double[]){-0.9805860393425995/
YAC_RAD,
3215 (
double[]){-1.0062913968529805/
YAC_RAD,
3224 intersection_lon[0],intersection_lon[1]},
3225 (
double[]){-0.9817477042468103/
YAC_RAD,
3236 TEST_START(
"example example take from ICON_toy");
3239 utest_test_clipping(
3246 (
double[]){-1.5418135420482968/
YAC_RAD,
3253 (
double[]){-1.5707963267948966/
YAC_RAD,
3265 TEST_START(
"example example take from ICON_toy");
3268 utest_test_clipping(
3275 (
double[]){-1.5418135425481947/
YAC_RAD,
3282 (
double[]){-1.5707963267948966/
YAC_RAD,
3294 TEST_START(
"example example take from ICON_toy");
3296 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3307 return EXIT_FAILURE;
3317 return EXIT_FAILURE;
3318 for (
int i = 0;
i < 2; ++
i) {
3319 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3324 utest_test_clipping(
3331 (
double[]){1.54180416508220/
YAC_RAD,
3338 (
double[]){1.52170894158256/
YAC_RAD,
3346 intersection_lon[0],
3347 intersection_lon[1]},
3348 (
double[]){1.54625263418873/
YAC_RAD,
3349 intersection_lat[0],
3350 intersection_lat[1]},
3355 intersection_lon[0],
3356 intersection_lon[1]},
3357 (
double[]){1.54625263418873/
YAC_RAD,
3359 intersection_lat[0],
3360 intersection_lat[1]},
3367 TEST_START(
"example example take from ICON_toy");
3369 utest_test_clipping(
3377 (
double[]){-1.2878426515089207/
YAC_RAD,
3386 (
double[]){-1.2946797849754812/
YAC_RAD,
3397 (
double[]){-1.2946797849754812/
YAC_RAD,
3411 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3422 return EXIT_FAILURE;
3432 return EXIT_FAILURE;
3433 for (
int i = 0;
i < 2; ++
i) {
3434 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3439 utest_test_clipping(
3447 (
double[]){1.5358897417550099/
YAC_RAD,
3458 (
double[]){1.5494144670074232/
YAC_RAD,
3470 (
double[]){1.5533430342749532/
YAC_RAD,
3472 intersection_lat[1]},
3483 utest_test_clipping(
3490 (
double[]){-0.4124872765902973/
YAC_RAD,
3497 (
double[]){-0.4121554426487201/
YAC_RAD,
3506 (
double[]){-0.4124872765902973/
YAC_RAD,
3515 double intersection[3], intersection_lon, intersection_lat;
3526 return EXIT_FAILURE;
3527 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
3531 utest_test_clipping(
3538 (
double[]){-0.4401294427665800/
YAC_RAD,
3545 (
double[]){-0.5268929705698896/
YAC_RAD,
3554 (
double[]){-0.4636476094897370/
YAC_RAD,
3565 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3576 return EXIT_FAILURE;
3586 return EXIT_FAILURE;
3587 for (
int i = 0;
i < 2; ++
i) {
3588 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3593 utest_test_clipping(
3600 (
double[]){-0.5882204740702072/
YAC_RAD,
3607 (
double[]){-0.4835340719879115/
YAC_RAD,
3615 intersection_lon[0],
3616 intersection_lon[1]},
3617 (
double[]){-0.5535743562505872/
YAC_RAD,
3618 intersection_lat[0],
3619 intersection_lat[1]},
gc_edges, 3)},
3625 TEST_START(
"handling of 'triangle' in which all corners on on a gc");
3627 utest_test_clipping(
3634 (
double[]){0, 0, 0},
gc_edges, 3)},
3639 (
double[]){0, 0, 0},
gc_edges, 3)},
3644 TEST_START(
"handling of 'triangle' in which all corners on on a gc");
3646 utest_test_clipping(
3653 (
double[]){0, 0, 0},
gc_edges, 3)},
3658 (
double[]){0, 0, 0},
gc_edges, 3)},
3666 utest_test_clipping(
3674 (
double[]){-1.5707963267948966/
YAC_RAD,
3683 (
double[]){-1.5462526341887277/
YAC_RAD,
3698 double intersection[3], intersection_lon, intersection_lat;
3709 return EXIT_FAILURE;
3710 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
3714 utest_test_clipping(
3721 (
double[]){-1.5462526341887264/
YAC_RAD,
3730 (
double[]){-1.5339807878856395/
YAC_RAD,
3741 (
double[]){-1.5217089415825564/
YAC_RAD,
3752 TEST_START(
"lon-lat cell that touches the pole");
3770 utest_test_clipping(
3774 (
double[]){85.0, 85.0, 90.0},
3778 (
double[]){ 84.0,84.0,84.0,84.0,84.0,84.0},
3785 (
double[]){85.0, 85.0, 90.0},
3793 TEST_START(
"two square that partially share two edges");
3814 utest_test_clipping(
3830 TEST_START(
"two polygons with two edges touch in a single point");
3851 double touch_point[3], touch_lon, touch_lat;
3855 return EXIT_FAILURE;
3856 XYZtoLL(touch_point, &touch_lon, &touch_lat);
3860 utest_test_clipping(
3865 (
double[]){touch_lat, touch_lat, 90.0, 90.0},
3868 (
double[]){0.0, 80.0, 80.0},
gc_edges, 3)},
3876 TEST_START(
"two polygons with two edges touch in a single point");
3897 double touch_point[3], touch_lon, touch_lat;
3901 return EXIT_FAILURE;
3902 XYZtoLL(touch_point, &touch_lon, &touch_lat);
3906 utest_test_clipping(
3911 (
double[]){60.0, 60.0, touch_lat, touch_lat},
3914 (
double[]){70.0, 80.0, 80.0},
gc_edges, 3)},
3918 (
double[]){70.0, 80.0, 80.0},
gc_edges, 3),
3920 (
double[]){70.0, 80.0, touch_lat, 80.0},
gc_edges, 4)},
3937 utest_test_clipping(
3942 (
double[]){0.0, 0.0, 1.0, 1.0},
3970 utest_test_clipping(
3975 (
double[]){2.0,0.5,0.0,-0.5,-2.0,-0.5,0.0,0.5},
3988 utest_test_clipping(
3995 {{-0.25877962570833368, 0.0045170151688387894, -0.9659258262890682},
3996 {-0.25881904510252096, 3.1696191514317674e-17, -0.9659258262890682},
3997 {-0.27563735581699916, 3.3755840552672809e-17, -0.96126169593831889},
3998 {-0.27559537491262875, 0.004810535163016382, -0.96126169593831889}},
4003 {{0.26672229713350176, 7.0351165064716449e-15, -0.96377342576553127},
4004 {0.26954589843896026, 3.2931183713464971e-16, -0.9629875433434919},
4005 {0.26812958837053386, -0.0028554026633992114, -0.9633786226172335}},
4018 enum {num_weights = 5};
4019 double weights[num_weights] = {1,3,2,0.5,3.5};
4020 double ref_weights[num_weights] = {0.1,0.3,0.2,0.05,0.35};
4021 utest_check_weight_correction(weights, num_weights,
ref_weights);
4025 enum {num_weights = 1};
4026 double weights[num_weights] = {3};
4028 utest_check_weight_correction(weights, num_weights,
ref_weights);
4032 enum {num_weights = 4};
4033 double weights[num_weights] = {1,2,3,4};
4034 double ref_weights[num_weights] = {0.1,0.2,0.3,0.4};
4035 utest_check_weight_correction(weights, num_weights,
ref_weights);
4041 double points_LL[][2] = {{0.0,0.0}, {45.0, 45.0}, {45.0+180.0,-45.0}, {90.0,90.0}};
4044 double ll[2], xyz[3];
4048 {{.a.ll = {-5.0, 0.0}, .b.ll = {5.0, 0.0}, .type =
GREAT_CIRCLE},
4049 {.a.ll = {0.0, 0.0}, .b.ll = {45.0, 45.0}, .type =
GREAT_CIRCLE},
4050 {.a.ll = {10.0, 5.0}, .b.ll = {10.0, 10.0}, .type =
GREAT_CIRCLE},
4051 {.a.ll = {10.0, 85.0}, .b.ll = {10.0+180.0, 88.0}, .type =
GREAT_CIRCLE},
4052 {.a.ll = {10.0, 85.0}, .b.ll = {10.0+180.0, 90.0}, .type =
GREAT_CIRCLE},
4053 {.a.ll = {1.0, 1.0}, .b.ll = {1.0, 1.1}, .type =
GREAT_CIRCLE},
4054 {.a.ll = {-5.0, 0.0}, .b.ll = {5.0, 0.0}, .type =
LAT_CIRCLE},
4055 {.a.ll = {35.0, 45.0}, .b.ll = {44.0, 45.0}, .type =
LAT_CIRCLE},
4056 {.a.ll = {44.0, 45.0}, .b.ll = {46.0, 45.0}, .type =
LAT_CIRCLE},
4057 {.a.ll = {5.0, 90.0}, .b.ll = {10.0, 90.0}, .type =
LAT_CIRCLE},
4058 {.a.ll = {5.0, 60.0}, .b.ll = {10.0, 60.0}, .type =
LAT_CIRCLE},
4059 {.a.ll = {0.0, -5.0}, .b.ll = {0.0, 5.0}, .type =
LON_CIRCLE},
4060 {.a.ll = {45.0, 45.0}, .b.ll = {45.0, 47.0}, .type =
LON_CIRCLE},
4061 {.a.ll = {10.0, 85.0}, .b.ll = {10.0, 90.0}, .type =
LON_CIRCLE},
4062 {.a.ll = {20.0, 30.0}, .b.ll = {20.0, 35.0}, .type =
LON_CIRCLE},
4063 {.a.ll = {0.0, 0.0}, .b.ll = {0.0, 0.0}, .type =
POINT},
4064 {.a.ll = {1.0, 1.0}, .b.ll = {1.0, 1.0}, .type =
POINT},
4065 {.a.ll = {15.0, 90.0}, .b.ll = {15.0, 90.0}, .type =
POINT}};
4067 NUM_POINTS =
sizeof(points_LL) /
sizeof(points_LL[0]),
4068 NUM_EDGES =
sizeof(edges) /
sizeof(edges[0]),
4072 {1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0},
4073 {0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0},
4074 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
4075 {0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1}};
4077 for (
size_t i = 0;
i < NUM_EDGES; ++
i) {
4078 LLtoXYZ_deg(edges[i].a.ll[0], edges[i].a.ll[1], edges[i].a.xyz);
4079 LLtoXYZ_deg(edges[i].b.ll[0], edges[i].b.ll[1], edges[i].b.xyz);
4081 for (
size_t point_idx = 0; point_idx <
NUM_POINTS; ++point_idx) {
4085 points_LL[point_idx][0], points_LL[point_idx][1], point);
4087 for (
size_t edge_idx = 0; edge_idx < NUM_EDGES; ++edge_idx)
4089 point, edges[edge_idx].a.xyz, edges[edge_idx].b.xyz,
4090 edges[edge_idx].type) != ref_results[point_idx][edge_idx]) {
4091 fprintf(stderr,
"points_idx = %zu, edge_idx = %zu\n", point_idx, edge_idx);
4092 PUT_ERR(
"ERROR in yac_point_on_edge");
4105 double const tol = 1e-8;
4114 for (
int order = -1; order <= 1; order += 2) {
4115 for (
int start = 0; start < (int)(a.
num_corners); ++start) {
4117 int differences = 0;
4134 if (!differences)
return 0;
4141static void utest_test_clipping(
struct yac_grid_cell cells[2],
4143 unsigned num_ref_cells) {
4145 int order[2], start[2];
4146 double mem_dummy_[2][128][3];
4151 .edge_type = edge_dummy[0],
4154 .edge_type = edge_dummy[1],
4159 for (order[0] = -1; order[0] <= 1; order[0] += 2) {
4160 for (order[1] = -1; order[1] <= 1; order[1] += 2) {
4161 for (start[0] = 0; start[0] < (int)(cells[0].num_corners); ++start[0]) {
4162 for (start[1] = 0; start[1] < (int)(cells[1].num_corners); ++start[1]) {
4164 for (
int k = 0; k <= 1; ++k) {
4165 for (
int i = 0;
i < ((int)(cells[k].num_corners)); ++
i) {
4167 (((int)(cells[k].num_corners))+start[k]+i*order[k])%
4168 ((int)(cells[k].num_corners));
4173 (((int)(cells[k].num_corners)) + j - (order[k] < 0))%
4179 for (
int k = 0; k <= 1; ++k) {
4182 for (
int i = 0;
i < (int)num_ref_cells; ++
i)
4183 match |= !utest_compare_cells(overlap_cell, ref_cells[i]);
4185 PUT_ERR(
"ERROR: wrong clipping cell\n");
4193 for (
unsigned i = 0;
i < num_ref_cells; ++
i)
4198static void utest_check_weight_correction(
4199 double * weights,
size_t count,
double *
ref_weights) {
4201 double scales[] = {0.001, 0.01, 0.1, 1.0, 10.0, 100.0};
4202 size_t num_tests =
sizeof(scales) /
sizeof(scales[0]);
4204 for (
size_t i = 0;
i < num_tests; ++
i) {
4206 double temp_weights[count];
4207 for (
size_t j = 0; j < count; ++j)
4208 temp_weights[j] = weights[j] * scales[i];
4212 double weight_diff = 1.0;
4213 for (
size_t j = 0; j < count; ++j) {
4214 weight_diff -= temp_weights[j];
4215 if (fabs(
ref_weights[j] - temp_weights[j]) > 1e-9)
4218 if (fabs(weight_diff) > 1e-12)
PUT_ERR(
"wrong weight sum");
double yac_huiliers_area(struct yac_grid_cell cell)
Area calculation on a unit sphere taken from ESMF based on L'Huilier's Theorem.
Structs and interfaces for area calculations.
void yac_correct_weights(size_t nSourceCells, double *weight)
correct interpolation weights
void yac_cell_clipping(size_t N, struct yac_grid_cell *source_cell, struct yac_grid_cell target_cell, struct yac_grid_cell *overlap_buffer)
cell clipping to get the cells describing the intersections
static void LLtoXYZ_deg(double lon, double lat, double p_out[])
int yac_point_on_edge(double p[3], double const a[3], double const b[3], enum yac_circle_type circle_type)
static double get_vector_angle(double const a[3], double const b[3])
void yac_init_grid_cell(struct yac_grid_cell *cell)
void yac_free_grid_cell(struct yac_grid_cell *cell)
@ YAC_GREAT_CIRCLE_EDGE
great circle
@ YAC_LAT_CIRCLE_EDGE
latitude circle
@ YAC_LON_CIRCLE_EDGE
longitude circle
static void XYZtoLL(double const p_in[], double *lon, double *lat)
enum yac_edge_type * edge_type
double(* coordinates_xyz)[3]
#define TEST_GROUP_START()
struct yac_grid_cell generate_cell_3d(yac_coordinate_pointer coords, enum yac_edge_type *edge_type, size_t num_corners)
struct yac_grid_cell generate_cell_deg(double *lon, double *lat, enum yac_edge_type *edge_type, size_t num_corners)
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)
static enum yac_edge_type gc_edges[]
static enum yac_edge_type latlon_edges[4]
double ref_weights[4 *36]
double(* yac_coordinate_pointer)[3]