YAC 3.21.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_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[] = {
48
49 struct yac_grid_cell overlap_cell[2];
50
51 yac_init_grid_cell(overlap_cell);
52 yac_init_grid_cell(overlap_cell+1);
53
54 int test_major_idx = 0, test_minor_idx;
55
57 TEST_START("clipping with an empty source cell");
58 {
59 struct yac_grid_cell SourceCells[] =
60 {utest_generate_cell_deg(NULL, NULL, gc_edges, 0)};
61 struct yac_grid_cell TargetCell =
62 utest_generate_cell_deg(
63 (double[]){0.0, 0.5, 0.0, -0.5},
64 (double[]){-0.5, 0.0, 0.7, 0.0}, gc_edges, 4);
65 yac_cell_clipping(1, SourceCells, TargetCell, overlap_cell);
66 if (utest_compare_cells(overlap_cell[0], SourceCells[0]))
67 PUT_ERR("ERROR: wrong clipping cell\n");
68 yac_free_grid_cell(&SourceCells[0]);
69 yac_free_grid_cell(&TargetCell);
70 }
71
72
74 TEST_START("Simple test case with two quadrangle");
75 /* source cell test data
76
77 0.0 (lon) [2]
78 0.7 (lat)
79 / \
80 / \
81 -0.5 [1] / \ 0.5 [3]
82 0.0 \ / 0.0
83 \ /
84 \ /
85 0.0 [0]
86 -0.5
87 */
88
89 /* target cell test data
90
91 0.0 (lon) [0]
92 0.6 (lat)
93 / \
94 / \
95 -0.6 [3] / \ 0.6 [1]
96 0.0 \ / 0.0
97 \ /
98 \ /
99 0.0 [2]
100 -0.6
101 */
102 {
103 double intersection[3], intersection_lon, intersection_lat;
104
105 if (!utest_intersect(
106 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.6, 0.6, 0.0,
107 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.7, 0.5, 0.0, intersection))
108 return EXIT_FAILURE;
109 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
110 intersection_lon /= YAC_RAD;
111 intersection_lat /= YAC_RAD;
112
113 utest_clipping(
114 // input cells
115 (struct yac_grid_cell[]){
116 utest_generate_cell_deg(
117 (double[]){0.0, 0.5, 0.0, -0.5},
118 (double[]){-0.5, 0.0, 0.7, 0.0}, gc_edges, 4),
119 utest_generate_cell_deg(
120 (double[]){0.0, 0.6, 0.0, -0.6},
121 (double[]){0.6, 0.0, -0.6, 0.0}, gc_edges, 4)},
122 // reference cells
123 (struct yac_grid_cell[]){
124 utest_generate_cell_deg(
125 (double[]){0.0, intersection_lon, 0.5, 0.0, -0.5, -intersection_lon},
126 (double[]){0.6, intersection_lat, 0.0, -0.5, 0.0, intersection_lat}, gc_edges, 6)},
127 // number of reference cells
128 1);
129 }
130
132 TEST_START("Simple test case with one quadrangle and one triangle");
133 /* source cell test data
134
135 0.0 (lon) [2]
136 0.7 (lat)
137 / \
138 / \
139 -0.5 [1] / \ 0.5 [3]
140 0.0 \ / 0.0
141 \ /
142 \ /
143 0.0 [0]
144 -0.5
145 */
146
147 /* target cell test data
148
149 0.0 (lon)
150 0.6 (lat)
151 / \
152 / \
153 -0.6 / \ 0.6
154 0.0 /_______\ 0.0
155
156 */
157
158 {
159 double intersection[3], intersection_lon, intersection_lat;
160 if (!utest_intersect(
161 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.6, 0.6, 0.0,
162 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.7, 0.5, 0.0, intersection))
163 return EXIT_FAILURE;
164 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
165 intersection_lon /= YAC_RAD;
166 intersection_lat /= YAC_RAD;
167
168 utest_clipping(
169 // input cells
170 (struct yac_grid_cell[]){
171 utest_generate_cell_deg(
172 (double[]){ 0.0,-0.5,0.0,0.5},
173 (double[]){-0.5,0.0,0.7,0.0}, gc_edges, 4),
174 utest_generate_cell_deg(
175 (double[]){0.6,0.0,-0.6},
176 (double[]){0.0,0.6,0.0}, gc_edges, 3)},
177 // reference cells
178 (struct yac_grid_cell[]){
179 utest_generate_cell_deg(
180 (double[]){0.0,intersection_lon,0.5,-0.5,-intersection_lon},
181 (double[]){0.6,intersection_lat,0.0,0.0,intersection_lat},
182 gc_edges, 5)},
183 // number of reference cells
184 1);
185 }
186
187 TEST_START("Simple test case with one quadrangle and one triangle");
188 /* source cell test data
189
190 0.0 (lon) [2]
191 0.7 (lat)
192 / \
193 / \
194 -0.5 [1] / \ 0.5 [3]
195 0.0 \ / 0.0
196 \ /
197 \ /
198 0.0 [0]
199 -0.5
200 */
201
202 /* target cell test data
203
204 0.6 (lon)
205 0.6 (lat)
206 / \
207 / \
208 0.0 / \ 1.0
209 0.1 /_______\ 0.1
210
211 */
212
213 {
214 double intersection[2][3], intersection_lon[2], intersection_lat[2];
215
216 if (!utest_intersect(
217 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.1, 1.0, 0.1,
218 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.7, 0.5, 0.0, intersection[0]))
219 return EXIT_FAILURE;
220 if (!utest_intersect(
221 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.1, 0.6, 0.6,
222 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.7, 0.5, 0.0, intersection[1]))
223 return EXIT_FAILURE;
224 for (int i = 0; i < 2; ++i) {
225 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
226 intersection_lon[i] /= YAC_RAD;
227 intersection_lat[i] /= YAC_RAD;
228 }
229
230 utest_clipping(
231 // input cells
232 (struct yac_grid_cell[]){
233 utest_generate_cell_deg(
234 (double[]){0.0,-0.5,0.0,0.5},
235 (double[]){-0.5,0.0,0.7,0.0}, gc_edges, 4),
236 utest_generate_cell_deg(
237 (double[]){1.0,0.6,0.0},
238 (double[]){0.1,0.6,0.1}, gc_edges, 3)},
239 // reference cells
240 (struct yac_grid_cell[]){
241 utest_generate_cell_deg(
242 (double[]){0.0,intersection_lon[0],intersection_lon[1]},
243 (double[]){0.1,intersection_lat[0],intersection_lat[1]},
244 gc_edges, 3)},
245 // number of reference cells
246 1);
247 }
248
249 TEST_START("Simple test case with one quadrangle and one triangle");
250 /* source cell test data
251
252 0.0 (lon) [2]
253 0.7 (lat)
254 / \
255 / \
256 -0.5 [1] / \ 0.5 [3]
257 0.0 \ / 0.0
258 \ /
259 \ /
260 0.0 [0]
261 -0.5
262 */
263
264 /* target cell test data
265
266 0.0 (lon)
267 0.6 (lat)
268 / \
269 / \
270 -0.5 / \ 0.5
271 0.1 /_______\ 0.1
272
273 */
274
275 {
276 double intersection[2][3], intersection_lon[2], intersection_lat[2];
277
278 if (!utest_intersect(
279 YAC_GREAT_CIRCLE_EDGE, 0.0,0.6,0.5,0.1,
280 YAC_GREAT_CIRCLE_EDGE, 0.0,0.7,0.5,0.0, intersection[0]))
281 return EXIT_FAILURE;
282 if (!utest_intersect(
283 YAC_GREAT_CIRCLE_EDGE, -0.5,0.1,0.5,0.1,
284 YAC_GREAT_CIRCLE_EDGE, 0.0,0.7,0.5,0.0, intersection[1]))
285 return EXIT_FAILURE;
286 for (int i = 0; i < 2; ++i) {
287 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
288 intersection_lon[i] /= YAC_RAD;
289 intersection_lat[i] /= YAC_RAD;
290 }
291
292 utest_clipping(
293 // input cells
294 (struct yac_grid_cell[]){
295 utest_generate_cell_deg(
296 (double[]){0.0,-0.5,0.0,0.5},
297 (double[]){-0.5,0.0,0.7,0.0}, gc_edges, 4),
298 utest_generate_cell_deg(
299 (double[]){0.5,0.0,-0.5},
300 (double[]){0.1,0.6,0.1}, gc_edges, 3)},
301 // reference cells
302 (struct yac_grid_cell[]){
303 utest_generate_cell_deg(
304 (double[]){0.0,intersection_lon[0], intersection_lon[1],
305 -intersection_lon[1],-intersection_lon[0]},
306 (double[]){0.6,intersection_lat[0],intersection_lat[1],
307 intersection_lat[1],intersection_lat[0]}, gc_edges, 5)},
308 // number of reference cells
309 1);
310 }
311
313 TEST_START("Two source cells overlapping one target cell");
314
315 /* target cell test data
316
317 0.0 (lon)
318 0.7 (lat)
319 / \
320 1 0
321 -0.5 / \ 0.5
322 0.0 \ / 0.0
323 2 3
324 \ /
325 0.0
326 -0.7
327
328 */
329
330 /* source cell test data
331
332 0.0 (lon)
333 0.5 (lat)
334 / \
335 1 0
336 -0.6 / \ 0.6
337 0.0 /___2___\ 0.0
338 _________
339 \ 0 /
340 \ /
341 1 2
342 \ /
343 0.0
344 -0.5
345 */
346
347 // generate reference intersection cells
348 {
349 double intersection[3], intersection_lon, intersection_lat;
350 if (!utest_intersect(
351 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.5, 0.6, 0.0,
352 YAC_GREAT_CIRCLE_EDGE, 0.0, 0.7, 0.5, 0.0, intersection))
353 return EXIT_FAILURE;
354 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
355 intersection_lon /= YAC_RAD;
356 intersection_lat /= YAC_RAD;
357
358 struct yac_grid_cell ref_cells[] = {
359 utest_generate_cell_deg(
360 (double[]){0.0,intersection_lon,0.5,-0.5,-intersection_lon},
361 (double[]){0.5,intersection_lat,0.0,0.0,intersection_lat},
362 gc_edges, 5),
363 utest_generate_cell_deg(
364 (double[]){0.0,-intersection_lon,-0.5,0.5,intersection_lon},
365 (double[]){-0.5,-intersection_lat,0.0,0.0,-intersection_lat},
366 gc_edges, 5)};
367
368 for (int src_order_a = -1; src_order_a <= 1; src_order_a += 2) {
369 for (int src_order_b = -1; src_order_b <= 1; src_order_b += 2) {
370 for (int tgt_order = -1; tgt_order <= 1; tgt_order += 2) {
371 for (int src_start_a = 0; src_start_a < 3; ++src_start_a) {
372 for (int src_start_b = 0; src_start_b < 3; ++src_start_b) {
373 for (int tgt_start = 0; tgt_start < 4; ++tgt_start) {
374
375 struct yac_grid_cell SourceCells[] = {
376 utest_generate_cell_deg(
377 (double[]){0.6,0.0,-0.6},
378 (double[]){0.0,0.5,0.0}, gc_edges, 3),
379 utest_generate_cell_deg(
380 (double[]){0.6,-0.6,0.0},
381 (double[]){0.0,0.0,-0.5}, gc_edges, 3)};
382 struct yac_grid_cell TargetCell =
383 utest_generate_cell_deg(
384 (double[]){0.5,0.0,-0.5,0.0},
385 (double[]){0.0,0.7,0.0,-0.7}, gc_edges, 4);
386
387 yac_cell_clipping ( 2, SourceCells, TargetCell, overlap_cell );
388 if (utest_compare_cells(overlap_cell[0], ref_cells[0]) ||
389 utest_compare_cells(overlap_cell[1], ref_cells[1]))
390 PUT_ERR("ERROR: wrong clipping cell\n");
391 yac_free_grid_cell(&SourceCells[0]);
392 yac_free_grid_cell(&SourceCells[1]);
393 yac_free_grid_cell(&TargetCell);
394 }
395 }
396 }
397 }
398 }
399 }
400 yac_free_grid_cell(&ref_cells[0]);
401 yac_free_grid_cell(&ref_cells[1]);
402 }
403
405 TEST_START("Simple cases: identity");
406 /* target cell test data
407
408 0.0 (lon)
409 0.5 (lat)
410 / \
411 1 0
412 -0.6 / \ 0.6
413 0.0 \ / 0.0
414 2 3
415 \ /
416 0.0
417 -0.5
418
419 */
420
421 /* source cell test data
422
423 0.0 (lon)
424 0.5 (lat)
425 / \
426 1 0
427 -0.6 / \ 0.6
428 0.0 /___2___\ 0.0
429 _________
430 \ 0 /
431 \ /
432 1 2
433 \ /
434 0.0
435 -0.5
436 */
437
438 // generate reference intersection cells
439 {
440 struct yac_grid_cell ref_cells[] = {
441 utest_generate_cell_deg(
442 (double[]){0.0,0.6,-0.6},
443 (double[]){0.5,0.0,0.0}, gc_edges, 3),
444 utest_generate_cell_deg(
445 (double[]){0.0,0.6,-0.6},
446 (double[]){-0.5,0.0,0.0}, gc_edges, 3)};
447
448 for (int src_order_a = -1; src_order_a <= 1; src_order_a += 2) {
449 for (int src_order_b = -1; src_order_b <= 1; src_order_b += 2) {
450 for (int tgt_order = -1; tgt_order <= 1; tgt_order += 2) {
451 for (int src_start_a = 0; src_start_a < 3; ++src_start_a) {
452 for (int src_start_b = 0; src_start_b < 3; ++src_start_b) {
453 for (int tgt_start = 0; tgt_start < 4; ++tgt_start) {
454
455 struct yac_grid_cell SourceCells[] = {
456 utest_generate_cell_deg(
457 (double[]){0.6,0.0,-0.6},
458 (double[]){0.0,0.5,0.0}, gc_edges, 3),
459 utest_generate_cell_deg(
460 (double[]){0.6,-0.6,0.0},
461 (double[]){0.0,0.0,-0.5}, gc_edges, 3)};
462 struct yac_grid_cell TargetCell =
463 utest_generate_cell_deg(
464 (double[]){0.0,-0.6,0.0,0.6},
465 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4);
466
467 yac_cell_clipping ( 2, SourceCells, TargetCell, overlap_cell );
468 if (utest_compare_cells(overlap_cell[0], ref_cells[0]) ||
469 utest_compare_cells(overlap_cell[1], ref_cells[1]))
470 PUT_ERR("ERROR: wrong clipping cell\n");
471 yac_free_grid_cell(overlap_cell);
472 yac_free_grid_cell(overlap_cell+1);
473 yac_free_grid_cell(&SourceCells[0]);
474 yac_free_grid_cell(&SourceCells[1]);
475 yac_free_grid_cell(&TargetCell);
476 }
477 }
478 }
479 }
480 }
481 }
482 yac_free_grid_cell(&ref_cells[0]);
483 yac_free_grid_cell(&ref_cells[1]);
484 }
485
486 TEST_START("Simple cases: identity");
487 /* target cell test data
488
489 0.0 (lon)
490 0.5 (lat)
491 / \
492 1 0
493 -0.6 / \ 0.6
494 0.0 \ / 0.0
495 2 3
496 \ /
497 0.0
498 -0.5
499
500 */
501
502 /* source cell test data
503
504 0.0 (lon)
505 0.5 (lat)
506 / \
507 1 0
508 -0.6 / \ 0.6
509 0.0 \ / 0.0
510 2 3
511 \ /
512 0.0
513 -0.5
514 */
515
516 {
517 utest_clipping(
518 // input cells
519 (struct yac_grid_cell[]){
520 utest_generate_cell_deg(
521 (double[]){0.0,-0.6,0.0,0.6},
522 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4),
523 utest_generate_cell_deg(
524 (double[]){0.0,-0.6,0.0,0.6},
525 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4)},
526 // reference cells
527 (struct yac_grid_cell[]){
528 utest_generate_cell_deg(
529 (double[]){0.0,-0.6,0.0,0.6},
530 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4)},
531 // number of reference cells
532 1);
533 }
534
535 TEST_START("Simple cases: source inside target cell");
536 /* target cell test data
537
538 0.0 (lon)
539 0.5 (lat)
540 / \
541 1 0
542 -0.6 / \ 0.6
543 0.0 \ / 0.0
544 2 3
545 \ /
546 0.0
547 -0.5
548
549 */
550
551 /* source cell test data
552
553 0.0 (lon)
554 0.4 (lat)
555 / \
556 1 0
557 -0.5 / \ 0.5
558 0.0 \ / 0.0
559 2 3
560 \ /
561 0.0
562 -0.4
563 */
564
565 {
566 utest_clipping(
567 // input cells
568 (struct yac_grid_cell[]){
569 utest_generate_cell_deg(
570 (double[]){0.0,-0.5,0.0,0.5},
571 (double[]){0.4,0.0,-0.4,0.0}, gc_edges, 4),
572 utest_generate_cell_deg(
573 (double[]){0.0,-0.6,0.0,0.6},
574 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4)},
575 // reference cells
576 (struct yac_grid_cell[]){
577 utest_generate_cell_deg(
578 (double[]){0.0,-0.5,0.0,0.5},
579 (double[]){0.4,0.0,-0.4,0.0}, gc_edges, 4)},
580 // number of reference cells
581 1);
582 }
583
584 TEST_START("Simple cases: target inside source cell");
585 /* target cell test data
586
587 0.0 (lon)
588 0.5 (lat)
589 / \
590 1 0
591 -0.6 / \ 0.6
592 0.0 \ / 0.0
593 2 3
594 \ /
595 0.0
596 -0.5
597
598 */
599
600 /* source cell test data
601
602 0.0 (lon)
603 0.6 (lat)
604 / \
605 1 0
606 -0.7 / \ 0.7
607 0.0 \ / 0.0
608 2 3
609 \ /
610 0.0
611 -0.6
612 */
613
614 {
615 utest_clipping(
616 // input cells
617 (struct yac_grid_cell[]){
618 utest_generate_cell_deg(
619 (double[]){0.0,-0.7,0.0,0.7},
620 (double[]){0.6,0.0,-0.6,0.0}, gc_edges, 4),
621 utest_generate_cell_deg(
622 (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 utest_generate_cell_deg(
627 (double[]){0.0,-0.6,0.0,0.6},
628 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4)},
629 // number of reference cells
630 1);
631 }
632
633 TEST_START("Simple cases: degenerated cell");
634 /* target cell test data
635
636 0.0 (lon)
637 0.5 (lat)
638 / \
639 1 0
640 -0.6 / \ 0.6
641 0.0 \ / 0.0
642 2 3
643 \ /
644 0.0
645 -0.5
646
647 */
648
649 /* source cell test data
650
651 0.0 0.0 (lon)
652 0.5 0.6 (lat)
653 --------
654 \ \
655 \ \
656 \ \
657 --------
658 0.6 1.0
659 0.0 0.0
660 */
661
662 {
663 utest_clipping(
664 // input cells
665 (struct yac_grid_cell[]){
666 utest_generate_cell_deg(
667 (double[]){0.0,0.6,1.0,0.5},
668 (double[]){0.5,0.0,0.0,0.5}, gc_edges, 4),
669 utest_generate_cell_deg(
670 (double[]){0.0,-0.6,0.0,0.6},
671 (double[]){0.5,0.0,-0.5,0.0}, gc_edges, 4)},
672 // reference cells
673 (struct yac_grid_cell[]){
674 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
675 // number of reference cells
676 1);
677 }
678
680 TEST_START("Special case from ICON_toy");
681 /* 5.) source cell test data
682
683 +------+
684 | |
685 | |
686 | |
687 +------+
688 */
689
690 /* target cell test data
691
692 /|
693 / |
694 / |
695 / |
696 \ |
697 \ |
698 \ |
699 \|
700 */
701
702 {
703 double intersection[4][3], intersection_lon[4], intersection_lat[4];
704
705 if (!utest_intersect(
706 YAC_GREAT_CIRCLE_EDGE, 108.0000, -7.2167, 88.4979, -19.2921,
707 YAC_GREAT_CIRCLE_EDGE, 90.0, 0.0, 90.0, -22.5, intersection[0]))
708 return EXIT_FAILURE;
709 if (!utest_intersect(
710 YAC_GREAT_CIRCLE_EDGE, 88.4979, -19.2921, 108.0000, -26.5650,
711 YAC_GREAT_CIRCLE_EDGE, 90.0, 0.0, 90.0, -22.5, intersection[1]))
712 return EXIT_FAILURE;
713 if (!utest_intersect(
714 YAC_GREAT_CIRCLE_EDGE, 88.4979, -19.2921, 108.0000, -26.5650,
715 YAC_GREAT_CIRCLE_EDGE, 90.0, -22.5, 112.5, -22.5, intersection[2]))
716 return EXIT_FAILURE;
717 if (!utest_intersect(
718 YAC_GREAT_CIRCLE_EDGE, 108.0000, -26.5650, 108.0000, -7.2167,
719 YAC_GREAT_CIRCLE_EDGE, 90.0, -22.5, 112.5, -22.5, intersection[3]))
720 return EXIT_FAILURE;
721 for (int i = 0; i < 4; ++i) {
722 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
723 intersection_lon[i] /= YAC_RAD;
724 intersection_lat[i] /= YAC_RAD;
725 }
726
727 utest_clipping(
728 // input cells
729 (struct yac_grid_cell[]){
730 utest_generate_cell_deg(
731 (double[]){90.0,112.5,112.5,90.0},
732 (double[]){-22.5,-22.5,0.0,0.0}, gc_edges, 4),
733 utest_generate_cell_deg(
734 (double[]){108.0000,88.4979,108.0000},
735 (double[]){-7.2167,-19.2921,-26.5650}, gc_edges, 3)},
736 // reference cells
737 (struct yac_grid_cell[]){
738 utest_generate_cell_deg(
739 (double[]){108.0000,
740 intersection_lon[0],
741 intersection_lon[1],
742 intersection_lon[2],
743 intersection_lon[3]},
744 (double[]){-7.2167,
745 intersection_lat[0],
746 intersection_lat[1],
747 intersection_lat[2],
748 intersection_lat[3]}, gc_edges, 5)},
749 // number of reference cells
750 1);
751 }
752
753 TEST_START("Special case from ICON_toy");
754 /* 6.) source cell test data
755
756 +------+ 0.5
757 | |
758 | |
759 | |
760 +------+ -0.5
761 -0.5 0.5
762 */
763
764 /* target cell test data
765
766 -0.75 0.0
767 ______ 0.0
768 \ |
769 \ |
770 \ |
771 \ |
772 \| -0.75
773 */
774
775 {
776 double intersection[4][3], intersection_lon[4], intersection_lat[4];
777
778 if (!utest_intersect(
779 YAC_GREAT_CIRCLE_EDGE, 0.0,0.0,-0.75,0.0,
780 YAC_GREAT_CIRCLE_EDGE, -0.5,0.5,-0.5,-0.5, intersection[0]))
781 return EXIT_FAILURE;
782 if (!utest_intersect(
783 YAC_GREAT_CIRCLE_EDGE, -0.75,0.0,0.0,-0.75,
784 YAC_GREAT_CIRCLE_EDGE, -0.5,0.5,-0.5,-0.5, intersection[1]))
785 return EXIT_FAILURE;
786 if (!utest_intersect(
787 YAC_GREAT_CIRCLE_EDGE, -0.75,0.0,0.0,-0.75,
788 YAC_GREAT_CIRCLE_EDGE, -0.5,-0.5,0.5,-0.5, intersection[2]))
789 return EXIT_FAILURE;
790 if (!utest_intersect(
791 YAC_GREAT_CIRCLE_EDGE, 0.0,-0.75,0.0,0.0,
792 YAC_GREAT_CIRCLE_EDGE, -0.5,-0.5,0.5,-0.5, intersection[3]))
793 return EXIT_FAILURE;
794 for (int i = 0; i < 4; ++i) {
795 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
796 intersection_lon[i] /= YAC_RAD;
797 intersection_lat[i] /= YAC_RAD;
798 }
799
800 utest_clipping(
801 // input cells
802 (struct yac_grid_cell[]){
803 utest_generate_cell_deg(
804 (double[]){-0.5,0.5,0.5,-0.5},
805 (double[]){-0.5,-0.5,0.5,0.5}, gc_edges, 4),
806 utest_generate_cell_deg(
807 (double[]){0.0,-0.75,0.0},
808 (double[]){0.0,0.0,-0.75}, gc_edges, 3)},
809 // reference cells
810 (struct yac_grid_cell[]){
811 utest_generate_cell_deg(
812 (double[]){0.0,
813 intersection_lon[0],
814 intersection_lon[1],
815 intersection_lon[2],
816 intersection_lon[3]},
817 (double[]){0.0,
818 intersection_lat[0],
819 intersection_lat[1],
820 intersection_lat[2],
821 intersection_lat[3]}, gc_edges, 5)},
822 // number of reference cells
823 1);
824 }
825
827 TEST_START("Special case in which no corner on any square is within the other");
828 /* 7.) source cell test data
829
830 +------+ 0.5
831 | |
832 | |
833 | |
834 +------+ -0.5
835 -0.5 0.5
836 */
837
838 /* target cell test data
839
840 -0.7 0.0 0.7
841 /\ 0.7
842 / \
843 / \
844 / \ 0.0
845 \ /
846 \ /
847 \ /
848 \/ -0.7
849 */
850
851 {
852 double intersection[3], intersection_lon[8], intersection_lat[8];
853 double src_data[2][4] = {{-0.5,-0.5, 0.5, 0.5},
854 { 0.5,-0.5,-0.5, 0.5}};
855 double tgt_data[2][4] = {{ 0.0,-0.7, 0.0, 0.7},
856 { 0.7, 0.0,-0.7, 0.0}};
857
858 for (int i = 0; i < 8; ++i) {
859 if (!utest_intersect(
860 YAC_GREAT_CIRCLE_EDGE, src_data[0][i/2],
861 src_data[1][i/2],
862 src_data[0][(i/2+1)%4],
863 src_data[1][(i/2+1)%4],
864 YAC_GREAT_CIRCLE_EDGE, tgt_data[0][((i+1)/2)%4],
865 tgt_data[1][((i+1)/2)%4],
866 tgt_data[0][((i+1)/2+1)%4],
867 tgt_data[1][((i+1)/2+1)%4], intersection))
868 return EXIT_FAILURE;
869 XYZtoLL(intersection, &intersection_lon[i], &intersection_lat[i]);
870 intersection_lon[i] /= YAC_RAD;
871 intersection_lat[i] /= YAC_RAD;
872 }
873
874 utest_clipping(
875 // input cells
876 (struct yac_grid_cell[]){
877 utest_generate_cell_deg(
878 (double[]){-0.5,0.5,0.5,-0.5},
879 (double[]){-0.5,-0.5,0.5,0.5}, gc_edges, 4),
880 utest_generate_cell_deg(
881 (double[]){0.0,0.7,0.0,-0.7},
882 (double[]){-0.7,0.0,0.7,0.0}, gc_edges, 4)},
883 // reference cells
884 (struct yac_grid_cell[]){
885 utest_generate_cell_deg(intersection_lon, intersection_lat, gc_edges, 8)},
886 // number of reference cells
887 1);
888 }
889
891 TEST_START("Test non intersecting cells");
892 /* 8.) source cell test data
893
894 +------+ 1
895 | |
896 | |
897 | |
898 +------+ 0
899 0 1
900 */
901
902 /* target cell test data
903
904 +------+ 1
905 | |
906 | |
907 | |
908 +------+ 0
909 2 3
910 */
911
912 {
913 utest_clipping(
914 // input cells
915 (struct yac_grid_cell[]){
916 utest_generate_cell_deg(
917 (double[]){0.0,1.0,1.0,0.0},
918 (double[]){0.0,0.0,1.0,1.0}, gc_edges, 4),
919 utest_generate_cell_deg(
920 (double[]){2.0,3.0,3.0,2.0},
921 (double[]){0.0,0.0,1.0,1.0}, gc_edges, 4)},
922 // reference cells
923 (struct yac_grid_cell[]){utest_generate_cell_deg(NULL, NULL, NULL, 0)},
924 // number of reference cells
925 1);
926 }
927
928 TEST_START("Test non intersecting cells");
929 /* 8.) source cell test data
930
931 +------+ 1
932 | |
933 | |
934 | |
935 +------+ 0
936 0 1
937 */
938
939 /* target cell test data
940
941 +------+ 3
942 | |
943 | |
944 | |
945 +------+ 2
946 1 2
947 */
948
949 {
950 utest_clipping(
951 // input cells
952 (struct yac_grid_cell[]){
953 utest_generate_cell_deg(
954 (double[]){0.0,1.0,1.0,0.0},
955 (double[]){0.0,0.0,1.0,1.0}, gc_edges, 4),
956 utest_generate_cell_deg(
957 (double[]){1.0,2.0,2.0,1.0},
958 (double[]){2.0,2.0,3.0,3.0}, gc_edges, 4)},
959 // reference cells
960 (struct yac_grid_cell[]){utest_generate_cell_deg(NULL, NULL, NULL, 0)},
961 // number of reference cells
962 1);
963 }
964
966 TEST_START("triangle-square intersection");
967 /* 9.) source cell test data
968
969 -1.5 1.5
970 -------- 0.5
971 \ /
972 \ /
973 \ /
974 \/ -0.5
975 */
976
977 /* target cell test data
978
979 +------+ 1
980 | |
981 | |
982 | |
983 +------+ -1
984 -1 1
985 */
986
987 {
988 double intersection[2][3], intersection_lon[2], intersection_lat[2];
989
990 if (!utest_intersect(
991 YAC_GREAT_CIRCLE_EDGE, 1.0,-1.0,1.0,1.0,
992 YAC_GREAT_CIRCLE_EDGE, 0.0,-0.5,1.5,0.5, intersection[0]))
993 return EXIT_FAILURE;
994 if (!utest_intersect(
995 YAC_GREAT_CIRCLE_EDGE, 1.0,-1.0,1.0,1.0,
996 YAC_GREAT_CIRCLE_EDGE, 1.5,0.5,-1.5,0.5, intersection[1]))
997 return EXIT_FAILURE;
998 for (int i = 0; i < 2; ++i) {
999 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1000 intersection_lon[i] /= YAC_RAD;
1001 intersection_lat[i] /= YAC_RAD;
1002 }
1003
1004 utest_clipping(
1005 // input cells
1006 (struct yac_grid_cell[]){
1007 utest_generate_cell_deg(
1008 (double[]){1.5,-1.5,0.0},
1009 (double[]){0.5,0.5,-0.5}, gc_edges, 3),
1010 utest_generate_cell_deg(
1011 (double[]){-1.0,1.0,1.0,-1.0},
1012 (double[]){-1.0,-1.0,1.0,1.0}, gc_edges, 4)},
1013 // reference cells
1014 (struct yac_grid_cell[]){
1015 utest_generate_cell_deg(
1016 (double[]){0.0,
1017 intersection_lon[0],
1018 intersection_lon[1],
1019 -intersection_lon[1],
1020 -intersection_lon[0]},
1021 (double[]){-0.5,
1022 intersection_lat[0],
1023 intersection_lat[1],
1024 intersection_lat[1],
1025 intersection_lat[0]}, gc_edges, 5)},
1026 // number of reference cells
1027 1);
1028 }
1029
1031 TEST_START("touching edges of two triangles");
1032 /* 10.1) source cell test data
1033
1034 /\ 1
1035 / \
1036 / \
1037 / \
1038 -------- 0
1039 0 2
1040 */
1041 /* target cell test data
1042
1043 -------- 0.0
1044 \ /
1045 \ /
1046 \ /
1047 \/ -0.5
1048 0 0.5 1
1049 */
1050
1051 {
1052 utest_clipping(
1053 // input cells
1054 (struct yac_grid_cell[]){
1055 utest_generate_cell_deg(
1056 (double[]){0.0,2.0,1.0},
1057 (double[]){0.0,0.0,1.0}, gc_edges, 3),
1058 utest_generate_cell_deg(
1059 (double[]){0.0,1.0, 0.5},
1060 (double[]){0.0,0.0,-0.5}, gc_edges, 3)},
1061 // reference cells
1062 (struct yac_grid_cell[]){
1063 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
1064 // number of reference cells
1065 1);
1066 }
1067
1068 TEST_START("touching edges")
1069 {
1070 utest_clipping(
1071 // input cells
1072 (struct yac_grid_cell[]){
1073 utest_generate_cell_deg(
1074 (double[]){160.0,180.0,180.0},
1075 (double[]){ 65.0, 65.0, 90.0}, gc_edges, 3),
1076 utest_generate_cell_deg(
1077 (double[]){180.0,200.0, 0.0},
1078 (double[]){ 70.0, 70.0, 90.0}, gc_edges, 3)},
1079 // reference cells
1080 (struct yac_grid_cell[]){
1081 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
1082 // number of reference cells
1083 1);
1084 }
1085
1087 TEST_START("test from test_interpolation_method_conserv.x");
1088 /* 11.) source cell test data
1089
1090 +------+ 0
1091 | |
1092 | |
1093 | |
1094 +------+ -1
1095 0 1
1096 */
1097 /* target cell test data
1098
1099 +------+ 0.5
1100 | |
1101 | |
1102 | |
1103 +------+ -0.5
1104 -0.5 0.5
1105 */
1106
1107 {
1108 utest_clipping(
1109 // input cells
1110 (struct yac_grid_cell[]){
1111 utest_generate_cell_deg(
1112 (double[]){ 0.0, 1.0,1.0,0.0},
1113 (double[]){-1.0,-1.0,0.0,0.0}, latlon_edges, 4),
1114 utest_generate_cell_deg(
1115 (double[]){-0.5, 0.5,0.5,-0.5},
1116 (double[]){-0.5,-0.5,0.5, 0.5}, latlon_edges, 4)},
1117 // reference cells
1118 (struct yac_grid_cell[]){
1119 utest_generate_cell_deg(
1120 (double[]){0.0,0.5, 0.5, 0.0},
1121 (double[]){0.0,0.0,-0.5,-0.5}, latlon_edges, 4)},
1122 // number of reference cells
1123 1);
1124 }
1125
1126 TEST_START("test from test_interpolation_method_conserv.x");
1127 /* 11.) source cell test data
1128
1129 -1 0
1130 +------+ 0
1131 | |
1132 | |
1133 | |
1134 +------+ -1
1135 */
1136 /* target cell test data
1137
1138 +------+ 0.5
1139 | |
1140 | |
1141 | |
1142 +------+ -0.5
1143 -0.5 0.5
1144 */
1145
1146 {
1147 utest_clipping(
1148 // input cells
1149 (struct yac_grid_cell[]){
1150 utest_generate_cell_deg(
1151 (double[]){ 0.0,-1.0,-1.0,0.0},
1152 (double[]){-1.0,-1.0, 0.0,0.0}, latlon_edges, 4),
1153 utest_generate_cell_deg(
1154 (double[]){-0.5, 0.5,0.5,-0.5},
1155 (double[]){-0.5,-0.5,0.5, 0.5}, latlon_edges, 4)},
1156 // reference cells
1157 (struct yac_grid_cell[]){
1158 utest_generate_cell_deg(
1159 (double[]){0.0,-0.5,-0.5, 0.0},
1160 (double[]){0.0, 0.0,-0.5,-0.5}, latlon_edges, 4)},
1161 // number of reference cells
1162 1);
1163 }
1164
1166 TEST_START("some mean tests");
1167 /* cell a
1168
1169 +------+ 60
1170 | |
1171 | |
1172 | |
1173 +------+ 40
1174 -20 20
1175 */
1176
1177 /* cell b
1178
1179 -------- 39
1180 \ /
1181 \ /
1182 \ /
1183 \/ 22
1184 -20 0 20
1185 */
1186
1187 {
1188 double intersection[3], intersection_lon, intersection_lat;
1189
1190 if (!utest_intersect(
1191 YAC_LAT_CIRCLE_EDGE, -20.0,40.0, 0.0,40.0,
1192 YAC_GREAT_CIRCLE_EDGE, -20.0,39.0,20.0,39.0, intersection))
1193 return EXIT_FAILURE;
1194 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1195 intersection_lon /= YAC_RAD;
1196 intersection_lat /= YAC_RAD;
1197
1198 utest_clipping(
1199 // input cells
1200 (struct yac_grid_cell[]){
1201 utest_generate_cell_deg(
1202 (double[]){-20.0,20.0,20.0,-20.0},
1203 (double[]){ 40.0,40.0,60.0, 60.0}, latlon_edges, 4),
1204 utest_generate_cell_deg(
1205 (double[]){-20.0, 0.0,20.0},
1206 (double[]){ 39.0,22.0,39.0}, gc_edges, 3)},
1207 // reference cells
1208 (struct yac_grid_cell[]){
1209 utest_generate_cell_deg(
1210 (double[]){intersection_lon,-intersection_lon},
1211 (double[]){intersection_lat,intersection_lat},
1212 (enum yac_edge_type[]){
1214 utest_generate_cell_deg(
1215 (double[]){intersection_lon,-intersection_lon},
1216 (double[]){intersection_lat,intersection_lat},
1217 (enum yac_edge_type[]){
1219 // number of reference cells
1220 2);
1221 }
1222
1223 TEST_START("some mean tests");
1224 /* cell a
1225
1226 +------+ 60
1227 | |
1228 | |
1229 | |
1230 +------+ 40
1231 -20 20
1232 */
1233
1234 /* cell b
1235
1236 40 --....__ 39
1237 \ /
1238 \ /
1239 \ /
1240 \/ 22
1241 -20 0 20
1242 */
1243
1244 {
1245 double intersection[3], intersection_lon, intersection_lat;
1246
1247 if (!utest_intersect(
1248 YAC_LAT_CIRCLE_EDGE, 20.0,40.0,-19.0,40.0,
1249 YAC_GREAT_CIRCLE_EDGE, 20.0,39.0,-20.0,40.0, intersection))
1250 return EXIT_FAILURE;
1251 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1252 intersection_lon /= YAC_RAD;
1253 intersection_lat /= YAC_RAD;
1254
1255 utest_clipping(
1256 // input cells
1257 (struct yac_grid_cell[]){
1258 utest_generate_cell_deg(
1259 (double[]){-20.0,20.0,20.0,-20.0},
1260 (double[]){ 40.0,40.0,60.0, 60.0}, latlon_edges, 4),
1261 utest_generate_cell_deg(
1262 (double[]){-20.0, 0.0,20.0},
1263 (double[]){ 40.0,22.0,39.0}, gc_edges, 3)},
1264 // reference cells
1265 (struct yac_grid_cell[]){
1266 utest_generate_cell_deg(
1267 (double[]){-20.0,intersection_lon},
1268 (double[]){ 40.0,intersection_lat},
1269 (enum yac_edge_type[]){
1271 utest_generate_cell_deg(
1272 (double[]){-20.0,intersection_lon},
1273 (double[]){ 40.0,intersection_lat},
1274 (enum yac_edge_type[]){
1276 // number of reference cells
1277 2);
1278 }
1279
1280 TEST_START("some mean tests");
1281 /* cell a
1282
1283 +------+ 60
1284 | |
1285 | |
1286 | |
1287 +------+ 40
1288 -20 20
1289 */
1290
1291 /* cell b
1292
1293 /\ 80
1294 / \
1295 / \
1296 / \
1297 -------- 59
1298 -19 0 19
1299 */
1300
1301 {
1302 double intersection[2][3], intersection_lon[2], intersection_lat[2];
1303
1304 if (!utest_intersect(
1305 YAC_GREAT_CIRCLE_EDGE, 19.0,59.0, 0.0,80.0,
1306 YAC_LAT_CIRCLE_EDGE, -20.0,60.0,20.0,60.0, intersection[0]))
1307 return EXIT_FAILURE;
1308 if (!utest_intersect(
1309 YAC_GREAT_CIRCLE_EDGE, 19.0, 59.0,-19.0, 59.0,
1310 YAC_LAT_CIRCLE_EDGE, -20.0, 60.0, 0.0, 60.0, intersection[1]))
1311 return EXIT_FAILURE;
1312 for (int i = 0; i < 2; ++i) {
1313 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1314 intersection_lon[i] /= YAC_RAD;
1315 intersection_lat[i] /= YAC_RAD;
1316 }
1317
1318 utest_clipping(
1319 // input cells
1320 (struct yac_grid_cell[]){
1321 utest_generate_cell_deg(
1322 (double[]){-20.0,20.0,20.0,-20.0},
1323 (double[]){ 40.0,40.0,60.0, 60.0}, latlon_edges, 4),
1324 utest_generate_cell_deg(
1325 (double[]){-19.0, 0.0,19.0},
1326 (double[]){ 59.0,80.0,59.0}, gc_edges, 3)},
1327 // reference cells
1328 (struct yac_grid_cell[]){
1329 utest_generate_cell_deg(
1330 (double[]){19.0,intersection_lon[0],
1331 fabs(intersection_lon[1]),
1332 -fabs(intersection_lon[1]),
1333 -intersection_lon[0],-19.0},
1334 (double[]){59.0,60.0,60.0,60.0,60.0,59.0},
1335 (enum yac_edge_type[]){
1338 utest_generate_cell_deg(
1339 (double[]){19.0,intersection_lon[0],-intersection_lon[0],
1340 -19.0,-fabs(intersection_lon[1]),fabs(intersection_lon[1])},
1341 (double[]){59.0,60.0,60.0,59.0,60.0,60.0},
1342 (enum yac_edge_type[]){
1345 // number of reference cells
1346 2);
1347 }
1348
1349 TEST_START("some mean tests");
1350 /* cell a
1351
1352 +------+ 60
1353 | |
1354 | |
1355 | |
1356 +------+ 40
1357 -20 20
1358 */
1359
1360 /* cell b
1361
1362 /| 80
1363 / |
1364 / |
1365 / |
1366 60 --...__|
1367 59
1368 -20 21
1369 */
1370
1371 {
1372 double intersection[2][3], intersection_lon[2], intersection_lat[2];
1373
1374 if (!utest_intersect(
1375 YAC_GREAT_CIRCLE_EDGE, -20.0,60.0,21.0,59.0,
1376 YAC_LAT_CIRCLE_EDGE, -19.0,60.0,20.0,60.0, intersection[0]))
1377 return EXIT_FAILURE;
1378 if (!utest_intersect(
1379 YAC_GREAT_CIRCLE_EDGE, -20.0,60.0,21.0,59.0,
1380 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[1]))
1381 return EXIT_FAILURE;
1382 for (int i = 0; i < 2; ++i) {
1383 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1384 intersection_lon[i] /= YAC_RAD;
1385 intersection_lat[i] /= YAC_RAD;
1386 }
1387
1388 utest_clipping(
1389 // input cells
1390 (struct yac_grid_cell[]){
1391 utest_generate_cell_deg(
1392 (double[]){-20.0,20.0,20.0,-20.0},
1393 (double[]){ 40.0,40.0,60.0, 60.0}, latlon_edges, 4),
1394 utest_generate_cell_deg(
1395 (double[]){-20.0,21.0,21.0},
1396 (double[]){ 60.0,80.0,59.0}, gc_edges, 3)},
1397 // reference cells
1398 (struct yac_grid_cell[]){
1399 utest_generate_cell_deg(
1400 (double[]){20.0,intersection_lon[0],intersection_lon[1]},
1401 (double[]){60.0,intersection_lat[0],intersection_lat[1]},
1402 (enum yac_edge_type[]){
1404 utest_generate_cell_deg(
1405 (double[]){20.0,intersection_lon[0],-20.0,intersection_lon[1]},
1406 (double[]){60.0,intersection_lat[0], 60.0,intersection_lat[1]},
1407 (enum yac_edge_type[]){
1410 // number of reference cells
1411 2);
1412 }
1413
1414 TEST_START("some mean tests");
1415 /* cell a
1416
1417 +------+ 60
1418 | |
1419 | |
1420 | |
1421 +------+ 40
1422 -20 20
1423 */
1424
1425 /* cell b
1426
1427 60 --...__ 59
1428 \ |
1429 \ |
1430 \ |
1431 \| 40
1432
1433 -20 21
1434
1435 */
1436
1437 {
1438 double intersection[3][3], intersection_lon[3], intersection_lat[3];
1439
1440 if (!utest_intersect(
1441 YAC_GREAT_CIRCLE_EDGE, -20.0,60.0,21.0,59.0,
1442 YAC_LAT_CIRCLE_EDGE, -19.0,60.0,20.0,60.0, intersection[0]))
1443 return EXIT_FAILURE;
1444 if (!utest_intersect(
1445 YAC_GREAT_CIRCLE_EDGE, -20.0,60.0,21.0,59.0,
1446 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[1]))
1447 return EXIT_FAILURE;
1448 if (!utest_intersect(
1449 YAC_GREAT_CIRCLE_EDGE, -20.0,60.0,21.0,40.0,
1450 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[2]))
1451 return EXIT_FAILURE;
1452 for (int i = 0; i < 3; ++i) {
1453 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1454 intersection_lon[i] /= YAC_RAD;
1455 intersection_lat[i] /= YAC_RAD;
1456 }
1457
1458 utest_clipping(
1459 // input cells
1460 (struct yac_grid_cell[]){
1461 utest_generate_cell_deg(
1462 (double[]){-20.0,20.0,20.0,-20.0},
1463 (double[]){ 40.0,40.0,60.0, 60.0}, latlon_edges, 4),
1464 utest_generate_cell_deg(
1465 (double[]){-20.0,21.0,21.0},
1466 (double[]){ 60.0,40.0,59.0}, gc_edges, 3)},
1467 // reference cells
1468 (struct yac_grid_cell[]){
1469 utest_generate_cell_deg(
1470 (double[]){intersection_lon[0],intersection_lon[1],
1471 intersection_lon[2],-20.0},
1472 (double[]){intersection_lat[0],intersection_lat[1],
1473 intersection_lat[2], 60.0},
1474 (enum yac_edge_type[]){
1477 // number of reference cells
1478 1);
1479 }
1480
1481 TEST_START("some mean tests");
1482 /* cell a
1483
1484 +------+ 60
1485 | |
1486 | |
1487 | |
1488 +------+ 40
1489 x x+40
1490 */
1491
1492 /* cell b
1493
1494 -------- 39
1495 \ /
1496 \ /
1497 \ /
1498 \/ 20
1499 -20 0 20
1500 */
1501
1502 {
1503 double intersection[3], intersection_lon, intersection_lat;
1504
1505 if (!utest_intersect(
1506 YAC_GREAT_CIRCLE_EDGE, -20.0,39.0,20.0,39.0,
1507 YAC_LAT_CIRCLE_EDGE, -20.0,40.0, 0.0,40.0, intersection))
1508 return EXIT_FAILURE;
1509 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1510 intersection_lon /= YAC_RAD;
1511 intersection_lat /= YAC_RAD;
1512
1513 utest_clipping(
1514 // input cells
1515 (struct yac_grid_cell[]){
1516 utest_generate_cell_deg(
1517 (double[]){intersection_lon,intersection_lon+40.0,
1518 intersection_lon+40.0,intersection_lon},
1519 (double[]){40.0,40.0,60.0,60.0}, latlon_edges, 4),
1520 utest_generate_cell_deg(
1521 (double[]){-20.0,20.0, 0.0},
1522 (double[]){ 39.0,39.0,20.0}, gc_edges, 3)},
1523 // reference cells
1524 (struct yac_grid_cell[]){
1525 utest_generate_cell_deg(
1526 (double[]){intersection_lon,-intersection_lon},
1527 (double[]){40.0,40.0},
1528 (enum yac_edge_type[]){
1530 utest_generate_cell_deg(
1531 (double[]){intersection_lon,-intersection_lon},
1532 (double[]){40.0,40.0},
1533 (enum yac_edge_type[]){
1535 // number of reference cells
1536 2);
1537 }
1538
1539 TEST_START("some mean tests");
1540 /* cell a
1541
1542 +------+ 60
1543 | |
1544 | |
1545 | |
1546 +------+ 40
1547 x x+40
1548 */
1549
1550 /* cell b
1551
1552 |\ 50
1553 | \
1554 | \
1555 | \
1556 -------- 39
1557 -20 0 20
1558 */
1559
1560 {
1561 double intersection[3][3], intersection_lon[3], intersection_lat[3];
1562
1563 if (!utest_intersect(
1564 YAC_GREAT_CIRCLE_EDGE, -20.0,39.0,20.0,39.0,
1565 YAC_LAT_CIRCLE_EDGE, -20.0,40.0, 0.0,40.0, intersection[0]))
1566 return EXIT_FAILURE;
1567 if (!utest_intersect(
1568 YAC_GREAT_CIRCLE_EDGE, 20.0,39.0,-20.0,50.0,
1569 YAC_LAT_CIRCLE_EDGE, -20.0,40.0, 20.0,40.0, intersection[1]))
1570 return EXIT_FAILURE;
1571 for (int i = 0; i < 2; ++i) {
1572 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1573 intersection_lon[i] /= YAC_RAD;
1574 intersection_lat[i] /= YAC_RAD;
1575 }
1576 if (!utest_intersect(
1577 YAC_GREAT_CIRCLE_EDGE, 20.0,39.0,-20.0,50.0,
1578 YAC_LON_CIRCLE_EDGE, intersection_lon[0],40.0,
1579 intersection_lon[0],60.0, intersection[2]))
1580 return EXIT_FAILURE;
1581 XYZtoLL(intersection[2], &intersection_lon[2], &intersection_lat[2]);
1582 intersection_lon[2] /= YAC_RAD;
1583 intersection_lat[2] /= YAC_RAD;
1584
1585 utest_clipping(
1586 // input cells
1587 (struct yac_grid_cell[]){
1588 utest_generate_cell_deg(
1589 (double[]){intersection_lon[0],
1590 intersection_lon[0]+40.0,
1591 intersection_lon[0]+40.0,
1592 intersection_lon[0]},
1593 (double[]){40.0,40.0,60.0,60.0}, latlon_edges, 4),
1594 utest_generate_cell_deg(
1595 (double[]){-20.0,20.0,-20.0},
1596 (double[]){ 39.0,39.0, 50.0}, gc_edges, 3)},
1597 // reference cells
1598 (struct yac_grid_cell[]){
1599 utest_generate_cell_deg(
1600 (double[]){intersection_lon[0],-intersection_lon[0],
1601 intersection_lon[1],intersection_lon[2]},
1602 (double[]){40.0,40.0,40.0,intersection_lat[2]},
1603 (enum yac_edge_type[]){
1606 // number of reference cells
1607 1);
1608 }
1609
1610 TEST_START("some mean tests");
1611 /* cell a
1612
1613 +------+ 60
1614 | |
1615 | |
1616 | |
1617 +------+ 40
1618 -20 20
1619 */
1620
1621 /* cell b
1622
1623 -------- 40
1624 \ /
1625 \ /
1626 \ /
1627 \/ 20
1628 -20 0 20
1629 */
1630
1631 {
1632 utest_clipping(
1633 // input cells
1634 (struct yac_grid_cell[]){
1635 utest_generate_cell_deg(
1636 (double[]){-20.0,20.0,20.0,-20.0},
1637 (double[]){ 40.0,40.0,60.0, 60.0}, latlon_edges, 4),
1638 utest_generate_cell_deg(
1639 (double[]){-20.0, 0.0,20.0},
1640 (double[]){ 40.0,20.0,40.0}, gc_edges, 3)},
1641 // reference cells
1642 (struct yac_grid_cell[]){
1643 utest_generate_cell_deg(
1644 (double[]){-20.0,20.0},
1645 (double[]){ 40.0,40.0},
1646 (enum yac_edge_type[]){
1648 utest_generate_cell_deg(
1649 (double[]){-20.0,20.0},
1650 (double[]){ 40.0,40.0},
1651 (enum yac_edge_type[]){
1653 // number of reference cells
1654 2);
1655 }
1656
1657 TEST_START("some mean tests");
1658 /* cell a
1659
1660 +------+ 60
1661 | |
1662 | |
1663 | |
1664 +------+ 40
1665 -20 20
1666 */
1667
1668 /* cell b
1669
1670 /\ 50
1671 / \
1672 / \
1673 / \
1674 -------- 40
1675 -20 0 20
1676 */
1677
1678 {
1679 utest_clipping(
1680 // input cells
1681 (struct yac_grid_cell[]){
1682 utest_generate_cell_deg(
1683 (double[]){-20.0,20.0,20.0,-20.0},
1684 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
1685 utest_generate_cell_deg(
1686 (double[]){-20.0, 0.0,20.0},
1687 (double[]){ 40.0,50.0,40.0}, gc_edges, 3)},
1688 // reference cells
1689 (struct yac_grid_cell[]){
1690 utest_generate_cell_deg(
1691 (double[]){-20.0,20.0,0.0},
1692 (double[]){40.0,40.0,50.0},
1693 (enum yac_edge_type[]){
1696 // number of reference cells
1697 1);
1698 }
1699
1700 TEST_START("some mean tests");
1701 /* cell a
1702
1703 +------+ 60
1704 | |
1705 | |
1706 | |
1707 +------+ 40
1708 -20 20
1709 */
1710
1711 /* cell b
1712
1713 -------- 60
1714 \ /
1715 \ /
1716 \ /
1717 \/ 50
1718 -20 0 20
1719 */
1720
1721 {
1722 utest_clipping(
1723 // input cells
1724 (struct yac_grid_cell[]){
1725 utest_generate_cell_deg(
1726 (double[]){-20.0,20.0,20.0,-20.0},
1727 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
1728 utest_generate_cell_deg(
1729 (double[]){-20.0, 0.0,20.0},
1730 (double[]){ 60.0,50.0,60.0}, gc_edges, 3)},
1731 // reference cells
1732 (struct yac_grid_cell[]){
1733 utest_generate_cell_deg(
1734 (double[]){-20.0,20.0,0.0},
1735 (double[]){60.0,60.0,50.0},
1736 (enum yac_edge_type[]){
1739 // number of reference cells
1740 1);
1741 }
1742
1743 TEST_START("some mean tests");
1744 /* cell a
1745
1746 +------+ 60
1747 | |
1748 | |
1749 | |
1750 +------+ 40
1751 -20 20
1752 */
1753
1754 /* cell b
1755
1756 /\ 70
1757 / \
1758 / \
1759 / \
1760 -------- 60
1761 -20 0 20
1762 */
1763
1764 {
1765 utest_clipping(
1766 // input cells
1767 (struct yac_grid_cell[]){
1768 utest_generate_cell_deg(
1769 (double[]){-20.0,20.0,20.0,-20.0},
1770 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
1771 utest_generate_cell_deg(
1772 (double[]){-20.0, 0.0,20.0},
1773 (double[]){ 60.0,70.0,60.0}, gc_edges, 3)},
1774 // reference cells
1775 (struct yac_grid_cell[]){
1776 utest_generate_cell_deg(
1777 (double[]){-20.0,20.0},
1778 (double[]){60.0,60.0},
1779 (enum yac_edge_type[]){
1781 utest_generate_cell_deg(
1782 (double[]){-20.0,20.0},
1783 (double[]){60.0,60.0},
1784 (enum yac_edge_type[]){
1786 // number of reference cells
1787 2);
1788 }
1789
1790 TEST_START("some mean tests");
1791 /* cell a
1792
1793 +------+ -40
1794 | |
1795 | |
1796 | |
1797 +------+ -60
1798 -20 20
1799 */
1800
1801 /* cell b
1802
1803 -------- -40
1804 \ /
1805 \ /
1806 \ /
1807 \/ -50
1808 -20 0 20
1809 */
1810
1811 {
1812 utest_clipping(
1813 // input cells
1814 (struct yac_grid_cell[]){
1815 utest_generate_cell_deg(
1816 (double[]){-20.0,20.0,20.0,-20.0},
1817 (double[]){-40.0,-40.0,-60.0,-60.0}, latlon_edges, 4),
1818 utest_generate_cell_deg(
1819 (double[]){-20.0, 0.0,20.0},
1820 (double[]){-40.0,-50.0,-40.0}, gc_edges, 3)},
1821 // reference cells
1822 (struct yac_grid_cell[]){
1823 utest_generate_cell_deg(
1824 (double[]){-20.0,20.0,0.0},
1825 (double[]){-40.0,-40.0,-50.0}, gc_edges, 3)},
1826 // number of reference cells
1827 1);
1828 }
1829
1830 TEST_START("some mean tests");
1831 /* cell a
1832
1833 +------+ 60
1834 | |
1835 | |
1836 | |
1837 +------+ 40
1838 -20 20
1839 */
1840
1841 /* cell b
1842
1843 59 ___..--- 60
1844 \ /
1845 \ /
1846 \ /
1847 \/ 45
1848 -15 0 15
1849 */
1850
1851 {
1852 double intersection[3], intersection_lon, intersection_lat;
1853
1854 if (!utest_intersect(
1855 YAC_LAT_CIRCLE_EDGE, -20.0,60.0,14.9,60.0,
1856 YAC_GREAT_CIRCLE_EDGE, -15.0,59.0,15.0,60.0, intersection))
1857 return EXIT_FAILURE;
1858 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
1859 intersection_lon /= YAC_RAD;
1860 intersection_lat /= YAC_RAD;
1861
1862 utest_clipping(
1863 // input cells
1864 (struct yac_grid_cell[]){
1865 utest_generate_cell_deg(
1866 (double[]){-20.0,20.0,20.0,-20.0},
1867 (double[]){60.0,60.0,40.0,40.0}, latlon_edges, 4),
1868 utest_generate_cell_deg(
1869 (double[]){-15.0, 0.0,15.0},
1870 (double[]){59.0,45.0,60.0}, gc_edges, 3)},
1871 // reference cells
1872 (struct yac_grid_cell[]){
1873 utest_generate_cell_deg(
1874 (double[]){intersection_lon,15.0,0.0,-15.0},
1875 (double[]){intersection_lat,60.0,45.0,59.0},
1876 (enum yac_edge_type[]){
1879 // number of reference cells
1880 1);
1881 }
1882
1883 TEST_START("some mean tests");
1884 /* cell a
1885
1886 +------+ 60
1887 +------+ 59
1888 -20 20
1889 */
1890
1891 /* cell b
1892
1893 -------- 58.5
1894 \ /
1895 \ /
1896 \ /
1897 \/ 40
1898 -20 0 20
1899 */
1900
1901 {
1902 double intersection[2][3], intersection_lon[2], intersection_lat[2];
1903
1904 if (!utest_intersect(
1905 YAC_LAT_CIRCLE_EDGE, -20.0, 59.0, 0.0, 59.0,
1906 YAC_GREAT_CIRCLE_EDGE, -20.0, 58.5,20.0, 58.5, intersection[0]))
1907 return EXIT_FAILURE;
1908 if (!utest_intersect(
1909 YAC_LAT_CIRCLE_EDGE, -20.0, 60.0, 0.0, 60.0,
1910 YAC_GREAT_CIRCLE_EDGE, -20.0, 58.5,20.0, 58.5, intersection[1]))
1911 return EXIT_FAILURE;
1912 for (int i = 0; i < 2; ++i) {
1913 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1914 intersection_lon[i] /= YAC_RAD;
1915 intersection_lat[i] /= YAC_RAD;
1916 }
1917
1918 utest_clipping(
1919 // input cells
1920 (struct yac_grid_cell[]){
1921 utest_generate_cell_deg(
1922 (double[]){-20.0,20.0,20.0,-20.0},
1923 (double[]){60.0,60.0,59.0,59.0}, latlon_edges, 4),
1924 utest_generate_cell_deg(
1925 (double[]){-20.0, 0.0,20.0},
1926 (double[]){58.5,40.0,58.5}, gc_edges, 3)},
1927 // reference cells
1928 (struct yac_grid_cell[]){
1929 utest_generate_cell_deg(
1930 (double[]){ intersection_lon[0],
1931 intersection_lon[1],
1932 -intersection_lon[1],
1933 -intersection_lon[0]},
1934 (double[]){59.0,60.0,60.0,59.0},
1935 (enum yac_edge_type[]){
1938 // number of reference cells
1939 1);
1940 }
1941
1942 TEST_START("some mean tests");
1943 /* cell a
1944
1945 +------+ 60
1946 | |
1947 | |
1948 | |
1949 +------+ 40
1950 -20 20
1951 */
1952
1953 /* cell b
1954
1955 /\ 80
1956 / \
1957 / \
1958 / \
1959 -------- 59
1960 -20 0 20
1961 */
1962
1963 {
1964 double intersection[2][3], intersection_lon[2], intersection_lat[2];
1965
1966 if (!utest_intersect(
1967 YAC_GREAT_CIRCLE_EDGE, 20.0,59.0,0.0,80.0,
1968 YAC_LAT_CIRCLE_EDGE, -20.0, 60.0,20.0,60.0, intersection[0]))
1969 return EXIT_FAILURE;
1970 if (!utest_intersect(
1971 YAC_GREAT_CIRCLE_EDGE, 20.0, 59.0,-20.0, 59.0,
1972 YAC_LAT_CIRCLE_EDGE, -20.0, 60.0, 0.0, 60.0, intersection[1]))
1973 return EXIT_FAILURE;
1974 for (int i = 0; i < 2; ++i) {
1975 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
1976 intersection_lon[i] /= YAC_RAD;
1977 intersection_lat[i] /= YAC_RAD;
1978 }
1979
1980 utest_clipping(
1981 // input cells
1982 (struct yac_grid_cell[]){
1983 utest_generate_cell_deg(
1984 (double[]){-20.0,20.0,20.0,-20.0},
1985 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
1986 utest_generate_cell_deg(
1987 (double[]){-20.0, 0.0,20.0},
1988 (double[]){59.0,80.0,59.0}, gc_edges, 3)},
1989 // reference cells
1990 (struct yac_grid_cell[]){
1991 utest_generate_cell_deg(
1992 (double[]){20.0,intersection_lon[0],
1993 fabs(intersection_lon[1]),
1994 -fabs(intersection_lon[1]),
1995 -intersection_lon[0],-20.0},
1996 (double[]){59.0,60.0,60.0,60.0,60.0,59.0},
1997 (enum yac_edge_type[]){
2000 utest_generate_cell_deg(
2001 (double[]){20.0,intersection_lon[0],
2002 -intersection_lon[0],-20.0,
2003 -fabs(intersection_lon[1]),
2004 fabs(intersection_lon[1])},
2005 (double[]){59.0,60.0,60.0,59.0,60.0,60.0},
2006 (enum yac_edge_type[]){
2009 // number of reference cells
2010 2);
2011 }
2012
2013 TEST_START("some mean tests");
2014 /* cell a
2015
2016 +------+ 60
2017 | |
2018 | |
2019 | |
2020 +------+ 40
2021 -20 20
2022 */
2023
2024 /* cell b
2025
2026 -------- 59
2027 \ /
2028 \ /
2029 \ /
2030 \/ 50
2031 -20 0 20
2032 */
2033
2034 {
2035 double intersection[3], intersection_lon, intersection_lat;
2036
2037 if (!utest_intersect(
2038 YAC_GREAT_CIRCLE_EDGE, 20.0,59.0,-20.0,59.0,
2039 YAC_LAT_CIRCLE_EDGE, -20.0,60.0,0.0,60.0, intersection))
2040 return EXIT_FAILURE;
2041 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
2042 intersection_lon /= YAC_RAD;
2043 intersection_lat /= YAC_RAD;
2044
2045 utest_clipping(
2046 // input cells
2047 (struct yac_grid_cell[]){
2048 utest_generate_cell_deg(
2049 (double[]){-20.0,20.0,20.0,-20.0},
2050 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2051 utest_generate_cell_deg(
2052 (double[]){-20.0, 0.0,20.0},
2053 (double[]){59.0,50.0,59.0}, gc_edges, 3)},
2054 // reference cells
2055 (struct yac_grid_cell[]){
2056 utest_generate_cell_deg(
2057 (double[]){intersection_lon,-intersection_lon,
2058 20.0,0.0,-20.0},
2059 (double[]){60.0,60.0,59.0,50.0,59.0},
2060 (enum yac_edge_type[]){
2063 // number of reference cells
2064 1);
2065 }
2066
2067 TEST_START("some mean tests");
2068 /* cell a
2069
2070 +------+ 20
2071 | |
2072 | |
2073 | |
2074 +------+ -20
2075 -20 20
2076 */
2077
2078 /* cell b
2079
2080 +------+ 19
2081 | |
2082 | |
2083 | |
2084 +------+ -19
2085 -19 19
2086 */
2087
2088 {
2089 double intersection[3], intersection_lon, intersection_lat;
2090
2091 if (!utest_intersect(
2092 YAC_GREAT_CIRCLE_EDGE, -19.0,19.0,19.0,19.0,
2093 YAC_LAT_CIRCLE_EDGE, -20.0,20.0, 0.0,20.0, intersection))
2094 return EXIT_FAILURE;
2095 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
2096 intersection_lon /= YAC_RAD;
2097 intersection_lat /= YAC_RAD;
2098
2099 utest_clipping(
2100 // input cells
2101 (struct yac_grid_cell[]){
2102 utest_generate_cell_deg(
2103 (double[]){-20.0,20.0,20.0,-20.0},
2104 (double[]){ 20.0,20.0,-20.0,-20.0}, latlon_edges, 4),
2105 utest_generate_cell_deg(
2106 (double[]){-19.0,-19.0,19.0,19.0},
2107 (double[]){ 19.0,-19.0,-19.0,19.0}, gc_edges, 4)},
2108 // reference cells
2109 (struct yac_grid_cell[]){
2110 utest_generate_cell_deg(
2111 (double[]){-19.0,intersection_lon,
2112 -intersection_lon,19.0,19.0,
2113 -intersection_lon,intersection_lon,-19.0},
2114 (double[]){19.0,20.0,20.0,19.0,
2115 -19.0,-20.0,-20.0,-19.0},
2116 (enum yac_edge_type[]){
2120 // number of reference cells
2121 1);
2122 }
2123
2124 TEST_START("some mean tests");
2125 /* cell a
2126
2127 +------+ 60
2128 | |
2129 | |
2130 | |
2131 +------+ 40
2132 -20 20
2133 */
2134
2135 /* cell b
2136
2137 /\ 55
2138 / \
2139 / \
2140 / \
2141 -------- 45
2142 -40 -20 0
2143 */
2144
2145 {
2146 double intersection[3], intersection_lon, intersection_lat;
2147
2148 if (!utest_intersect(
2149 YAC_GREAT_CIRCLE_EDGE, -40.0, 45.0, 0.0, 45.0,
2150 YAC_LON_CIRCLE_EDGE, -20.0, 40.0,-20.0, 60.0, intersection))
2151 return EXIT_FAILURE;
2152 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
2153 intersection_lon /= YAC_RAD;
2154 intersection_lat /= YAC_RAD;
2155
2156 utest_clipping(
2157 // input cells
2158 (struct yac_grid_cell[]){
2159 utest_generate_cell_deg(
2160 (double[]){-20.0,20.0,20.0,-20.0},
2161 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2162 utest_generate_cell_deg(
2163 (double[]){-40.0, 0.0,-20.0},
2164 (double[]){ 45.0,45.0,55.0}, gc_edges, 3)},
2165 // reference cells
2166 (struct yac_grid_cell[]){
2167 utest_generate_cell_deg(
2168 (double[]){-20.0,-20.0,0.0},
2169 (double[]){intersection_lat,55.0,45.0},
2170 (enum yac_edge_type[]){
2172 // number of reference cells
2173 1);
2174 }
2175
2176 TEST_START("some mean tests");
2177 /* cell a
2178
2179 +------+ 60
2180 | |
2181 | |
2182 | |
2183 +------+ 40
2184 -20 20
2185 */
2186
2187 /* cell b
2188
2189 /| 50
2190 / |
2191 / | 40
2192 \ |
2193 \ |
2194 \| 30
2195 -10 10
2196 */
2197
2198 {
2199 utest_clipping(
2200 // input cells
2201 (struct yac_grid_cell[]){
2202 utest_generate_cell_deg(
2203 (double[]){-20.0,20.0,20.0,-20.0},
2204 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2205 utest_generate_cell_deg(
2206 (double[]){-10.0,10.0,10.0},
2207 (double[]){ 40.0,30.0,50.0}, gc_edges, 3)},
2208 // reference cells
2209 (struct yac_grid_cell[]){
2210 utest_generate_cell_deg(
2211 (double[]){-10.0,10.0,10.0},
2212 (double[]){40.0,50.0,40.0},
2213 (enum yac_edge_type[]){
2215 // number of reference cells
2216 1);
2217 }
2218
2219 TEST_START("some mean tests");
2220 /* cell a
2221
2222 +------+ 60
2223 | |
2224 | |
2225 | |
2226 +------+ 40
2227 -20 20
2228 */
2229
2230 /* cell b
2231
2232 /| 80
2233 / |
2234 / |
2235 / |
2236 61 --...__|
2237 59
2238 -20 21
2239 */
2240
2241 {
2242 double intersection[2][3], intersection_lon[2], intersection_lat[2];
2243
2244 if (!utest_intersect(
2245 YAC_GREAT_CIRCLE_EDGE, -20.0, 61.0,21.0, 59.0,
2246 YAC_LAT_CIRCLE_EDGE, -20.0, 60.0,20.0, 60.0, intersection[0]))
2247 return EXIT_FAILURE;
2248 if (!utest_intersect(
2249 YAC_GREAT_CIRCLE_EDGE, -20.0, 61.0,21.0, 59.0,
2250 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[1]))
2251 return EXIT_FAILURE;
2252 for (int i = 0; i < 2; ++i) {
2253 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2254 intersection_lon[i] /= YAC_RAD;
2255 intersection_lat[i] /= YAC_RAD;
2256 }
2257
2258 utest_clipping(
2259 // input cells
2260 (struct yac_grid_cell[]){
2261 utest_generate_cell_deg(
2262 (double[]){-20.0,20.0,20.0,-20.0},
2263 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2264 utest_generate_cell_deg(
2265 (double[]){-20.0,21.0,21.0},
2266 (double[]){61.0,80.0,59.0}, gc_edges, 3)},
2267 // reference cells
2268 (struct yac_grid_cell[]){
2269 utest_generate_cell_deg(
2270 (double[]){20.0,intersection_lon[0],
2271 intersection_lon[1]},
2272 (double[]){60.0,intersection_lat[0],
2273 intersection_lat[1]},
2274 (enum yac_edge_type[]){
2276 // number of reference cells
2277 1);
2278 }
2279
2280 TEST_START("some mean tests");
2281 /* cell a
2282
2283 +------+ 60
2284 | |
2285 | |
2286 | |
2287 +------+ 40
2288 -20 20
2289 */
2290
2291 /* cell b
2292
2293 /\ x (slightly above 40)
2294 / \
2295 / \
2296 / \
2297 -------- 30
2298 -20 0 20
2299 */
2300
2301 {
2302 double intersection[2][3], intersection_lon[2], intersection_lat[2];
2303
2304 if (!utest_intersect(
2305 YAC_LON_CIRCLE_EDGE, 0.0,60.0,0.0,30.0,
2306 YAC_GREAT_CIRCLE_EDGE, -20.0, 40.0,20.0, 40.0, intersection[0]))
2307 return EXIT_FAILURE;
2308 XYZtoLL(intersection[0], &intersection_lon[0], &intersection_lat[0]);
2309 intersection_lon[0] /= YAC_RAD;
2310 intersection_lat[0] /= YAC_RAD;
2311 if (!utest_intersect(
2312 YAC_GREAT_CIRCLE_EDGE, 0.0,intersection_lat[0],20.0,30.0,
2313 YAC_LAT_CIRCLE_EDGE, -20.0, 40.0,20.0, 40.0, intersection[1]))
2314 return EXIT_FAILURE;
2315 XYZtoLL(intersection[1], &intersection_lon[1], &intersection_lat[1]);
2316 intersection_lon[1] /= YAC_RAD;
2317 intersection_lat[1] /= YAC_RAD;
2318
2319 utest_clipping(
2320 // input cells
2321 (struct yac_grid_cell[]){
2322 utest_generate_cell_deg(
2323 (double[]){-20.0,20.0,20.0,-20.0},
2324 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2325 utest_generate_cell_deg(
2326 (double[]){-20.0,20.0, 0.0},
2327 (double[]){30.0,30.0,intersection_lat[0]},
2328 gc_edges, 3)},
2329 // reference cells
2330 (struct yac_grid_cell[]){
2331 utest_generate_cell_deg(
2332 (double[]){0.0,intersection_lon[1],
2333 -intersection_lon[1]},
2334 (double[]){intersection_lat[0],40.0,40.0},
2335 (enum yac_edge_type[]){
2337 // number of reference cells
2338 1);
2339 }
2340
2341 TEST_START("some mean tests");
2342 /* cell a
2343
2344 +------+ 60
2345 | |
2346 | |
2347 | |
2348 +------+ 40
2349 -20 20
2350 */
2351
2352 /* cell b
2353
2354 /\ 70
2355 / \
2356 / \
2357 / \
2358 -------- 59
2359 -21 0 21
2360 */
2361
2362 {
2363 double intersection[4][3], intersection_lon[4], intersection_lat[4];
2364
2365 if (!utest_intersect(
2366 YAC_GREAT_CIRCLE_EDGE, -21.0, 59.0,21.0, 59.0,
2367 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[0]))
2368 return EXIT_FAILURE;
2369 if (!utest_intersect(
2370 YAC_GREAT_CIRCLE_EDGE, 0.0,70.0,21.0,59.0,
2371 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[1]))
2372 return EXIT_FAILURE;
2373 if (!utest_intersect(
2374 YAC_GREAT_CIRCLE_EDGE, 0.0,70.0,21.0,59.0,
2375 YAC_LAT_CIRCLE_EDGE, -20.0, 60.0,20.0, 60.0, intersection[2]))
2376 return EXIT_FAILURE;
2377 if (!utest_intersect(
2378 YAC_GREAT_CIRCLE_EDGE,-21.0, 59.0,21.0, 59.0,
2379 YAC_LAT_CIRCLE_EDGE, 0.0,60.0,20.0,60.0, intersection[3]))
2380 return EXIT_FAILURE;
2381 for (int i = 0; i < 4; ++i) {
2382 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2383 intersection_lon[i] /= YAC_RAD;
2384 intersection_lat[i] /= YAC_RAD;
2385 }
2386
2387 utest_clipping(
2388 // input cells
2389 (struct yac_grid_cell[]){
2390 utest_generate_cell_deg(
2391 (double[]){-20.0,20.0,20.0,-20.0},
2392 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2393 utest_generate_cell_deg(
2394 (double[]){-21.0, 0.0,21.0},
2395 (double[]){59.0,70.0,59.0}, gc_edges, 3)},
2396 // reference cells
2397 (struct yac_grid_cell[]){
2398 utest_generate_cell_deg(
2399 (double[]){20.0,20.0,intersection_lon[2],
2400 intersection_lon[3],-intersection_lon[3],
2401 -intersection_lon[2],-20.0,-20.0},
2402 (double[]){intersection_lat[0],intersection_lat[1],
2403 60.0,60.0,60.0,60.0,intersection_lat[1],
2404 intersection_lat[0]},
2405 (enum yac_edge_type[]){
2409 utest_generate_cell_deg(
2410 (double[]){20.0,20.0,intersection_lon[2],
2411 intersection_lon[3],-intersection_lon[3],
2412 -intersection_lon[2],-20.0,-20.0,
2413 -intersection_lon[3],intersection_lon[3]},
2414 (double[]){intersection_lat[0],intersection_lat[1],
2415 60.0,60.0,60.0,60.0,intersection_lat[1],
2416 intersection_lat[0],60.0,60.0},
2417 (enum yac_edge_type[]){
2422 utest_generate_cell_deg(
2423 (double[]){20.0,20.0,intersection_lon[2],
2424 -intersection_lon[2],-20.0,-20.0,
2425 -intersection_lon[3],intersection_lon[3]},
2426 (double[]){intersection_lat[0],intersection_lat[1],
2427 60.0,60.0,intersection_lat[1],
2428 intersection_lat[0],60.0,60.0},
2429 (enum yac_edge_type[]){
2433 // number of reference cells
2434 3);
2435 }
2436
2437 TEST_START("some mean tests");
2438 /* cell a
2439
2440 +------+ 60
2441 | |
2442 | |
2443 | |
2444 +------+ 40
2445 -x x (x is choosen such that the upper corners of the
2446 quadrangle touch the sloping edges of the triangle)
2447 */
2448
2449 /* cell b
2450
2451 /\ 70
2452 / \
2453 / \
2454 / \
2455 -------- 59
2456 -21 0 21
2457 */
2458
2459 {
2460 double intersection[3][3], intersection_lon[3], intersection_lat[3];
2461
2462 if (!utest_intersect(
2463 YAC_GREAT_CIRCLE_EDGE, 0.0,70.0,21.0,59.0,
2464 YAC_LAT_CIRCLE_EDGE, 0.0,60.0,25.0,60.0, intersection[0]))
2465 return EXIT_FAILURE;
2466 if (!utest_intersect(
2467 YAC_GREAT_CIRCLE_EDGE,-21.0,59.0,21.0,59.0,
2468 YAC_LAT_CIRCLE_EDGE, 0.0,60.0,25.0,60.0, intersection[1]))
2469 return EXIT_FAILURE;
2470 for (int i = 0; i < 2; ++i) {
2471 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2472 intersection_lon[i] /= YAC_RAD;
2473 intersection_lat[i] /= YAC_RAD;
2474 }
2475 if (!utest_intersect(
2476 YAC_GREAT_CIRCLE_EDGE, -21.0, 59.0,21.0, 59.0,
2477 YAC_LON_CIRCLE_EDGE, intersection_lon[0],60.0,intersection_lon[0],
2478 40.0, intersection[2]))
2479 return EXIT_FAILURE;
2480 XYZtoLL(intersection[2], &intersection_lon[2], &intersection_lat[2]);
2481 intersection_lon[2] /= YAC_RAD;
2482 intersection_lat[2] /= YAC_RAD;
2483
2484 utest_clipping(
2485 // input cells
2486 (struct yac_grid_cell[]){
2487 utest_generate_cell_deg(
2488 (double[]){-intersection_lon[0],intersection_lon[0],
2489 intersection_lon[0],-intersection_lon[0]},
2490 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2491 utest_generate_cell_deg(
2492 (double[]){-21.0, 0.0,21.0},
2493 (double[]){59.0,70.0,59.0}, gc_edges, 3)},
2494 // reference cells
2495 (struct yac_grid_cell[]){
2496 utest_generate_cell_deg(
2497 (double[]){intersection_lon[2],intersection_lon[0],
2498 intersection_lon[1],-intersection_lon[1],
2499 -intersection_lon[0],-intersection_lon[2]},
2500 (double[]){intersection_lat[2],60.0,60.0,60.0,60.0,
2501 intersection_lat[2]},
2502 (enum yac_edge_type[]){
2505 utest_generate_cell_deg(
2506 (double[]){intersection_lon[2],intersection_lon[0],
2507 intersection_lon[1],-intersection_lon[1],
2508 -intersection_lon[0],-intersection_lon[2],
2509 -intersection_lon[1],intersection_lon[1]},
2510 (double[]){intersection_lat[2],60.0,60.0,60.0,60.0,
2511 intersection_lat[2],60.0,60.0},
2512 (enum yac_edge_type[]){
2516 utest_generate_cell_deg(
2517 (double[]){intersection_lon[2],intersection_lon[0],
2518 -intersection_lon[0],-intersection_lon[2],
2519 -intersection_lon[1],intersection_lon[1]},
2520 (double[]){intersection_lat[2],60.0,60.0,
2521 intersection_lat[2],60.0,60.0},
2522 (enum yac_edge_type[]){
2525 // number of reference cells
2526 3);
2527 }
2528
2529 TEST_START("some mean tests");
2530 /* cell a
2531
2532 +------+ 60
2533 | |
2534 | |
2535 | |
2536 +------+ 40
2537 -20 20
2538 */
2539
2540 /* cell b
2541
2542 -------- 59
2543 \ /
2544 \ /
2545 \ /
2546 \/ 50
2547 -21 0 21
2548 */
2549
2550 {
2551 double intersection[3][3], intersection_lon[3], intersection_lat[3];
2552
2553 if (!utest_intersect(
2554 YAC_GREAT_CIRCLE_EDGE, 21.0,59.0,-21.0,59.0,
2555 YAC_LAT_CIRCLE_EDGE, 0.0,60.0,20.0,60.0, intersection[0]))
2556 return EXIT_FAILURE;
2557 if (!utest_intersect(
2558 YAC_GREAT_CIRCLE_EDGE, 21.0, 59.0,-21.0, 59.0,
2559 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[1]))
2560 return EXIT_FAILURE;
2561
2562 if (!utest_intersect(
2563 YAC_GREAT_CIRCLE_EDGE, 0.0,50.0,21.0,59.0,
2564 YAC_LON_CIRCLE_EDGE, 20.0,40.0,20.0,60.0, intersection[2]))
2565 return EXIT_FAILURE;
2566 for (int i = 0; i < 3; ++i) {
2567 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2568 intersection_lon[i] /= YAC_RAD;
2569 intersection_lat[i] /= YAC_RAD;
2570 }
2571
2572 utest_clipping(
2573 // input cells
2574 (struct yac_grid_cell[]){
2575 utest_generate_cell_deg(
2576 (double[]){-20.0,20.0,20.0,-20.0},
2577 (double[]){ 40.0,40.0,60.0,60.0}, latlon_edges, 4),
2578 utest_generate_cell_deg(
2579 (double[]){-21.0, 0.0,21.0},
2580 (double[]){59.0,50.0,59.0}, gc_edges, 3)},
2581 // reference cells
2582 (struct yac_grid_cell[]){
2583 utest_generate_cell_deg(
2584 (double[]){intersection_lon[0],20.0,20.0,0.0,-20.0,
2585 -20.0,-intersection_lon[0]},
2586 (double[]){60.0,intersection_lat[1],
2587 intersection_lat[2],50.0,
2588 intersection_lat[2],intersection_lat[1],
2589 60.0},
2590 (enum yac_edge_type[]){
2593 YAC_LAT_CIRCLE_EDGE}, 7)},
2594 // number of reference cells
2595 1);
2596 }
2597
2598 TEST_START("some mean tests");
2599 /* cell a (circle around a pole)
2600
2601 .--.
2602 / \
2603 \ /
2604 '--'
2605 */
2606
2607 /* cell b (circle around a pole; bigger than cell a)
2608
2609 .-""-.
2610 / \
2611 ; ;
2612 \ /
2613 '-..-'
2614 */
2615
2616 {
2617
2618 utest_clipping(
2619 // input cells
2620 (struct yac_grid_cell[]){
2621 utest_generate_cell_deg(
2622 (double[]){ 0.0,72.0,144.0,216.0,288.0},
2623 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2624 (enum yac_edge_type[]){
2627 utest_generate_cell_deg(
2628 (double[]){ 0.0,72.0,144.0,216.0,288.0},
2629 (double[]){ 80.0,80.0,80.0,80.0,80.0},
2630 (enum yac_edge_type[]){
2633 // reference cells
2634 (struct yac_grid_cell[]){
2635 utest_generate_cell_deg(
2636 (double[]){ 0.0,72.0,144.0,216.0,288.0},
2637 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2638 (enum yac_edge_type[]){
2641 // number of reference cells
2642 1);
2643 }
2644
2645 TEST_START("some mean tests");
2646 /* cell a (circle around a pole)
2647
2648 .-""-.
2649 / \
2650 ; ;
2651 \ /
2652 '-..-'
2653 */
2654
2655 /* cell b (circle around a pole; same size as cell a)
2656
2657 .-""-.
2658 / \
2659 ; ;
2660 \ /
2661 '-..-'
2662 */
2663
2664 {
2665
2666 utest_clipping(
2667 // input cells
2668 (struct yac_grid_cell[]){
2669 utest_generate_cell_deg(
2670 (double[]){ 0.0,72.0,144.0,216.0,288.0},
2671 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2672 (enum yac_edge_type[]){
2675 utest_generate_cell_deg(
2676 (double[]){ 0.0,72.0,144.0,216.0,288.0},
2677 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2678 (enum yac_edge_type[]){
2681 // reference cells
2682 (struct yac_grid_cell[]){
2683 utest_generate_cell_deg(
2684 (double[]){ 0.0,72.0,144.0,216.0,288.0},
2685 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2686 (enum yac_edge_type[]){
2689 // number of reference cells
2690 1);
2691 }
2692
2693 TEST_START("some mean tests");
2694 /* cell a (circle around a pole)
2695
2696 .-""-.
2697 / \
2698 ; ;
2699 \ /
2700 '-..-'
2701 */
2702
2703 /* cell b (circle around different pole than cell a)
2704
2705 .-""-.
2706 / \
2707 ; ;
2708 \ /
2709 '-..-'
2710 */
2711
2712 {
2713
2714 utest_clipping(
2715 // input cells
2716 (struct yac_grid_cell[]){
2717 utest_generate_cell_deg(
2718 (double[]){ 0.0,72.0,144.0,216.0,288.0},
2719 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2720 (enum yac_edge_type[]){
2723 utest_generate_cell_deg(
2724 (double[]){ 0.0,72.0,144.0,216.0,288.0},
2725 (double[]){-85.0,-85.0,-85.0,-85.0,-85.0},
2726 (enum yac_edge_type[]){
2729 // reference cells
2730 (struct yac_grid_cell[]){
2731 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
2732 // number of reference cells
2733 1);
2734 }
2735
2736 TEST_START("some mean tests");
2737 /* cell a (circle around a pole; made of lat circle edges)
2738
2739 .-""-.
2740 / \
2741 ; ;
2742 \ /
2743 '-..-'
2744 */
2745
2746 /* cell b (circle around a pole; made of great circle edges;
2747 corners are on the lat circles)
2748
2749 ____
2750 / \
2751 / \
2752 * *
2753 \ /
2754 \____/
2755 */
2756
2757 {
2758
2759 utest_clipping(
2760 // input cells
2761 (struct yac_grid_cell[]){
2762 utest_generate_cell_deg(
2763 (double[]){ 0.0,72.0,144.0,216.0,288.0},
2764 (double[]){ 85.0,85.0,85.0,85.0,85.0},
2765 (enum yac_edge_type[]){
2768 utest_generate_cell_deg(
2769 (double[]){ 0.0,60.0,120.0,180.0,240.0,300.0},
2770 (double[]){ 85.0,85.0,85.0,85.0,85.0,85.0},
2771 (enum yac_edge_type[]){
2774 // reference cells
2775 (struct yac_grid_cell[]){
2776 utest_generate_cell_deg(
2777 (double[]){ 0.0,60.0,120.0,180.0,240.0,300.0},
2778 (double[]){ 85.0,85.0,85.0,85.0,85.0,85.0},
2779 (enum yac_edge_type[]){
2782 // number of reference cells
2783 1);
2784 }
2785
2786 TEST_START("some mean tests");
2787 /* cell a (circle around a pole; made of lat circle edges)
2788
2789 .-""-.
2790 / \
2791 ; ;
2792 \ /
2793 '-..-'
2794 */
2795
2796 /* cell b (circle around a pole; made of great circle edges;
2797 all great circles edges intersect with the lat circles twice)
2798
2799 ____
2800 / \
2801 / \
2802 * *
2803 \ /
2804 \____/
2805 */
2806
2807 {
2808
2809 double intersection[2][3], intersection_lon[2], intersection_lat[2];
2810
2811 if (!utest_intersect(
2812 YAC_LAT_CIRCLE_EDGE, 0.0,85.5,30.0,85.5,
2813 YAC_GREAT_CIRCLE_EDGE, 0.0,85.0,60.0,85.0, intersection[0]))
2814 return EXIT_FAILURE;
2815 if (!utest_intersect(
2816 YAC_LAT_CIRCLE_EDGE, 30.0,85.5,60.0,85.5,
2817 YAC_GREAT_CIRCLE_EDGE, 0.0,85.0,60.0,85.0, intersection[1]))
2818 return EXIT_FAILURE;
2819 for (int i = 0; i < 2; ++i) {
2820 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
2821 intersection_lon[i] /= YAC_RAD;
2822 intersection_lat[i] /= YAC_RAD;
2823 }
2824
2825 utest_clipping(
2826 // input cells
2827 (struct yac_grid_cell[]){
2828 utest_generate_cell_deg(
2829 (double[]){ 0.0,72.0,144.0,216.0,288.0},
2830 (double[]){ 85.5,85.5,85.5,85.5,85.5},
2831 (enum yac_edge_type[]){
2834 utest_generate_cell_deg(
2835 (double[]){ 0.0,60.0,120.0,180.0,240.0,300.0},
2836 (double[]){ 85.0,85.0,85.0,85.0,85.0,85.0},
2837 (enum yac_edge_type[]){
2841 // reference cells
2842 (struct yac_grid_cell[]){
2843 utest_generate_cell_deg(
2844 (double[]){intersection_lon[0]+60.0*0.0,
2845 intersection_lon[1]+60.0*0.0,
2846 intersection_lon[0]+60.0*1.0,
2847 intersection_lon[1]+60.0*1.0,
2848 intersection_lon[0]+60.0*2.0,
2849 intersection_lon[1]+60.0*2.0,
2850 intersection_lon[0]+60.0*3.0,
2851 intersection_lon[1]+60.0*3.0,
2852 intersection_lon[0]+60.0*4.0,
2853 intersection_lon[1]+60.0*4.0,
2854 intersection_lon[0]+60.0*5.0,
2855 intersection_lon[1]+60.0*5.0},
2856 (double[]){85.5,85.5,85.5,85.5,85.5,85.5,85.5,85.5,
2857 85.5,85.5,85.5,85.5},
2858 (enum yac_edge_type[]){
2865 12)},
2866 // number of reference cells
2867 1);
2868 }
2869
2871 TEST_START("example taken from bug report by Uwe");
2872
2873 /* 13.) source cell test data
2874
2875 +------+ 5
2876 | |
2877 | |
2878 | |
2879 +------+ 0
2880 355 360
2881 */
2882
2883 /* target cell test data
2884
2885 +------+ 0
2886 | |
2887 | |
2888 | |
2889 +------+ -10
2890 240 250
2891 */
2892
2893 {
2894 utest_clipping(
2895 // input cells
2896 (struct yac_grid_cell[]){
2897 utest_generate_cell_deg(
2898 (double[]){355.0,360.0,360.0,355.0},
2899 (double[]){ 0.0, 0.0, 5.0, 5.0}, gc_edges, 4),
2900 utest_generate_cell_deg(
2901 (double[]){240.0,250.0,250.0,240.0},
2902 (double[]){-10.0,-10.0, 0.0, 0.0}, gc_edges, 4)},
2903 // reference cells
2904 (struct yac_grid_cell[]){
2905 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
2906 // number of reference cells
2907 1);
2908 }
2909
2911 TEST_START("example taken from icon toy");
2912
2913 /* 14.1) source cell test data
2914
2915 +------+ 2
2916 | |
2917 | |
2918 | |
2919 +------+ 0
2920 0 2
2921 */
2922
2923 /* target cell test data
2924
2925 _______
2926 | / 1
2927 | /
2928 | /
2929 |/ -1
2930 2 4
2931 */
2932
2933 {
2934 utest_clipping(
2935 // input cells
2936 (struct yac_grid_cell[]){
2937 utest_generate_cell_deg(
2938 (double[]){ 2.0,2.0,4.0},
2939 (double[]){-1.0,1.0,1.0}, gc_edges, 3),
2940 utest_generate_cell_deg(
2941 (double[]){0.0,2.0,2.0,0.0},
2942 (double[]){0.0,0.0,2.0,2.0}, latlon_edges, 4)},
2943 // reference cells
2944 (struct yac_grid_cell[]){
2945 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
2946 // number of reference cells
2947 1);
2948 }
2949
2950 TEST_START("example taken from icon toy");
2951
2952 {
2953 double intersection[3], intersection_lon, intersection_lat;
2954
2955 if (!utest_intersect(
2956 YAC_LON_CIRCLE_EDGE, 1.0,90.0,1.0,80.0,
2957 YAC_GREAT_CIRCLE_EDGE, 0.0,85.0,5.0,85.0, intersection))
2958 return EXIT_FAILURE;
2959 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
2960 intersection_lon /= YAC_RAD;
2961 intersection_lat /= YAC_RAD;
2962
2963 utest_clipping(
2964 // input cells
2965 (struct yac_grid_cell[]){
2966 utest_generate_cell_deg(
2967 (double[]){ 0.0,180.0, 5.0},
2968 (double[]){85.0,90.0,85.0}, gc_edges, 3),
2969 utest_generate_cell_deg(
2970 (double[]){ 1.0,-5.0,-5.0,1.0},
2971 (double[]){80.0,80.0,90.0,90.0}, latlon_edges, 4)},
2972 // reference cells
2973 (struct yac_grid_cell[]){
2974 utest_generate_cell_deg(
2975 (double[]){1.0,0.0,0.0},
2976 (double[]){intersection_lat,85.0,90.0},
2977 (enum yac_edge_type[]){
2979 // number of reference cells
2980 1);
2981 }
2982
2983 TEST_START("example taken from icon toy");
2984
2985 {
2986
2987 double intersection[4][3], intersection_lon[4], intersection_lat[4];
2988
2989 if (!utest_intersect(
2990 YAC_LAT_CIRCLE_EDGE, 0.46633015951723494341,-0.88357293382212931387,
2991 0.49087385212340517437,-0.88357293382212931387,
2992 YAC_GREAT_CIRCLE_EDGE, 0.47953965147452792817,-0.90109638077934106626,
2993 0.46519399935013672209,-0.88122392525212978054,
2994 intersection[0]))
2995 return EXIT_FAILURE;
2996 if (!utest_intersect(
2997 YAC_LON_CIRCLE_EDGE, 0.46633015951723494341,-0.88357293382212931387,
2998 0.46633015951723494341,-0.85902924121595902740,
2999 YAC_GREAT_CIRCLE_EDGE, 0.47953965147452792817,-0.90109638077934106626,
3000 0.46519399935013672209,-0.88122392525212978054,
3001 intersection[1]))
3002 return EXIT_FAILURE;
3003 if (!utest_intersect(
3004 YAC_LON_CIRCLE_EDGE, 0.46633015951723494341,-0.88357293382212931387,
3005 0.46633015951723494341,-0.85902924121595902740,
3006 YAC_GREAT_CIRCLE_EDGE, 0.50100250912415544846,-0.88440597750634275531,
3007 0.46519399935013672209,-0.88122392525212978054,
3008 intersection[2]))
3009 return EXIT_FAILURE;
3010 if (!utest_intersect(
3011 YAC_LON_CIRCLE_EDGE, 0.49087385212340517437,-0.88357293382212931387,
3012 0.49087385212340517437,-0.85902924121595902740,
3013 YAC_GREAT_CIRCLE_EDGE, 0.50100250912415544846,-0.88440597750634275531,
3014 0.46519399935013672209,-0.88122392525212978054,
3015 intersection[3]))
3016 return EXIT_FAILURE;
3017 for (int i = 0; i < 4; ++i) {
3018 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3019 intersection_lon[i] /= YAC_RAD;
3020 intersection_lat[i] /= YAC_RAD;
3021 }
3022
3023 utest_clipping(
3024 // input cells
3025 (struct yac_grid_cell[]){
3026 utest_generate_cell_deg(
3027 (double[]){ 0.46633015951723494341,
3028 0.49087385212340517437,
3029 0.49087385212340517437,
3030 0.46633015951723494341},
3031 (double[]){-0.88357293382212931387,
3032 -0.88357293382212931387,
3033 -0.85902924121595902740,
3034 -0.85902924121595902740}, latlon_edges, 4),
3035 utest_generate_cell_deg(
3036 (double[]){ 0.47953965147452792817,
3037 0.50100250912415544846,
3038 0.46519399935013672209},
3039 (double[]){-0.90109638077934106626,
3040 -0.88440597750634275531,
3041 -0.88122392525212978054}, gc_edges, 3)},
3042 // reference cells
3043 (struct yac_grid_cell[]){
3044 utest_generate_cell_deg(
3045 (double[]){0.49087385212340517437,
3046 intersection_lon[0],
3047 0.46633015951723494341,
3048 0.46633015951723494341,
3049 0.49087385212340517437},
3050 (double[]){-0.88357293382212931387,
3051 intersection_lat[0],
3052 intersection_lat[1],
3053 intersection_lat[2],
3054 intersection_lat[3]},
3055 (enum yac_edge_type[]){
3058 // number of reference cells
3059 1);
3060 }
3061
3062 TEST_START("example provided by Uwe");
3063
3064 {
3065
3066 double intersection[4][3], intersection_lon[4], intersection_lat[4];
3067
3068 if (!utest_intersect(
3069 YAC_GREAT_CIRCLE_EDGE, 180.25,-89.75,180.25,-89.50,
3070 YAC_GREAT_CIRCLE_EDGE, 180.2,-89.6,180.3,-89.6, intersection[0]))
3071 return EXIT_FAILURE;
3072 if (!utest_intersect(
3073 YAC_GREAT_CIRCLE_EDGE, 180.25,-89.75,180.25,-89.50,
3074 YAC_GREAT_CIRCLE_EDGE, 180.3,-89.5,180.2,-89.5, intersection[1]))
3075 return EXIT_FAILURE;
3076 if (!utest_intersect(
3077 YAC_GREAT_CIRCLE_EDGE, 180.25,-89.5,180.00,-89.5,
3078 YAC_GREAT_CIRCLE_EDGE, 180.3,-89.5,180.2,-89.5, intersection[2]))
3079 return EXIT_FAILURE;
3080 if (!utest_intersect(
3081 YAC_GREAT_CIRCLE_EDGE, 180.25,-89.5,180.00,-89.5,
3082 YAC_GREAT_CIRCLE_EDGE, 180.2,-89.5,180.2,-89.6, intersection[3]))
3083 return EXIT_FAILURE;
3084 for (int i = 0; i < 4; ++i) {
3085 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3086 intersection_lon[i] /= YAC_RAD;
3087 intersection_lat[i] /= YAC_RAD;
3088 }
3089
3090 utest_clipping(
3091 // input cells
3092 (struct yac_grid_cell[]){
3093 utest_generate_cell_deg(
3094 (double[]){180.2,180.3,180.3,180.2},
3095 (double[]){-89.6,-89.6,-89.5,-89.5}, gc_edges, 4),
3096 utest_generate_cell_deg(
3097 (double[]){180.00,180.25,180.25,180.00},
3098 (double[]){-89.75,-89.75,-89.50,-89.50}, gc_edges, 4)},
3099 // reference cells
3100 (struct yac_grid_cell[]){
3101 utest_generate_cell_deg(
3102 (double[]){180.2,180.25,180.25,
3103 intersection_lon[2],180.20},
3104 (double[]){-89.6,intersection_lat[0],
3105 intersection_lat[1],intersection_lat[2],
3106 intersection_lat[3]}, gc_edges, 5)},
3107 // number of reference cells
3108 1);
3109 }
3110
3111 TEST_START("example taken from icon toy");
3112
3113 {
3114 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3115
3116 if (!utest_intersect(
3117 YAC_LAT_CIRCLE_EDGE, 1.20264093770234/YAC_RAD,
3118 -0.76085447079128/YAC_RAD,
3119 1.22718463030851/YAC_RAD,
3120 -0.76085447079128/YAC_RAD,
3121 YAC_GREAT_CIRCLE_EDGE, 1.20552692320133/YAC_RAD,
3122 -0.76075226373764/YAC_RAD,
3123 1.30774719967050/YAC_RAD,
3124 -0.76075226373764/YAC_RAD, intersection[0]))
3125 return EXIT_FAILURE;
3126 if (!utest_intersect(
3127 YAC_LAT_CIRCLE_EDGE, 1.20264093770234/YAC_RAD,
3128 -0.76085447079128/YAC_RAD,
3129 1.22718463030851/YAC_RAD,
3130 -0.76085447079128/YAC_RAD,
3131 YAC_GREAT_CIRCLE_EDGE, 1.20552692320133/YAC_RAD,
3132 -0.76075226373764/YAC_RAD,
3133 1.25663706143592/YAC_RAD,
3134 -0.82925269516665/YAC_RAD, intersection[1]))
3135 return EXIT_FAILURE;
3136 for (int i = 0; i < 2; ++i) {
3137 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3138 intersection_lon[i] /= YAC_RAD;
3139 intersection_lat[i] /= YAC_RAD;
3140 }
3141
3142 utest_clipping(
3143 // input cells
3144
3145 (struct yac_grid_cell[2]){
3146 utest_generate_cell_deg(
3147 (double[]){ 1.20264093770234/YAC_RAD,
3148 1.22718463030851/YAC_RAD,
3149 1.22718463030851/YAC_RAD,
3150 1.20264093770234/YAC_RAD},
3151 (double[]){-0.76085447079128/YAC_RAD,
3152 -0.76085447079128/YAC_RAD,
3153 -0.73631077818511/YAC_RAD,
3154 -0.73631077818511/YAC_RAD},
3155 latlon_edges, 4),
3156 utest_generate_cell_deg(
3157 (double[]){ 1.20552692320133/YAC_RAD,
3158 1.25663706143592/YAC_RAD,
3159 1.30774719967050/YAC_RAD},
3160 (double[]){-0.76075226373764/YAC_RAD,
3161 -0.82925269516665/YAC_RAD,
3162 -0.76075226373763/YAC_RAD}, gc_edges, 3)},
3163 // reference cells
3164 (struct yac_grid_cell[]){
3165 utest_generate_cell_deg(
3166 (double[]){1.20552692320133/YAC_RAD,
3167 intersection_lon[0], intersection_lon[1]},
3168 (double[]){-0.76075226373764/YAC_RAD,
3169 intersection_lat[0], intersection_lat[1]},
3170 (enum yac_edge_type[]){
3172 utest_generate_cell_deg(
3173 (double[]){1.20552692320133/YAC_RAD,
3174 intersection_lon[0],
3175 1.22718463030851/YAC_RAD,
3176 intersection_lon[1]},
3177 (double[]){-0.76075226373764/YAC_RAD,
3178 intersection_lat[0],
3179 -0.76085447079128/YAC_RAD,
3180 intersection_lat[1]},
3181 (enum yac_edge_type[]){
3184 // number of reference cells
3185 2);
3186 }
3187
3188 TEST_START("example in which all coordinates are 0 (occurred in a test"
3189 " of Uwe due to erroneous input data)")
3190 {
3191 utest_clipping(
3192 // input cells
3193
3194 (struct yac_grid_cell[2]){
3195 utest_generate_cell_deg(
3196 (double[]){0, 0, 0, 0},
3197 (double[]){0, 0, 0, 0}, latlon_edges, 4),
3198 utest_generate_cell_deg(
3199 (double[]){0, 0, 0},
3200 (double[]){0, 0, 0}, gc_edges, 3)},
3201 // reference cells
3202 (struct yac_grid_cell[]){
3203 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
3204 // number of reference cells
3205 1);
3206 }
3207
3208 TEST_START("example example take from ICON_toy");
3209 {
3210 utest_clipping(
3211 // input cells
3212
3213 (struct yac_grid_cell[2]){
3214 utest_generate_cell_deg(
3215 (double[]){3.1415926372157803/YAC_RAD,
3216 0.9682712007396151/YAC_RAD,
3217 -1.8849555862661402/YAC_RAD},
3218 (double[]){-1.5418135425481947/YAC_RAD,
3219 -1.5707963262077691/YAC_RAD,
3220 -1.5418135428532602/YAC_RAD},
3221 gc_edges, 3),
3222 utest_generate_cell_deg(
3223 (double[]){1.2517283229146832/YAC_RAD,
3224 1.2762720155208536/YAC_RAD,
3225 1.2762720155208536/YAC_RAD,
3226 1.2517283229146832/YAC_RAD},
3227 (double[]){-1.5707963267948966/YAC_RAD,
3228 -1.5707963267948966/YAC_RAD,
3229 -1.5462526341887264/YAC_RAD,
3230 -1.5462526341887264/YAC_RAD},
3231 latlon_edges, 4)},
3232 // reference cells
3233 (struct yac_grid_cell[]){
3234 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
3235 // number of reference cells
3236 1);
3237 }
3238
3239 TEST_START("example take from ICON_toy");
3240 {
3241 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3242
3243 if (!utest_intersect(
3244 YAC_GREAT_CIRCLE_EDGE, 0.9682712007396151/YAC_RAD,
3245 -1.5707963262077691/YAC_RAD,
3246 3.1415926372157803/YAC_RAD,
3247 -1.5418135425481947/YAC_RAD,
3248 YAC_LAT_CIRCLE_EDGE, 3.1170489609836229/YAC_RAD,
3249 -1.5462526341887264/YAC_RAD,
3250 3.1415926535897931/YAC_RAD,
3251 -1.5462526341887264/YAC_RAD,
3252 intersection[0]))
3253 return EXIT_FAILURE;
3254 if (!utest_intersect(
3255 YAC_GREAT_CIRCLE_EDGE, -1.8849555862661402/YAC_RAD,
3256 -1.5418135428532602/YAC_RAD,
3257 3.1415926372157803/YAC_RAD,
3258 -1.5418135425481947/YAC_RAD,
3259 YAC_LON_CIRCLE_EDGE, 3.1415926535897931/YAC_RAD,
3260 -1.5462526341887264/YAC_RAD,
3261 3.1415926535897931/YAC_RAD,
3262 -1.5217089415825560/YAC_RAD,
3263 intersection[1]))
3264 return EXIT_FAILURE;
3265 for (int i = 0; i < 2; ++i) {
3266 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3267 intersection_lon[i] /= YAC_RAD;
3268 intersection_lat[i] /= YAC_RAD;
3269 }
3270
3271 utest_clipping(
3272 // input cells
3273
3274 (struct yac_grid_cell[]){
3275 utest_generate_cell_deg(
3276 (double[]){ 3.1415926372157803/YAC_RAD,
3277 0.9682712007396151/YAC_RAD,
3278 -1.8849555862661402/YAC_RAD},
3279 (double[]){-1.5418135425481947/YAC_RAD,
3280 -1.5707963262077691/YAC_RAD,
3281 -1.5418135428532602/YAC_RAD}, gc_edges, 3),
3282 utest_generate_cell_deg(
3283 (double[]){ 3.1170489609836229/YAC_RAD,
3284 3.1415926535897931/YAC_RAD,
3285 3.1415926535897931/YAC_RAD,
3286 3.1170489609836229/YAC_RAD},
3287 (double[]){-1.5462526341887264/YAC_RAD,
3288 -1.5462526341887264/YAC_RAD,
3289 -1.5217089415825560/YAC_RAD,
3290 -1.5217089415825560/YAC_RAD},
3291 latlon_edges, 4)},
3292 // reference cells
3293 (struct yac_grid_cell[]){
3294 utest_generate_cell_deg(
3295 (double[]){ 3.1415926535897931/YAC_RAD,
3296 intersection_lon[0],
3297 3.1415926372157803/YAC_RAD,
3298 intersection_lon[1]},
3299 (double[]){-1.5462526341887264/YAC_RAD,
3300 intersection_lat[0],
3301 -1.5418135425481947/YAC_RAD,
3302 intersection_lat[1]},
3303 (enum yac_edge_type[]){
3306 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
3307 // number of reference cells
3308 2);
3309 }
3310
3311 TEST_START("example example take from ICON_toy");
3312 {
3313 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3314
3315 if (!utest_intersect(
3316 YAC_GREAT_CIRCLE_EDGE, -1.2564300972590368/YAC_RAD,
3317 1.5418206553283160/YAC_RAD,
3318 1.2277260313871721/YAC_RAD,
3319 1.5707871564758291/YAC_RAD,
3320 YAC_LON_CIRCLE_EDGE, 0.0000000000000000/YAC_RAD,
3321 1.5462526341887264/YAC_RAD,
3322 0.0000000000000000/YAC_RAD,
3323 1.5707963267948966/YAC_RAD,
3324 intersection[0]))
3325 return EXIT_FAILURE;
3326 if (!utest_intersect(
3327 YAC_GREAT_CIRCLE_EDGE, -1.2564300972590368/YAC_RAD,
3328 1.5418206553283160/YAC_RAD,
3329 1.2277260313871721/YAC_RAD,
3330 1.5707871564758291/YAC_RAD,
3331 YAC_LON_CIRCLE_EDGE, 0.0245436926061703/YAC_RAD,
3332 1.5462526341887264/YAC_RAD,
3333 0.0245436926061703/YAC_RAD,
3334 1.5707963267948966/YAC_RAD,
3335 intersection[1]))
3336 return EXIT_FAILURE;
3337 for (int i = 0; i < 2; ++i) {
3338 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3339 intersection_lon[i] /= YAC_RAD;
3340 intersection_lat[i] /= YAC_RAD;
3341 }
3342
3343 utest_clipping(
3344 // input cells
3345 (struct yac_grid_cell[]){
3346 utest_generate_cell_deg(
3347 (double[]){-1.2564300972590368/YAC_RAD,
3348 1.2277260313871721/YAC_RAD,
3349 -2.5134348157836111/YAC_RAD},
3350 (double[]){ 1.5418206553283160/YAC_RAD,
3351 1.5707871564758291/YAC_RAD,
3352 1.5418209335124486/YAC_RAD}, gc_edges, 3),
3353 utest_generate_cell_deg(
3354 (double[]){ 0.0000000000000000/YAC_RAD,
3355 0.0245436926061703/YAC_RAD,
3356 0.0245436926061703/YAC_RAD,
3357 0.0000000000000000/YAC_RAD},
3358 (double[]){ 1.5462526341887264/YAC_RAD,
3359 1.5462526341887264/YAC_RAD,
3360 1.5707963267948966/YAC_RAD,
3361 1.5707963267948966/YAC_RAD},
3362 latlon_edges, 4)},
3363 // reference cells
3364 (struct yac_grid_cell[]){
3365 utest_generate_cell_deg(
3366 (double[]){0,intersection_lon[0],intersection_lon[1]},
3367 (double[]){90.0,intersection_lat[0],
3368 intersection_lat[1]},
3369 (enum yac_edge_type[]){
3371 // number of reference cells
3372 1);
3373 }
3374
3375 TEST_START("example example take from ICON_toy");
3376 {
3377 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3378
3379 if (!utest_intersect(
3380 YAC_GREAT_CIRCLE_EDGE, -2.1798479726998332/YAC_RAD,
3381 -0.0311624518327736/YAC_RAD,
3382 -2.1991148570983681/YAC_RAD,
3383 0.0000000043633749/YAC_RAD,
3384 YAC_LAT_CIRCLE_EDGE, 4.0742529726242633/YAC_RAD,
3385 0.0000000000000000/YAC_RAD,
3386 4.0987966652304335/YAC_RAD,
3387 0.0000000000000000/YAC_RAD,
3388 intersection[0]))
3389 return EXIT_FAILURE;
3390 if (!utest_intersect(
3391 YAC_GREAT_CIRCLE_EDGE, -2.2190472361409284/YAC_RAD,
3392 -0.0338654325037920/YAC_RAD,
3393 -2.1991148570983681/YAC_RAD,
3394 0.0000000043633749/YAC_RAD,
3395 YAC_LAT_CIRCLE_EDGE, 4.0742529726242633/YAC_RAD,
3396 0.0000000000000000/YAC_RAD,
3397 4.0987966652304335/YAC_RAD,
3398 0.0000000000000000/YAC_RAD,
3399 intersection[1]))
3400 return EXIT_FAILURE;
3401 for (int i = 0; i < 2; ++i) {
3402 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3403 intersection_lon[i] /= YAC_RAD;
3404 intersection_lat[i] /= YAC_RAD;
3405 }
3406
3407 utest_clipping(
3408
3409 // input cells
3410 (struct yac_grid_cell[]){
3411 utest_generate_cell_deg(
3412 (double[]){-2.1798479726998332/YAC_RAD,
3413 -2.1991148570983681/YAC_RAD,
3414 -2.2190472361409284/YAC_RAD},
3415 (double[]){-0.0311624518327736/YAC_RAD,
3416 0.0000000043633749/YAC_RAD,
3417 -0.0338654325037920/YAC_RAD},
3418 gc_edges, 3),
3419 utest_generate_cell_deg(
3420 (double[]){ 4.0742529726242633/YAC_RAD,
3421 4.0987966652304335/YAC_RAD,
3422 4.0987966652304335/YAC_RAD,
3423 4.0742529726242633/YAC_RAD},
3424 (double[]){ 0.0000000000000000/YAC_RAD,
3425 0.0000000000000000/YAC_RAD,
3426 0.0245436926061703/YAC_RAD,
3427 0.0245436926061703/YAC_RAD},
3428 latlon_edges, 4)},
3429 // reference cells
3430 (struct yac_grid_cell[]){
3431 utest_generate_cell_deg(
3432 (double[]){-2.1991148570983681/YAC_RAD,
3433 intersection_lon[0],
3434 intersection_lon[1]},
3435 (double[]){0.0000000043633749/YAC_RAD,
3436 0.0000000000000000/YAC_RAD,
3437 0.0000000000000000/YAC_RAD},
3438 (enum yac_edge_type[]){
3440 // number of reference cells
3441 1);
3442 }
3443
3444 TEST_START("example example take from ICON_toy");
3445 {
3446 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3447
3448 if (!utest_intersect(
3449 YAC_GREAT_CIRCLE_EDGE, 3.1415926521557882/YAC_RAD,
3450 -0.9805860393425995/YAC_RAD,
3451 3.1415926520689506/YAC_RAD,
3452 -1.0172219678978514/YAC_RAD,
3453 YAC_LAT_CIRCLE_EDGE, 3.1415926535897931/YAC_RAD,
3454 -1.0062913968529805/YAC_RAD,
3455 3.1170489609836229/YAC_RAD,
3456 -1.0062913968529805/YAC_RAD,
3457 intersection[0]))
3458 return EXIT_FAILURE;
3459 if (!utest_intersect(
3460 YAC_GREAT_CIRCLE_EDGE, 3.1415926521557882/YAC_RAD,
3461 -0.9805860393425995/YAC_RAD,
3462 3.1415926520689506/YAC_RAD,
3463 -1.0172219678978514/YAC_RAD,
3464 YAC_LAT_CIRCLE_EDGE, 3.1415926535897931/YAC_RAD,
3465 -0.9817477042468103/YAC_RAD,
3466 3.1170489609836229/YAC_RAD,
3467 -0.9817477042468103/YAC_RAD,
3468 intersection[1]))
3469 return EXIT_FAILURE;
3470 for (int i = 0; i < 2; ++i) {
3471 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3472 intersection_lon[i] /= YAC_RAD;
3473 intersection_lat[i] /= YAC_RAD;
3474 }
3475
3476 utest_clipping(
3477
3478 // input cells
3479 (struct yac_grid_cell[]){
3480 utest_generate_cell_deg(
3481 (double[]){ 3.1415926521557882/YAC_RAD,
3482 3.1415926520689506/YAC_RAD,
3483 -3.0774466652769172/YAC_RAD},
3484 (double[]){-0.9805860393425995/YAC_RAD,
3485 -1.0172219678978514/YAC_RAD,
3486 -0.9979427097227050/YAC_RAD}, gc_edges, 3),
3487 utest_generate_cell_deg(
3488 (double[]){ 3.1170489609836229/YAC_RAD,
3489 3.1415926535897931/YAC_RAD,
3490 3.1415926535897931/YAC_RAD,
3491 3.1170489609836229/YAC_RAD},
3492 (double[]){-1.0062913968529805/YAC_RAD,
3493 -1.0062913968529805/YAC_RAD,
3494 -0.9817477042468103/YAC_RAD,
3495 -0.9817477042468103/YAC_RAD},
3496 latlon_edges, 4)},
3497 // reference cells
3498 (struct yac_grid_cell[]){
3499 utest_generate_cell_deg(
3500 (double[]){ 3.1415926535897931/YAC_RAD,
3501 3.1415926535897931/YAC_RAD,
3502 intersection_lon[0],intersection_lon[1]},
3503 (double[]){-0.9817477042468103/YAC_RAD,
3504 -1.0062913968529805/YAC_RAD,
3505 -1.0062913968529805/YAC_RAD,
3506 -0.9817477042468103/YAC_RAD},
3507 (enum yac_edge_type[]){
3509 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
3510 // number of reference cells
3511 2);
3512 }
3513
3514 TEST_START("example example take from ICON_toy");
3515 {
3516
3517 utest_clipping(
3518
3519 // input cells
3520 (struct yac_grid_cell[]){
3521 utest_generate_cell_deg(
3522 (double[]){ 1.8849555814614660/YAC_RAD,
3523 0.9682712007396151/YAC_RAD,
3524 3.1415926372157803/YAC_RAD},
3525 (double[]){-1.5418135420482968/YAC_RAD,
3526 -1.5707963262077691/YAC_RAD,
3527 -1.5418135425481947/YAC_RAD}, gc_edges, 3),
3528 utest_generate_cell_deg(
3529 (double[]){ 1.0799224746714915/YAC_RAD,
3530 1.1044661672776617/YAC_RAD,
3531 1.1044661672776617/YAC_RAD,
3532 1.0799224746714915/YAC_RAD},
3533 (double[]){-1.5707963267948966/YAC_RAD,
3534 -1.5707963267948966/YAC_RAD,
3535 -1.5462526341887264/YAC_RAD,
3536 -1.5462526341887264/YAC_RAD},
3537 latlon_edges, 4)},
3538 // reference cells
3539 (struct yac_grid_cell[]){
3540 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
3541 // number of reference cells
3542 1);
3543 }
3544
3545 TEST_START("example example take from ICON_toy");
3546 {
3547
3548 utest_clipping(
3549
3550 // input cells
3551 (struct yac_grid_cell[]){
3552 utest_generate_cell_deg(
3553 (double[]){ 3.1415926372157803/YAC_RAD,
3554 0.9682712007396151/YAC_RAD,
3555 -1.8849555862661402/YAC_RAD},
3556 (double[]){-1.5418135425481947/YAC_RAD,
3557 -1.5707963262077691/YAC_RAD,
3558 -1.5418135428532602/YAC_RAD}, gc_edges, 3),
3559 utest_generate_cell_deg(
3560 (double[]){ 1.5707963267948966/YAC_RAD,
3561 1.5953400194010670/YAC_RAD,
3562 1.5953400194010670/YAC_RAD,
3563 1.5707963267948966/YAC_RAD},
3564 (double[]){-1.5707963267948966/YAC_RAD,
3565 -1.5707963267948966/YAC_RAD,
3566 -1.5462526341887264/YAC_RAD,
3567 -1.5462526341887264/YAC_RAD},
3568 latlon_edges, 4)},
3569 // reference cells
3570 (struct yac_grid_cell[]){
3571 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
3572 // number of reference cells
3573 1);
3574 }
3575
3576 TEST_START("example example take from ICON_toy");
3577 {
3578 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3579
3580 if (!utest_intersect(
3581 YAC_GREAT_CIRCLE_EDGE, 1.25664579522418/YAC_RAD,
3582 1.54180416508220/YAC_RAD,
3583 0.00031736492867/YAC_RAD,
3584 1.54181036404629/YAC_RAD,
3585 YAC_LAT_CIRCLE_EDGE, 0.90811662642830/YAC_RAD,
3586 1.54625263418873/YAC_RAD,
3587 0.93266031903447/YAC_RAD,
3588 1.54625263418873/YAC_RAD,
3589 intersection[0]))
3590 return EXIT_FAILURE;
3591 if (!utest_intersect(
3592 YAC_GREAT_CIRCLE_EDGE, 1.25664579522418/YAC_RAD,
3593 1.54180416508220/YAC_RAD,
3594 0.00031736492867/YAC_RAD,
3595 1.54181036404629/YAC_RAD,
3596 YAC_LON_CIRCLE_EDGE, 0.93266031903447/YAC_RAD,
3597 1.52170894158256/YAC_RAD,
3598 0.93266031903447/YAC_RAD,
3599 1.54625263418873/YAC_RAD,
3600 intersection[1]))
3601 return EXIT_FAILURE;
3602 for (int i = 0; i < 2; ++i) {
3603 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3604 intersection_lon[i] /= YAC_RAD;
3605 intersection_lat[i] /= YAC_RAD;
3606 }
3607
3608 utest_clipping(
3609
3610 // input cells
3611 (struct yac_grid_cell[]){
3612 utest_generate_cell_deg(
3613 (double[]){1.25664579522418/YAC_RAD,
3614 1.22772603138717/YAC_RAD,
3615 0.00031736492867/YAC_RAD},
3616 (double[]){1.54180416508220/YAC_RAD,
3617 1.57078715647583/YAC_RAD,
3618 1.54181036404629/YAC_RAD}, gc_edges, 3),
3619 utest_generate_cell_deg(
3620 (double[]){0.90811662642830/YAC_RAD,
3621 0.93266031903447/YAC_RAD,
3622 0.93266031903447/YAC_RAD,
3623 0.90811662642830/YAC_RAD},
3624 (double[]){1.52170894158256/YAC_RAD,
3625 1.52170894158256/YAC_RAD,
3626 1.54625263418873/YAC_RAD,
3627 1.54625263418873/YAC_RAD},
3628 latlon_edges, 4)},
3629 // reference cells
3630 (struct yac_grid_cell[]){
3631 utest_generate_cell_deg(
3632 (double[]){0.93266031903447/YAC_RAD,
3633 intersection_lon[0],
3634 intersection_lon[1]},
3635 (double[]){1.54625263418873/YAC_RAD,
3636 intersection_lat[0],
3637 intersection_lat[1]},
3638 (enum yac_edge_type[]){
3640 utest_generate_cell_deg(
3641 (double[]){0.93266031903447/YAC_RAD,
3642 0.90811662642830/YAC_RAD,
3643 intersection_lon[0],
3644 intersection_lon[1]},
3645 (double[]){1.54625263418873/YAC_RAD,
3646 1.54625263418873/YAC_RAD,
3647 intersection_lat[0],
3648 intersection_lat[1]},
3649 (enum yac_edge_type[]){
3651 // number of reference cells
3652 2);
3653 }
3654
3655 TEST_START("example example take from ICON_toy");
3656 {
3657 utest_clipping(
3658
3659 // input cells
3660 (struct yac_grid_cell[]){
3661 utest_generate_cell_deg(
3662 (double[]){ 4.9999997254688875/YAC_RAD,
3663 4.9999997254688875/YAC_RAD,
3664 5.0078539201557488/YAC_RAD,
3665 5.0078539201557488/YAC_RAD},
3666 (double[]){-1.2878426515089207/YAC_RAD,
3667 -1.2946756570757916/YAC_RAD,
3668 -1.2946797849754812/YAC_RAD,
3669 -1.2878469125666649/YAC_RAD},
3670 gc_edges, 4),
3671 utest_generate_cell_deg(
3672 (double[]){ 5.0069132916587327/YAC_RAD,
3673 5.0130492148102759/YAC_RAD,
3674 5.0130492148102759/YAC_RAD,
3675 5.0069132916587327/YAC_RAD},
3676 (double[]){-1.2946797849754812/YAC_RAD,
3677 -1.2946797849754812/YAC_RAD,
3678 -1.2885438618239387/YAC_RAD,
3679 -1.2885438618239387/YAC_RAD},
3680 latlon_edges, 4)},
3681 // reference cells
3682 (struct yac_grid_cell[]){
3683 utest_generate_cell_deg(
3684 (double[]){ 5.0069132916587327/YAC_RAD,
3685 5.0078539201557488/YAC_RAD,
3686 5.0078539201557488/YAC_RAD,
3687 5.0069132916587327/YAC_RAD},
3688 (double[]){-1.2946797849754812/YAC_RAD,
3689 -1.2946797849754812/YAC_RAD,
3690 -1.2885438618239387/YAC_RAD,
3691 -1.2885438618239387/YAC_RAD},
3692 (enum yac_edge_type[]){
3694 // number of reference cells
3695 1);
3696 }
3697
3699 TEST_START("example provided by Uwe");
3700 {
3701
3702 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3703
3704 if (!utest_intersect(
3705 YAC_GREAT_CIRCLE_EDGE, 2.5132741228718345/YAC_RAD,
3706 1.5494144670074232/YAC_RAD,
3707 3.7699111843077517/YAC_RAD,
3708 1.5494144670074232/YAC_RAD,
3709 YAC_LAT_CIRCLE_EDGE, 3.2637657012293961/YAC_RAD,
3710 1.5533430342749532/YAC_RAD,
3711 3.2812189937493392/YAC_RAD,
3712 1.5533430342749532/YAC_RAD,
3713 intersection[0]))
3714 return EXIT_FAILURE;
3715 if (!utest_intersect(
3716 YAC_GREAT_CIRCLE_EDGE, 2.5132741228718345/YAC_RAD,
3717 1.5494144670074232/YAC_RAD,
3718 3.7699111843077517/YAC_RAD,
3719 1.5494144670074232/YAC_RAD,
3720 YAC_LON_CIRCLE_EDGE, 3.2812189937493392/YAC_RAD,
3721 1.5533430342749532/YAC_RAD,
3722 3.2812189937493392/YAC_RAD,
3723 1.5358897417550099/YAC_RAD,
3724 intersection[1]))
3725 return EXIT_FAILURE;
3726 for (int i = 0; i < 2; ++i) {
3727 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3728 intersection_lon[i] /= YAC_RAD;
3729 intersection_lat[i] /= YAC_RAD;
3730 }
3731
3732 utest_clipping(
3733
3734 // input cells
3735 (struct yac_grid_cell[]){
3736 utest_generate_cell_deg(
3737 (double[]){3.2637657012293961/YAC_RAD,
3738 3.2812189937493392/YAC_RAD,
3739 3.2812189937493392/YAC_RAD,
3740 3.2637657012293961/YAC_RAD},
3741 (double[]){1.5358897417550099/YAC_RAD,
3742 1.5358897417550099/YAC_RAD,
3743 1.5533430342749532/YAC_RAD,
3744 1.5533430342749532/YAC_RAD},
3745 latlon_edges, 4),
3746 utest_generate_cell_deg(
3747 (double[]){1.2566370614359175/YAC_RAD,
3748 2.5132741228718345/YAC_RAD,
3749 3.7699111843077517/YAC_RAD,
3750 5.0265482457436690/YAC_RAD,
3751 0.0000000000000000/YAC_RAD,
3752 0.0000000000000000/YAC_RAD},
3753 (double[]){1.5494144670074232/YAC_RAD,
3754 1.5494144670074232/YAC_RAD,
3755 1.5494144670074232/YAC_RAD,
3756 1.5494144670074232/YAC_RAD,
3757 1.5494144670074232/YAC_RAD,
3758 1.5494144670074232/YAC_RAD},
3759 gc_edges, 6)},
3760 // reference cells
3761 (struct yac_grid_cell[]){
3762 utest_generate_cell_deg(
3763 (double[]){intersection_lon[0],
3764 3.2812189937493392/YAC_RAD,
3765 3.2812189937493392/YAC_RAD},
3766 (double[]){1.5533430342749532/YAC_RAD,
3767 1.5533430342749532/YAC_RAD,
3768 intersection_lat[1]},
3769 (enum yac_edge_type[]){
3771 // number of reference cells
3772 1);
3773 }
3774
3776 TEST_START("example provided by Rene");
3777 {
3778
3779 utest_clipping(
3780
3781 // input cells
3782 (struct yac_grid_cell[]){
3783 utest_generate_cell_deg(
3784 (double[]){ 1.8849563731522099/YAC_RAD,
3785 1.8465416851483734/YAC_RAD,
3786 1.8661276404324745/YAC_RAD},
3787 (double[]){-0.4124872765902973/YAC_RAD,
3788 -0.4149531265147232/YAC_RAD,
3789 -0.4401304121445256/YAC_RAD},
3790 gc_edges, 3),
3791 utest_generate_cell_deg(
3792 (double[]){ 1.8443992887189797/YAC_RAD,
3793 1.8849555921538759/YAC_RAD,
3794 1.9255118955887724/YAC_RAD},
3795 (double[]){-0.4121554426487201/YAC_RAD,
3796 -0.4636476090008059/YAC_RAD,
3797 -0.4121554426487201/YAC_RAD},
3798 gc_edges, 3)},
3799 // reference cells
3800 (struct yac_grid_cell[]){
3801 utest_generate_cell_deg(
3802 (double[]){ 1.8849563731522099/YAC_RAD,
3803 1.8465416851483734/YAC_RAD,
3804 1.8661276404324745/YAC_RAD},
3805 (double[]){-0.4124872765902973/YAC_RAD,
3806 -0.4149531265147232/YAC_RAD,
3807 -0.4401304121445256/YAC_RAD}, gc_edges, 3)},
3808 // number of reference cells
3809 1);
3810 }
3811
3812 TEST_START("example provided by Rene");
3813 {
3814 double intersection[3], intersection_lon, intersection_lat;
3815
3816 if (!utest_intersect(
3817 YAC_GREAT_CIRCLE_EDGE, -1.9037843097448526/YAC_RAD,
3818 -0.4401294427665800/YAC_RAD,
3819 -1.8849555925510342/YAC_RAD,
3820 -0.4636476094897370/YAC_RAD,
3821 YAC_GREAT_CIRCLE_EDGE, -1.8849555921538759/YAC_RAD,
3822 -0.4636476090008059/YAC_RAD,
3823 -1.9528559331227824/YAC_RAD,
3824 -0.4822665528104840/YAC_RAD,
3825 intersection))
3826 return EXIT_FAILURE;
3827 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
3828 intersection_lon /= YAC_RAD;
3829 intersection_lat /= YAC_RAD;
3830
3831 utest_clipping(
3832
3833 // input cells
3834 (struct yac_grid_cell[]){
3835 utest_generate_cell_deg(
3836 (double[]){-1.9037843097448526/YAC_RAD,
3837 -1.8849555925510342/YAC_RAD,
3838 -1.8661268754099334/YAC_RAD},
3839 (double[]){-0.4401294427665800/YAC_RAD,
3840 -0.4636476094897370/YAC_RAD,
3841 -0.4401294427950335/YAC_RAD},
3842 gc_edges, 3),
3843 utest_generate_cell_deg(
3844 (double[]){-1.8849555921538759/YAC_RAD,
3845 -1.8849555921538759/YAC_RAD,
3846 -1.9528559331227824/YAC_RAD},
3847 (double[]){-0.5268929705698896/YAC_RAD,
3848 -0.4636476090008059/YAC_RAD,
3849 -0.4822665528104840/YAC_RAD},
3850 gc_edges, 3)},
3851 // reference cells
3852 (struct yac_grid_cell[]){
3853 utest_generate_cell_deg(
3854 (double[]){-1.8849555921538759/YAC_RAD,
3855 -1.8849555921538759/YAC_RAD,
3856 intersection_lon},
3857 (double[]){-0.4636476094897370/YAC_RAD,
3858 -0.4636476090008059/YAC_RAD,
3859 intersection_lat}, gc_edges, 3),
3860 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
3861 // number of reference cells
3862 2);
3863 }
3864
3865 TEST_START("example provided by Rene");
3866 {
3867
3868 double intersection[2][3], intersection_lon[2], intersection_lat[2];
3869
3870 if (!utest_intersect(
3871 YAC_GREAT_CIRCLE_EDGE, -1.2566370614359172/YAC_RAD,
3872 -0.5535743588970451/YAC_RAD,
3873 -1.1715639552378114/YAC_RAD,
3874 -0.5519553785110131/YAC_RAD,
3875 YAC_GREAT_CIRCLE_EDGE, -1.2566370573287293/YAC_RAD,
3876 -0.5535743562505872/YAC_RAD,
3877 -1.2346024154180213/YAC_RAD,
3878 -0.5882204740702072/YAC_RAD,
3879 intersection[0]))
3880 return EXIT_FAILURE;
3881 if (!utest_intersect(
3882 YAC_GREAT_CIRCLE_EDGE, -1.2566370614359172/YAC_RAD,
3883 -0.5535743588970451/YAC_RAD,
3884 -1.1715639552378114/YAC_RAD,
3885 -0.5519553785110131/YAC_RAD,
3886 YAC_GREAT_CIRCLE_EDGE, -1.2566370573287293/YAC_RAD,
3887 -0.5535743562505872/YAC_RAD,
3888 -1.2786717012447690/YAC_RAD,
3889 -0.5882204751704803/YAC_RAD,
3890 intersection[1]))
3891 return EXIT_FAILURE;
3892 for (int i = 0; i < 2; ++i) {
3893 XYZtoLL(intersection[i], &intersection_lon[i], &intersection_lat[i]);
3894 intersection_lon[i] /= YAC_RAD;
3895 intersection_lat[i] /= YAC_RAD;
3896 }
3897
3898 utest_clipping(
3899
3900 // input cells
3901 (struct yac_grid_cell[]){
3902 utest_generate_cell_deg(
3903 (double[]){-1.2346024154180213/YAC_RAD,
3904 -1.2566370573287293/YAC_RAD,
3905 -1.2786717012447690/YAC_RAD},
3906 (double[]){-0.5882204740702072/YAC_RAD,
3907 -0.5535743562505872/YAC_RAD,
3908 -0.5882204751704803/YAC_RAD},
3909 gc_edges, 3),
3910 utest_generate_cell_deg(
3911 (double[]){-1.2156135107669752/YAC_RAD,
3912 -1.2566370614359172/YAC_RAD,
3913 -1.1715639552378114/YAC_RAD},
3914 (double[]){-0.4835340719879115/YAC_RAD,
3915 -0.5535743588970451/YAC_RAD,
3916 -0.5519553785110131/YAC_RAD},
3917 gc_edges, 3)},
3918 // reference cells
3919 (struct yac_grid_cell[]){
3920 utest_generate_cell_deg(NULL, NULL, NULL, 0),
3921 utest_generate_cell_deg(
3922 (double[]){-1.2566370573287293/YAC_RAD,
3923 intersection_lon[0],
3924 intersection_lon[1]},
3925 (double[]){-0.5535743562505872/YAC_RAD,
3926 intersection_lat[0],
3927 intersection_lat[1]}, gc_edges, 3)},
3928 // number of reference cells
3929 2);
3930 }
3931
3933 TEST_START("handling of 'triangle' in which all corners on on a gc");
3934 {
3935 utest_clipping(
3936
3937 // input cells
3938 (struct yac_grid_cell[]){
3939 utest_generate_cell_deg(
3940 (double[]){0, 1, 2},
3941 (double[]){0, 0, 0}, gc_edges, 3),
3942 utest_generate_cell_deg(
3943 (double[]){0, 1, 2},
3944 (double[]){0, 0, 0}, gc_edges, 3)},
3945 // reference cells
3946 (struct yac_grid_cell[]){
3947 utest_generate_cell_deg(NULL, NULL, NULL, 0),
3948 utest_generate_cell_deg(
3949 (double[]){0, 1, 2},
3950 (double[]){0, 0, 0}, gc_edges, 3)},
3951 // number of reference cells
3952 2);
3953 }
3954
3955 TEST_START("handling of 'triangle' in which all corners on on a gc");
3956 {
3957 utest_clipping(
3958
3959 // input cells
3960 (struct yac_grid_cell[]){
3961 utest_generate_cell_deg(
3962 (double[]){0, 1, 1},
3963 (double[]){0, 0, 1}, gc_edges, 3),
3964 utest_generate_cell_deg(
3965 (double[]){0, 1, 2},
3966 (double[]){0, 0, 0}, gc_edges, 3)},
3967 // reference cells
3968 (struct yac_grid_cell[]){
3969 utest_generate_cell_deg(NULL, NULL, NULL, 0),
3970 utest_generate_cell_deg(
3971 (double[]){0, 1, 2},
3972 (double[]){0, 0, 0}, gc_edges, 3)},
3973 // number of reference cells
3974 2);
3975 }
3976
3977 TEST_START("");
3978 {
3979
3980 utest_clipping(
3981
3982 // input cells
3983 (struct yac_grid_cell[]){
3984 utest_generate_cell_deg(
3985 (double[]){ 1.5462526341887264/YAC_RAD,
3986 1.5707963267948966/YAC_RAD,
3987 1.5707963267948966/YAC_RAD,
3988 1.5462526341887264/YAC_RAD},
3989 (double[]){-1.5707963267948966/YAC_RAD,
3990 -1.5707963267948966/YAC_RAD,
3991 -1.5462526341887264/YAC_RAD,
3992 -1.5462526341887264/YAC_RAD},
3993 latlon_edges, 4),
3994 utest_generate_cell_deg(
3995 (double[]){ 1.5707963267948966/YAC_RAD,
3996 1.5707963267948966/YAC_RAD,
3997 1.2491662739534428/YAC_RAD,
3998 1.1072089649419674/YAC_RAD},
3999 (double[]){-1.5462526341887277/YAC_RAD,
4000 -1.5339807878856395/YAC_RAD,
4001 -1.5319928455462422/YAC_RAD,
4002 -1.5433578475477794/YAC_RAD},
4003 gc_edges, 4)},
4004 // reference cells
4005 (struct yac_grid_cell[]){
4006 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
4007 // number of reference cells
4008 1);
4009 }
4010
4011 TEST_START("");
4012 {
4013
4014 double intersection[3], intersection_lon, intersection_lat;
4015
4016 if (!utest_intersect(
4018 -1.5339807878856395/YAC_RAD,
4019 0.32163005284145374/YAC_RAD,
4020 -1.5319928455462422/YAC_RAD,
4021 YAC_LON_CIRCLE_EDGE, 0.024543692606170259/YAC_RAD,
4022 -1.5462526341887264/YAC_RAD,
4023 0.024543692606170259/YAC_RAD,
4024 -1.5217089415825564/YAC_RAD,
4025 intersection))
4026 return EXIT_FAILURE;
4027 XYZtoLL(intersection, &intersection_lon, &intersection_lat);
4028 intersection_lon /= YAC_RAD;
4029 intersection_lat /= YAC_RAD;
4030
4031 utest_clipping(
4032 // input cells
4033 (struct yac_grid_cell[]){
4034 utest_generate_cell_deg(
4035 (double[]){ 0/YAC_RAD,
4036 0.024543692606170259/YAC_RAD,
4037 0.024543692606170259/YAC_RAD,
4038 0/YAC_RAD},
4039 (double[]){-1.5462526341887264/YAC_RAD,
4040 -1.5462526341887264/YAC_RAD,
4041 -1.5217089415825564/YAC_RAD,
4042 -1.5217089415825564/YAC_RAD},
4043 latlon_edges, 4),
4044 utest_generate_cell_deg(
4045 (double[]){ 0/YAC_RAD,
4046 0.32163005284145374/YAC_RAD,
4047 0.24480144176769322/YAC_RAD,
4048 0/YAC_RAD},
4049 (double[]){-1.5339807878856395/YAC_RAD,
4050 -1.5319928455462422/YAC_RAD,
4051 -1.5202029837469972/YAC_RAD,
4052 -1.5217089415825564/YAC_RAD},
4053 gc_edges, 4)},
4054 // reference cells
4055 (struct yac_grid_cell[]){
4056 utest_generate_cell_deg(
4057 (double[]){ 0/YAC_RAD,
4058 0.024543692606170259/YAC_RAD,
4059 0.024543692606170259/YAC_RAD,
4060 0/YAC_RAD},
4061 (double[]){-1.5217089415825564/YAC_RAD,
4062 -1.5217089415825564/YAC_RAD,
4063 intersection_lat,
4064 -1.5339807878856395/YAC_RAD},
4065 (enum yac_edge_type[]){
4068 // number of reference cells
4069 1);
4070 }
4071
4073 TEST_START("lon-lat cell that touches the pole");
4074 /* cell a (circle around a pole; made of lat circle edges)
4075
4076 .-""-.
4077 / \
4078 ; ;
4079 \ /
4080 '-..-'
4081 */
4082
4083 /* cell b (lon-lat cell whose upper bound is a zero lenght edge at the pole)
4084
4085 /\
4086 / \
4087 '-..-'
4088 */
4089
4090 {
4091 utest_clipping(
4092 // input cells
4093 (struct yac_grid_cell[]){
4094 utest_generate_cell_deg(
4095 (double[]){-5.0, 5.0, 0.0},
4096 (double[]){85.0, 85.0, 90.0},
4097 (enum yac_edge_type[]){
4099 utest_generate_cell_deg(
4100 (double[]){ 0.0,60.0,120.0,180.0,240.0,300.0},
4101 (double[]){ 84.0,84.0,84.0,84.0,84.0,84.0},
4102 (enum yac_edge_type[]){
4105 // reference cells
4106 (struct yac_grid_cell[]){
4107 utest_generate_cell_deg(
4108 (double[]){-5.0, 5.0, 0.0},
4109 (double[]){85.0, 85.0, 90.0},
4110 (enum yac_edge_type[]){
4112 // number of reference cells
4113 1);
4114 }
4115
4117 TEST_START("two square that partially share two edges");
4118 /* 11.) source cell test data
4119
4120 -1 1
4121 +------+ 1
4122 | |
4123 | |
4124 | |
4125 +------+ -1
4126 */
4127 /* target cell test data
4128
4129 +------+ 0.5
4130 | |
4131 | |
4132 | |
4133 +------+ -0.5
4134 -1 1
4135 */
4136
4137 {
4138 utest_clipping(
4139 // input cells
4140 (struct yac_grid_cell[]){
4141 utest_generate_cell_deg(
4142 (double[]){-1.0, 1.0, 1.0,-1.0},
4143 (double[]){-1.0,-1.0, 1.0, 1.0}, latlon_edges, 4),
4144 utest_generate_cell_deg(
4145 (double[]){-1.0, 1.0, 1.0,-1.0},
4146 (double[]){-0.5,-0.5, 0.5, 0.5}, latlon_edges, 4)},
4147 // reference cells
4148 (struct yac_grid_cell[]){
4149 utest_generate_cell_deg(
4150 (double[]){-1.0, 1.0, 1.0,-1.0},
4151 (double[]){-0.5,-0.5, 0.5, 0.5}, latlon_edges, 4)},
4152 // number of reference cells
4153 1);
4154 }
4155
4157 TEST_START("two polygons with two edges touch in a single point");
4158 /* 11.) source cell test data
4159
4160 -10 10
4161 +------+ 90
4162 | |
4163 | |
4164 | |
4165 +------+ 80 + dx
4166 */
4167 /* target cell test data
4168
4169 -------- 80
4170 \ /
4171 \ /
4172 \ /
4173 \/ 0
4174 -10 0 10
4175 */
4176
4177 {
4178 double touch_point[3], touch_lon, touch_lat;
4179
4180 if (!utest_intersect(
4181 YAC_GREAT_CIRCLE_EDGE, -10.0, 80.0, 10.0, 80.0,
4182 YAC_LON_CIRCLE_EDGE, 0.0, 70.0, 0.0, 90.0, touch_point))
4183 return EXIT_FAILURE;
4184 XYZtoLL(touch_point, &touch_lon, &touch_lat);
4185 touch_lon /= YAC_RAD;
4186 touch_lat /= YAC_RAD;
4187
4188 utest_clipping(
4189 // input cells
4190
4191 (struct yac_grid_cell[2]){
4192 utest_generate_cell_deg(
4193 (double[]){-10.0, 10.0, 10.0, -10.0},
4194 (double[]){touch_lat, touch_lat, 90.0, 90.0},
4195 latlon_edges, 4),
4196 utest_generate_cell_deg(
4197 (double[]){0.0, 10.0, -10.0},
4198 (double[]){0.0, 80.0, 80.0}, gc_edges, 3)},
4199 // reference cells
4200 (struct yac_grid_cell[]){utest_generate_cell_deg(NULL, NULL, NULL, 0)},
4201 // number of reference cells
4202 1);
4203 }
4204
4205
4206 TEST_START("two polygons with two edges touch in a single point");
4207 /* 11.) source cell test data
4208
4209 -15 15
4210 +------+ 80 + dx
4211 | |
4212 | |
4213 | |
4214 +------+ 60
4215 */
4216 /* target cell test data
4217
4218 -------- 80
4219 \ /
4220 \ /
4221 \ /
4222 \/ 70
4223 -10 0 10
4224 */
4225
4226 {
4227 double touch_point[3], touch_lon, touch_lat;
4228
4229 if (!utest_intersect(
4230 YAC_GREAT_CIRCLE_EDGE, -10.0, 80.0, 10.0, 80.0,
4231 YAC_LON_CIRCLE_EDGE, 0.0, 70.0, 0.0, 90.0, touch_point))
4232 return EXIT_FAILURE;
4233 XYZtoLL(touch_point, &touch_lon, &touch_lat);
4234 touch_lon /= YAC_RAD;
4235 touch_lat /= YAC_RAD;
4236
4237 utest_clipping(
4238 // input cells
4239
4240 (struct yac_grid_cell[2]){
4241 utest_generate_cell_deg(
4242 (double[]){-15.0, 15.0, 15.0, -15.0},
4243 (double[]){60.0, 60.0, touch_lat, touch_lat},
4244 latlon_edges, 4),
4245 utest_generate_cell_deg(
4246 (double[]){0.0, 10.0, -10.0},
4247 (double[]){70.0, 80.0, 80.0}, gc_edges, 3)},
4248 // reference cells
4249 (struct yac_grid_cell[]){
4250 utest_generate_cell_deg(
4251 (double[]){0.0, 10.0, -10.0},
4252 (double[]){70.0, 80.0, 80.0}, gc_edges, 3),
4253 utest_generate_cell_deg(
4254 (double[]){0.0, 10.0, 0.0, -10.0},
4255 (double[]){70.0, 80.0, touch_lat, 80.0}, gc_edges, 4)},
4256 // number of reference cells
4257 2);
4258 }
4259
4261 TEST_START("one cell is empty");
4262 /* 11.) source cell test data
4263
4264 +------+
4265 | |
4266 | |
4267 | |
4268 +------+
4269 */
4270
4271 {
4272 utest_clipping(
4273 // input cells
4274
4275 (struct yac_grid_cell[2]){
4276 utest_generate_cell_deg(
4277 (double[]){0.0, 1.0, 1.0, 0.0},
4278 (double[]){0.0, 0.0, 1.0, 1.0},
4279 latlon_edges, 4),
4280 utest_generate_cell_deg((double[]){0.0}, (double[]){0.0}, gc_edges, 1)},
4281 // reference cells
4282 (struct yac_grid_cell[]){utest_generate_cell_deg(NULL, NULL, NULL, 0)},
4283 // number of reference cells
4284 1);
4285 }
4286
4288 TEST_START("star-shaped cell");
4289 /* source cell test data
4290
4291
4292 +
4293 / \
4294 / \
4295 + +
4296 - -
4297 + +
4298 - -
4299 + +
4300 \ /
4301 \ /
4302 +
4303 */
4304
4305 {
4306 utest_clipping(
4307 // input cells
4308
4309 (struct yac_grid_cell[2]){
4310 utest_generate_cell_deg(
4311 (double[]){0.0,0.5,2.0,0.5,0.0,-0.5,-2.0,-0.5},
4312 (double[]){2.0,0.5,0.0,-0.5,-2.0,-0.5,0.0,0.5},
4313 gc_edges, 8),
4314 utest_generate_cell_deg(
4315 (double[]){-0.4,0.4,0.4,-0.4},
4316 (double[]){0.4,0.4,-0.4,-0.4}, latlon_edges, 4)},
4317 // reference cells
4318 (struct yac_grid_cell[]){
4319 utest_generate_cell_deg(
4320 (double[]){-0.4,0.4,0.4,-0.4},
4321 (double[]){0.4,0.4,-0.4,-0.4}, latlon_edges, 4)},
4322 // number of reference cells
4323 1);
4324 }
4325
4326 { // example from the CDO
4327 utest_clipping(
4328 // input cells
4329
4330 (struct yac_grid_cell[2]){
4331 utest_generate_cell_3d(
4333 (double[4][3])
4334 {{-0.25877962570833368, 0.0045170151688387894, -0.9659258262890682},
4335 {-0.25881904510252096, 3.1696191514317674e-17, -0.9659258262890682},
4336 {-0.27563735581699916, 3.3755840552672809e-17, -0.96126169593831889},
4337 {-0.27559537491262875, 0.004810535163016382, -0.96126169593831889}},
4338 latlon_edges, 4),
4339 utest_generate_cell_3d(
4341 (double[3][3])
4342 {{0.26672229713350176, 7.0351165064716449e-15, -0.96377342576553127},
4343 {0.26954589843896026, 3.2931183713464971e-16, -0.9629875433434919},
4344 {0.26812958837053386, -0.0028554026633992114, -0.9633786226172335}},
4345 gc_edges, 3)},
4346
4347 // reference cells
4348 (struct yac_grid_cell[]){
4349 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
4350 // number of reference cells
4351 1);
4352 }
4353
4354 { // example from the ICON -> HEALPIX coupling
4355 // (HEALPIX using multiple vertices per edge)
4356 // an edge of one cell is on the plane of an edge of the other cell
4357 utest_clipping(
4358 // input cells
4359
4360 (struct yac_grid_cell[2]){
4361 utest_generate_cell_3d(
4363 (double[3][3])
4364 {{2.696547328754725914e-01,4.443826381960052641e-01, -8.542894099237189343e-01},
4365 {2.688564204809740787e-01,4.437764761162059091e-01, -8.548559319628309394e-01},
4366 {2.699802844797243861e-01,4.433103539234195534e-01, -8.547435732993490243e-01}},
4367 gc_edges, 3),
4368 utest_generate_cell_3d(
4370 (double[3][3])
4371 {{2.697116319678348195e-01, 4.415099038379987628e-01, -8.557596861235099439e-01},
4372 {2.697419421247737037e-01, 4.439739859929083821e-01, -8.544743322185424095e-01},
4373 {2.697443730259111994e-01, 4.441790962908549467e-01, -8.543669607604787997e-01}},
4374 gc_edges, 3)},
4375
4376 // reference cells
4377 (struct yac_grid_cell[]){
4378 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
4379 // number of reference cells
4380 1);
4381 }
4382
4384 TEST_START("degenerated cell that collapses into a single point");
4385 /* All corners of the degenerated cell are on the same circle of latitude
4386 and all its edges are circles of latitude. Therefore its edges are
4387 merged into a single point while its point list is being generated. The
4388 cell has no area, hence there is no overlap. (The cell is not detected
4389 by the check for the cell point ordering, because the norm vectors of
4390 its edges are not identical.)
4391
4392 +-----+-----+ <-- degenerated cell
4393 */
4394
4395 {
4396 // the other cell is a lon-lat cell
4397 utest_clipping(
4398 // input cells
4399
4400 (struct yac_grid_cell[2]){
4401 utest_generate_cell_deg(
4402 (double[]){0.0, 10.0, 10.0, 0.0},
4403 (double[]){40.0, 40.0, 50.0, 50.0},
4404 latlon_edges, 4),
4405 utest_generate_cell_deg(
4406 (double[]){0.0, 30.0, 60.0},
4407 (double[]){45.0, 45.0, 45.0},
4408 (enum yac_edge_type[]){
4410 YAC_LAT_CIRCLE_EDGE}, 3)},
4411 // reference cells
4412 (struct yac_grid_cell[]){
4413 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
4414 // number of reference cells
4415 1);
4416 }
4417
4418 {
4419 // the other cell only has great circle edges
4420 // (in this case the clipping of the two cells is being switched, because
4421 // the degenerated cell is a YAC_LAT_CELL)
4422 utest_clipping(
4423 // input cells
4424
4425 (struct yac_grid_cell[2]){
4426 utest_generate_cell_deg(
4427 (double[]){0.0, 10.0, 10.0, 0.0},
4428 (double[]){40.0, 40.0, 50.0, 50.0},
4429 gc_edges, 4),
4430 utest_generate_cell_deg(
4431 (double[]){0.0, 30.0, 60.0},
4432 (double[]){45.0, 45.0, 45.0},
4433 (enum yac_edge_type[]){
4435 YAC_LAT_CIRCLE_EDGE}, 3)},
4436 // reference cells
4437 (struct yac_grid_cell[]){
4438 utest_generate_cell_deg(NULL, NULL, NULL, 0)},
4439 // number of reference cells
4440 1);
4441 }
4442
4443 { // the last edge of the cell is on the plane of a clipping circle, while
4444 // the first vertex of the cell is slightly outside of it
4445 //
4446 // The two cell vertices close to the equator are lat_offset off of it,
4447 // which has to be within the following bounds:
4448 // - the edge between these two vertices has to be on the plane of the
4449 // equator; the vertices are 10 degree away from the longitude at which
4450 // their edge crosses the equator, hence the angle between the two planes
4451 // is lat_offset / sin(10 degree), which has to be below yac_angle_tol
4452 // => factor < sin(10 degree) ~ 1.7e-1
4453 // - the vertices themselves must not be considered as being on the
4454 // equator (see \ref yac_circle_point_is_inside)
4455 // => factor > 1.0e-3 (in practice the case is only triggered for
4456 // factors above ~1.0e-2)
4457 // Several factors are tested, because the range in which this case is
4458 // actually triggered depends on rounding and may therefore differ between
4459 // compilers and optimisation settings. All of them are well below the
4460 // upper bound, because exceeding it changes the expected result (the
4461 // vertex is then clipped, which adds a corner to the overlap), while
4462 // staying below the lower bound only means that this particular case is
4463 // not triggered.
4464 double lat_offset_factor[] = {1.0e-2, 2.0e-2, 4.0e-2, 8.0e-2};
4465 enum {
4466 lat_offset_factor_count =
4467 sizeof(lat_offset_factor) / sizeof(lat_offset_factor[0])};
4468
4469 for (size_t i = 0; i < lat_offset_factor_count; ++i) {
4470
4471 double lat_offset = lat_offset_factor[i] * yac_angle_tol / YAC_RAD;
4472
4473 utest_clipping(
4474 // input cells
4475
4476 (struct yac_grid_cell[2]){
4477 utest_generate_cell_deg(
4478 (double[]){10.0, 0.0, -10.0},
4479 (double[]){-lat_offset, 2.0, lat_offset},
4480 gc_edges, 3),
4481 utest_generate_cell_deg(
4482 (double[]){-20.0, 20.0, 20.0, -20.0},
4483 (double[]){0.0, 0.0, 4.0, 4.0}, gc_edges, 4)},
4484
4485 // reference cells
4486 (struct yac_grid_cell[]){
4487 utest_generate_cell_deg(
4488 (double[]){10.0, 0.0, -10.0},
4489 (double[]){0.0, 2.0, 0.0}, gc_edges, 3)},
4490 // number of reference cells
4491 1);
4492 }
4493 }
4494
4495//-----------------test yac_correct_weights------------------------------------
4496
4497 {
4498 enum {num_weights = 5};
4499 double weights[num_weights] = {1,3,2,0.5,3.5};
4500 double ref_weights[num_weights] = {0.1,0.3,0.2,0.05,0.35};
4501 utest_check_weight_correction(weights, num_weights, ref_weights);
4502 }
4503
4504 {
4505 enum {num_weights = 1};
4506 double weights[num_weights] = {3};
4507 double ref_weights[num_weights] = {1};
4508 utest_check_weight_correction(weights, num_weights, ref_weights);
4509 }
4510
4511 {
4512 enum {num_weights = 4};
4513 double weights[num_weights] = {1,2,3,4};
4514 double ref_weights[num_weights] = {0.1,0.2,0.3,0.4};
4515 utest_check_weight_correction(weights, num_weights, ref_weights);
4516 }
4517
4518 // weights that add up to (nearly) zero cannot be scaled to a sum of 1.0
4519 // and have to be left unchanged
4520 // (utest_check_weight_correction cannot be used for these cases, because it
4521 // checks that the corrected weights add up to 1.0)
4522 {
4523 enum {num_weights = 4};
4524 double weights[num_weights] = {1.0, -2.0, 3.0, -2.0};
4525 double ref_weights[num_weights] = {1.0, -2.0, 3.0, -2.0};
4526 yac_correct_weights(num_weights, weights);
4527 for (size_t i = 0; i < num_weights; ++i)
4528 if (weights[i] != ref_weights[i]) PUT_ERR("wrong weight");
4529 }
4530
4531 {
4532 enum {num_weights = 3};
4533 double weights[num_weights] = {0.0, 0.0, 0.0};
4534 double ref_weights[num_weights] = {0.0, 0.0, 0.0};
4535 yac_correct_weights(num_weights, weights);
4536 for (size_t i = 0; i < num_weights; ++i)
4537 if (weights[i] != ref_weights[i]) PUT_ERR("wrong weight");
4538 }
4539
4540 { // no weights at all
4541 double weights[1] = {1.0};
4542 yac_correct_weights(0, weights);
4543 if (weights[0] != 1.0) PUT_ERR("wrong weight");
4544 }
4545
4546//-----------------test yac_point_on_edge------------------------------------
4547
4548 {
4549 double points_LL[][2] = {{0.0,0.0}, {45.0, 45.0}, {45.0+180.0,-45.0}, {90.0,90.0}};
4550 struct {
4551 union {
4552 double ll[2], xyz[3];
4553 } a, b;
4554 enum yac_circle_type type;
4555 } edges[] =
4556 {{.a.ll = {-5.0, 0.0}, .b.ll = {5.0, 0.0}, .type = GREAT_CIRCLE},
4557 {.a.ll = {0.0, 0.0}, .b.ll = {45.0, 45.0}, .type = GREAT_CIRCLE},
4558 {.a.ll = {10.0, 5.0}, .b.ll = {10.0, 10.0}, .type = GREAT_CIRCLE},
4559 {.a.ll = {10.0, 85.0}, .b.ll = {10.0+180.0, 88.0}, .type = GREAT_CIRCLE},
4560 {.a.ll = {10.0, 85.0}, .b.ll = {10.0+180.0, 90.0}, .type = GREAT_CIRCLE},
4561 {.a.ll = {1.0, 1.0}, .b.ll = {1.0, 1.1}, .type = GREAT_CIRCLE},
4562 {.a.ll = {-5.0, 0.0}, .b.ll = {5.0, 0.0}, .type = LAT_CIRCLE},
4563 {.a.ll = {35.0, 45.0}, .b.ll = {44.0, 45.0}, .type = LAT_CIRCLE},
4564 {.a.ll = {44.0, 45.0}, .b.ll = {46.0, 45.0}, .type = LAT_CIRCLE},
4565 {.a.ll = {5.0, 90.0}, .b.ll = {10.0, 90.0}, .type = LAT_CIRCLE},
4566 {.a.ll = {5.0, 60.0}, .b.ll = {10.0, 60.0}, .type = LAT_CIRCLE},
4567 {.a.ll = {0.0, -5.0}, .b.ll = {0.0, 5.0}, .type = LON_CIRCLE},
4568 {.a.ll = {45.0, 45.0}, .b.ll = {45.0, 47.0}, .type = LON_CIRCLE},
4569 {.a.ll = {10.0, 85.0}, .b.ll = {10.0, 90.0}, .type = LON_CIRCLE},
4570 {.a.ll = {20.0, 30.0}, .b.ll = {20.0, 35.0}, .type = LON_CIRCLE},
4571 {.a.ll = {0.0, 0.0}, .b.ll = {0.0, 0.0}, .type = POINT},
4572 {.a.ll = {1.0, 1.0}, .b.ll = {1.0, 1.0}, .type = POINT},
4573 {.a.ll = {15.0, 90.0}, .b.ll = {15.0, 90.0}, .type = POINT}};
4574 enum {
4575 NUM_POINTS = sizeof(points_LL) / sizeof(points_LL[0]),
4576 NUM_EDGES = sizeof(edges) / sizeof(edges[0]),
4577 };
4578
4579 int ref_results[NUM_POINTS][NUM_EDGES] = {
4580 {1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0},
4581 {0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0},
4582 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
4583 {0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1}};
4584
4585 for (size_t i = 0; i < NUM_EDGES; ++i) {
4586 LLtoXYZ_deg(edges[i].a.ll[0], edges[i].a.ll[1], edges[i].a.xyz);
4587 LLtoXYZ_deg(edges[i].b.ll[0], edges[i].b.ll[1], edges[i].b.xyz);
4588 }
4589 for (size_t point_idx = 0; point_idx < NUM_POINTS; ++point_idx) {
4590
4591 double point[3];
4593 points_LL[point_idx][0], points_LL[point_idx][1], point);
4594
4595 for (size_t edge_idx = 0; edge_idx < NUM_EDGES; ++edge_idx)
4597 point, edges[edge_idx].a.xyz, edges[edge_idx].b.xyz,
4598 edges[edge_idx].type) != ref_results[point_idx][edge_idx]) {
4599 fprintf(stderr, "points_idx = %zu, edge_idx = %zu\n", point_idx, edge_idx);
4600 PUT_ERR("ERROR in yac_point_on_edge");
4601 }
4602 }
4603 }
4604
4605 yac_free_grid_cell(overlap_cell);
4606 yac_free_grid_cell(overlap_cell+1);
4607
4608 return TEST_EXIT_CODE;
4609}
4610
4611static int utest_compare_cells(struct yac_grid_cell a, struct yac_grid_cell b) {
4612
4613 double const tol = 1e-8;
4614
4617
4618 if (a.num_corners != b.num_corners) return 1;
4619
4620 if (a.num_corners == 0) return 0;
4621
4622 for (int order = -1; order <= 1; order += 2) {
4623 for (int start = 0; start < (int)(a.num_corners); ++start) {
4624
4625 int differences = 0;
4626
4627 for (int i = 0; i < (int)(a.num_corners); ++i) {
4628
4629 int j =
4630 ((int)(a.num_corners) + start + order * i) % (int)(a.num_corners);
4631
4633 ++differences;
4634
4635 else if ((a.edge_type[i] == YAC_LAT_CIRCLE_EDGE) !=
4636 (b.edge_type[
4637 (((int)(a.num_corners))+j-(order<0))%
4638 ((int)(a.num_corners))] == YAC_LAT_CIRCLE_EDGE))
4639 ++differences;
4640 }
4641
4642 if (!differences) return 0;
4643 }
4644 }
4645
4646 return 1;
4647}
4648
4649static void utest_clipping(struct yac_grid_cell cells[2],
4650 struct yac_grid_cell * ref_cells,
4651 unsigned num_ref_cells) {
4652
4653 int order[2], start[2];
4654 double mem_dummy_[2][128][3];
4655 enum yac_edge_type edge_dummy[2][128];
4656 struct yac_grid_cell overlap_cell,
4657 test_cells[2] = {
4658 (struct yac_grid_cell){.coordinates_xyz = mem_dummy_[0],
4659 .edge_type = edge_dummy[0],
4660 .num_corners = cells[0].num_corners},
4661 (struct yac_grid_cell){.coordinates_xyz = mem_dummy_[1],
4662 .edge_type = edge_dummy[1],
4663 .num_corners = cells[1].num_corners}};
4664
4665 yac_init_grid_cell(&overlap_cell);
4666
4667 for (order[0] = -1; order[0] <= 1; order[0] += 2) {
4668 for (order[1] = -1; order[1] <= 1; order[1] += 2) {
4669 for (start[0] = 0; start[0] < (int)(cells[0].num_corners); ++start[0]) {
4670 for (start[1] = 0; start[1] < (int)(cells[1].num_corners); ++start[1]) {
4671
4672 for (int k = 0; k <= 1; ++k) {
4673 for (int i = 0; i < ((int)(cells[k].num_corners)); ++i) {
4674 int j =
4675 (((int)(cells[k].num_corners))+start[k]+i*order[k])%
4676 ((int)(cells[k].num_corners));
4677 test_cells[k].coordinates_xyz[i][0] = cells[k].coordinates_xyz[j][0];
4678 test_cells[k].coordinates_xyz[i][1] = cells[k].coordinates_xyz[j][1];
4679 test_cells[k].coordinates_xyz[i][2] = cells[k].coordinates_xyz[j][2];
4680 j =
4681 (((int)(cells[k].num_corners)) + j - (order[k] < 0))%
4682 ((int)(cells[k].num_corners));
4683 test_cells[k].edge_type[i] = cells[k].edge_type[j];
4684 }
4685 }
4686
4687 for (int k = 0; k <= 1; ++k) {
4688 yac_cell_clipping(1, test_cells + k, test_cells[k^1], &overlap_cell);
4689 int match = 0;
4690 for (int i = 0; i < (int)num_ref_cells; ++i)
4691 match |= !utest_compare_cells(overlap_cell, ref_cells[i]);
4692 if (!match)
4693 PUT_ERR("ERROR: wrong clipping cell\n");
4694 }
4695 }
4696 }
4697 }
4698 }
4699 yac_free_grid_cell(&cells[0]);
4700 yac_free_grid_cell(&cells[1]);
4701 for (unsigned i = 0; i < num_ref_cells; ++i)
4702 yac_free_grid_cell(&ref_cells[i]);
4703 yac_free_grid_cell(&overlap_cell);
4704}
4705
4706static void utest_check_weight_correction(
4707 double * weights, size_t count, double * ref_weights) {
4708
4709 double scales[] = {0.001, 0.01, 0.1, 1.0, 10.0, 100.0};
4710 size_t num_tests = sizeof(scales) / sizeof(scales[0]);
4711
4712 for (size_t i = 0; i < num_tests; ++i) {
4713
4714 double temp_weights[count];
4715 for (size_t j = 0; j < count; ++j)
4716 temp_weights[j] = weights[j] * scales[i];
4717
4718 yac_correct_weights(count, temp_weights);
4719
4720 double weight_diff = 1.0;
4721 for (size_t j = 0; j < count; ++j) {
4722 weight_diff -= temp_weights[j];
4723 if (fabs(ref_weights[j] - temp_weights[j]) > 1e-9)
4724 PUT_ERR("wrong weight");
4725 }
4726 if (fabs(weight_diff) > 1e-12) PUT_ERR("wrong weight sum");
4727 }
4728}
double yac_grid_cell_area(struct yac_grid_cell cell)
Area calculation of a spherical cell.
Definition area.c:276
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:1513
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:1125
#define YAC_RAD
static void LLtoXYZ_deg(double lon, double lat, double p_out[])
Definition geometry.h:278
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:472
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
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()
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:15
#define PUT_ERR(string)
Definition tests.h:10
static void XYZtoLL(double const p_in[], double *lon, double *lat)
Definition toy_common.h:23
double(* yac_coordinate_pointer)[3]
Definition yac_types.h:21