YetAnotherCoupler 3.2.0_a
Loading...
Searching...
No Matches
interp_method_spmap.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#ifdef HAVE_CONFIG_H
6// Get the definition of the 'restrict' keyword.
7#include "config.h"
8#endif
9
10#include <float.h>
11#include <string.h>
12
14#include "interp_method_spmap.h"
15#include "ensure_array_size.h"
16#include "area.h"
17
18static size_t do_search_spmap(struct interp_method * method,
19 struct yac_interp_grid * interp_grid,
20 size_t * tgt_points, size_t count,
21 struct yac_interp_weights * weights);
22static void delete_spmap(struct interp_method * method);
23
24static struct interp_method_vtable
29
40
41static inline int compare_size_t(const void * a, const void * b) {
42
43 size_t const * a_ = a, * b_ = b;
44
45 return (*a_ > *b_) - (*b_ > *a_);
46}
47
48static int lists_overlap(
49 size_t * list_a, size_t count_a, size_t * list_b, size_t count_b) {
50
51 if ((count_a == 0) || (count_b == 0)) return 0;
52
53 size_t i = 0, j = 0;
54 size_t curr_a = SIZE_MAX, curr_b = list_b[0];
55
56 do {
57 while ((i < count_a) && (((curr_a = list_a[i++])) < curr_b));
58 if (curr_a == curr_b) return 1;
59 while ((j < count_b) && (((curr_b = list_b[j++])) < curr_a));
60 if (curr_a == curr_b) return 1;
61 } while ((i < count_a) || (j < count_b));
62
63 return 0;
64}
65
66static void merge_lists(
67 size_t * list, size_t * list_size, size_t * insert, size_t insert_size) {
68
69 if (insert_size == 0) return;
70
71 size_t new_list_size = *list_size;
72 size_t old_list_size = *list_size;
73
74 for (size_t i = 0, j = 0; i < insert_size; ++i) {
75 size_t curr_insert = insert[i];
76 while ((j < old_list_size) && (list[j] < curr_insert)) ++j;
77 if ((j >= old_list_size) || (list[j] != curr_insert))
78 list[new_list_size++] = curr_insert;
79 }
80
81 if (new_list_size != old_list_size) {
82 qsort(list, new_list_size, sizeof(*list), compare_size_t);
83 *list_size = new_list_size;
84 }
85}
86
88 yac_const_coordinate_pointer tgt_field_coords, double max_distance,
89 size_t tgt_start_point, size_t * tgt_points, size_t * count) {
90
91 double const * start_coord = tgt_field_coords[tgt_start_point];
92 size_t new_count = 0;
93 for (size_t i = 0, old_count = *count; i < old_count; ++i) {
95 start_coord, tgt_field_coords[tgt_points[i]]) <= max_distance) {
96 if (new_count != i) tgt_points[new_count] = tgt_points[i];
97 ++new_count;
98 }
99 }
100
101 *count = new_count;
102}
103
105 struct yac_interp_grid * interp_grid, size_t tgt_start_point,
106 size_t * from_tgt_points, size_t * to_tgt_points,
107 size_t * count, int * flag, size_t * temp_cell_edges,
108 size_t ** edges_buffer, size_t * edges_buffer_array_size) {
109
110 struct yac_const_basic_grid_data * tgt_grid_data =
114 tgt_grid_data->cell_to_edge_offsets;
115 const int * num_vertices_per_cell =
116 tgt_grid_data->num_vertices_per_cell;
117
118 size_t old_count = *count;
119 memset(flag, 0, old_count * sizeof(*flag));
120
121 for (size_t i = 0; i < old_count; ++i) {
122 if (from_tgt_points[i] == tgt_start_point) {
123 flag[i] = 1;
124 break;
125 }
126 }
127
128 size_t * edges = *edges_buffer;
129 size_t num_edges = 0;
130 size_t edges_array_size = *edges_buffer_array_size;
131
132 const_size_t_pointer curr_edges =
133 cell_to_edge + cell_to_edge_offsets[tgt_start_point];
134 size_t curr_num_edges = num_vertices_per_cell[tgt_start_point];
135
136 ENSURE_ARRAY_SIZE(edges, edges_array_size, curr_num_edges);
137 num_edges = curr_num_edges;
138 memcpy(edges, curr_edges, num_edges * sizeof(*edges));
139 qsort(edges, num_edges, sizeof(*edges), compare_size_t);
140
141 int change_flag = 0;
142 do {
143
144 change_flag = 0;
145
146 for (size_t i = 0; i < old_count; ++i) {
147
148 if (flag[i]) continue;
149
150 const_size_t_pointer curr_edges =
151 tgt_grid_data->cell_to_edge + cell_to_edge_offsets[from_tgt_points[i]];
152 curr_num_edges = num_vertices_per_cell[from_tgt_points[i]];
153 memcpy(
154 temp_cell_edges, curr_edges, curr_num_edges * sizeof(*temp_cell_edges));
155 qsort(temp_cell_edges, curr_num_edges, sizeof(*edges), compare_size_t);
156 ENSURE_ARRAY_SIZE(edges, edges_array_size, num_edges + curr_num_edges);
157
158 if (lists_overlap(edges, num_edges, temp_cell_edges, curr_num_edges)) {
159 merge_lists(edges, &num_edges, temp_cell_edges, curr_num_edges);
160 flag[i] = 1;
161 change_flag = 1;
162 }
163 }
164 } while (change_flag);
165
166 *edges_buffer = edges;
167 *edges_buffer_array_size = edges_array_size;
168
169 size_t new_count = 0;
170 for (size_t i = 0; i < old_count; ++i)
171 if (flag[i]) to_tgt_points[new_count++] = from_tgt_points[i];
172
173 *count = new_count;
174}
175
177 struct yac_interp_grid * interp_grid, double spread_distance,
178 size_t num_src_points, size_t const * const tgt_result_points,
179 size_t * num_tgt_per_src, size_t * spread_tgt_result_points) {
180
181 size_t max_num_tgt_per_src = 0;
182 for (size_t i = 0; i < num_src_points; ++i)
183 if (num_tgt_per_src[i] > max_num_tgt_per_src)
184 max_num_tgt_per_src = num_tgt_per_src[i];
185
186 int * flag = xmalloc(max_num_tgt_per_src * sizeof(*flag));
187
188 size_t new_offset = 0;
189 size_t * cell_edge_buffer = NULL;
190 size_t cell_edge_buffer_array_size = 0;
191 size_t * edge_buffer = NULL;
192 size_t edge_buffer_array_size = 0;
193 size_t max_num_vertice_per_tgt = 0;
194 const int * num_vertices_per_tgt =
197
198 yac_const_coordinate_pointer tgt_field_coords =
200
201 // for all source points
202 for (size_t i = 0, old_offset = 0; i < num_src_points; ++i) {
203
204 size_t * old_results = spread_tgt_result_points + old_offset;
205 size_t * new_results = spread_tgt_result_points + new_offset;
206 old_offset += num_tgt_per_src[i];
207
208 // remove all target points, which exceed the spread distance from
209 // the original tgt
211 tgt_field_coords, spread_distance, tgt_result_points[i],
212 old_results, num_tgt_per_src + i);
213
214 // check buffer sizes required by routine remove_disconnected_points
215 for (size_t j = 0, curr_num_tgt_per_src = num_tgt_per_src[i];
216 j < curr_num_tgt_per_src; ++j)
217 if (num_vertices_per_tgt[old_results[j]] > max_num_vertice_per_tgt)
218 max_num_vertice_per_tgt = num_vertices_per_tgt[old_results[j]];
219
221 cell_edge_buffer, cell_edge_buffer_array_size,
222 max_num_vertice_per_tgt);
223
224 // remove all tgts that are not directly connected to the original tgt
226 interp_grid, tgt_result_points[i],
227 old_results, new_results, num_tgt_per_src + i, flag,
228 cell_edge_buffer, &edge_buffer, &edge_buffer_array_size);
229
230 new_offset += num_tgt_per_src[i];
231 }
232
233 free(edge_buffer);
234 free(cell_edge_buffer);
235 free(flag);
236
237 return new_offset;
238}
239
241 struct yac_interp_grid * interp_grid, double max_search_distance,
242 size_t * num_src_points_, size_t * src_points,
243 yac_coordinate_pointer src_coords, size_t * tgt_result_points) {
244
245 if (max_search_distance > 0.0) {
246 yac_const_coordinate_pointer tgt_field_coords =
248 size_t const num_src_points = *num_src_points_;
249 size_t new_num_src_points = 0;
250 for (size_t i = 0; i < num_src_points; ++i) {
252 src_coords[i], tgt_field_coords[tgt_result_points[i]]) <=
253 max_search_distance) {
254 if (i != new_num_src_points) {
255 src_points[new_num_src_points] = src_points[i];
256 tgt_result_points[new_num_src_points] = tgt_result_points[i];
257 }
258 new_num_src_points++;
259 }
260 }
261 *num_src_points_ = new_num_src_points;
262 }
263}
264
265static double * compute_weights(
266 struct yac_interp_grid * interp_grid,
267 enum yac_interp_spmap_weight_type weight_type, size_t num_src_points,
268 size_t const * const src_points, size_t const * const num_tgt_per_src,
269 size_t total_num_tgt, size_t const * const spread_tgt_result_points) {
270
271 double * weights = xmalloc(total_num_tgt * sizeof(*weights));
273 (weight_type == YAC_INTERP_SPMAP_AVG) ||
274 (weight_type == YAC_INTERP_SPMAP_DIST),
275 "ERROR(do_search_spmap): invalid weight_type")
276 switch (weight_type) {
277 case (YAC_INTERP_SPMAP_AVG): {
278 for (size_t i = 0, offset = 0; i < num_src_points; ++i) {
279 double curr_weight_data = 1.0 / (double)(num_tgt_per_src[i]);
280 for (size_t j = 0; j < num_tgt_per_src[i]; ++j, ++offset) {
281 weights[offset] = curr_weight_data;
282 }
283 }
284 break;
285 }
286 default:
287 case (YAC_INTERP_SPMAP_DIST): {
288
289 yac_const_coordinate_pointer src_field_coords =
291 yac_const_coordinate_pointer tgt_field_coords =
293
294 for (size_t i = 0, offset = 0; i < num_src_points; ++i) {
295
296 size_t curr_num_tgt = num_tgt_per_src[i];
297 size_t const * const curr_result_points =
298 spread_tgt_result_points + offset;
299 double const * curr_src_coord = src_field_coords[src_points[i]];
300 double * curr_weights = weights + offset;
301 offset += curr_num_tgt;
302
303 int match_flag = 0;
304
305 for (size_t j = 0; j < curr_num_tgt; ++j) {
306
307 double distance =
309 (double*)curr_src_coord,
310 (double*)tgt_field_coords[curr_result_points[j]]);
311
312 if (distance < yac_angle_tol) {
313 for (size_t k = 0; k < curr_num_tgt; ++k) curr_weights[k] = 0.0;
314 curr_weights[j] = 1.0;
315 match_flag = 1;
316 break;
317 }
318 curr_weights[j] = 1.0 / distance;
319 }
320
321 if (!match_flag) {
322
323 // compute scaling factor for the weights
324 double inv_distance_sum = 0.0;
325 for (size_t j = 0; j < curr_num_tgt; ++j)
326 inv_distance_sum += curr_weights[j];
327 double scale = 1.0 / inv_distance_sum;
328
329 for (size_t j = 0; j < curr_num_tgt; ++j) curr_weights[j] *= scale;
330 }
331 }
332 break;
333 }
334 };
335
336 return weights;
337}
338
339static void scale_weights(
340 struct yac_interp_grid * interp_grid,
341 enum yac_interp_spmap_scale_type scale_type,
342 double src_area_scale, double tgt_area_scale,
343 size_t num_src_points, size_t const * src_points,
344 size_t const * num_tgt_per_src, size_t const * tgt_points,
345 double * weights) {
346
348 (scale_type == YAC_INTERP_SPMAP_NONE) ||
349 (scale_type == YAC_INTERP_SPMAP_SRCAREA) ||
350 (scale_type == YAC_INTERP_SPMAP_INVTGTAREA) ||
351 (scale_type == YAC_INTERP_SPMAP_FRACAREA),
352 "ERROR(scale_weights): invalid scale_type")
353
354 // if there is no scaling
355 if (scale_type == YAC_INTERP_SPMAP_NONE) return;
356
357 struct yac_grid_cell grid_cell;
358 yac_init_grid_cell(&grid_cell);
359
360 struct yac_const_basic_grid_data * src_basic_grid_data =
362 struct yac_const_basic_grid_data * tgt_basic_grid_data =
364
365#define COMPUTE_CELL_AREA(PREFIX, IDX) \
366 yac_const_basic_grid_data_get_grid_cell( \
367 PREFIX ## _basic_grid_data, PREFIX ## _points[IDX], &grid_cell); \
368 double PREFIX ## _cell_area = yac_huiliers_area(grid_cell) * PREFIX ## _area_scale; \
369 YAC_ASSERT_F( \
370 PREFIX ## _cell_area > YAC_AREA_TOL, \
371 "ERROR(scale_weights): " \
372 "area of %s cell (global id %"XT_INT_FMT") is close to zero (%e)", \
373 # PREFIX, \
374 PREFIX ## _basic_grid_data->ids[YAC_LOC_CELL][PREFIX ## _points[IDX]], \
375 PREFIX ## _cell_area)
376#define NO_COMPUTE_CELL_AREA(PREFIX, IDX)
377
378#define SCALE_WEIGHTS( \
379 COMPUTE_SRC_CELL_AREA, \
380 COMPUTE_TGT_CELL_AREA, \
381 SRC_CELL_AREA, TGT_CELL_AREA) \
382{ \
383 for (size_t i = 0, offset = 0; i < num_src_points; ++i) { \
384 COMPUTE_SRC_CELL_AREA(src, i) \
385 size_t curr_num_tgt = num_tgt_per_src[i]; \
386 for (size_t j = 0; j < curr_num_tgt; ++j, ++offset) { \
387 COMPUTE_TGT_CELL_AREA(tgt, offset) \
388 weights[offset] *= SRC_CELL_AREA / TGT_CELL_AREA; \
389 } \
390 } \
391}
392
393 switch (scale_type) {
396 COMPUTE_CELL_AREA, NO_COMPUTE_CELL_AREA, src_cell_area, 1.0)
397 break;
400 NO_COMPUTE_CELL_AREA, COMPUTE_CELL_AREA, 1.0, tgt_cell_area)
401 break;
402 default:
405 COMPUTE_CELL_AREA, COMPUTE_CELL_AREA, src_cell_area, tgt_cell_area)
406 break;
407 }
408
409 yac_free_grid_cell(&grid_cell);
410}
411
412static void spread_src_data(
413 struct yac_interp_grid * interp_grid, double spread_distance,
414 enum yac_interp_spmap_weight_type weight_type,
415 enum yac_interp_spmap_scale_type scale_type,
416 double src_area_scale, double tgt_area_scale,
417 size_t num_src_points, size_t ** src_points_,
418 size_t ** tgt_result_points_, double ** weights_,
419 size_t * total_num_weights_) {
420
421 if (spread_distance <= 0.0) {
422 *weights_ = NULL;
423 *total_num_weights_ = num_src_points;
424 return;
425 }
426
427 size_t const * const src_points = *src_points_;
428 size_t const * const tgt_result_points = *tgt_result_points_;
429
430 struct sin_cos_angle inc_angle =
431 sin_cos_angle_new(sin(spread_distance), cos(spread_distance));
432 yac_const_coordinate_pointer tgt_field_coords =
434
435 struct bounding_circle * search_bnd_circles =
436 xmalloc(num_src_points * sizeof(*search_bnd_circles));
437 for (size_t i = 0; i < num_src_points; ++i) {
438 memcpy(
439 search_bnd_circles[i].base_vector,
440 tgt_field_coords[tgt_result_points[i]], sizeof(*tgt_field_coords));
441 search_bnd_circles[i].inc_angle = inc_angle;
442 search_bnd_circles[i].sq_crd = DBL_MAX;
443 }
444 size_t * spread_tgt_result_points = NULL;
445
446 // do bounding circle search around found tgt points
447 size_t * num_tgt_per_src =
448 xmalloc(num_src_points * sizeof(*num_tgt_per_src));
450 interp_grid, search_bnd_circles, num_src_points,
451 &spread_tgt_result_points, num_tgt_per_src);
452 free(search_bnd_circles);
453
454 // remove target points which exceed the spread distance and only keep
455 // targets that are connected to the original target point or other
456 // target that have already been selected
457 size_t total_num_weights =
459 interp_grid, spread_distance, num_src_points, tgt_result_points,
460 num_tgt_per_src, spread_tgt_result_points);
461
462 // adjust src_points (one source per target)
463 size_t * new_src_points =
464 xmalloc(total_num_weights * sizeof(*new_src_points));
465 for (size_t i = 0, offset = 0; i < num_src_points; ++i)
466 for (size_t j = 0, curr_src_point = src_points[i];
467 j < num_tgt_per_src[i]; ++j, ++offset)
468 new_src_points[offset] = curr_src_point;
469
470 // compute weights
471 double * weights =
473 interp_grid, weight_type, num_src_points, src_points,
474 num_tgt_per_src, total_num_weights, spread_tgt_result_points);
475
476 // scale weights
478 interp_grid, scale_type, src_area_scale, tgt_area_scale, num_src_points,
479 src_points, num_tgt_per_src, spread_tgt_result_points, weights);
480
481 free(num_tgt_per_src);
482 free(*tgt_result_points_);
483
484 // set return values
485 *tgt_result_points_ =
486 xrealloc(
487 spread_tgt_result_points,
488 total_num_weights * sizeof(*spread_tgt_result_points));
489 free(*src_points_);
490 *src_points_ = new_src_points;
491 *weights_ = weights;
492 *total_num_weights_ = total_num_weights;
493}
494
495static size_t do_search_spmap (struct interp_method * method,
496 struct yac_interp_grid * interp_grid,
497 size_t * tgt_points, size_t count,
498 struct yac_interp_weights * weights) {
499
501 yac_interp_grid_get_num_src_fields(interp_grid) == 1,
502 "ERROR(do_search_spmap): invalid number of source fields")
505 "ERROR(do_search_spmap): "
506 "invalid source field location (has to be YAC_LOC_CELL)")
509 "ERROR(do_search_spmap): "
510 "invalid target field location (has to be YAC_LOC_CELL)")
511
512 // get coordinates of all source points
513 size_t * src_points;
514 size_t num_src_points;
516 interp_grid, 0, &src_points, &num_src_points);
517 yac_coordinate_pointer src_coords = xmalloc(num_src_points * sizeof(*src_coords));
519 interp_grid, src_points, num_src_points, 0, src_coords);
520
521 // search for matching tgt points
522 size_t * tgt_result_points =
523 xmalloc(num_src_points * sizeof(*tgt_result_points));
525 interp_grid, src_coords, num_src_points, 1, tgt_result_points);
526
527 // check that we found a target for each source point
528 for (size_t i = 0; i < num_src_points; ++i)
530 tgt_result_points[i] != SIZE_MAX,
531 "ERROR(do_search_spmap): could not find matching target point")
532
533 // remove results that exceed the maximum search distance
535 interp_grid, ((struct interp_method_spmap*)method)->max_search_distance,
536 &num_src_points, src_points, src_coords, tgt_result_points);
537
538 free(src_coords);
539
540 // spread the data from each source point to multiple target points
541 // (weight_data is set to NULL if no spreading was applied)
542 double * weight_data;
543 size_t total_num_weights;
545 interp_grid, ((struct interp_method_spmap*)method)->spread_distance,
546 ((struct interp_method_spmap*)method)->weight_type,
547 ((struct interp_method_spmap*)method)->scale_type,
548 ((struct interp_method_spmap*)method)->src_area_scale,
549 ((struct interp_method_spmap*)method)->tgt_area_scale, num_src_points,
550 &src_points, &tgt_result_points, &weight_data, &total_num_weights);
551
552 // relocate source-target-point-pairs to dist owners of the respective
553 // target points
554 size_t result_count = total_num_weights;
555 int to_tgt_owner = 1;
557 interp_grid, to_tgt_owner,
558 0, &src_points, &tgt_result_points, &weight_data, &result_count);
559 total_num_weights = result_count;
560
561 // sort source-target-point-pairs by target points
563 tgt_result_points, result_count, src_points, weight_data);
564
565 // generate num_src_per_tgt and compact tgt_result_points
566 size_t * num_src_per_tgt = xmalloc(result_count * sizeof(*num_src_per_tgt));
567 size_t num_unique_tgt_result_points = 0;
568 for (size_t i = 0; i < result_count;) {
569 size_t prev_i = i;
570 size_t curr_tgt = tgt_result_points[i];
571 while ((i < result_count) && (curr_tgt == tgt_result_points[i])) ++i;
572 num_src_per_tgt[num_unique_tgt_result_points] = i - prev_i;
573 tgt_result_points[num_unique_tgt_result_points] = curr_tgt;
574 ++num_unique_tgt_result_points;
575 }
576 result_count = num_unique_tgt_result_points;
577 num_src_per_tgt =
578 xrealloc(num_src_per_tgt, result_count * sizeof(*num_src_per_tgt));
579 tgt_result_points =
580 xrealloc(tgt_result_points, result_count * sizeof(*tgt_result_points));
581
582 // match tgt_result_points with available target points
583 qsort(tgt_points, count, sizeof(*tgt_points), compare_size_t);
584 int * reorder_flag = xmalloc(count * sizeof(*tgt_points));
585 {
586 size_t j = 0;
587 for (size_t i = 0; i < result_count; ++i) {
588 size_t curr_result_tgt = tgt_result_points[i];
589 while ((j < count) && (tgt_points[j] < curr_result_tgt))
590 reorder_flag[j++] = 1;
592 (j < count) && (curr_result_tgt == tgt_points[j]),
593 "ERROR(do_search_spmap): "
594 "required target points already in use or not available")
595 reorder_flag[j++] = 0;
596 }
597 for (; j < count; ++j) reorder_flag[j] = 1;
598 }
599
600 // sort used target points to the beginning of the array
601 yac_quicksort_index_int_size_t(reorder_flag, count, tgt_points);
602 free(reorder_flag);
603
604 struct remote_point * srcs =
606 interp_grid, 0, src_points, total_num_weights);
607 struct remote_points tgts = {
608 .data =
610 interp_grid, tgt_result_points, result_count),
611 .count = result_count};
612 free(tgt_result_points);
613
614 // store results
615 if (weight_data == NULL)
617 weights, &tgts, num_src_per_tgt, srcs);
618 else
620 weights, &tgts, num_src_per_tgt, srcs, weight_data);
621
622 free(weight_data);
623 free(src_points);
624 free(tgts.data);
625 free(srcs);
626 free(num_src_per_tgt);
627
628 return result_count;
629}
630
632 double spread_distance, double max_search_distance,
633 enum yac_interp_spmap_weight_type weight_type,
634 enum yac_interp_spmap_scale_type scale_type,
635 double src_sphere_radius, double tgt_sphere_radius) {
636
637 struct interp_method_spmap * method = xmalloc(1 * sizeof(*method));
638
642 method->weight_type = weight_type;
643 method->scale_type = scale_type;
644 method->src_area_scale = src_sphere_radius * src_sphere_radius;
645 method->tgt_area_scale = tgt_sphere_radius * tgt_sphere_radius;
646
648 (spread_distance >= 0.0) && (spread_distance <= M_PI_2),
649 "ERROR(yac_interp_method_spmap_new): invalid spread_distance "
650 "(has to be >= 0 and <= PI/2")
651
653 (max_search_distance >= 0.0) && (max_search_distance <= M_PI),
654 "ERROR(yac_interp_method_spmap_new): invalid max_search_distance "
655 "(has to be >= 0 and <= PI")
656
658 src_sphere_radius > 0.0,
659 "ERROR(yac_interp_method_spmap_new): invalid src_sphere_radius "
660 "(has to be >= 0.0")
661
663 tgt_sphere_radius > 0.0,
664 "ERROR(yac_interp_method_spmap_new): invalid tgt_sphere_radius "
665 "(has to be >= 0.0")
666
667 return (struct interp_method*)method;
668}
669
670static void delete_spmap(struct interp_method * method) {
671 free(method);
672}
Structs and interfaces for area calculations.
size_t const *const const_size_t_pointer
#define ENSURE_ARRAY_SIZE(arrayp, curr_array_size, req_size)
#define yac_angle_tol
Definition geometry.h:34
static double get_vector_angle(double const a[3], double const b[3])
Definition geometry.h:364
static struct sin_cos_angle sin_cos_angle_new(double sin, double cos)
Definition geometry.h:405
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
enum yac_location yac_interp_grid_get_tgt_field_location(struct yac_interp_grid *interp_grid)
void yac_interp_grid_relocate_src_tgt_pairs(struct yac_interp_grid *interp_grid, int to_tgt_owner, size_t src_field_idx, size_t **src_points, size_t **tgt_points, double **weights, size_t *count)
size_t yac_interp_grid_get_num_src_fields(struct yac_interp_grid *interp_grid)
void yac_interp_grid_do_nnn_search_tgt(struct yac_interp_grid *interp_grid, yac_coordinate_pointer search_coords, size_t count, size_t n, size_t *tgt_points)
void yac_interp_grid_do_bnd_circle_search_tgt(struct yac_interp_grid *interp_grid, const_bounding_circle_pointer bnd_circles, size_t count, size_t **tgt_cells, size_t *num_tgt_per_bnd_circle)
struct remote_point * yac_interp_grid_get_tgt_remote_points(struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count)
void yac_interp_grid_get_src_points(struct yac_interp_grid *interp_grid, size_t src_field_idx, size_t **src_indices, size_t *count)
Definition interp_grid.c:77
enum yac_location yac_interp_grid_get_src_field_location(struct yac_interp_grid *interp_grid, size_t src_field_idx)
void yac_interp_grid_get_src_coordinates(struct yac_interp_grid *interp_grid, size_t *src_points, size_t count, size_t src_field_idx, yac_coordinate_pointer src_coordinates)
struct remote_point * yac_interp_grid_get_src_remote_points(struct yac_interp_grid *interp_grid, size_t src_field_idx, size_t *src_points, size_t count)
yac_const_coordinate_pointer yac_interp_grid_get_src_field_coords(struct yac_interp_grid *interp_grid, size_t src_field_idx)
yac_const_coordinate_pointer yac_interp_grid_get_tgt_field_coords(struct yac_interp_grid *interp_grid)
struct yac_const_basic_grid_data * yac_interp_grid_get_basic_grid_data_tgt(struct yac_interp_grid *interp_grid)
struct yac_const_basic_grid_data * yac_interp_grid_get_basic_grid_data_src(struct yac_interp_grid *interp_grid)
static int lists_overlap(size_t *list_a, size_t count_a, size_t *list_b, size_t count_b)
static void delete_spmap(struct interp_method *method)
static int compare_size_t(const void *a, const void *b)
static size_t do_search_spmap(struct interp_method *method, struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count, struct yac_interp_weights *weights)
static struct interp_method_vtable interp_method_spmap_vtable
static void check_max_search_distance(struct yac_interp_grid *interp_grid, double max_search_distance, size_t *num_src_points_, size_t *src_points, yac_coordinate_pointer src_coords, size_t *tgt_result_points)
struct interp_method * yac_interp_method_spmap_new(double spread_distance, double max_search_distance, enum yac_interp_spmap_weight_type weight_type, enum yac_interp_spmap_scale_type scale_type, double src_sphere_radius, double tgt_sphere_radius)
static void merge_lists(size_t *list, size_t *list_size, size_t *insert, size_t insert_size)
#define COMPUTE_CELL_AREA(PREFIX, IDX)
static void scale_weights(struct yac_interp_grid *interp_grid, enum yac_interp_spmap_scale_type scale_type, double src_area_scale, double tgt_area_scale, size_t num_src_points, size_t const *src_points, size_t const *num_tgt_per_src, size_t const *tgt_points, double *weights)
static double * compute_weights(struct yac_interp_grid *interp_grid, enum yac_interp_spmap_weight_type weight_type, size_t num_src_points, size_t const *const src_points, size_t const *const num_tgt_per_src, size_t total_num_tgt, size_t const *const spread_tgt_result_points)
static void remove_disconnected_points(struct yac_interp_grid *interp_grid, size_t tgt_start_point, size_t *from_tgt_points, size_t *to_tgt_points, size_t *count, int *flag, size_t *temp_cell_edges, size_t **edges_buffer, size_t *edges_buffer_array_size)
static void spread_src_data(struct yac_interp_grid *interp_grid, double spread_distance, enum yac_interp_spmap_weight_type weight_type, enum yac_interp_spmap_scale_type scale_type, double src_area_scale, double tgt_area_scale, size_t num_src_points, size_t **src_points_, size_t **tgt_result_points_, double **weights_, size_t *total_num_weights_)
static size_t check_tgt_result_points(struct yac_interp_grid *interp_grid, double spread_distance, size_t num_src_points, size_t const *const tgt_result_points, size_t *num_tgt_per_src, size_t *spread_tgt_result_points)
static void check_spread_distance(yac_const_coordinate_pointer tgt_field_coords, double max_distance, size_t tgt_start_point, size_t *tgt_points, size_t *count)
#define SCALE_WEIGHTS(COMPUTE_SRC_CELL_AREA, COMPUTE_TGT_CELL_AREA, SRC_CELL_AREA, TGT_CELL_AREA)
#define NO_COMPUTE_CELL_AREA(PREFIX, IDX)
yac_interp_spmap_scale_type
@ YAC_INTERP_SPMAP_NONE
weights are not scaled
@ YAC_INTERP_SPMAP_INVTGTAREA
@ YAC_INTERP_SPMAP_SRCAREA
@ YAC_INTERP_SPMAP_FRACAREA
yac_interp_spmap_weight_type
@ YAC_INTERP_SPMAP_AVG
@ YAC_INTERP_SPMAP_DIST
void yac_interp_weights_add_wsum(struct yac_interp_weights *weights, struct remote_points *tgts, size_t *num_src_per_tgt, struct remote_point *srcs, double *w)
void yac_interp_weights_add_sum(struct yac_interp_weights *weights, struct remote_points *tgts, size_t *num_src_per_tgt, struct remote_point *srcs)
@ YAC_LOC_CELL
Definition location.h:14
#define xrealloc(ptr, size)
Definition ppm_xfuncs.h:67
#define xmalloc(size)
Definition ppm_xfuncs.h:66
struct sin_cos_angle inc_angle
angle between the middle point and the boundary of the spherical cap
Definition geometry.h:61
double base_vector[3]
Definition geometry.h:59
double sq_crd
Definition geometry.h:64
enum yac_interp_spmap_scale_type scale_type
enum yac_interp_spmap_weight_type weight_type
struct interp_method_vtable * vtable
size_t(* do_search)(struct interp_method *method, struct yac_interp_grid *grid, size_t *tgt_points, size_t count, struct yac_interp_weights *weights)
struct remote_point * data
double sin
Definition geometry.h:41
double cos
Definition geometry.h:41
const_int_pointer num_vertices_per_cell
const_size_t_pointer cell_to_edge
const_size_t_pointer cell_to_edge_offsets
void yac_quicksort_index_size_t_size_t_double(size_t *a, size_t n, size_t *b, double *c)
void yac_quicksort_index_int_size_t(int *a, size_t n, size_t *idx)
#define YAC_ASSERT(exp, msg)
Definition yac_assert.h:15
double const (*const yac_const_coordinate_pointer)[3]
Definition yac_types.h:20
double(* yac_coordinate_pointer)[3]
Definition yac_types.h:19