YAC 3.12.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_clipping.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 <math.h>
8
9#include "grids/basic_grid.h"
10#include "clipping.h"
11#include "geometry.h"
12#include "tests.h"
13#include "area.h"
14#include "test_common.h"
15
21#define TEST_GROUP_START() \
22 {++test_major_idx; test_minor_idx = 0;}
23#define TEST_START(DESC) \
24 { \
25 ++test_minor_idx; \
26 printf("%d.%d) %s\n", test_major_idx, test_minor_idx, (DESC)); \
27 }
28
29static void utest_test_clipping(struct yac_grid_cell cells[2],
30 struct yac_grid_cell * ref_cells,
31 unsigned num_ref_cells);
32
33static int utest_compare_cells(struct yac_grid_cell a, struct yac_grid_cell b);
34
35static void utest_check_weight_correction(
36 double * weights, size_t count, double * ref_weights);
37
38int main (void) {
39
40 enum yac_edge_type gc_edges[] = {
45
46 struct yac_grid_cell overlap_cell[2];
47
48 yac_init_grid_cell(overlap_cell);
49 yac_init_grid_cell(overlap_cell+1);
50
51 int test_major_idx = 0, test_minor_idx;
52
54 TEST_START("clipping with an empty source cell");
55 {
56 struct yac_grid_cell SourceCells[] =
57 {generate_cell_deg(NULL, NULL, gc_edges, 0)};
58 struct yac_grid_cell TargetCell =
59 generate_cell_deg((double[]){0.0, 0.5, 0.0, -0.5},
60 (double[]){-0.5, 0.0, 0.7, 0.0}, gc_edges, 4);
61 yac_cell_clipping(1, SourceCells, TargetCell, overlap_cell);
62 if (utest_compare_cells(overlap_cell[0], SourceCells[0]))
63 PUT_ERR("ERROR: wrong clipping cell\n");
64 yac_free_grid_cell(&SourceCells[0]);
65 yac_free_grid_cell(&TargetCell);
66 }
67
68
70 TEST_START("Simple test case with two quadrangle");
71 /* source cell test data
72
73 0.0 (lon) [2]
74 0.7 (lat)
75 / \
76 / \
77 -0.5 [1] / \ 0.5 [3]
78 0.0 \ / 0.0
79 \ /
80 \ /
81 0.0 [0]
82 -0.5
83 */
84
85 /* target cell test data
86
87 0.0 (lon) [0]
88 0.6 (lat)
89 / \
90 / \
91 -0.6 [3] / \ 0.6 [1]
92 0.0 \ / 0.0
93 \ /
94 \ /
95 0.0 [2]
96 -0.6
97 */
98 {
99 double intersection[3], intersection_lon, intersection_lat;
100
101 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.0, 0.6, 0.6, 0.0,
102 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.7, 0.5, 0.0, intersection))
103 return EXIT_FAILURE;
104 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
105 intersection_lon /= YAC_RAD;
106 intersection_lat /= YAC_RAD;
107
108 utest_test_clipping(
109 // input cells
110 (struct yac_grid_cell[]){
111 generate_cell_deg((double[]){0.0, 0.5, 0.0, -0.5},
112 (double[]){-0.5, 0.0, 0.7, 0.0}, gc_edges, 4),
113 generate_cell_deg((double[]){0.0, 0.6, 0.0, -0.6},
114 (double[]){0.6, 0.0, -0.6, 0.0}, gc_edges, 4)},
115 // reference cells
116 (struct yac_grid_cell[]){
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)},
119 // number of reference cells
120 1);
121 }
122
124 TEST_START("Simple test case with one quadrangle and one triangle");
125 /* source cell test data
126
127 0.0 (lon) [2]
128 0.7 (lat)
129 / \
130 / \
131 -0.5 [1] / \ 0.5 [3]
132 0.0 \ / 0.0
133 \ /
134 \ /
135 0.0 [0]
136 -0.5
137 */
138
139 /* target cell test data
140
141 0.0 (lon)
142 0.6 (lat)
143 / \
144 / \
145 -0.6 / \ 0.6
146 0.0 /_______\ 0.0
147
148 */
149
150 {
151 double intersection[3], intersection_lon, intersection_lat;
152 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.0, 0.6, 0.6, 0.0,
153 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.7, 0.5, 0.0, intersection))
154 return EXIT_FAILURE;
155 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
156 intersection_lon /= YAC_RAD;
157 intersection_lat /= YAC_RAD;
158
159 utest_test_clipping(
160 // input cells
161 (struct yac_grid_cell[]){
162 generate_cell_deg((double[]){ 0.0,-0.5,0.0,0.5},
163 (double[]){-0.5,0.0,0.7,0.0}, gc_edges, 4),
164 generate_cell_deg((double[]){0.6,0.0,-0.6},
165 (double[]){0.0,0.6,0.0}, gc_edges, 3)},
166 // reference cells
167 (struct yac_grid_cell[]){
168 generate_cell_deg((double[]){0.0,intersection_lon,0.5,-0.5,-intersection_lon},
169 (double[]){0.6,intersection_lat,0.0,0.0,intersection_lat}, gc_edges, 5)},
170 // number of reference cells
171 1);
172 }
173
174 TEST_START("Simple test case with one quadrangle and one triangle");
175 /* source cell test data
176
177 0.0 (lon) [2]
178 0.7 (lat)
179 / \
180 / \
181 -0.5 [1] / \ 0.5 [3]
182 0.0 \ / 0.0
183 \ /
184 \ /
185 0.0 [0]
186 -0.5
187 */
188
189 /* target cell test data
190
191 0.6 (lon)
192 0.6 (lat)
193 / \
194 / \
195 0.0 / \ 1.0
196 0.1 /_______\ 0.1
197
198 */
199
200 {
201 double intersection[2][3], intersection_lon[2], intersection_lat[2];
202
203 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.0, 0.1, 1.0, 0.1,
204 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.7, 0.5, 0.0, intersection[0]))
205 return EXIT_FAILURE;
206 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.0, 0.1, 0.6, 0.6,
207 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.7, 0.5, 0.0, intersection[1]))
208 return EXIT_FAILURE;
209 for (int i = 0; i < 2; ++i) {
210 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
211 intersection_lon[i] /= YAC_RAD;
212 intersection_lat[i] /= YAC_RAD;
213 }
214
215 utest_test_clipping(
216 // input cells
217 (struct yac_grid_cell[]){
218 generate_cell_deg((double[]){0.0,-0.5,0.0,0.5},
219 (double[]){-0.5,0.0,0.7,0.0}, gc_edges, 4),
220 generate_cell_deg((double[]){1.0,0.6,0.0},
221 (double[]){0.1,0.6,0.1}, gc_edges, 3)},
222 // reference cells
223 (struct yac_grid_cell[]){
224 generate_cell_deg((double[]){0.0,intersection_lon[0],intersection_lon[1]},
225 (double[]){0.1,intersection_lat[0],intersection_lat[1]}, gc_edges, 3)},
226 // number of reference cells
227 1);
228 }
229
230 TEST_START("Simple test case with one quadrangle and one triangle");
231 /* source cell test data
232
233 0.0 (lon) [2]
234 0.7 (lat)
235 / \
236 / \
237 -0.5 [1] / \ 0.5 [3]
238 0.0 \ / 0.0
239 \ /
240 \ /
241 0.0 [0]
242 -0.5
243 */
244
245 /* target cell test data
246
247 0.0 (lon)
248 0.6 (lat)
249 / \
250 / \
251 -0.5 / \ 0.5
252 0.1 /_______\ 0.1
253
254 */
255
256 {
257 double intersection[2][3], intersection_lon[2], intersection_lat[2];
258
259 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.0,0.6,0.5,0.1,
260 YAC_GREAT_CIRCLE_EDGE, 0.0,0.7,0.5,0.0, intersection[0]))
261 return EXIT_FAILURE;
262 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -0.5,0.1,0.5,0.1,
263 YAC_GREAT_CIRCLE_EDGE, 0.0,0.7,0.5,0.0, intersection[1]))
264 return EXIT_FAILURE;
265 for (int i = 0; i < 2; ++i) {
266 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
267 intersection_lon[i] /= YAC_RAD;
268 intersection_lat[i] /= YAC_RAD;
269 }
270
271 utest_test_clipping(
272 // input cells
273 (struct yac_grid_cell[]){
274 generate_cell_deg((double[]){0.0,-0.5,0.0,0.5},
275 (double[]){-0.5,0.0,0.7,0.0}, gc_edges, 4),
276 generate_cell_deg((double[]){0.5,0.0,-0.5},
277 (double[]){0.1,0.6,0.1}, gc_edges, 3)},
278 // reference cells
279 (struct yac_grid_cell[]){
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)},
282 // number of reference cells
283 1);
284 }
285
287 TEST_START("Two source cells overlapping one target cell");
288
289 /* target cell test data
290
291 0.0 (lon)
292 0.7 (lat)
293 / \
294 1 0
295 -0.5 / \ 0.5
296 0.0 \ / 0.0
297 2 3
298 \ /
299 0.0
300 -0.7
301
302 */
303
304 /* source cell test data
305
306 0.0 (lon)
307 0.5 (lat)
308 / \
309 1 0
310 -0.6 / \ 0.6
311 0.0 /___2___\ 0.0
312 _________
313 \ 0 /
314 \ /
315 1 2
316 \ /
317 0.0
318 -0.5
319 */
320
321 // generate reference intersection cells
322 {
323 double intersection[3], intersection_lon, intersection_lat;
324 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.0, 0.5, 0.6, 0.0,
325 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.7, 0.5, 0.0, intersection))
326 return EXIT_FAILURE;
327 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
328 intersection_lon /= YAC_RAD;
329 intersection_lat /= YAC_RAD;
330
331 struct yac_grid_cell ref_cells[] = {
332 generate_cell_deg((double[]){0.0,intersection_lon,0.5,-0.5,-intersection_lon},
333 (double[]){0.5,intersection_lat,0.0,0.0,intersection_lat},
334 gc_edges, 5),
335 generate_cell_deg((double[]){0.0,-intersection_lon,-0.5,0.5,intersection_lon},
336 (double[]){-0.5,-intersection_lat,0.0,0.0,-intersection_lat},
337 gc_edges, 5)};
338
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) {
345
346 struct yac_grid_cell SourceCells[] = {
347 generate_cell_deg((double[]){0.6,0.0,-0.6},
348 (double[]){0.0,0.5,0.0}, gc_edges, 3),
349 generate_cell_deg((double[]){0.6,-0.6,0.0},
350 (double[]){0.0,0.0,-0.5}, gc_edges, 3)};
351 struct yac_grid_cell TargetCell =
352 generate_cell_deg((double[]){0.5,0.0,-0.5,0.0},
353 (double[]){0.0,0.7,0.0,-0.7}, gc_edges, 4);
354
355 yac_cell_clipping ( 2, SourceCells, TargetCell, overlap_cell );
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");
359 yac_free_grid_cell(&SourceCells[0]);
360 yac_free_grid_cell(&SourceCells[1]);
361 yac_free_grid_cell(&TargetCell);
362 }
363 }
364 }
365 }
366 }
367 }
368 yac_free_grid_cell(&ref_cells[0]);
369 yac_free_grid_cell(&ref_cells[1]);
370 }
371
373 TEST_START("Simple cases: identity");
374 /* target cell test data
375
376 0.0 (lon)
377 0.5 (lat)
378 / \
379 1 0
380 -0.6 / \ 0.6
381 0.0 \ / 0.0
382 2 3
383 \ /
384 0.0
385 -0.5
386
387 */
388
389 /* source cell test data
390
391 0.0 (lon)
392 0.5 (lat)
393 / \
394 1 0
395 -0.6 / \ 0.6
396 0.0 /___2___\ 0.0
397 _________
398 \ 0 /
399 \ /
400 1 2
401 \ /
402 0.0
403 -0.5
404 */
405
406 // generate reference intersection cells
407 {
408 struct yac_grid_cell ref_cells[] = {
409 generate_cell_deg((double[]){0.0,0.6,-0.6},
410 (double[]){0.5,0.0,0.0}, gc_edges, 3),
411 generate_cell_deg((double[]){0.0,0.6,-0.6},
412 (double[]){-0.5,0.0,0.0}, gc_edges, 3)};
413
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) {
420
421 struct yac_grid_cell SourceCells[] = {
422 generate_cell_deg((double[]){0.6,0.0,-0.6},
423 (double[]){0.0,0.5,0.0}, gc_edges, 3),
424 generate_cell_deg((double[]){0.6,-0.6,0.0},
425 (double[]){0.0,0.0,-0.5}, gc_edges, 3)};
426 struct yac_grid_cell TargetCell =
427 generate_cell_deg((double[]){0.0,-0.6,0.0,0.6},
428 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4);
429
430 yac_cell_clipping ( 2, SourceCells, TargetCell, overlap_cell );
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");
434 yac_free_grid_cell(overlap_cell);
435 yac_free_grid_cell(overlap_cell+1);
436 yac_free_grid_cell(&SourceCells[0]);
437 yac_free_grid_cell(&SourceCells[1]);
438 yac_free_grid_cell(&TargetCell);
439 }
440 }
441 }
442 }
443 }
444 }
445 yac_free_grid_cell(&ref_cells[0]);
446 yac_free_grid_cell(&ref_cells[1]);
447 }
448
449 TEST_START("Simple cases: identity");
450 /* target cell test data
451
452 0.0 (lon)
453 0.5 (lat)
454 / \
455 1 0
456 -0.6 / \ 0.6
457 0.0 \ / 0.0
458 2 3
459 \ /
460 0.0
461 -0.5
462
463 */
464
465 /* source cell test data
466
467 0.0 (lon)
468 0.5 (lat)
469 / \
470 1 0
471 -0.6 / \ 0.6
472 0.0 \ / 0.0
473 2 3
474 \ /
475 0.0
476 -0.5
477 */
478
479 {
480 utest_test_clipping(
481 // input cells
482 (struct yac_grid_cell[]){
483 generate_cell_deg((double[]){0.0,-0.6,0.0,0.6},
484 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4),
485 generate_cell_deg((double[]){0.0,-0.6,0.0,0.6},
486 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4)},
487 // reference cells
488 (struct yac_grid_cell[]){
489 generate_cell_deg((double[]){0.0,-0.6,0.0,0.6},
490 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4)},
491 // number of reference cells
492 1);
493 }
494
495 TEST_START("Simple cases: source inside target cell");
496 /* target cell test data
497
498 0.0 (lon)
499 0.5 (lat)
500 / \
501 1 0
502 -0.6 / \ 0.6
503 0.0 \ / 0.0
504 2 3
505 \ /
506 0.0
507 -0.5
508
509 */
510
511 /* source cell test data
512
513 0.0 (lon)
514 0.4 (lat)
515 / \
516 1 0
517 -0.5 / \ 0.5
518 0.0 \ / 0.0
519 2 3
520 \ /
521 0.0
522 -0.4
523 */
524
525 {
526 utest_test_clipping(
527 // input cells
528 (struct yac_grid_cell[]){
529 generate_cell_deg((double[]){0.0,-0.5,0.0,0.5},
530 (double[]){0.4,0.0,-0.4,0.0}, gc_edges, 4),
531 generate_cell_deg((double[]){0.0,-0.6,0.0,0.6},
532 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4)},
533 // reference cells
534 (struct yac_grid_cell[]){
535 generate_cell_deg((double[]){0.0,-0.5,0.0,0.5},
536 (double[]){0.4,0.0,-0.4,0.0}, gc_edges, 4)},
537 // number of reference cells
538 1);
539 }
540
541 TEST_START("Simple cases: target inside source cell");
542 /* target cell test data
543
544 0.0 (lon)
545 0.5 (lat)
546 / \
547 1 0
548 -0.6 / \ 0.6
549 0.0 \ / 0.0
550 2 3
551 \ /
552 0.0
553 -0.5
554
555 */
556
557 /* source cell test data
558
559 0.0 (lon)
560 0.6 (lat)
561 / \
562 1 0
563 -0.7 / \ 0.7
564 0.0 \ / 0.0
565 2 3
566 \ /
567 0.0
568 -0.6
569 */
570
571 {
572 utest_test_clipping(
573 // input cells
574 (struct yac_grid_cell[]){
575 generate_cell_deg((double[]){0.0,-0.7,0.0,0.7},
576 (double[]){0.6,0.0,-0.6,0.0}, gc_edges, 4),
577 generate_cell_deg((double[]){0.0,-0.6,0.0,0.6},
578 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4)},
579 // reference cells
580 (struct yac_grid_cell[]){
581 generate_cell_deg((double[]){0.0,-0.6,0.0,0.6},
582 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4)},
583 // number of reference cells
584 1);
585 }
586
587 TEST_START("Simple cases: degenerated cell");
588 /* target cell test data
589
590 0.0 (lon)
591 0.5 (lat)
592 / \
593 1 0
594 -0.6 / \ 0.6
595 0.0 \ / 0.0
596 2 3
597 \ /
598 0.0
599 -0.5
600
601 */
602
603 /* source cell test data
604
605 0.0 0.0 (lon)
606 0.5 0.6 (lat)
607 --------
608 \ \
609 \ \
610 \ \
611 --------
612 0.6 1.0
613 0.0 0.0
614 */
615
616 {
617 utest_test_clipping(
618 // input cells
619 (struct yac_grid_cell[]){
620 generate_cell_deg((double[]){0.0,0.6,1.0,0.5},
621 (double[]){0.5,0.0,0.0,0.5}, gc_edges, 4),
622 generate_cell_deg((double[]){0.0,-0.6,0.0,0.6},
623 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4)},
624 // reference cells
625 (struct yac_grid_cell[]){
626 generate_cell_deg(NULL, NULL, NULL, 0)},
627 // number of reference cells
628 1);
629 }
630
632 TEST_START("Special case from ICON_toy");
633 /* 5.) source cell test data
634
635 +------+
636 | |
637 | |
638 | |
639 +------+
640 */
641
642 /* target cell test data
643
644 /|
645 / |
646 / |
647 / |
648 \ |
649 \ |
650 \ |
651 \|
652 */
653
654 {
655 double intersection[4][3], intersection_lon[4], intersection_lat[4];
656
657 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 108.0000, -7.2167, 88.4979, -19.2921,
658 YAC_GREAT_CIRCLE_EDGE, 90.0, 0.0, 90.0, -22.5, intersection[0]))
659 return EXIT_FAILURE;
660 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 88.4979, -19.2921, 108.0000, -26.5650,
661 YAC_GREAT_CIRCLE_EDGE, 90.0, 0.0, 90.0, -22.5, intersection[1]))
662 return EXIT_FAILURE;
663 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 88.4979, -19.2921, 108.0000, -26.5650,
664 YAC_GREAT_CIRCLE_EDGE, 90.0, -22.5, 112.5, -22.5, intersection[2]))
665 return EXIT_FAILURE;
666 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 108.0000, -26.5650, 108.0000, -7.2167,
667 YAC_GREAT_CIRCLE_EDGE, 90.0, -22.5, 112.5, -22.5, intersection[3]))
668 return EXIT_FAILURE;
669 for (int i = 0; i < 4; ++i) {
670 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
671 intersection_lon[i] /= YAC_RAD;
672 intersection_lat[i] /= YAC_RAD;
673 }
674
675 utest_test_clipping(
676 // input cells
677 (struct yac_grid_cell[]){
678 generate_cell_deg((double[]){90.0,112.5,112.5,90.0},
679 (double[]){-22.5,-22.5,0.0,0.0}, gc_edges, 4),
680 generate_cell_deg((double[]){108.0000,88.4979,108.0000},
681 (double[]){-7.2167,-19.2921,-26.5650}, gc_edges, 3)},
682 // reference cells
683 (struct yac_grid_cell[]){
684 generate_cell_deg((double[]){108.0000,
685 intersection_lon[0],
686 intersection_lon[1],
687 intersection_lon[2],
688 intersection_lon[3]},
689 (double[]){-7.2167,
690 intersection_lat[0],
691 intersection_lat[1],
692 intersection_lat[2],
693 intersection_lat[3]}, gc_edges, 5)},
694 // number of reference cells
695 1);
696 }
697
698 TEST_START("Special case from ICON_toy");
699 /* 6.) source cell test data
700
701 +------+ 0.5
702 | |
703 | |
704 | |
705 +------+ -0.5
706 -0.5 0.5
707 */
708
709 /* target cell test data
710
711 -0.75 0.0
712 ______ 0.0
713 \ |
714 \ |
715 \ |
716 \ |
717 \| -0.75
718 */
719
720 {
721 double intersection[4][3], intersection_lon[4], intersection_lat[4];
722
723 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.0,0.0,-0.75,0.0,
724 YAC_GREAT_CIRCLE_EDGE, -0.5,0.5,-0.5,-0.5, intersection[0]))
725 return EXIT_FAILURE;
726 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -0.75,0.0,0.0,-0.75,
727 YAC_GREAT_CIRCLE_EDGE, -0.5,0.5,-0.5,-0.5, intersection[1]))
728 return EXIT_FAILURE;
729 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -0.75,0.0,0.0,-0.75,
730 YAC_GREAT_CIRCLE_EDGE, -0.5,-0.5,0.5,-0.5, intersection[2]))
731 return EXIT_FAILURE;
732 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.0,-0.75,0.0,0.0,
733 YAC_GREAT_CIRCLE_EDGE, -0.5,-0.5,0.5,-0.5, intersection[3]))
734 return EXIT_FAILURE;
735 for (int i = 0; i < 4; ++i) {
736 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
737 intersection_lon[i] /= YAC_RAD;
738 intersection_lat[i] /= YAC_RAD;
739 }
740
741 utest_test_clipping(
742 // input cells
743 (struct yac_grid_cell[]){
744 generate_cell_deg((double[]){-0.5,0.5,0.5,-0.5},
745 (double[]){-0.5,-0.5,0.5,0.5}, gc_edges, 4),
746 generate_cell_deg((double[]){0.0,-0.75,0.0},
747 (double[]){0.0,0.0,-0.75}, gc_edges, 3)},
748 // reference cells
749 (struct yac_grid_cell[]){
750 generate_cell_deg((double[]){0.0,
751 intersection_lon[0],
752 intersection_lon[1],
753 intersection_lon[2],
754 intersection_lon[3]},
755 (double[]){0.0,
756 intersection_lat[0],
757 intersection_lat[1],
758 intersection_lat[2],
759 intersection_lat[3]}, gc_edges, 5)},
760 // number of reference cells
761 1);
762 }
763
765 TEST_START("Special case in which no corner on any square is within the other");
766 /* 7.) source cell test data
767
768 +------+ 0.5
769 | |
770 | |
771 | |
772 +------+ -0.5
773 -0.5 0.5
774 */
775
776 /* target cell test data
777
778 -0.7 0.0 0.7
779 /\ 0.7
780 / \
781 / \
782 / \ 0.0
783 \ /
784 \ /
785 \ /
786 \/ -0.7
787 */
788
789 {
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}};
795
796 for (int i = 0; i < 8; ++i) {
797 if (!intersect(YAC_GREAT_CIRCLE_EDGE, src_data[0][i/2],
798 src_data[1][i/2],
799 src_data[0][(i/2+1)%4],
800 src_data[1][(i/2+1)%4],
801 YAC_GREAT_CIRCLE_EDGE, tgt_data[0][((i+1)/2)%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))
805 return EXIT_FAILURE;
806 XYZtoLL(intersection, &intersection_lon[i], &intersection_lat[i]);
807 intersection_lon[i] /= YAC_RAD;
808 intersection_lat[i] /= YAC_RAD;
809 }
810
811 utest_test_clipping(
812 // input cells
813 (struct yac_grid_cell[]){
814 generate_cell_deg((double[]){-0.5,0.5,0.5,-0.5},
815 (double[]){-0.5,-0.5,0.5,0.5}, gc_edges, 4),
816 generate_cell_deg((double[]){0.0,0.7,0.0,-0.7},
817 (double[]){-0.7,0.0,0.7,0.0}, gc_edges, 4)},
818 // reference cells
819 (struct yac_grid_cell[]){
820 generate_cell_deg(intersection_lon, intersection_lat, gc_edges, 8)},
821 // number of reference cells
822 1);
823 }
824
826 TEST_START("Test non intersecting cells");
827 /* 8.) source cell test data
828
829 +------+ 1
830 | |
831 | |
832 | |
833 +------+ 0
834 0 1
835 */
836
837 /* target cell test data
838
839 +------+ 1
840 | |
841 | |
842 | |
843 +------+ 0
844 2 3
845 */
846
847 {
848 utest_test_clipping(
849 // input cells
850 (struct yac_grid_cell[]){
851 generate_cell_deg((double[]){0.0,1.0,1.0,0.0},
852 (double[]){0.0,0.0,1.0,1.0}, gc_edges, 4),
853 generate_cell_deg((double[]){2.0,3.0,3.0,2.0},
854 (double[]){0.0,0.0,1.0,1.0}, gc_edges, 4)},
855 // reference cells
856 (struct yac_grid_cell[]){generate_cell_deg(NULL, NULL, NULL, 0)},
857 // number of reference cells
858 1);
859 }
860
861 TEST_START("Test non intersecting cells");
862 /* 8.) source cell test data
863
864 +------+ 1
865 | |
866 | |
867 | |
868 +------+ 0
869 0 1
870 */
871
872 /* target cell test data
873
874 +------+ 3
875 | |
876 | |
877 | |
878 +------+ 2
879 1 2
880 */
881
882 {
883 utest_test_clipping(
884 // input cells
885 (struct yac_grid_cell[]){
886 generate_cell_deg((double[]){0.0,1.0,1.0,0.0},
887 (double[]){0.0,0.0,1.0,1.0}, gc_edges, 4),
888 generate_cell_deg((double[]){1.0,2.0,2.0,1.0},
889 (double[]){2.0,2.0,3.0,3.0}, gc_edges, 4)},
890 // reference cells
891 (struct yac_grid_cell[]){generate_cell_deg(NULL, NULL, NULL, 0)},
892 // number of reference cells
893 1);
894 }
895
897 TEST_START("triangle-square intersection");
898 /* 9.) source cell test data
899
900 -1.5 1.5
901 -------- 0.5
902 \ /
903 \ /
904 \ /
905 \/ -0.5
906 */
907
908 /* target cell test data
909
910 +------+ 1
911 | |
912 | |
913 | |
914 +------+ -1
915 -1 1
916 */
917
918 {
919 double intersection[2][3], intersection_lon[2], intersection_lat[2];
920
921 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 1.0,-1.0,1.0,1.0,
922 YAC_GREAT_CIRCLE_EDGE, 0.0,-0.5,1.5,0.5, intersection[0]))
923 return EXIT_FAILURE;
924 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 1.0,-1.0,1.0,1.0,
925 YAC_GREAT_CIRCLE_EDGE, 1.5,0.5,-1.5,0.5, intersection[1]))
926 return EXIT_FAILURE;
927 for (int i = 0; i < 2; ++i) {
928 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
929 intersection_lon[i] /= YAC_RAD;
930 intersection_lat[i] /= YAC_RAD;
931 }
932
933 utest_test_clipping(
934 // input cells
935 (struct yac_grid_cell[]){
936 generate_cell_deg((double[]){1.5,-1.5,0.0},
937 (double[]){0.5,0.5,-0.5}, gc_edges, 3),
938 generate_cell_deg((double[]){-1.0,1.0,1.0,-1.0},
939 (double[]){-1.0,-1.0,1.0,1.0}, gc_edges, 4)},
940 // reference cells
941 (struct yac_grid_cell[]){
942 generate_cell_deg((double[]){0.0,
943 intersection_lon[0],
944 intersection_lon[1],
945 -intersection_lon[1],
946 -intersection_lon[0]},
947 (double[]){-0.5,
948 intersection_lat[0],
949 intersection_lat[1],
950 intersection_lat[1],
951 intersection_lat[0]}, gc_edges, 5)},
952 // number of reference cells
953 1);
954 }
955
957 TEST_START("touching edges of two triangles");
958 /* 10.1) source cell test data
959
960 /\ 1
961 / \
962 / \
963 / \
964 -------- 0
965 0 2
966 */
967 /* target cell test data
968
969 -------- 0.0
970 \ /
971 \ /
972 \ /
973 \/ -0.5
974 0 0.5 1
975 */
976
977 {
978 utest_test_clipping(
979 // input cells
980 (struct yac_grid_cell[]){
981 generate_cell_deg((double[]){0.0,2.0,1.0},
982 (double[]){0.0,0.0,1.0}, gc_edges, 3),
983 generate_cell_deg((double[]){0.0,1.0, 0.5},
984 (double[]){0.0,0.0,-0.5}, gc_edges, 3)},
985 // reference cells
986 (struct yac_grid_cell[]){
987 generate_cell_deg(NULL, NULL, NULL, 0)},
988 // number of reference cells
989 1);
990 }
991
992 TEST_START("touching edges")
993 {
994 utest_test_clipping(
995 // input cells
996 (struct yac_grid_cell[]){
997 generate_cell_deg((double[]){160.0,180.0,180.0},
998 (double[]){ 65.0, 65.0, 90.0}, gc_edges, 3),
999 generate_cell_deg((double[]){180.0,200.0, 0.0},
1000 (double[]){ 70.0, 70.0, 90.0}, gc_edges, 3)},
1001 // reference cells
1002 (struct yac_grid_cell[]){
1003 generate_cell_deg(NULL, NULL, NULL, 0)},
1004 // number of reference cells
1005 1);
1006 }
1007
1009 TEST_START("test from test_interpolation_method_conserv.x");
1010 /* 11.) source cell test data
1011
1012 +------+ 0
1013 | |
1014 | |
1015 | |
1016 +------+ -1
1017 0 1
1018 */
1019 /* target cell test data
1020
1021 +------+ 0.5
1022 | |
1023 | |
1024 | |
1025 +------+ -0.5
1026 -0.5 0.5
1027 */
1028
1029 {
1030 utest_test_clipping(
1031 // input cells
1032 (struct yac_grid_cell[]){
1033 generate_cell_deg((double[]){ 0.0, 1.0,1.0,0.0},
1034 (double[]){-1.0,-1.0,0.0,0.0}, latlon_edges, 4),
1035 generate_cell_deg((double[]){-0.5, 0.5,0.5,-0.5},
1036 (double[]){-0.5,-0.5,0.5, 0.5}, latlon_edges, 4)},
1037 // reference cells
1038 (struct yac_grid_cell[]){
1039 generate_cell_deg((double[]){0.0,0.5, 0.5, 0.0},
1040 (double[]){0.0,0.0,-0.5,-0.5}, latlon_edges, 4)},
1041 // number of reference cells
1042 1);
1043 }
1044
1045 TEST_START("test from test_interpolation_method_conserv.x");
1046 /* 11.) source cell test data
1047
1048 -1 0
1049 +------+ 0
1050 | |
1051 | |
1052 | |
1053 +------+ -1
1054 */
1055 /* target cell test data
1056
1057 +------+ 0.5
1058 | |
1059 | |
1060 | |
1061 +------+ -0.5
1062 -0.5 0.5
1063 */
1064
1065 {
1066 utest_test_clipping(
1067 // input cells
1068 (struct yac_grid_cell[]){
1069 generate_cell_deg((double[]){ 0.0,-1.0,-1.0,0.0},
1070 (double[]){-1.0,-1.0, 0.0,0.0}, latlon_edges, 4),
1071 generate_cell_deg((double[]){-0.5, 0.5,0.5,-0.5},
1072 (double[]){-0.5,-0.5,0.5, 0.5}, latlon_edges, 4)},
1073 // reference cells
1074 (struct yac_grid_cell[]){
1075 generate_cell_deg((double[]){0.0,-0.5,-0.5, 0.0},
1076 (double[]){0.0, 0.0,-0.5,-0.5}, latlon_edges, 4)},
1077 // number of reference cells
1078 1);
1079 }
1080
1082 TEST_START("some mean tests");
1083 /* cell a
1084
1085 +------+ 60
1086 | |
1087 | |
1088 | |
1089 +------+ 40
1090 -20 20
1091 */
1092
1093 /* cell b
1094
1095 -------- 39
1096 \ /
1097 \ /
1098 \ /
1099 \/ 22
1100 -20 0 20
1101 */
1102
1103 {
1104 double intersection[3], intersection_lon, intersection_lat;
1105
1106 if (!intersect(YAC_LAT_CIRCLE_EDGE, -20.0,40.0, 0.0,40.0,
1107 YAC_GREAT_CIRCLE_EDGE, -20.0,39.0,20.0,39.0, intersection))
1108 return EXIT_FAILURE;
1109 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1110 intersection_lon /= YAC_RAD;
1111 intersection_lat /= YAC_RAD;
1112
1113 utest_test_clipping(
1114 // input cells
1115 (struct yac_grid_cell[]){
1116 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1117 (double[]){ 40.0,40.0,60.0, 60.0}, latlon_edges, 4),
1118 generate_cell_deg((double[]){-20.0, 0.0,20.0},
1119 (double[]){ 39.0,22.0,39.0}, gc_edges, 3)},
1120 // reference cells
1121 (struct yac_grid_cell[]){
1122 generate_cell_deg((double[]){intersection_lon,-intersection_lon},
1123 (double[]){intersection_lat,intersection_lat},
1124 (enum yac_edge_type[]){
1126 generate_cell_deg((double[]){intersection_lon,-intersection_lon},
1127 (double[]){intersection_lat,intersection_lat},
1128 (enum yac_edge_type[]){
1130 // number of reference cells
1131 2);
1132 }
1133
1134 TEST_START("some mean tests");
1135 /* cell a
1136
1137 +------+ 60
1138 | |
1139 | |
1140 | |
1141 +------+ 40
1142 -20 20
1143 */
1144
1145 /* cell b
1146
1147 40 --....__ 39
1148 \ /
1149 \ /
1150 \ /
1151 \/ 22
1152 -20 0 20
1153 */
1154
1155 {
1156 double intersection[3], intersection_lon, intersection_lat;
1157
1158 if (!intersect(YAC_LAT_CIRCLE_EDGE, 20.0,40.0,-19.0,40.0,
1159 YAC_GREAT_CIRCLE_EDGE, 20.0,39.0,-20.0,40.0, intersection))
1160 return EXIT_FAILURE;
1161 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1162 intersection_lon /= YAC_RAD;
1163 intersection_lat /= YAC_RAD;
1164
1165 utest_test_clipping(
1166 // input cells
1167 (struct yac_grid_cell[]){
1168 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1169 (double[]){ 40.0,40.0,60.0, 60.0}, latlon_edges, 4),
1170 generate_cell_deg((double[]){-20.0, 0.0,20.0},
1171 (double[]){ 40.0,22.0,39.0}, gc_edges, 3)},
1172 // reference cells
1173 (struct yac_grid_cell[]){
1174 generate_cell_deg((double[]){-20.0,intersection_lon},
1175 (double[]){ 40.0,intersection_lat},
1176 (enum yac_edge_type[]){
1178 generate_cell_deg((double[]){-20.0,intersection_lon},
1179 (double[]){ 40.0,intersection_lat},
1180 (enum yac_edge_type[]){
1182 // number of reference cells
1183 2);
1184 }
1185
1186 TEST_START("some mean tests");
1187 /* cell a
1188
1189 +------+ 60
1190 | |
1191 | |
1192 | |
1193 +------+ 40
1194 -20 20
1195 */
1196
1197 /* cell b
1198
1199 /\ 80
1200 / \
1201 / \
1202 / \
1203 -------- 59
1204 -19 0 19
1205 */
1206
1207 {
1208 double intersection[2][3], intersection_lon[2], intersection_lat[2];
1209
1210 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 19.0,59.0, 0.0,80.0,
1211 YAC_LAT_CIRCLE_EDGE, -20.0,60.0,20.0,60.0, intersection[0]))
1212 return EXIT_FAILURE;
1213 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 19.0, 59.0,-19.0, 59.0,
1214 YAC_LAT_CIRCLE_EDGE, -20.0, 60.0, 0.0, 60.0, intersection[1]))
1215 return EXIT_FAILURE;
1216 for (int i = 0; i < 2; ++i) {
1217 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1218 intersection_lon[i] /= YAC_RAD;
1219 intersection_lat[i] /= YAC_RAD;
1220 }
1221
1222 utest_test_clipping(
1223 // input cells
1224 (struct yac_grid_cell[]){
1225 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1226 (double[]){ 40.0,40.0,60.0, 60.0}, latlon_edges, 4),
1227 generate_cell_deg((double[]){-19.0, 0.0,19.0},
1228 (double[]){ 59.0,80.0,59.0}, gc_edges, 3)},
1229 // reference cells
1230 (struct yac_grid_cell[]){
1231 generate_cell_deg((double[]){19.0,intersection_lon[0],
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},
1236 (enum yac_edge_type[]){
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},
1241 (enum yac_edge_type[]){
1244 // number of reference cells
1245 2);
1246 }
1247
1248 TEST_START("some mean tests");
1249 /* cell a
1250
1251 +------+ 60
1252 | |
1253 | |
1254 | |
1255 +------+ 40
1256 -20 20
1257 */
1258
1259 /* cell b
1260
1261 /| 80
1262 / |
1263 / |
1264 / |
1265 60 --...__|
1266 59
1267 -20 21
1268 */
1269
1270 {
1271 double intersection[2][3], intersection_lon[2], intersection_lat[2];
1272
1273 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -20.0,60.0,21.0,59.0,
1274 YAC_LAT_CIRCLE_EDGE, -19.0,60.0,20.0,60.0, intersection[0]))
1275 return EXIT_FAILURE;
1276 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -20.0,60.0,21.0,59.0,
1277 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[1]))
1278 return EXIT_FAILURE;
1279 for (int i = 0; i < 2; ++i) {
1280 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1281 intersection_lon[i] /= YAC_RAD;
1282 intersection_lat[i] /= YAC_RAD;
1283 }
1284
1285 utest_test_clipping(
1286 // input cells
1287 (struct yac_grid_cell[]){
1288 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1289 (double[]){ 40.0,40.0,60.0, 60.0}, latlon_edges, 4),
1290 generate_cell_deg((double[]){-20.0,21.0,21.0},
1291 (double[]){ 60.0,80.0,59.0}, gc_edges, 3)},
1292 // reference cells
1293 (struct yac_grid_cell[]){
1294 generate_cell_deg((double[]){20.0,intersection_lon[0],intersection_lon[1]},
1295 (double[]){60.0,intersection_lat[0],intersection_lat[1]},
1296 (enum yac_edge_type[]){
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]},
1300 (enum yac_edge_type[]){
1302 // number of reference cells
1303 2);
1304 }
1305
1306 TEST_START("some mean tests");
1307 /* cell a
1308
1309 +------+ 60
1310 | |
1311 | |
1312 | |
1313 +------+ 40
1314 -20 20
1315 */
1316
1317 /* cell b
1318
1319 60 --...__ 59
1320 \ |
1321 \ |
1322 \ |
1323 \| 40
1324
1325 -20 21
1326
1327 */
1328
1329 {
1330 double intersection[3][3], intersection_lon[3], intersection_lat[3];
1331
1332 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -20.0,60.0,21.0,59.0,
1333 YAC_LAT_CIRCLE_EDGE, -19.0,60.0,20.0,60.0, intersection[0]))
1334 return EXIT_FAILURE;
1335 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -20.0,60.0,21.0,59.0,
1336 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[1]))
1337 return EXIT_FAILURE;
1338 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -20.0,60.0,21.0,40.0,
1339 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[2]))
1340 return EXIT_FAILURE;
1341 for (int i = 0; i < 3; ++i) {
1342 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1343 intersection_lon[i] /= YAC_RAD;
1344 intersection_lat[i] /= YAC_RAD;
1345 }
1346
1347 utest_test_clipping(
1348 // input cells
1349 (struct yac_grid_cell[]){
1350 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1351 (double[]){ 40.0,40.0,60.0, 60.0}, latlon_edges, 4),
1352 generate_cell_deg((double[]){-20.0,21.0,21.0},
1353 (double[]){ 60.0,40.0,59.0}, gc_edges, 3)},
1354 // reference cells
1355 (struct yac_grid_cell[]){
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},
1358 (enum yac_edge_type[]){
1360 // number of reference cells
1361 1);
1362 }
1363
1364 TEST_START("some mean tests");
1365 /* cell a
1366
1367 +------+ 60
1368 | |
1369 | |
1370 | |
1371 +------+ 40
1372 x x+40
1373 */
1374
1375 /* cell b
1376
1377 -------- 39
1378 \ /
1379 \ /
1380 \ /
1381 \/ 20
1382 -20 0 20
1383 */
1384
1385 {
1386 double intersection[3], intersection_lon, intersection_lat;
1387
1388 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -20.0,39.0,20.0,39.0,
1389 YAC_LAT_CIRCLE_EDGE, -20.0,40.0, 0.0,40.0, intersection))
1390 return EXIT_FAILURE;
1391 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1392 intersection_lon /= YAC_RAD;
1393 intersection_lat /= YAC_RAD;
1394
1395 utest_test_clipping(
1396 // input cells
1397 (struct yac_grid_cell[]){
1398 generate_cell_deg((double[]){intersection_lon,intersection_lon+40.0,
1399 intersection_lon+40.0,intersection_lon},
1400 (double[]){40.0,40.0,60.0,60.0}, latlon_edges, 4),
1401 generate_cell_deg((double[]){-20.0,20.0, 0.0},
1402 (double[]){ 39.0,39.0,20.0}, gc_edges, 3)},
1403 // reference cells
1404 (struct yac_grid_cell[]){
1405 generate_cell_deg((double[]){intersection_lon,-intersection_lon},
1406 (double[]){40.0,40.0},
1407 (enum yac_edge_type[]){
1409 generate_cell_deg((double[]){intersection_lon,-intersection_lon},
1410 (double[]){40.0,40.0},
1411 (enum yac_edge_type[]){
1413 // number of reference cells
1414 2);
1415 }
1416
1417 TEST_START("some mean tests");
1418 /* cell a
1419
1420 +------+ 60
1421 | |
1422 | |
1423 | |
1424 +------+ 40
1425 x x+40
1426 */
1427
1428 /* cell b
1429
1430 |\ 50
1431 | \
1432 | \
1433 | \
1434 -------- 39
1435 -20 0 20
1436 */
1437
1438 {
1439 double intersection[3][3], intersection_lon[3], intersection_lat[3];
1440
1441 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -20.0,39.0,20.0,39.0,
1442 YAC_LAT_CIRCLE_EDGE, -20.0,40.0, 0.0,40.0, intersection[0]))
1443 return EXIT_FAILURE;
1444 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 20.0,39.0,-20.0,50.0,
1445 YAC_LAT_CIRCLE_EDGE, -20.0,40.0, 20.0,40.0, intersection[1]))
1446 return EXIT_FAILURE;
1447 for (int i = 0; i < 2; ++i) {
1448 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1449 intersection_lon[i] /= YAC_RAD;
1450 intersection_lat[i] /= YAC_RAD;
1451 }
1452 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 20.0,39.0,-20.0,50.0,
1453 YAC_LON_CIRCLE_EDGE, intersection_lon[0],40.0,
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;
1459
1460 utest_test_clipping(
1461 // input cells
1462 (struct yac_grid_cell[]){
1463 generate_cell_deg((double[]){intersection_lon[0],
1464 intersection_lon[0]+40.0,
1465 intersection_lon[0]+40.0,
1466 intersection_lon[0]},
1467 (double[]){40.0,40.0,60.0,60.0}, latlon_edges, 4),
1468 generate_cell_deg((double[]){-20.0,20.0,-20.0},
1469 (double[]){ 39.0,39.0, 50.0}, gc_edges, 3)},
1470 // reference cells
1471 (struct yac_grid_cell[]){
1472 generate_cell_deg((double[]){intersection_lon[0],-intersection_lon[0],
1473 intersection_lon[1],intersection_lon[2]},
1474 (double[]){40.0,40.0,40.0,intersection_lat[2]},
1475 (enum yac_edge_type[]){
1478 // number of reference cells
1479 1);
1480 }
1481
1482 TEST_START("some mean tests");
1483 /* cell a
1484
1485 +------+ 60
1486 | |
1487 | |
1488 | |
1489 +------+ 40
1490 -20 20
1491 */
1492
1493 /* cell b
1494
1495 -------- 40
1496 \ /
1497 \ /
1498 \ /
1499 \/ 20
1500 -20 0 20
1501 */
1502
1503 {
1504 utest_test_clipping(
1505 // input cells
1506 (struct yac_grid_cell[]){
1507 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1508 (double[]){ 40.0,40.0,60.0, 60.0}, latlon_edges, 4),
1509 generate_cell_deg((double[]){-20.0, 0.0,20.0},
1510 (double[]){ 40.0,20.0,40.0}, gc_edges, 3)},
1511 // reference cells
1512 (struct yac_grid_cell[]){
1513 generate_cell_deg((double[]){-20.0,20.0},
1514 (double[]){ 40.0,40.0},
1515 (enum yac_edge_type[]){
1517 generate_cell_deg((double[]){-20.0,20.0},
1518 (double[]){ 40.0,40.0},
1519 (enum yac_edge_type[]){
1521 // number of reference cells
1522 2);
1523 }
1524
1525 TEST_START("some mean tests");
1526 /* cell a
1527
1528 +------+ 60
1529 | |
1530 | |
1531 | |
1532 +------+ 40
1533 -20 20
1534 */
1535
1536 /* cell b
1537
1538 /\ 50
1539 / \
1540 / \
1541 / \
1542 -------- 40
1543 -20 0 20
1544 */
1545
1546 {
1547 utest_test_clipping(
1548 // input cells
1549 (struct yac_grid_cell[]){
1550 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1551 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
1552 generate_cell_deg((double[]){-20.0, 0.0,20.0},
1553 (double[]){ 40.0,50.0,40.0}, gc_edges, 3)},
1554 // reference cells
1555 (struct yac_grid_cell[]){
1556 generate_cell_deg((double[]){-20.0,20.0,0.0},
1557 (double[]){40.0,40.0,50.0},
1558 (enum yac_edge_type[]){
1560 // number of reference cells
1561 1);
1562 }
1563
1564 TEST_START("some mean tests");
1565 /* cell a
1566
1567 +------+ 60
1568 | |
1569 | |
1570 | |
1571 +------+ 40
1572 -20 20
1573 */
1574
1575 /* cell b
1576
1577 -------- 60
1578 \ /
1579 \ /
1580 \ /
1581 \/ 50
1582 -20 0 20
1583 */
1584
1585 {
1586 utest_test_clipping(
1587 // input cells
1588 (struct yac_grid_cell[]){
1589 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1590 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
1591 generate_cell_deg((double[]){-20.0, 0.0,20.0},
1592 (double[]){ 60.0,50.0,60.0}, gc_edges, 3)},
1593 // reference cells
1594 (struct yac_grid_cell[]){
1595 generate_cell_deg((double[]){-20.0,20.0,0.0},
1596 (double[]){60.0,60.0,50.0},
1597 (enum yac_edge_type[]){
1599 // number of reference cells
1600 1);
1601 }
1602
1603 TEST_START("some mean tests");
1604 /* cell a
1605
1606 +------+ 60
1607 | |
1608 | |
1609 | |
1610 +------+ 40
1611 -20 20
1612 */
1613
1614 /* cell b
1615
1616 /\ 70
1617 / \
1618 / \
1619 / \
1620 -------- 60
1621 -20 0 20
1622 */
1623
1624 {
1625 utest_test_clipping(
1626 // input cells
1627 (struct yac_grid_cell[]){
1628 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1629 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
1630 generate_cell_deg((double[]){-20.0, 0.0,20.0},
1631 (double[]){ 60.0,70.0,60.0}, gc_edges, 3)},
1632 // reference cells
1633 (struct yac_grid_cell[]){
1634 generate_cell_deg((double[]){-20.0,20.0},
1635 (double[]){60.0,60.0},
1636 (enum yac_edge_type[]){
1638 generate_cell_deg((double[]){-20.0,20.0},
1639 (double[]){60.0,60.0},
1640 (enum yac_edge_type[]){
1642 // number of reference cells
1643 2);
1644 }
1645
1646 TEST_START("some mean tests");
1647 /* cell a
1648
1649 +------+ -40
1650 | |
1651 | |
1652 | |
1653 +------+ -60
1654 -20 20
1655 */
1656
1657 /* cell b
1658
1659 -------- -40
1660 \ /
1661 \ /
1662 \ /
1663 \/ -50
1664 -20 0 20
1665 */
1666
1667 {
1668 utest_test_clipping(
1669 // input cells
1670 (struct yac_grid_cell[]){
1671 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1672 (double[]){-40.0,-40.0,-60.0,-60.0}, latlon_edges, 4),
1673 generate_cell_deg((double[]){-20.0, 0.0,20.0},
1674 (double[]){-40.0,-50.0,-40.0}, gc_edges, 3)},
1675 // reference cells
1676 (struct yac_grid_cell[]){
1677 generate_cell_deg((double[]){-20.0,20.0,0.0},
1678 (double[]){-40.0,-40.0,-50.0}, gc_edges, 3)},
1679 // number of reference cells
1680 1);
1681 }
1682
1683 TEST_START("some mean tests");
1684 /* cell a
1685
1686 +------+ 60
1687 | |
1688 | |
1689 | |
1690 +------+ 40
1691 -20 20
1692 */
1693
1694 /* cell b
1695
1696 59 ___..--- 60
1697 \ /
1698 \ /
1699 \ /
1700 \/ 45
1701 -15 0 15
1702 */
1703
1704 {
1705 double intersection[3], intersection_lon, intersection_lat;
1706
1707 if (!intersect(YAC_LAT_CIRCLE_EDGE, -20.0,60.0,14.9,60.0,
1708 YAC_GREAT_CIRCLE_EDGE, -15.0,59.0,15.0,60.0, intersection))
1709 return EXIT_FAILURE;
1710 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1711 intersection_lon /= YAC_RAD;
1712 intersection_lat /= YAC_RAD;
1713
1714 utest_test_clipping(
1715 // input cells
1716 (struct yac_grid_cell[]){
1717 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1718 (double[]){60.0,60.0,40.0,40.0}, latlon_edges, 4),
1719 generate_cell_deg((double[]){-15.0, 0.0,15.0},
1720 (double[]){59.0,45.0,60.0}, gc_edges, 3)},
1721 // reference cells
1722 (struct yac_grid_cell[]){
1723 generate_cell_deg((double[]){intersection_lon,15.0,0.0,-15.0},
1724 (double[]){intersection_lat,60.0,45.0,59.0},
1725 (enum yac_edge_type[]){
1728 // number of reference cells
1729 1);
1730 }
1731
1732 TEST_START("some mean tests");
1733 /* cell a
1734
1735 +------+ 60
1736 +------+ 59
1737 -20 20
1738 */
1739
1740 /* cell b
1741
1742 -------- 58.5
1743 \ /
1744 \ /
1745 \ /
1746 \/ 40
1747 -20 0 20
1748 */
1749
1750 {
1751 double intersection[2][3], intersection_lon[2], intersection_lat[2];
1752
1753 if (!intersect(YAC_LAT_CIRCLE_EDGE, -20.0, 59.0, 0.0, 59.0,
1754 YAC_GREAT_CIRCLE_EDGE, -20.0, 58.5,20.0, 58.5, intersection[0]))
1755 return EXIT_FAILURE;
1756 if (!intersect(YAC_LAT_CIRCLE_EDGE, -20.0, 60.0, 0.0, 60.0,
1757 YAC_GREAT_CIRCLE_EDGE, -20.0, 58.5,20.0, 58.5, intersection[1]))
1758 return EXIT_FAILURE;
1759 for (int i = 0; i < 2; ++i) {
1760 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1761 intersection_lon[i] /= YAC_RAD;
1762 intersection_lat[i] /= YAC_RAD;
1763 }
1764
1765 utest_test_clipping(
1766 // input cells
1767 (struct yac_grid_cell[]){
1768 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1769 (double[]){60.0,60.0,59.0,59.0}, latlon_edges, 4),
1770 generate_cell_deg((double[]){-20.0, 0.0,20.0},
1771 (double[]){58.5,40.0,58.5}, gc_edges, 3)},
1772 // reference cells
1773 (struct yac_grid_cell[]){
1774 generate_cell_deg((double[]){ intersection_lon[0],
1775 intersection_lon[1],
1776 -intersection_lon[1],
1777 -intersection_lon[0]},
1778 (double[]){59.0,60.0,60.0,59.0},
1779 (enum yac_edge_type[]){
1782 // number of reference cells
1783 1);
1784 }
1785
1786 TEST_START("some mean tests");
1787 /* cell a
1788
1789 +------+ 60
1790 | |
1791 | |
1792 | |
1793 +------+ 40
1794 -20 20
1795 */
1796
1797 /* cell b
1798
1799 /\ 80
1800 / \
1801 / \
1802 / \
1803 -------- 59
1804 -20 0 20
1805 */
1806
1807 {
1808 double intersection[2][3], intersection_lon[2], intersection_lat[2];
1809
1810 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 20.0,59.0,0.0,80.0,
1811 YAC_LAT_CIRCLE_EDGE, -20.0, 60.0,20.0,60.0, intersection[0]))
1812 return EXIT_FAILURE;
1813 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 20.0, 59.0,-20.0, 59.0,
1814 YAC_LAT_CIRCLE_EDGE, -20.0, 60.0, 0.0, 60.0, intersection[1]))
1815 return EXIT_FAILURE;
1816 for (int i = 0; i < 2; ++i) {
1817 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1818 intersection_lon[i] /= YAC_RAD;
1819 intersection_lat[i] /= YAC_RAD;
1820 }
1821
1822 utest_test_clipping(
1823 // input cells
1824 (struct yac_grid_cell[]){
1825 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1826 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
1827 generate_cell_deg((double[]){-20.0, 0.0,20.0},
1828 (double[]){59.0,80.0,59.0}, gc_edges, 3)},
1829 // reference cells
1830 (struct yac_grid_cell[]){
1831 generate_cell_deg((double[]){20.0,intersection_lon[0],
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},
1836 (enum yac_edge_type[]){
1839 generate_cell_deg((double[]){20.0,intersection_lon[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},
1844 (enum yac_edge_type[]){
1847 // number of reference cells
1848 2);
1849 }
1850
1851 TEST_START("some mean tests");
1852 /* cell a
1853
1854 +------+ 60
1855 | |
1856 | |
1857 | |
1858 +------+ 40
1859 -20 20
1860 */
1861
1862 /* cell b
1863
1864 -------- 59
1865 \ /
1866 \ /
1867 \ /
1868 \/ 50
1869 -20 0 20
1870 */
1871
1872 {
1873 double intersection[3], intersection_lon, intersection_lat;
1874
1875 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 20.0,59.0,-20.0,59.0,
1876 YAC_LAT_CIRCLE_EDGE, -20.0,60.0,0.0,60.0, intersection))
1877 return EXIT_FAILURE;
1878 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1879 intersection_lon /= YAC_RAD;
1880 intersection_lat /= YAC_RAD;
1881
1882 utest_test_clipping(
1883 // input cells
1884 (struct yac_grid_cell[]){
1885 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1886 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
1887 generate_cell_deg((double[]){-20.0, 0.0,20.0},
1888 (double[]){59.0,50.0,59.0}, gc_edges, 3)},
1889 // reference cells
1890 (struct yac_grid_cell[]){
1891 generate_cell_deg((double[]){intersection_lon,-intersection_lon,
1892 20.0,0.0,-20.0},
1893 (double[]){60.0,60.0,59.0,50.0,59.0},
1894 (enum yac_edge_type[]){
1897 // number of reference cells
1898 1);
1899 }
1900
1901 TEST_START("some mean tests");
1902 /* cell a
1903
1904 +------+ 20
1905 | |
1906 | |
1907 | |
1908 +------+ -20
1909 -20 20
1910 */
1911
1912 /* cell b
1913
1914 +------+ 19
1915 | |
1916 | |
1917 | |
1918 +------+ -19
1919 -19 19
1920 */
1921
1922 {
1923 double intersection[3], intersection_lon, intersection_lat;
1924
1925 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -19.0,19.0,19.0,19.0,
1926 YAC_LAT_CIRCLE_EDGE, -20.0,20.0, 0.0,20.0, intersection))
1927 return EXIT_FAILURE;
1928 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1929 intersection_lon /= YAC_RAD;
1930 intersection_lat /= YAC_RAD;
1931
1932 utest_test_clipping(
1933 // input cells
1934 (struct yac_grid_cell[]){
1935 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1936 (double[]){ 20.0,20.0,-20.0,-20.0}, latlon_edges, 4),
1937 generate_cell_deg((double[]){-19.0,-19.0,19.0,19.0},
1938 (double[]){ 19.0,-19.0,-19.0,19.0}, gc_edges, 4)},
1939 // reference cells
1940 (struct yac_grid_cell[]){
1941 generate_cell_deg((double[]){-19.0,intersection_lon,
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},
1946 (enum yac_edge_type[]){
1950 // number of reference cells
1951 1);
1952 }
1953
1954 TEST_START("some mean tests");
1955 /* cell a
1956
1957 +------+ 60
1958 | |
1959 | |
1960 | |
1961 +------+ 40
1962 -20 20
1963 */
1964
1965 /* cell b
1966
1967 /\ 55
1968 / \
1969 / \
1970 / \
1971 -------- 45
1972 -40 -20 0
1973 */
1974
1975 {
1976 double intersection[3], intersection_lon, intersection_lat;
1977
1978 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -40.0, 45.0, 0.0, 45.0,
1979 YAC_LON_CIRCLE_EDGE, -20.0, 40.0,-20.0, 60.0, intersection))
1980 return EXIT_FAILURE;
1981 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1982 intersection_lon /= YAC_RAD;
1983 intersection_lat /= YAC_RAD;
1984
1985 utest_test_clipping(
1986 // input cells
1987 (struct yac_grid_cell[]){
1988 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
1989 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
1990 generate_cell_deg((double[]){-40.0, 0.0,-20.0},
1991 (double[]){ 45.0,45.0,55.0}, gc_edges, 3)},
1992 // reference cells
1993 (struct yac_grid_cell[]){
1994 generate_cell_deg((double[]){-20.0,-20.0,0.0},
1995 (double[]){intersection_lat,55.0,45.0},
1996 (enum yac_edge_type[]){
1998 // number of reference cells
1999 1);
2000 }
2001
2002 TEST_START("some mean tests");
2003 /* cell a
2004
2005 +------+ 60
2006 | |
2007 | |
2008 | |
2009 +------+ 40
2010 -20 20
2011 */
2012
2013 /* cell b
2014
2015 /| 50
2016 / |
2017 / | 40
2018 \ |
2019 \ |
2020 \| 30
2021 -10 10
2022 */
2023
2024 {
2025 utest_test_clipping(
2026 // input cells
2027 (struct yac_grid_cell[]){
2028 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
2029 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2030 generate_cell_deg((double[]){-10.0,10.0,10.0},
2031 (double[]){ 40.0,30.0,50.0}, gc_edges, 3)},
2032 // reference cells
2033 (struct yac_grid_cell[]){
2034 generate_cell_deg((double[]){-10.0,10.0,10.0},
2035 (double[]){40.0,50.0,40.0},
2036 (enum yac_edge_type[]){
2038 // number of reference cells
2039 1);
2040 }
2041
2042 TEST_START("some mean tests");
2043 /* cell a
2044
2045 +------+ 60
2046 | |
2047 | |
2048 | |
2049 +------+ 40
2050 -20 20
2051 */
2052
2053 /* cell b
2054
2055 /| 80
2056 / |
2057 / |
2058 / |
2059 61 --...__|
2060 59
2061 -20 21
2062 */
2063
2064 {
2065 double intersection[2][3], intersection_lon[2], intersection_lat[2];
2066
2067 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -20.0, 61.0,21.0, 59.0,
2068 YAC_LAT_CIRCLE_EDGE, -20.0, 60.0,20.0, 60.0, intersection[0]))
2069 return EXIT_FAILURE;
2070 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -20.0, 61.0,21.0, 59.0,
2071 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[1]))
2072 return EXIT_FAILURE;
2073 for (int i = 0; i < 2; ++i) {
2074 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2075 intersection_lon[i] /= YAC_RAD;
2076 intersection_lat[i] /= YAC_RAD;
2077 }
2078
2079 utest_test_clipping(
2080 // input cells
2081 (struct yac_grid_cell[]){
2082 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
2083 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2084 generate_cell_deg((double[]){-20.0,21.0,21.0},
2085 (double[]){61.0,80.0,59.0}, gc_edges, 3)},
2086 // reference cells
2087 (struct yac_grid_cell[]){
2088 generate_cell_deg((double[]){20.0,intersection_lon[0],
2089 intersection_lon[1]},
2090 (double[]){60.0,intersection_lat[0],
2091 intersection_lat[1]},
2092 (enum yac_edge_type[]){
2094 // number of reference cells
2095 1);
2096 }
2097
2098 TEST_START("some mean tests");
2099 /* cell a
2100
2101 +------+ 60
2102 | |
2103 | |
2104 | |
2105 +------+ 40
2106 -20 20
2107 */
2108
2109 /* cell b
2110
2111 /\ x (slightly above 40)
2112 / \
2113 / \
2114 / \
2115 -------- 30
2116 -20 0 20
2117 */
2118
2119 {
2120 double intersection[2][3], intersection_lon[2], intersection_lat[2];
2121
2122 if (!intersect(YAC_LON_CIRCLE_EDGE, 0.0,60.0,0.0,30.0,
2123 YAC_GREAT_CIRCLE_EDGE, -20.0, 40.0,20.0, 40.0, intersection[0]))
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;
2128 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.0,intersection_lat[0],20.0,30.0,
2129 YAC_LAT_CIRCLE_EDGE, -20.0, 40.0,20.0, 40.0, intersection[1]))
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;
2134
2135 utest_test_clipping(
2136 // input cells
2137 (struct yac_grid_cell[]){
2138 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
2139 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2140 generate_cell_deg((double[]){-20.0,20.0, 0.0},
2141 (double[]){30.0,30.0,intersection_lat[0]},
2142 gc_edges, 3)},
2143 // reference cells
2144 (struct yac_grid_cell[]){
2145 generate_cell_deg((double[]){0.0,intersection_lon[1],
2146 -intersection_lon[1]},
2147 (double[]){intersection_lat[0],40.0,40.0},
2148 (enum yac_edge_type[]){
2150 // number of reference cells
2151 1);
2152 }
2153
2154 TEST_START("some mean tests");
2155 /* cell a
2156
2157 +------+ 60
2158 | |
2159 | |
2160 | |
2161 +------+ 40
2162 -20 20
2163 */
2164
2165 /* cell b
2166
2167 /\ 70
2168 / \
2169 / \
2170 / \
2171 -------- 59
2172 -21 0 21
2173 */
2174
2175 {
2176 double intersection[4][3], intersection_lon[4], intersection_lat[4];
2177
2178 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -21.0, 59.0,21.0, 59.0,
2179 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[0]))
2180 return EXIT_FAILURE;
2181 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.0,70.0,21.0,59.0,
2182 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[1]))
2183 return EXIT_FAILURE;
2184 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.0,70.0,21.0,59.0,
2185 YAC_LAT_CIRCLE_EDGE, -20.0, 60.0,20.0, 60.0, intersection[2]))
2186 return EXIT_FAILURE;
2187 if (!intersect(YAC_GREAT_CIRCLE_EDGE,-21.0, 59.0,21.0, 59.0,
2188 YAC_LAT_CIRCLE_EDGE, 0.0,60.0,20.0,60.0, intersection[3]))
2189 return EXIT_FAILURE;
2190 for (int i = 0; i < 4; ++i) {
2191 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2192 intersection_lon[i] /= YAC_RAD;
2193 intersection_lat[i] /= YAC_RAD;
2194 }
2195
2196 utest_test_clipping(
2197 // input cells
2198 (struct yac_grid_cell[]){
2199 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
2200 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2201 generate_cell_deg((double[]){-21.0, 0.0,21.0},
2202 (double[]){59.0,70.0,59.0}, gc_edges, 3)},
2203 // reference cells
2204 (struct yac_grid_cell[]){
2205 generate_cell_deg((double[]){20.0,20.0,intersection_lon[2],
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]},
2211 (enum yac_edge_type[]){
2215 generate_cell_deg((double[]){20.0,20.0,intersection_lon[2],
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},
2222 (enum yac_edge_type[]){
2227 generate_cell_deg((double[]){20.0,20.0,intersection_lon[2],
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},
2233 (enum yac_edge_type[]){
2237 // number of reference cells
2238 3);
2239 }
2240
2241 TEST_START("some mean tests");
2242 /* cell a
2243
2244 +------+ 60
2245 | |
2246 | |
2247 | |
2248 +------+ 40
2249 -x x (x is choosen such that the upper corners of the
2250 quadrangle touch the sloping edges of the triangle)
2251 */
2252
2253 /* cell b
2254
2255 /\ 70
2256 / \
2257 / \
2258 / \
2259 -------- 59
2260 -21 0 21
2261 */
2262
2263 {
2264 double intersection[3][3], intersection_lon[3], intersection_lat[3];
2265
2266 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.0,70.0,21.0,59.0,
2267 YAC_LAT_CIRCLE_EDGE, 0.0,60.0,25.0,60.0, intersection[0]))
2268 return EXIT_FAILURE;
2269 if (!intersect(YAC_GREAT_CIRCLE_EDGE,-21.0,59.0,21.0,59.0,
2270 YAC_LAT_CIRCLE_EDGE, 0.0,60.0,25.0,60.0, intersection[1]))
2271 return EXIT_FAILURE;
2272 for (int i = 0; i < 2; ++i) {
2273 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2274 intersection_lon[i] /= YAC_RAD;
2275 intersection_lat[i] /= YAC_RAD;
2276 }
2277 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -21.0, 59.0,21.0, 59.0,
2278 YAC_LON_CIRCLE_EDGE, intersection_lon[0],60.0,intersection_lon[0],
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;
2284
2285 utest_test_clipping(
2286 // input cells
2287 (struct yac_grid_cell[]){
2288 generate_cell_deg((double[]){-intersection_lon[0],intersection_lon[0],
2289 intersection_lon[0],-intersection_lon[0]},
2290 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2291 generate_cell_deg((double[]){-21.0, 0.0,21.0},
2292 (double[]){59.0,70.0,59.0}, gc_edges, 3)},
2293 // reference cells
2294 (struct yac_grid_cell[]){
2295 generate_cell_deg((double[]){intersection_lon[2],intersection_lon[0],
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]},
2300 (enum yac_edge_type[]){
2303 generate_cell_deg((double[]){intersection_lon[2],intersection_lon[0],
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},
2309 (enum yac_edge_type[]){
2313 generate_cell_deg((double[]){intersection_lon[2],intersection_lon[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},
2318 (enum yac_edge_type[]){
2321 // number of reference cells
2322 3);
2323 }
2324
2325 TEST_START("some mean tests");
2326 /* cell a
2327
2328 +------+ 60
2329 | |
2330 | |
2331 | |
2332 +------+ 40
2333 -20 20
2334 */
2335
2336 /* cell b
2337
2338 -------- 59
2339 \ /
2340 \ /
2341 \ /
2342 \/ 50
2343 -21 0 21
2344 */
2345
2346 {
2347 double intersection[3][3], intersection_lon[3], intersection_lat[3];
2348
2349 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 21.0,59.0,-21.0,59.0,
2350 YAC_LAT_CIRCLE_EDGE, 0.0,60.0,20.0,60.0, intersection[0]))
2351 return EXIT_FAILURE;
2352 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 21.0, 59.0,-21.0, 59.0,
2353 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[1]))
2354 return EXIT_FAILURE;
2355
2356 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.0,50.0,21.0,59.0,
2357 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[2]))
2358 return EXIT_FAILURE;
2359 for (int i = 0; i < 3; ++i) {
2360 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2361 intersection_lon[i] /= YAC_RAD;
2362 intersection_lat[i] /= YAC_RAD;
2363 }
2364
2365 utest_test_clipping(
2366 // input cells
2367 (struct yac_grid_cell[]){
2368 generate_cell_deg((double[]){-20.0,20.0,20.0,-20.0},
2369 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2370 generate_cell_deg((double[]){-21.0, 0.0,21.0},
2371 (double[]){59.0,50.0,59.0}, gc_edges, 3)},
2372 // reference cells
2373 (struct yac_grid_cell[]){
2374 generate_cell_deg((double[]){intersection_lon[0],20.0,20.0,0.0,-20.0,
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],
2379 60.0},
2380 (enum yac_edge_type[]){
2383 YAC_LAT_CIRCLE_EDGE}, 7)},
2384 // number of reference cells
2385 1);
2386 }
2387
2388 TEST_START("some mean tests");
2389 /* cell a (circle around a pole)
2390
2391 .--.
2392 / \
2393 \ /
2394 '--'
2395 */
2396
2397 /* cell b (circle around a pole; bigger than cell a)
2398
2399 .-""-.
2400 / \
2401 ; ;
2402 \ /
2403 '-..-'
2404 */
2405
2406 {
2407
2408 utest_test_clipping(
2409 // input cells
2410 (struct yac_grid_cell[]){
2411 generate_cell_deg((double[]){ 0.0,72.0,144.0,216.0,288.0},
2412 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2413 (enum yac_edge_type[]){
2416 generate_cell_deg((double[]){ 0.0,72.0,144.0,216.0,288.0},
2417 (double[]){ 80.0,80.0,80.0,80.0,80.0},
2418 (enum yac_edge_type[]){
2421 // reference cells
2422 (struct yac_grid_cell[]){
2423 generate_cell_deg((double[]){ 0.0,72.0,144.0,216.0,288.0},
2424 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2425 (enum yac_edge_type[]){
2428 // number of reference cells
2429 1);
2430 }
2431
2432 TEST_START("some mean tests");
2433 /* cell a (circle around a pole)
2434
2435 .-""-.
2436 / \
2437 ; ;
2438 \ /
2439 '-..-'
2440 */
2441
2442 /* cell b (circle around a pole; same size as cell a)
2443
2444 .-""-.
2445 / \
2446 ; ;
2447 \ /
2448 '-..-'
2449 */
2450
2451 {
2452
2453 utest_test_clipping(
2454 // input cells
2455 (struct yac_grid_cell[]){
2456 generate_cell_deg((double[]){ 0.0,72.0,144.0,216.0,288.0},
2457 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2458 (enum yac_edge_type[]){
2461 generate_cell_deg((double[]){ 0.0,72.0,144.0,216.0,288.0},
2462 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2463 (enum yac_edge_type[]){
2466 // reference cells
2467 (struct yac_grid_cell[]){
2468 generate_cell_deg((double[]){ 0.0,72.0,144.0,216.0,288.0},
2469 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2470 (enum yac_edge_type[]){
2473 // number of reference cells
2474 1);
2475 }
2476
2477 TEST_START("some mean tests");
2478 /* cell a (circle around a pole)
2479
2480 .-""-.
2481 / \
2482 ; ;
2483 \ /
2484 '-..-'
2485 */
2486
2487 /* cell b (circle around different pole than cell a)
2488
2489 .-""-.
2490 / \
2491 ; ;
2492 \ /
2493 '-..-'
2494 */
2495
2496 {
2497
2498 utest_test_clipping(
2499 // input cells
2500 (struct yac_grid_cell[]){
2501 generate_cell_deg((double[]){ 0.0,72.0,144.0,216.0,288.0},
2502 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2503 (enum yac_edge_type[]){
2506 generate_cell_deg((double[]){ 0.0,72.0,144.0,216.0,288.0},
2507 (double[]){-85.0,-85.0,-85.0,-85.0,-85.0},
2508 (enum yac_edge_type[]){
2511 // reference cells
2512 (struct yac_grid_cell[]){
2513 generate_cell_deg(NULL, NULL, NULL, 0)},
2514 // number of reference cells
2515 1);
2516 }
2517
2518 TEST_START("some mean tests");
2519 /* cell a (circle around a pole; made of lat circle edges)
2520
2521 .-""-.
2522 / \
2523 ; ;
2524 \ /
2525 '-..-'
2526 */
2527
2528 /* cell b (circle around a pole; made of great circle edges;
2529 corners are on the lat circles)
2530
2531 ____
2532 / \
2533 / \
2534 * *
2535 \ /
2536 \____/
2537 */
2538
2539 {
2540
2541 utest_test_clipping(
2542 // input cells
2543 (struct yac_grid_cell[]){
2544 generate_cell_deg((double[]){ 0.0,72.0,144.0,216.0,288.0},
2545 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2546 (enum yac_edge_type[]){
2549 generate_cell_deg((double[]){ 0.0,60.0,120.0,180.0,240.0,300.0},
2550 (double[]){ 85.0,85.0,85.0,85.0,85.0,85.0},
2551 (enum yac_edge_type[]){
2554 // reference cells
2555 (struct yac_grid_cell[]){
2556 generate_cell_deg((double[]){ 0.0,60.0,120.0,180.0,240.0,300.0},
2557 (double[]){ 85.0,85.0,85.0,85.0,85.0,85.0},
2558 (enum yac_edge_type[]){
2561 // number of reference cells
2562 1);
2563 }
2564
2565 TEST_START("some mean tests");
2566 /* cell a (circle around a pole; made of lat circle edges)
2567
2568 .-""-.
2569 / \
2570 ; ;
2571 \ /
2572 '-..-'
2573 */
2574
2575 /* cell b (circle around a pole; made of great circle edges;
2576 all great circles edges intersect with the lat circles twice)
2577
2578 ____
2579 / \
2580 / \
2581 * *
2582 \ /
2583 \____/
2584 */
2585
2586 {
2587
2588 double intersection[2][3], intersection_lon[2], intersection_lat[2];
2589
2590 if (!intersect(YAC_LAT_CIRCLE_EDGE, 0.0,85.5,30.0,85.5,
2591 YAC_GREAT_CIRCLE_EDGE, 0.0,85.0,60.0,85.0, intersection[0]))
2592 return EXIT_FAILURE;
2593 if (!intersect(YAC_LAT_CIRCLE_EDGE, 30.0,85.5,60.0,85.5,
2594 YAC_GREAT_CIRCLE_EDGE, 0.0,85.0,60.0,85.0, intersection[1]))
2595 return EXIT_FAILURE;
2596 for (int i = 0; i < 2; ++i) {
2597 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2598 intersection_lon[i] /= YAC_RAD;
2599 intersection_lat[i] /= YAC_RAD;
2600 }
2601
2602 utest_test_clipping(
2603 // input cells
2604 (struct yac_grid_cell[]){
2605 generate_cell_deg((double[]){ 0.0,72.0,144.0,216.0,288.0},
2606 (double[]){ 85.5,85.5,85.5,85.5,85.5},
2607 (enum yac_edge_type[]){
2610 generate_cell_deg((double[]){ 0.0,60.0,120.0,180.0,240.0,300.0},
2611 (double[]){ 85.0,85.0,85.0,85.0,85.0,85.0},
2612 (enum yac_edge_type[]){
2616 // reference cells
2617 (struct yac_grid_cell[]){
2618 generate_cell_deg((double[]){intersection_lon[0]+60.0*0.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},
2632 (enum yac_edge_type[]){
2639 12)},
2640 // number of reference cells
2641 1);
2642 }
2643
2645 TEST_START("example taken from bug report by Uwe");
2646
2647 /* 13.) source cell test data
2648
2649 +------+ 5
2650 | |
2651 | |
2652 | |
2653 +------+ 0
2654 355 360
2655 */
2656
2657 /* target cell test data
2658
2659 +------+ 0
2660 | |
2661 | |
2662 | |
2663 +------+ -10
2664 240 250
2665 */
2666
2667 {
2668 utest_test_clipping(
2669 // input cells
2670 (struct yac_grid_cell[]){
2671 generate_cell_deg((double[]){355.0,360.0,360.0,355.0},
2672 (double[]){ 0.0, 0.0, 5.0, 5.0}, gc_edges, 4),
2673 generate_cell_deg((double[]){240.0,250.0,250.0,240.0},
2674 (double[]){-10.0,-10.0, 0.0, 0.0}, gc_edges, 4)},
2675 // reference cells
2676 (struct yac_grid_cell[]){
2677 generate_cell_deg(NULL, NULL, NULL, 0)},
2678 // number of reference cells
2679 1);
2680 }
2681
2683 TEST_START("example taken from icon toy");
2684
2685 /* 14.1) source cell test data
2686
2687 +------+ 2
2688 | |
2689 | |
2690 | |
2691 +------+ 0
2692 0 2
2693 */
2694
2695 /* target cell test data
2696
2697 _______
2698 | / 1
2699 | /
2700 | /
2701 |/ -1
2702 2 4
2703 */
2704
2705 {
2706 utest_test_clipping(
2707 // input cells
2708 (struct yac_grid_cell[]){
2709 generate_cell_deg((double[]){ 2.0,2.0,4.0},
2710 (double[]){-1.0,1.0,1.0}, gc_edges, 3),
2711 generate_cell_deg((double[]){0.0,2.0,2.0,0.0},
2712 (double[]){0.0,0.0,2.0,2.0}, latlon_edges, 4)},
2713 // reference cells
2714 (struct yac_grid_cell[]){
2715 generate_cell_deg(NULL, NULL, NULL, 0)},
2716 // number of reference cells
2717 1);
2718 }
2719
2720 TEST_START("example taken from icon toy");
2721
2722 {
2723 double intersection[3], intersection_lon, intersection_lat;
2724
2725 if (!intersect(YAC_LON_CIRCLE_EDGE, 1.0,90.0,1.0,80.0,
2726 YAC_GREAT_CIRCLE_EDGE, 0.0,85.0,5.0,85.0, intersection))
2727 return EXIT_FAILURE;
2728 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
2729 intersection_lon /= YAC_RAD;
2730 intersection_lat /= YAC_RAD;
2731
2732 utest_test_clipping(
2733 // input cells
2734 (struct yac_grid_cell[]){
2735 generate_cell_deg((double[]){ 0.0,180.0, 5.0},
2736 (double[]){85.0,90.0,85.0}, gc_edges, 3),
2737 generate_cell_deg((double[]){ 1.0,-5.0,-5.0,1.0},
2738 (double[]){80.0,80.0,90.0,90.0}, latlon_edges, 4)},
2739 // reference cells
2740 (struct yac_grid_cell[]){
2741 generate_cell_deg((double[]){1.0,0.0,0.0},
2742 (double[]){intersection_lat,85.0,90.0},
2743 (enum yac_edge_type[]){
2745 // number of reference cells
2746 1);
2747 }
2748
2749 TEST_START("example taken from icon toy");
2750
2751 {
2752
2753 double intersection[4][3], intersection_lon[4], intersection_lat[4];
2754
2755 if (!intersect(YAC_LAT_CIRCLE_EDGE, 0.46633015951723494341,-0.88357293382212931387,
2756 0.49087385212340517437,-0.88357293382212931387,
2757 YAC_GREAT_CIRCLE_EDGE, 0.47953965147452792817,-0.90109638077934106626,
2758 0.46519399935013672209,-0.88122392525212978054,
2759 intersection[0]))
2760 return EXIT_FAILURE;
2761 if (!intersect(YAC_LON_CIRCLE_EDGE, 0.46633015951723494341,-0.88357293382212931387,
2762 0.46633015951723494341,-0.85902924121595902740,
2763 YAC_GREAT_CIRCLE_EDGE, 0.47953965147452792817,-0.90109638077934106626,
2764 0.46519399935013672209,-0.88122392525212978054,
2765 intersection[1]))
2766 return EXIT_FAILURE;
2767 if (!intersect(YAC_LON_CIRCLE_EDGE, 0.46633015951723494341,-0.88357293382212931387,
2768 0.46633015951723494341,-0.85902924121595902740,
2769 YAC_GREAT_CIRCLE_EDGE, 0.50100250912415544846,-0.88440597750634275531,
2770 0.46519399935013672209,-0.88122392525212978054,
2771 intersection[2]))
2772 return EXIT_FAILURE;
2773 if (!intersect(YAC_LON_CIRCLE_EDGE, 0.49087385212340517437,-0.88357293382212931387,
2774 0.49087385212340517437,-0.85902924121595902740,
2775 YAC_GREAT_CIRCLE_EDGE, 0.50100250912415544846,-0.88440597750634275531,
2776 0.46519399935013672209,-0.88122392525212978054,
2777 intersection[3]))
2778 return EXIT_FAILURE;
2779 for (int i = 0; i < 4; ++i) {
2780 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2781 intersection_lon[i] /= YAC_RAD;
2782 intersection_lat[i] /= YAC_RAD;
2783 }
2784
2785 utest_test_clipping(
2786 // input cells
2787 (struct yac_grid_cell[]){
2788 generate_cell_deg((double[]){ 0.46633015951723494341,
2789 0.49087385212340517437,
2790 0.49087385212340517437,
2791 0.46633015951723494341},
2792 (double[]){-0.88357293382212931387,
2793 -0.88357293382212931387,
2794 -0.85902924121595902740,
2795 -0.85902924121595902740}, latlon_edges, 4),
2796 generate_cell_deg((double[]){ 0.47953965147452792817,
2797 0.50100250912415544846,
2798 0.46519399935013672209},
2799 (double[]){-0.90109638077934106626,
2800 -0.88440597750634275531,
2801 -0.88122392525212978054}, gc_edges, 3)},
2802 // reference cells
2803 (struct yac_grid_cell[]){
2804 generate_cell_deg((double[]){0.49087385212340517437,
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]},
2814 (enum yac_edge_type[]){
2817 // number of reference cells
2818 1);
2819 }
2820
2821 TEST_START("example provided by Uwe");
2822
2823 {
2824
2825 double intersection[4][3], intersection_lon[4], intersection_lat[4];
2826
2827 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 180.25,-89.75,180.25,-89.50,
2828 YAC_GREAT_CIRCLE_EDGE, 180.2,-89.6,180.3,-89.6, intersection[0]))
2829 return EXIT_FAILURE;
2830 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 180.25,-89.75,180.25,-89.50,
2831 YAC_GREAT_CIRCLE_EDGE, 180.3,-89.5,180.2,-89.5, intersection[1]))
2832 return EXIT_FAILURE;
2833 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 180.25,-89.5,180.00,-89.5,
2834 YAC_GREAT_CIRCLE_EDGE, 180.3,-89.5,180.2,-89.5, intersection[2]))
2835 return EXIT_FAILURE;
2836 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 180.25,-89.5,180.00,-89.5,
2837 YAC_GREAT_CIRCLE_EDGE, 180.2,-89.5,180.2,-89.6, intersection[3]))
2838 return EXIT_FAILURE;
2839 for (int i = 0; i < 4; ++i) {
2840 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2841 intersection_lon[i] /= YAC_RAD;
2842 intersection_lat[i] /= YAC_RAD;
2843 }
2844
2845 utest_test_clipping(
2846 // input cells
2847 (struct yac_grid_cell[]){
2848 generate_cell_deg((double[]){180.2,180.3,180.3,180.2},
2849 (double[]){-89.6,-89.6,-89.5,-89.5}, gc_edges, 4),
2850 generate_cell_deg((double[]){180.00,180.25,180.25,180.00},
2851 (double[]){-89.75,-89.75,-89.50,-89.50}, gc_edges, 4)},
2852 // reference cells
2853 (struct yac_grid_cell[]){
2854 generate_cell_deg((double[]){180.2,180.25,180.25,
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)},
2859 // number of reference cells
2860 1);
2861 }
2862
2863 TEST_START("example taken from icon toy");
2864
2865 {
2866 double intersection[2][3], intersection_lon[2], intersection_lat[2];
2867
2868 if (!intersect(YAC_LAT_CIRCLE_EDGE, 1.20264093770234/YAC_RAD,
2869 -0.76085447079128/YAC_RAD,
2870 1.22718463030851/YAC_RAD,
2871 -0.76085447079128/YAC_RAD,
2872 YAC_GREAT_CIRCLE_EDGE, 1.20552692320133/YAC_RAD,
2873 -0.76075226373764/YAC_RAD,
2874 1.30774719967050/YAC_RAD,
2875 -0.76075226373764/YAC_RAD, intersection[0]))
2876 return EXIT_FAILURE;
2877 if (!intersect(YAC_LAT_CIRCLE_EDGE, 1.20264093770234/YAC_RAD,
2878 -0.76085447079128/YAC_RAD,
2879 1.22718463030851/YAC_RAD,
2880 -0.76085447079128/YAC_RAD,
2881 YAC_GREAT_CIRCLE_EDGE, 1.20552692320133/YAC_RAD,
2882 -0.76075226373764/YAC_RAD,
2883 1.25663706143592/YAC_RAD,
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]);
2888 intersection_lon[i] /= YAC_RAD;
2889 intersection_lat[i] /= YAC_RAD;
2890 }
2891
2892 utest_test_clipping(
2893 // input cells
2894
2895 (struct yac_grid_cell[2]){
2896 generate_cell_deg((double[]){ 1.20264093770234/YAC_RAD,
2897 1.22718463030851/YAC_RAD,
2898 1.22718463030851/YAC_RAD,
2899 1.20264093770234/YAC_RAD},
2900 (double[]){-0.76085447079128/YAC_RAD,
2901 -0.76085447079128/YAC_RAD,
2902 -0.73631077818511/YAC_RAD,
2903 -0.73631077818511/YAC_RAD},
2904 latlon_edges, 4),
2905 generate_cell_deg((double[]){ 1.20552692320133/YAC_RAD,
2906 1.25663706143592/YAC_RAD,
2907 1.30774719967050/YAC_RAD},
2908 (double[]){-0.76075226373764/YAC_RAD,
2909 -0.82925269516665/YAC_RAD,
2910 -0.76075226373763/YAC_RAD}, gc_edges, 3)},
2911 // reference cells
2912 (struct yac_grid_cell[]){
2913 generate_cell_deg((double[]){1.20552692320133/YAC_RAD,
2914 intersection_lon[0], intersection_lon[1]},
2915 (double[]){-0.76075226373764/YAC_RAD,
2916 intersection_lat[0], intersection_lat[1]},
2917 (enum yac_edge_type[]){
2919 generate_cell_deg((double[]){1.20552692320133/YAC_RAD,
2920 intersection_lon[0],
2921 1.22718463030851/YAC_RAD,
2922 intersection_lon[1]},
2923 (double[]){-0.76075226373764/YAC_RAD,
2924 intersection_lat[0],
2925 -0.76085447079128/YAC_RAD,
2926 intersection_lat[1]},
2927 (enum yac_edge_type[]){
2930 // number of reference cells
2931 2);
2932 }
2933
2934 TEST_START("example in which all coordinates are 0 (occurred in a test"
2935 " of Uwe due to erroneous input data)")
2936 {
2937 utest_test_clipping(
2938 // input cells
2939
2940 (struct yac_grid_cell[2]){
2941 generate_cell_deg((double[]){0, 0, 0, 0},
2942 (double[]){0, 0, 0, 0}, latlon_edges, 4),
2943 generate_cell_deg((double[]){0, 0, 0},
2944 (double[]){0, 0, 0}, gc_edges, 3)},
2945 // reference cells
2946 (struct yac_grid_cell[]){
2947 generate_cell_deg(NULL, NULL, NULL, 0)},
2948 // number of reference cells
2949 1);
2950 }
2951
2952 TEST_START("example example take from ICON_toy");
2953 {
2954 utest_test_clipping(
2955 // input cells
2956
2957 (struct yac_grid_cell[2]){
2958 generate_cell_deg((double[]){3.1415926372157803/YAC_RAD,
2959 0.9682712007396151/YAC_RAD,
2960 -1.8849555862661402/YAC_RAD},
2961 (double[]){-1.5418135425481947/YAC_RAD,
2962 -1.5707963262077691/YAC_RAD,
2963 -1.5418135428532602/YAC_RAD},
2964 gc_edges, 3),
2965 generate_cell_deg((double[]){1.2517283229146832/YAC_RAD,
2966 1.2762720155208536/YAC_RAD,
2967 1.2762720155208536/YAC_RAD,
2968 1.2517283229146832/YAC_RAD},
2969 (double[]){-1.5707963267948966/YAC_RAD,
2970 -1.5707963267948966/YAC_RAD,
2971 -1.5462526341887264/YAC_RAD,
2972 -1.5462526341887264/YAC_RAD},
2973 latlon_edges, 4)},
2974 // reference cells
2975 (struct yac_grid_cell[]){
2976 generate_cell_deg(NULL, NULL, NULL, 0)},
2977 // number of reference cells
2978 1);
2979 }
2980
2981 TEST_START("example take from ICON_toy");
2982 {
2983 double intersection[2][3], intersection_lon[2], intersection_lat[2];
2984
2985 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 0.9682712007396151/YAC_RAD,
2986 -1.5707963262077691/YAC_RAD,
2987 3.1415926372157803/YAC_RAD,
2988 -1.5418135425481947/YAC_RAD,
2989 YAC_LAT_CIRCLE_EDGE, 3.1170489609836229/YAC_RAD,
2990 -1.5462526341887264/YAC_RAD,
2991 3.1415926535897931/YAC_RAD,
2992 -1.5462526341887264/YAC_RAD,
2993 intersection[0]))
2994 return EXIT_FAILURE;
2995 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -1.8849555862661402/YAC_RAD,
2996 -1.5418135428532602/YAC_RAD,
2997 3.1415926372157803/YAC_RAD,
2998 -1.5418135425481947/YAC_RAD,
2999 YAC_LON_CIRCLE_EDGE, 3.1415926535897931/YAC_RAD,
3000 -1.5462526341887264/YAC_RAD,
3001 3.1415926535897931/YAC_RAD,
3002 -1.5217089415825560/YAC_RAD,
3003 intersection[1]))
3004 return EXIT_FAILURE;
3005 for (int i = 0; i < 2; ++i) {
3006 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3007 intersection_lon[i] /= YAC_RAD;
3008 intersection_lat[i] /= YAC_RAD;
3009 }
3010
3011 utest_test_clipping(
3012 // input cells
3013
3014 (struct yac_grid_cell[]){
3015 generate_cell_deg((double[]){ 3.1415926372157803/YAC_RAD,
3016 0.9682712007396151/YAC_RAD,
3017 -1.8849555862661402/YAC_RAD},
3018 (double[]){-1.5418135425481947/YAC_RAD,
3019 -1.5707963262077691/YAC_RAD,
3020 -1.5418135428532602/YAC_RAD}, gc_edges, 3),
3021 generate_cell_deg((double[]){ 3.1170489609836229/YAC_RAD,
3022 3.1415926535897931/YAC_RAD,
3023 3.1415926535897931/YAC_RAD,
3024 3.1170489609836229/YAC_RAD},
3025 (double[]){-1.5462526341887264/YAC_RAD,
3026 -1.5462526341887264/YAC_RAD,
3027 -1.5217089415825560/YAC_RAD,
3028 -1.5217089415825560/YAC_RAD},
3029 latlon_edges, 4)},
3030 // reference cells
3031 (struct yac_grid_cell[]){
3032 generate_cell_deg((double[]){ 3.1415926535897931/YAC_RAD,
3033 intersection_lon[0],
3034 3.1415926372157803/YAC_RAD,
3035 intersection_lon[1]},
3036 (double[]){-1.5462526341887264/YAC_RAD,
3037 intersection_lat[0],
3038 -1.5418135425481947/YAC_RAD,
3039 intersection_lat[1]},
3040 (enum yac_edge_type[]){
3043 generate_cell_deg(NULL, NULL, NULL, 0)},
3044 // number of reference cells
3045 2);
3046 }
3047
3048 TEST_START("example example take from ICON_toy");
3049 {
3050 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3051
3052 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -1.2564300972590368/YAC_RAD,
3053 1.5418206553283160/YAC_RAD,
3054 1.2277260313871721/YAC_RAD,
3055 1.5707871564758291/YAC_RAD,
3056 YAC_LON_CIRCLE_EDGE, 0.0000000000000000/YAC_RAD,
3057 1.5462526341887264/YAC_RAD,
3058 0.0000000000000000/YAC_RAD,
3059 1.5707963267948966/YAC_RAD,
3060 intersection[0]))
3061 return EXIT_FAILURE;
3062 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -1.2564300972590368/YAC_RAD,
3063 1.5418206553283160/YAC_RAD,
3064 1.2277260313871721/YAC_RAD,
3065 1.5707871564758291/YAC_RAD,
3066 YAC_LON_CIRCLE_EDGE, 0.0245436926061703/YAC_RAD,
3067 1.5462526341887264/YAC_RAD,
3068 0.0245436926061703/YAC_RAD,
3069 1.5707963267948966/YAC_RAD,
3070 intersection[1]))
3071 return EXIT_FAILURE;
3072 for (int i = 0; i < 2; ++i) {
3073 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3074 intersection_lon[i] /= YAC_RAD;
3075 intersection_lat[i] /= YAC_RAD;
3076 }
3077
3078 utest_test_clipping(
3079 // input cells
3080 (struct yac_grid_cell[]){
3081 generate_cell_deg((double[]){-1.2564300972590368/YAC_RAD,
3082 1.2277260313871721/YAC_RAD,
3083 -2.5134348157836111/YAC_RAD},
3084 (double[]){ 1.5418206553283160/YAC_RAD,
3085 1.5707871564758291/YAC_RAD,
3086 1.5418209335124486/YAC_RAD}, gc_edges, 3),
3087 generate_cell_deg((double[]){ 0.0000000000000000/YAC_RAD,
3088 0.0245436926061703/YAC_RAD,
3089 0.0245436926061703/YAC_RAD,
3090 0.0000000000000000/YAC_RAD},
3091 (double[]){ 1.5462526341887264/YAC_RAD,
3092 1.5462526341887264/YAC_RAD,
3093 1.5707963267948966/YAC_RAD,
3094 1.5707963267948966/YAC_RAD},
3095 latlon_edges, 4)},
3096 // reference cells
3097 (struct yac_grid_cell[]){
3098 generate_cell_deg((double[]){0,intersection_lon[0],intersection_lon[1]},
3099 (double[]){90.0,intersection_lat[0],
3100 intersection_lat[1]},
3101 (enum yac_edge_type[]){
3103 // number of reference cells
3104 1);
3105 }
3106
3107 TEST_START("example example take from ICON_toy");
3108 {
3109 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3110
3111 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -2.1798479726998332/YAC_RAD,
3112 -0.0311624518327736/YAC_RAD,
3113 -2.1991148570983681/YAC_RAD,
3114 0.0000000043633749/YAC_RAD,
3115 YAC_LAT_CIRCLE_EDGE, 4.0742529726242633/YAC_RAD,
3116 0.0000000000000000/YAC_RAD,
3117 4.0987966652304335/YAC_RAD,
3118 0.0000000000000000/YAC_RAD,
3119 intersection[0]))
3120 return EXIT_FAILURE;
3121 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -2.2190472361409284/YAC_RAD,
3122 -0.0338654325037920/YAC_RAD,
3123 -2.1991148570983681/YAC_RAD,
3124 0.0000000043633749/YAC_RAD,
3125 YAC_LAT_CIRCLE_EDGE, 4.0742529726242633/YAC_RAD,
3126 0.0000000000000000/YAC_RAD,
3127 4.0987966652304335/YAC_RAD,
3128 0.0000000000000000/YAC_RAD,
3129 intersection[1]))
3130 return EXIT_FAILURE;
3131 for (int i = 0; i < 2; ++i) {
3132 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3133 intersection_lon[i] /= YAC_RAD;
3134 intersection_lat[i] /= YAC_RAD;
3135 }
3136
3137 utest_test_clipping(
3138
3139 // input cells
3140 (struct yac_grid_cell[]){
3141 generate_cell_deg((double[]){-2.1798479726998332/YAC_RAD,
3142 -2.1991148570983681/YAC_RAD,
3143 -2.2190472361409284/YAC_RAD},
3144 (double[]){-0.0311624518327736/YAC_RAD,
3145 0.0000000043633749/YAC_RAD,
3146 -0.0338654325037920/YAC_RAD},
3147 gc_edges, 3),
3148 generate_cell_deg((double[]){ 4.0742529726242633/YAC_RAD,
3149 4.0987966652304335/YAC_RAD,
3150 4.0987966652304335/YAC_RAD,
3151 4.0742529726242633/YAC_RAD},
3152 (double[]){ 0.0000000000000000/YAC_RAD,
3153 0.0000000000000000/YAC_RAD,
3154 0.0245436926061703/YAC_RAD,
3155 0.0245436926061703/YAC_RAD},
3156 latlon_edges, 4)},
3157 // reference cells
3158 (struct yac_grid_cell[]){
3159 generate_cell_deg((double[]){-2.1991148570983681/YAC_RAD,
3160 intersection_lon[0],
3161 intersection_lon[1]},
3162 (double[]){0.0000000043633749/YAC_RAD,
3163 0.0000000000000000/YAC_RAD,
3164 0.0000000000000000/YAC_RAD},
3165 (enum yac_edge_type[]){
3167 // number of reference cells
3168 1);
3169 }
3170
3171 TEST_START("example example take from ICON_toy");
3172 {
3173 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3174
3175 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 3.1415926521557882/YAC_RAD,
3176 -0.9805860393425995/YAC_RAD,
3177 3.1415926520689506/YAC_RAD,
3178 -1.0172219678978514/YAC_RAD,
3179 YAC_LAT_CIRCLE_EDGE, 3.1415926535897931/YAC_RAD,
3180 -1.0062913968529805/YAC_RAD,
3181 3.1170489609836229/YAC_RAD,
3182 -1.0062913968529805/YAC_RAD,
3183 intersection[0]))
3184 return EXIT_FAILURE;
3185 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 3.1415926521557882/YAC_RAD,
3186 -0.9805860393425995/YAC_RAD,
3187 3.1415926520689506/YAC_RAD,
3188 -1.0172219678978514/YAC_RAD,
3189 YAC_LAT_CIRCLE_EDGE, 3.1415926535897931/YAC_RAD,
3190 -0.9817477042468103/YAC_RAD,
3191 3.1170489609836229/YAC_RAD,
3192 -0.9817477042468103/YAC_RAD,
3193 intersection[1]))
3194 return EXIT_FAILURE;
3195 for (int i = 0; i < 2; ++i) {
3196 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3197 intersection_lon[i] /= YAC_RAD;
3198 intersection_lat[i] /= YAC_RAD;
3199 }
3200
3201 utest_test_clipping(
3202
3203 // input cells
3204 (struct yac_grid_cell[]){
3205 generate_cell_deg((double[]){ 3.1415926521557882/YAC_RAD,
3206 3.1415926520689506/YAC_RAD,
3207 -3.0774466652769172/YAC_RAD},
3208 (double[]){-0.9805860393425995/YAC_RAD,
3209 -1.0172219678978514/YAC_RAD,
3210 -0.9979427097227050/YAC_RAD}, gc_edges, 3),
3211 generate_cell_deg((double[]){ 3.1170489609836229/YAC_RAD,
3212 3.1415926535897931/YAC_RAD,
3213 3.1415926535897931/YAC_RAD,
3214 3.1170489609836229/YAC_RAD},
3215 (double[]){-1.0062913968529805/YAC_RAD,
3216 -1.0062913968529805/YAC_RAD,
3217 -0.9817477042468103/YAC_RAD,
3218 -0.9817477042468103/YAC_RAD},
3219 latlon_edges, 4)},
3220 // reference cells
3221 (struct yac_grid_cell[]){
3222 generate_cell_deg((double[]){ 3.1415926535897931/YAC_RAD,
3223 3.1415926535897931/YAC_RAD,
3224 intersection_lon[0],intersection_lon[1]},
3225 (double[]){-0.9817477042468103/YAC_RAD,
3226 -1.0062913968529805/YAC_RAD,
3227 -1.0062913968529805/YAC_RAD,
3228 -0.9817477042468103/YAC_RAD},
3229 (enum yac_edge_type[]){
3231 generate_cell_deg(NULL, NULL, NULL, 0)},
3232 // number of reference cells
3233 2);
3234 }
3235
3236 TEST_START("example example take from ICON_toy");
3237 {
3238
3239 utest_test_clipping(
3240
3241 // input cells
3242 (struct yac_grid_cell[]){
3243 generate_cell_deg((double[]){ 1.8849555814614660/YAC_RAD,
3244 0.9682712007396151/YAC_RAD,
3245 3.1415926372157803/YAC_RAD},
3246 (double[]){-1.5418135420482968/YAC_RAD,
3247 -1.5707963262077691/YAC_RAD,
3248 -1.5418135425481947/YAC_RAD}, gc_edges, 3),
3249 generate_cell_deg((double[]){ 1.0799224746714915/YAC_RAD,
3250 1.1044661672776617/YAC_RAD,
3251 1.1044661672776617/YAC_RAD,
3252 1.0799224746714915/YAC_RAD},
3253 (double[]){-1.5707963267948966/YAC_RAD,
3254 -1.5707963267948966/YAC_RAD,
3255 -1.5462526341887264/YAC_RAD,
3256 -1.5462526341887264/YAC_RAD},
3257 latlon_edges, 4)},
3258 // reference cells
3259 (struct yac_grid_cell[]){
3260 generate_cell_deg(NULL, NULL, NULL, 0)},
3261 // number of reference cells
3262 1);
3263 }
3264
3265 TEST_START("example example take from ICON_toy");
3266 {
3267
3268 utest_test_clipping(
3269
3270 // input cells
3271 (struct yac_grid_cell[]){
3272 generate_cell_deg((double[]){ 3.1415926372157803/YAC_RAD,
3273 0.9682712007396151/YAC_RAD,
3274 -1.8849555862661402/YAC_RAD},
3275 (double[]){-1.5418135425481947/YAC_RAD,
3276 -1.5707963262077691/YAC_RAD,
3277 -1.5418135428532602/YAC_RAD}, gc_edges, 3),
3278 generate_cell_deg((double[]){ 1.5707963267948966/YAC_RAD,
3279 1.5953400194010670/YAC_RAD,
3280 1.5953400194010670/YAC_RAD,
3281 1.5707963267948966/YAC_RAD},
3282 (double[]){-1.5707963267948966/YAC_RAD,
3283 -1.5707963267948966/YAC_RAD,
3284 -1.5462526341887264/YAC_RAD,
3285 -1.5462526341887264/YAC_RAD},
3286 latlon_edges, 4)},
3287 // reference cells
3288 (struct yac_grid_cell[]){
3289 generate_cell_deg(NULL, NULL, NULL, 0)},
3290 // number of reference cells
3291 1);
3292 }
3293
3294 TEST_START("example example take from ICON_toy");
3295 {
3296 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3297
3298 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 1.25664579522418/YAC_RAD,
3299 1.54180416508220/YAC_RAD,
3300 0.00031736492867/YAC_RAD,
3301 1.54181036404629/YAC_RAD,
3302 YAC_LAT_CIRCLE_EDGE, 0.90811662642830/YAC_RAD,
3303 1.54625263418873/YAC_RAD,
3304 0.93266031903447/YAC_RAD,
3305 1.54625263418873/YAC_RAD,
3306 intersection[0]))
3307 return EXIT_FAILURE;
3308 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 1.25664579522418/YAC_RAD,
3309 1.54180416508220/YAC_RAD,
3310 0.00031736492867/YAC_RAD,
3311 1.54181036404629/YAC_RAD,
3312 YAC_LON_CIRCLE_EDGE, 0.93266031903447/YAC_RAD,
3313 1.52170894158256/YAC_RAD,
3314 0.93266031903447/YAC_RAD,
3315 1.54625263418873/YAC_RAD,
3316 intersection[1]))
3317 return EXIT_FAILURE;
3318 for (int i = 0; i < 2; ++i) {
3319 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3320 intersection_lon[i] /= YAC_RAD;
3321 intersection_lat[i] /= YAC_RAD;
3322 }
3323
3324 utest_test_clipping(
3325
3326 // input cells
3327 (struct yac_grid_cell[]){
3328 generate_cell_deg((double[]){1.25664579522418/YAC_RAD,
3329 1.22772603138717/YAC_RAD,
3330 0.00031736492867/YAC_RAD},
3331 (double[]){1.54180416508220/YAC_RAD,
3332 1.57078715647583/YAC_RAD,
3333 1.54181036404629/YAC_RAD}, gc_edges, 3),
3334 generate_cell_deg((double[]){0.90811662642830/YAC_RAD,
3335 0.93266031903447/YAC_RAD,
3336 0.93266031903447/YAC_RAD,
3337 0.90811662642830/YAC_RAD},
3338 (double[]){1.52170894158256/YAC_RAD,
3339 1.52170894158256/YAC_RAD,
3340 1.54625263418873/YAC_RAD,
3341 1.54625263418873/YAC_RAD},
3342 latlon_edges, 4)},
3343 // reference cells
3344 (struct yac_grid_cell[]){
3345 generate_cell_deg((double[]){0.93266031903447/YAC_RAD,
3346 intersection_lon[0],
3347 intersection_lon[1]},
3348 (double[]){1.54625263418873/YAC_RAD,
3349 intersection_lat[0],
3350 intersection_lat[1]},
3351 (enum yac_edge_type[]){
3353 generate_cell_deg((double[]){0.93266031903447/YAC_RAD,
3354 0.90811662642830/YAC_RAD,
3355 intersection_lon[0],
3356 intersection_lon[1]},
3357 (double[]){1.54625263418873/YAC_RAD,
3358 1.54625263418873/YAC_RAD,
3359 intersection_lat[0],
3360 intersection_lat[1]},
3361 (enum yac_edge_type[]){
3363 // number of reference cells
3364 2);
3365 }
3366
3367 TEST_START("example example take from ICON_toy");
3368 {
3369 utest_test_clipping(
3370
3371 // input cells
3372 (struct yac_grid_cell[]){
3373 generate_cell_deg((double[]){ 4.9999997254688875/YAC_RAD,
3374 4.9999997254688875/YAC_RAD,
3375 5.0078539201557488/YAC_RAD,
3376 5.0078539201557488/YAC_RAD},
3377 (double[]){-1.2878426515089207/YAC_RAD,
3378 -1.2946756570757916/YAC_RAD,
3379 -1.2946797849754812/YAC_RAD,
3380 -1.2878469125666649/YAC_RAD},
3381 gc_edges, 4),
3382 generate_cell_deg((double[]){ 5.0069132916587327/YAC_RAD,
3383 5.0130492148102759/YAC_RAD,
3384 5.0130492148102759/YAC_RAD,
3385 5.0069132916587327/YAC_RAD},
3386 (double[]){-1.2946797849754812/YAC_RAD,
3387 -1.2946797849754812/YAC_RAD,
3388 -1.2885438618239387/YAC_RAD,
3389 -1.2885438618239387/YAC_RAD},
3390 latlon_edges, 4)},
3391 // reference cells
3392 (struct yac_grid_cell[]){
3393 generate_cell_deg((double[]){ 5.0069132916587327/YAC_RAD,
3394 5.0078539201557488/YAC_RAD,
3395 5.0078539201557488/YAC_RAD,
3396 5.0069132916587327/YAC_RAD},
3397 (double[]){-1.2946797849754812/YAC_RAD,
3398 -1.2946797849754812/YAC_RAD,
3399 -1.2885438618239387/YAC_RAD,
3400 -1.2885438618239387/YAC_RAD},
3401 (enum yac_edge_type[]){
3403 // number of reference cells
3404 1);
3405 }
3406
3408 TEST_START("example provided by Uwe");
3409 {
3410
3411 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3412
3413 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 2.5132741228718345/YAC_RAD,
3414 1.5494144670074232/YAC_RAD,
3415 3.7699111843077517/YAC_RAD,
3416 1.5494144670074232/YAC_RAD,
3417 YAC_LAT_CIRCLE_EDGE, 3.2637657012293961/YAC_RAD,
3418 1.5533430342749532/YAC_RAD,
3419 3.2812189937493392/YAC_RAD,
3420 1.5533430342749532/YAC_RAD,
3421 intersection[0]))
3422 return EXIT_FAILURE;
3423 if (!intersect(YAC_GREAT_CIRCLE_EDGE, 2.5132741228718345/YAC_RAD,
3424 1.5494144670074232/YAC_RAD,
3425 3.7699111843077517/YAC_RAD,
3426 1.5494144670074232/YAC_RAD,
3427 YAC_LON_CIRCLE_EDGE, 3.2812189937493392/YAC_RAD,
3428 1.5533430342749532/YAC_RAD,
3429 3.2812189937493392/YAC_RAD,
3430 1.5358897417550099/YAC_RAD,
3431 intersection[1]))
3432 return EXIT_FAILURE;
3433 for (int i = 0; i < 2; ++i) {
3434 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3435 intersection_lon[i] /= YAC_RAD;
3436 intersection_lat[i] /= YAC_RAD;
3437 }
3438
3439 utest_test_clipping(
3440
3441 // input cells
3442 (struct yac_grid_cell[]){
3443 generate_cell_deg((double[]){3.2637657012293961/YAC_RAD,
3444 3.2812189937493392/YAC_RAD,
3445 3.2812189937493392/YAC_RAD,
3446 3.2637657012293961/YAC_RAD},
3447 (double[]){1.5358897417550099/YAC_RAD,
3448 1.5358897417550099/YAC_RAD,
3449 1.5533430342749532/YAC_RAD,
3450 1.5533430342749532/YAC_RAD},
3451 latlon_edges, 4),
3452 generate_cell_deg((double[]){1.2566370614359175/YAC_RAD,
3453 2.5132741228718345/YAC_RAD,
3454 3.7699111843077517/YAC_RAD,
3455 5.0265482457436690/YAC_RAD,
3456 0.0000000000000000/YAC_RAD,
3457 0.0000000000000000/YAC_RAD},
3458 (double[]){1.5494144670074232/YAC_RAD,
3459 1.5494144670074232/YAC_RAD,
3460 1.5494144670074232/YAC_RAD,
3461 1.5494144670074232/YAC_RAD,
3462 1.5494144670074232/YAC_RAD,
3463 1.5494144670074232/YAC_RAD},
3464 gc_edges, 6)},
3465 // reference cells
3466 (struct yac_grid_cell[]){
3467 generate_cell_deg((double[]){intersection_lon[0],
3468 3.2812189937493392/YAC_RAD,
3469 3.2812189937493392/YAC_RAD},
3470 (double[]){1.5533430342749532/YAC_RAD,
3471 1.5533430342749532/YAC_RAD,
3472 intersection_lat[1]},
3473 (enum yac_edge_type[]){
3475 // number of reference cells
3476 1);
3477 }
3478
3480 TEST_START("example provided by Rene");
3481 {
3482
3483 utest_test_clipping(
3484
3485 // input cells
3486 (struct yac_grid_cell[]){
3487 generate_cell_deg((double[]){ 1.8849563731522099/YAC_RAD,
3488 1.8465416851483734/YAC_RAD,
3489 1.8661276404324745/YAC_RAD},
3490 (double[]){-0.4124872765902973/YAC_RAD,
3491 -0.4149531265147232/YAC_RAD,
3492 -0.4401304121445256/YAC_RAD},
3493 gc_edges, 3),
3494 generate_cell_deg((double[]){ 1.8443992887189797/YAC_RAD,
3495 1.8849555921538759/YAC_RAD,
3496 1.9255118955887724/YAC_RAD},
3497 (double[]){-0.4121554426487201/YAC_RAD,
3498 -0.4636476090008059/YAC_RAD,
3499 -0.4121554426487201/YAC_RAD},
3500 gc_edges, 3)},
3501 // reference cells
3502 (struct yac_grid_cell[]){
3503 generate_cell_deg((double[]){ 1.8849563731522099/YAC_RAD,
3504 1.8465416851483734/YAC_RAD,
3505 1.8661276404324745/YAC_RAD},
3506 (double[]){-0.4124872765902973/YAC_RAD,
3507 -0.4149531265147232/YAC_RAD,
3508 -0.4401304121445256/YAC_RAD}, gc_edges, 3)},
3509 // number of reference cells
3510 1);
3511 }
3512
3513 TEST_START("example provided by Rene");
3514 {
3515 double intersection[3], intersection_lon, intersection_lat;
3516
3517 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -1.9037843097448526/YAC_RAD,
3518 -0.4401294427665800/YAC_RAD,
3519 -1.8849555925510342/YAC_RAD,
3520 -0.4636476094897370/YAC_RAD,
3521 YAC_GREAT_CIRCLE_EDGE, -1.8849555921538759/YAC_RAD,
3522 -0.4636476090008059/YAC_RAD,
3523 -1.9528559331227824/YAC_RAD,
3524 -0.4822665528104840/YAC_RAD,
3525 intersection))
3526 return EXIT_FAILURE;
3527 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
3528 intersection_lon /= YAC_RAD;
3529 intersection_lat /= YAC_RAD;
3530
3531 utest_test_clipping(
3532
3533 // input cells
3534 (struct yac_grid_cell[]){
3535 generate_cell_deg((double[]){-1.9037843097448526/YAC_RAD,
3536 -1.8849555925510342/YAC_RAD,
3537 -1.8661268754099334/YAC_RAD},
3538 (double[]){-0.4401294427665800/YAC_RAD,
3539 -0.4636476094897370/YAC_RAD,
3540 -0.4401294427950335/YAC_RAD},
3541 gc_edges, 3),
3542 generate_cell_deg((double[]){-1.8849555921538759/YAC_RAD,
3543 -1.8849555921538759/YAC_RAD,
3544 -1.9528559331227824/YAC_RAD},
3545 (double[]){-0.5268929705698896/YAC_RAD,
3546 -0.4636476090008059/YAC_RAD,
3547 -0.4822665528104840/YAC_RAD},
3548 gc_edges, 3)},
3549 // reference cells
3550 (struct yac_grid_cell[]){
3551 generate_cell_deg((double[]){-1.8849555921538759/YAC_RAD,
3552 -1.8849555921538759/YAC_RAD,
3553 intersection_lon},
3554 (double[]){-0.4636476094897370/YAC_RAD,
3555 -0.4636476090008059/YAC_RAD,
3556 intersection_lat}, gc_edges, 3),
3557 generate_cell_deg(NULL, NULL, NULL, 0)},
3558 // number of reference cells
3559 2);
3560 }
3561
3562 TEST_START("example provided by Rene");
3563 {
3564
3565 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3566
3567 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -1.2566370614359172/YAC_RAD,
3568 -0.5535743588970451/YAC_RAD,
3569 -1.1715639552378114/YAC_RAD,
3570 -0.5519553785110131/YAC_RAD,
3571 YAC_GREAT_CIRCLE_EDGE, -1.2566370573287293/YAC_RAD,
3572 -0.5535743562505872/YAC_RAD,
3573 -1.2346024154180213/YAC_RAD,
3574 -0.5882204740702072/YAC_RAD,
3575 intersection[0]))
3576 return EXIT_FAILURE;
3577 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -1.2566370614359172/YAC_RAD,
3578 -0.5535743588970451/YAC_RAD,
3579 -1.1715639552378114/YAC_RAD,
3580 -0.5519553785110131/YAC_RAD,
3581 YAC_GREAT_CIRCLE_EDGE, -1.2566370573287293/YAC_RAD,
3582 -0.5535743562505872/YAC_RAD,
3583 -1.2786717012447690/YAC_RAD,
3584 -0.5882204751704803/YAC_RAD,
3585 intersection[1]))
3586 return EXIT_FAILURE;
3587 for (int i = 0; i < 2; ++i) {
3588 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3589 intersection_lon[i] /= YAC_RAD;
3590 intersection_lat[i] /= YAC_RAD;
3591 }
3592
3593 utest_test_clipping(
3594
3595 // input cells
3596 (struct yac_grid_cell[]){
3597 generate_cell_deg((double[]){-1.2346024154180213/YAC_RAD,
3598 -1.2566370573287293/YAC_RAD,
3599 -1.2786717012447690/YAC_RAD},
3600 (double[]){-0.5882204740702072/YAC_RAD,
3601 -0.5535743562505872/YAC_RAD,
3602 -0.5882204751704803/YAC_RAD},
3603 gc_edges, 3),
3604 generate_cell_deg((double[]){-1.2156135107669752/YAC_RAD,
3605 -1.2566370614359172/YAC_RAD,
3606 -1.1715639552378114/YAC_RAD},
3607 (double[]){-0.4835340719879115/YAC_RAD,
3608 -0.5535743588970451/YAC_RAD,
3609 -0.5519553785110131/YAC_RAD},
3610 gc_edges, 3)},
3611 // reference cells
3612 (struct yac_grid_cell[]){
3613 generate_cell_deg(NULL, NULL, NULL, 0),
3614 generate_cell_deg((double[]){-1.2566370573287293/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)},
3620 // number of reference cells
3621 2);
3622 }
3623
3625 TEST_START("handling of 'triangle' in which all corners on on a gc");
3626 {
3627 utest_test_clipping(
3628
3629 // input cells
3630 (struct yac_grid_cell[]){
3631 generate_cell_deg((double[]){0, 1, 2},
3632 (double[]){0, 0, 0}, gc_edges, 3),
3633 generate_cell_deg((double[]){0, 1, 2},
3634 (double[]){0, 0, 0}, gc_edges, 3)},
3635 // reference cells
3636 (struct yac_grid_cell[]){
3637 generate_cell_deg(NULL, NULL, NULL, 0),
3638 generate_cell_deg((double[]){0, 1, 2},
3639 (double[]){0, 0, 0}, gc_edges, 3)},
3640 // number of reference cells
3641 2);
3642 }
3643
3644 TEST_START("handling of 'triangle' in which all corners on on a gc");
3645 {
3646 utest_test_clipping(
3647
3648 // input cells
3649 (struct yac_grid_cell[]){
3650 generate_cell_deg((double[]){0, 1, 1},
3651 (double[]){0, 0, 1}, gc_edges, 3),
3652 generate_cell_deg((double[]){0, 1, 2},
3653 (double[]){0, 0, 0}, gc_edges, 3)},
3654 // reference cells
3655 (struct yac_grid_cell[]){
3656 generate_cell_deg(NULL, NULL, NULL, 0),
3657 generate_cell_deg((double[]){0, 1, 2},
3658 (double[]){0, 0, 0}, gc_edges, 3)},
3659 // number of reference cells
3660 2);
3661 }
3662
3663 TEST_START("");
3664 {
3665
3666 utest_test_clipping(
3667
3668 // input cells
3669 (struct yac_grid_cell[]){
3670 generate_cell_deg((double[]){ 1.5462526341887264/YAC_RAD,
3671 1.5707963267948966/YAC_RAD,
3672 1.5707963267948966/YAC_RAD,
3673 1.5462526341887264/YAC_RAD},
3674 (double[]){-1.5707963267948966/YAC_RAD,
3675 -1.5707963267948966/YAC_RAD,
3676 -1.5462526341887264/YAC_RAD,
3677 -1.5462526341887264/YAC_RAD},
3678 latlon_edges, 4),
3679 generate_cell_deg((double[]){ 1.5707963267948966/YAC_RAD,
3680 1.5707963267948966/YAC_RAD,
3681 1.2491662739534428/YAC_RAD,
3682 1.1072089649419674/YAC_RAD},
3683 (double[]){-1.5462526341887277/YAC_RAD,
3684 -1.5339807878856395/YAC_RAD,
3685 -1.5319928455462422/YAC_RAD,
3686 -1.5433578475477794/YAC_RAD},
3687 gc_edges, 4)},
3688 // reference cells
3689 (struct yac_grid_cell[]){
3690 generate_cell_deg(NULL, NULL, NULL, 0)},
3691 // number of reference cells
3692 1);
3693 }
3694
3695 TEST_START("");
3696 {
3697
3698 double intersection[3], intersection_lon, intersection_lat;
3699
3701 -1.5339807878856395/YAC_RAD,
3702 0.32163005284145374/YAC_RAD,
3703 -1.5319928455462422/YAC_RAD,
3704 YAC_LON_CIRCLE_EDGE, 0.024543692606170259/YAC_RAD,
3705 -1.5462526341887264/YAC_RAD,
3706 0.024543692606170259/YAC_RAD,
3707 -1.5217089415825564/YAC_RAD,
3708 intersection))
3709 return EXIT_FAILURE;
3710 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
3711 intersection_lon /= YAC_RAD;
3712 intersection_lat /= YAC_RAD;
3713
3714 utest_test_clipping(
3715 // input cells
3716 (struct yac_grid_cell[]){
3717 generate_cell_deg((double[]){ 0/YAC_RAD,
3718 0.024543692606170259/YAC_RAD,
3719 0.024543692606170259/YAC_RAD,
3720 0/YAC_RAD},
3721 (double[]){-1.5462526341887264/YAC_RAD,
3722 -1.5462526341887264/YAC_RAD,
3723 -1.5217089415825564/YAC_RAD,
3724 -1.5217089415825564/YAC_RAD},
3725 latlon_edges, 4),
3726 generate_cell_deg((double[]){ 0/YAC_RAD,
3727 0.32163005284145374/YAC_RAD,
3728 0.24480144176769322/YAC_RAD,
3729 0/YAC_RAD},
3730 (double[]){-1.5339807878856395/YAC_RAD,
3731 -1.5319928455462422/YAC_RAD,
3732 -1.5202029837469972/YAC_RAD,
3733 -1.5217089415825564/YAC_RAD},
3734 gc_edges, 4)},
3735 // reference cells
3736 (struct yac_grid_cell[]){
3737 generate_cell_deg((double[]){ 0/YAC_RAD,
3738 0.024543692606170259/YAC_RAD,
3739 0.024543692606170259/YAC_RAD,
3740 0/YAC_RAD},
3741 (double[]){-1.5217089415825564/YAC_RAD,
3742 -1.5217089415825564/YAC_RAD,
3743 intersection_lat,
3744 -1.5339807878856395/YAC_RAD},
3745 (enum yac_edge_type[]){
3747 // number of reference cells
3748 1);
3749 }
3750
3752 TEST_START("lon-lat cell that touches the pole");
3753 /* cell a (circle around a pole; made of lat circle edges)
3754
3755 .-""-.
3756 / \
3757 ; ;
3758 \ /
3759 '-..-'
3760 */
3761
3762 /* cell b (lon-lat cell whose upper bound is a zero lenght edge at the pole)
3763
3764 /\
3765 / \
3766 '-..-'
3767 */
3768
3769 {
3770 utest_test_clipping(
3771 // input cells
3772 (struct yac_grid_cell[]){
3773 generate_cell_deg((double[]){-5.0, 5.0, 0.0},
3774 (double[]){85.0, 85.0, 90.0},
3775 (enum yac_edge_type[]){
3777 generate_cell_deg((double[]){ 0.0,60.0,120.0,180.0,240.0,300.0},
3778 (double[]){ 84.0,84.0,84.0,84.0,84.0,84.0},
3779 (enum yac_edge_type[]){
3782 // reference cells
3783 (struct yac_grid_cell[]){
3784 generate_cell_deg((double[]){-5.0, 5.0, 0.0},
3785 (double[]){85.0, 85.0, 90.0},
3786 (enum yac_edge_type[]){
3788 // number of reference cells
3789 1);
3790 }
3791
3793 TEST_START("two square that partially share two edges");
3794 /* 11.) source cell test data
3795
3796 -1 1
3797 +------+ 1
3798 | |
3799 | |
3800 | |
3801 +------+ -1
3802 */
3803 /* target cell test data
3804
3805 +------+ 0.5
3806 | |
3807 | |
3808 | |
3809 +------+ -0.5
3810 -1 1
3811 */
3812
3813 {
3814 utest_test_clipping(
3815 // input cells
3816 (struct yac_grid_cell[]){
3817 generate_cell_deg((double[]){-1.0, 1.0, 1.0,-1.0},
3818 (double[]){-1.0,-1.0, 1.0, 1.0}, latlon_edges, 4),
3819 generate_cell_deg((double[]){-1.0, 1.0, 1.0,-1.0},
3820 (double[]){-0.5,-0.5, 0.5, 0.5}, latlon_edges, 4)},
3821 // reference cells
3822 (struct yac_grid_cell[]){
3823 generate_cell_deg((double[]){-1.0, 1.0, 1.0,-1.0},
3824 (double[]){-0.5,-0.5, 0.5, 0.5}, latlon_edges, 4)},
3825 // number of reference cells
3826 1);
3827 }
3828
3830 TEST_START("two polygons with two edges touch in a single point");
3831 /* 11.) source cell test data
3832
3833 -10 10
3834 +------+ 90
3835 | |
3836 | |
3837 | |
3838 +------+ 80 + dx
3839 */
3840 /* target cell test data
3841
3842 -------- 80
3843 \ /
3844 \ /
3845 \ /
3846 \/ 0
3847 -10 0 10
3848 */
3849
3850 {
3851 double touch_point[3], touch_lon, touch_lat;
3852
3853 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -10.0, 80.0, 10.0, 80.0,
3854 YAC_LON_CIRCLE_EDGE, 0.0, 70.0, 0.0, 90.0, touch_point))
3855 return EXIT_FAILURE;
3856 XYZtoLL(touch_point, &touch_lon, &touch_lat);
3857 touch_lon /= YAC_RAD;
3858 touch_lat /= YAC_RAD;
3859
3860 utest_test_clipping(
3861 // input cells
3862
3863 (struct yac_grid_cell[2]){
3864 generate_cell_deg((double[]){-10.0, 10.0, 10.0, -10.0},
3865 (double[]){touch_lat, touch_lat, 90.0, 90.0},
3866 latlon_edges, 4),
3867 generate_cell_deg((double[]){0.0, 10.0, -10.0},
3868 (double[]){0.0, 80.0, 80.0}, gc_edges, 3)},
3869 // reference cells
3870 (struct yac_grid_cell[]){generate_cell_deg(NULL, NULL, NULL, 0)},
3871 // number of reference cells
3872 1);
3873 }
3874
3875
3876 TEST_START("two polygons with two edges touch in a single point");
3877 /* 11.) source cell test data
3878
3879 -15 15
3880 +------+ 80 + dx
3881 | |
3882 | |
3883 | |
3884 +------+ 60
3885 */
3886 /* target cell test data
3887
3888 -------- 80
3889 \ /
3890 \ /
3891 \ /
3892 \/ 70
3893 -10 0 10
3894 */
3895
3896 {
3897 double touch_point[3], touch_lon, touch_lat;
3898
3899 if (!intersect(YAC_GREAT_CIRCLE_EDGE, -10.0, 80.0, 10.0, 80.0,
3900 YAC_LON_CIRCLE_EDGE, 0.0, 70.0, 0.0, 90.0, touch_point))
3901 return EXIT_FAILURE;
3902 XYZtoLL(touch_point, &touch_lon, &touch_lat);
3903 touch_lon /= YAC_RAD;
3904 touch_lat /= YAC_RAD;
3905
3906 utest_test_clipping(
3907 // input cells
3908
3909 (struct yac_grid_cell[2]){
3910 generate_cell_deg((double[]){-15.0, 15.0, 15.0, -15.0},
3911 (double[]){60.0, 60.0, touch_lat, touch_lat},
3912 latlon_edges, 4),
3913 generate_cell_deg((double[]){0.0, 10.0, -10.0},
3914 (double[]){70.0, 80.0, 80.0}, gc_edges, 3)},
3915 // reference cells
3916 (struct yac_grid_cell[]){
3917 generate_cell_deg((double[]){0.0, 10.0, -10.0},
3918 (double[]){70.0, 80.0, 80.0}, gc_edges, 3),
3919 generate_cell_deg((double[]){0.0, 10.0, 0.0, -10.0},
3920 (double[]){70.0, 80.0, touch_lat, 80.0}, gc_edges, 4)},
3921 // number of reference cells
3922 2);
3923 }
3924
3926 TEST_START("one cell is empty");
3927 /* 11.) source cell test data
3928
3929 +------+
3930 | |
3931 | |
3932 | |
3933 +------+
3934 */
3935
3936 {
3937 utest_test_clipping(
3938 // input cells
3939
3940 (struct yac_grid_cell[2]){
3941 generate_cell_deg((double[]){0.0, 1.0, 1.0, 0.0},
3942 (double[]){0.0, 0.0, 1.0, 1.0},
3943 latlon_edges, 4),
3944 generate_cell_deg((double[]){0.0}, (double[]){0.0}, gc_edges, 1)},
3945 // reference cells
3946 (struct yac_grid_cell[]){generate_cell_deg(NULL, NULL, NULL, 0)},
3947 // number of reference cells
3948 1);
3949 }
3950
3952 TEST_START("star-shaped cell");
3953 /* source cell test data
3954
3955
3956 +
3957 / \
3958 / \
3959 + +
3960 - -
3961 + +
3962 - -
3963 + +
3964 \ /
3965 \ /
3966 +
3967 */
3968
3969 {
3970 utest_test_clipping(
3971 // input cells
3972
3973 (struct yac_grid_cell[2]){
3974 generate_cell_deg((double[]){0.0,0.5,2.0,0.5,0.0,-0.5,-2.0,-0.5},
3975 (double[]){2.0,0.5,0.0,-0.5,-2.0,-0.5,0.0,0.5},
3976 gc_edges, 8),
3977 generate_cell_deg((double[]){-0.4,0.4,0.4,-0.4},
3978 (double[]){0.4,0.4,-0.4,-0.4}, latlon_edges, 4)},
3979 // reference cells
3980 (struct yac_grid_cell[]){
3981 generate_cell_deg((double[]){-0.4,0.4,0.4,-0.4},
3982 (double[]){0.4,0.4,-0.4,-0.4}, latlon_edges, 4)},
3983 // number of reference cells
3984 1);
3985 }
3986
3987 { // example from the CDO
3988 utest_test_clipping(
3989 // input cells
3990
3991 (struct yac_grid_cell[2]){
3994 (double[4][3])
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}},
3999 latlon_edges, 4),
4002 (double[3][3])
4003 {{0.26672229713350176, 7.0351165064716449e-15, -0.96377342576553127},
4004 {0.26954589843896026, 3.2931183713464971e-16, -0.9629875433434919},
4005 {0.26812958837053386, -0.0028554026633992114, -0.9633786226172335}},
4006 gc_edges, 3)},
4007
4008 // reference cells
4009 (struct yac_grid_cell[]){
4010 generate_cell_deg(NULL, NULL, NULL, 0)},
4011 // number of reference cells
4012 1);
4013 }
4014
4015//-----------------test yac_correct_weights------------------------------------
4016
4017 {
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);
4022 }
4023
4024 {
4025 enum {num_weights = 1};
4026 double weights[num_weights] = {3};
4027 double ref_weights[num_weights] = {1};
4028 utest_check_weight_correction(weights, num_weights, ref_weights);
4029 }
4030
4031 {
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);
4036 }
4037
4038//-----------------test yac_point_on_edge------------------------------------
4039
4040 {
4041 double points_LL[][2] = {{0.0,0.0}, {45.0, 45.0}, {45.0+180.0,-45.0}, {90.0,90.0}};
4042 struct {
4043 union {
4044 double ll[2], xyz[3];
4045 } a, b;
4046 enum yac_circle_type type;
4047 } edges[] =
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}};
4066 enum {
4067 NUM_POINTS = sizeof(points_LL) / sizeof(points_LL[0]),
4068 NUM_EDGES = sizeof(edges) / sizeof(edges[0]),
4069 };
4070
4071 int ref_results[NUM_POINTS][NUM_EDGES] = {
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}};
4076
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);
4080 }
4081 for (size_t point_idx = 0; point_idx < NUM_POINTS; ++point_idx) {
4082
4083 double point[3];
4085 points_LL[point_idx][0], points_LL[point_idx][1], point);
4086
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");
4093 }
4094 }
4095 }
4096
4097 yac_free_grid_cell(overlap_cell);
4098 yac_free_grid_cell(overlap_cell+1);
4099
4100 return TEST_EXIT_CODE;
4101}
4102
4103static int utest_compare_cells(struct yac_grid_cell a, struct yac_grid_cell b) {
4104
4105 double const tol = 1e-8;
4106
4109
4110 if (a.num_corners != b.num_corners) return 1;
4111
4112 if (a.num_corners == 0) return 0;
4113
4114 for (int order = -1; order <= 1; order += 2) {
4115 for (int start = 0; start < (int)(a.num_corners); ++start) {
4116
4117 int differences = 0;
4118
4119 for (int i = 0; i < (int)(a.num_corners); ++i) {
4120
4121 int j =
4122 ((int)(a.num_corners) + start + order * i) % (int)(a.num_corners);
4123
4125 ++differences;
4126
4127 else if ((a.edge_type[i] == YAC_LAT_CIRCLE_EDGE) !=
4128 (b.edge_type[
4129 (((int)(a.num_corners))+j-(order<0))%
4130 ((int)(a.num_corners))] == YAC_LAT_CIRCLE_EDGE))
4131 ++differences;
4132 }
4133
4134 if (!differences) return 0;
4135 }
4136 }
4137
4138 return 1;
4139}
4140
4141static void utest_test_clipping(struct yac_grid_cell cells[2],
4142 struct yac_grid_cell * ref_cells,
4143 unsigned num_ref_cells) {
4144
4145 int order[2], start[2];
4146 double mem_dummy_[2][128][3];
4147 enum yac_edge_type edge_dummy[2][128];
4148 struct yac_grid_cell overlap_cell,
4149 test_cells[2] = {
4150 (struct yac_grid_cell){.coordinates_xyz = mem_dummy_[0],
4151 .edge_type = edge_dummy[0],
4152 .num_corners = cells[0].num_corners},
4153 (struct yac_grid_cell){.coordinates_xyz = mem_dummy_[1],
4154 .edge_type = edge_dummy[1],
4155 .num_corners = cells[1].num_corners}};
4156
4157 yac_init_grid_cell(&overlap_cell);
4158
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]) {
4163
4164 for (int k = 0; k <= 1; ++k) {
4165 for (int i = 0; i < ((int)(cells[k].num_corners)); ++i) {
4166 int j =
4167 (((int)(cells[k].num_corners))+start[k]+i*order[k])%
4168 ((int)(cells[k].num_corners));
4169 test_cells[k].coordinates_xyz[i][0] = cells[k].coordinates_xyz[j][0];
4170 test_cells[k].coordinates_xyz[i][1] = cells[k].coordinates_xyz[j][1];
4171 test_cells[k].coordinates_xyz[i][2] = cells[k].coordinates_xyz[j][2];
4172 j =
4173 (((int)(cells[k].num_corners)) + j - (order[k] < 0))%
4174 ((int)(cells[k].num_corners));
4175 test_cells[k].edge_type[i] = cells[k].edge_type[j];
4176 }
4177 }
4178
4179 for (int k = 0; k <= 1; ++k) {
4180 yac_cell_clipping(1, test_cells + k, test_cells[k^1], &overlap_cell);
4181 int match = 0;
4182 for (int i = 0; i < (int)num_ref_cells; ++i)
4183 match |= !utest_compare_cells(overlap_cell, ref_cells[i]);
4184 if (!match)
4185 PUT_ERR("ERROR: wrong clipping cell\n");
4186 }
4187 }
4188 }
4189 }
4190 }
4191 yac_free_grid_cell(&cells[0]);
4192 yac_free_grid_cell(&cells[1]);
4193 for (unsigned i = 0; i < num_ref_cells; ++i)
4194 yac_free_grid_cell(&ref_cells[i]);
4195 yac_free_grid_cell(&overlap_cell);
4196}
4197
4198static void utest_check_weight_correction(
4199 double * weights, size_t count, double * ref_weights) {
4200
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]);
4203
4204 for (size_t i = 0; i < num_tests; ++i) {
4205
4206 double temp_weights[count];
4207 for (size_t j = 0; j < count; ++j)
4208 temp_weights[j] = weights[j] * scales[i];
4209
4210 yac_correct_weights(count, temp_weights);
4211
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)
4216 PUT_ERR("wrong weight");
4217 }
4218 if (fabs(weight_diff) > 1e-12) PUT_ERR("wrong weight sum");
4219 }
4220}
double yac_huiliers_area(struct yac_grid_cell cell)
Area calculation on a unit sphere taken from ESMF based on L'Huilier's Theorem.
Definition area.c:449
Structs and interfaces for area calculations.
static double const tol
void yac_correct_weights(size_t nSourceCells, double *weight)
correct interpolation weights
Definition clipping.c:1445
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
Definition clipping.c:1088
#define YAC_RAD
static void LLtoXYZ_deg(double lon, double lat, double p_out[])
Definition geometry.h:269
int yac_point_on_edge(double p[3], double const a[3], double const b[3], enum yac_circle_type circle_type)
#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_circle_type
Definition geometry.h:59
@ POINT
Definition geometry.h:63
@ LAT_CIRCLE
Definition geometry.h:61
@ GREAT_CIRCLE
Definition geometry.h:60
@ LON_CIRCLE
Definition geometry.h:62
void yac_init_grid_cell(struct yac_grid_cell *cell)
Definition grid_cell.c:14
void yac_free_grid_cell(struct yac_grid_cell *cell)
Definition grid_cell.c:44
yac_edge_type
Definition grid_cell.h:12
@ YAC_GREAT_CIRCLE_EDGE
great circle
Definition grid_cell.h:13
@ YAC_LAT_CIRCLE_EDGE
latitude circle
Definition grid_cell.h:14
@ YAC_LON_CIRCLE_EDGE
longitude circle
Definition grid_cell.h:15
enum callback_type type
static void XYZtoLL(double const p_in[], double *lon, double *lat)
size_t num_corners
Definition grid_cell.h:21
enum yac_edge_type * edge_type
Definition grid_cell.h:20
double(* coordinates_xyz)[3]
Definition grid_cell.h:19
#define TEST_START(DESC)
#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)
Definition test_common.c:48
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
static enum yac_edge_type gc_edges[]
static enum yac_edge_type latlon_edges[4]
double ref_weights[4 *36]
#define TEST_EXIT_CODE
Definition tests.h:14
#define PUT_ERR(string)
Definition tests.h:10
double(* yac_coordinate_pointer)[3]
Definition yac_types.h:19