YAC 3.13.0
Yet Another Coupler
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
15#include "ensure_array_size.h"
16#include "area.h"
17#include "io_utils.h"
18#include "point_selection.h"
19#include "yac_mpi_internal.h"
20
21static size_t do_search_spmap(struct interp_method * method,
22 struct yac_interp_grid * interp_grid,
23 size_t * tgt_points, size_t count,
24 struct yac_interp_weights * weights,
25 int * interpolation_complete);
26static void delete_spmap(struct interp_method * method);
27
28static struct interp_method_vtable
33
41typedef struct interp_link {
42 size_t tgt_point;
43 struct {
45 size_t local;
47 double weight;
49
52 union {
53 struct {
54 double sphere_radius; // used for computing the cell areas
55 } yac;
56 struct yac_spmap_cell_area_file_config {
57 char const * filename;
58 char const * varname;
60 } file_config; // used for read the cell areas from file
61 };
62};
63
67
73
76 .src = NULL,
77 .tgt = NULL};
78
85
91
96
98 {.src_point_selection = NULL,
99 .config = NULL};
100
107
108static inline int compare_size_t(const void * a, const void * b) {
109
110 size_t const * a_ = a, * b_ = b;
111
112 return (*a_ > *b_) - (*b_ > *a_);
113}
114
133 struct yac_interp_grid * interp_grid, struct sin_cos_angle spread_distance,
134 size_t num_src_points, size_t const * const tgt_result_points,
135 size_t * num_tgt_per_src, size_t * spread_tgt_result_points) {
136
137 struct yac_const_basic_grid_data * tgt_basic_grid_data =
139 size_t local_num_tgt_cells = tgt_basic_grid_data->count[YAC_LOC_CELL];
140 yac_const_coordinate_pointer tgt_field_coords =
142 yac_size_t_2_pointer edge_to_cell =
144
145 enum {
146 OUTSIDE = 0, // not part of initial bounding circle search results
147 // --> not to be considered
148 INCLUDED = 0, // already included in the final list of target result points
149 CANDIDATE = 1, // potential candidate based on initial bounding
150 // circle search results
151 } * tgt_state =
152 xmalloc(local_num_tgt_cells * sizeof(*tgt_state));
153
154 size_t * curr_tgt_results = spread_tgt_result_points;
155 size_t * curr_bnd_search_tgt_results = spread_tgt_result_points;
156
157 size_t total_num_weights = 0;
158
159 // for all source points
160 for (size_t i = 0; i < num_src_points; ++i) {
161
162 // first mark all target cell as being outside and the only set results
163 // from the bounding circle search as potential candidates that can be
164 // considered for the final result
165 memset(
166 tgt_state, OUTSIDE, local_num_tgt_cells * sizeof(*tgt_state));
167 size_t curr_bnd_search_result_count = num_tgt_per_src[i];
168 for (size_t j = 0; j < curr_bnd_search_result_count; ++j) {
169 tgt_state[curr_bnd_search_tgt_results[j]] = CANDIDATE;
170 }
171 curr_bnd_search_tgt_results += curr_bnd_search_result_count;
172
173 // add original results to list of final results
174 size_t tgt_start_point = tgt_result_points[i];
175 size_t curr_num_tgt_results = 1;
176 curr_tgt_results[0] = tgt_start_point;
177 tgt_state[tgt_start_point] = INCLUDED;
178 double const * start_coord = tgt_field_coords[tgt_start_point];
179 size_t * prev_added_tgts = curr_tgt_results;
180
181 size_t prev_num_added_tgt = 0; // number of added targets in prev iteration
182 size_t curr_num_added_tgt = 1; // number of added targets in curr iteration
183 do {
184
185 prev_added_tgts += prev_num_added_tgt;
186 prev_num_added_tgt = curr_num_added_tgt;
187 curr_num_added_tgt = 0;
188
189 // for all targets that were added in the previous iteration
190 for (size_t j = 0; j < prev_num_added_tgt; ++j) {
191
192 // get target that was added in previous iteration
193 size_t curr_tgt_result = prev_added_tgts[j];
194
195 size_t const * curr_cell_to_edge =
196 tgt_basic_grid_data->cell_to_edge +
197 tgt_basic_grid_data->cell_to_edge_offsets[curr_tgt_result];
198 size_t curr_num_edges =
199 tgt_basic_grid_data->num_vertices_per_cell[curr_tgt_result];
200
201 // for all neighbour cells
202 for (size_t k = 0; k < curr_num_edges; ++k) {
203
204 size_t * curr_edge_to_cell = edge_to_cell[curr_cell_to_edge[k]];
205 size_t tgt_candidate =
206 curr_edge_to_cell[curr_edge_to_cell[0] == curr_tgt_result];
207
208 // if there actually is a cell (SIZE_MAX -> no cell) and
209 // if the target is a potential candiate
210 if ((tgt_candidate != SIZE_MAX) &&
211 (tgt_state[tgt_candidate] == CANDIDATE)) {
212
213 // add target if within spread distance
214 struct sin_cos_angle distance =
215 get_vector_angle_2(start_coord, tgt_field_coords[tgt_candidate]);
216 if (compare_angles(distance, spread_distance) <= 0) {
217
218 curr_tgt_results[curr_num_tgt_results] = tgt_candidate;
219 ++curr_num_tgt_results;
220 ++curr_num_added_tgt;
221
222 // mark target as being included in the result list
223 tgt_state[tgt_candidate] = INCLUDED;
224
225 } else {
226
227 // mark target as being to far away for the initial search result
228 tgt_state[tgt_candidate] = OUTSIDE;
229 }
230 } // is valid new tgt
231 } // num edges
232 } // prev num added tgt
233
234 } while (curr_num_added_tgt > 0); // continue until no new targets were added
235
236 curr_tgt_results += curr_num_tgt_results;
237 num_tgt_per_src[i] = curr_num_tgt_results;
238 total_num_weights += curr_num_tgt_results;
239 }
240
241 free(edge_to_cell);
242 free(tgt_state);
243
244 return total_num_weights;
245}
246
261static double * compute_weights(
262 struct yac_interp_grid * interp_grid,
263 enum yac_interp_spmap_weight_type weight_type, size_t num_src_points,
264 size_t const * const src_points, size_t const * const num_tgt_per_src,
265 size_t total_num_tgt, size_t const * const tgt_result_points) {
266
267 double * weights = xmalloc(total_num_tgt * sizeof(*weights));
268
269 switch (weight_type) {
270
271 YAC_UNREACHABLE_DEFAULT("ERROR(do_search_spmap): invalid weight_type");
272
273 // simple average
274 case (YAC_INTERP_SPMAP_AVG): {
275 for (size_t i = 0, offset = 0; i < num_src_points; ++i) {
276 size_t curr_num_tgt = num_tgt_per_src[i];
277 if (curr_num_tgt == 0) continue;
278 if (curr_num_tgt > 1) {
279 double curr_weight_data = 1.0 / (double)(curr_num_tgt);
280 for (size_t j = 0; j < curr_num_tgt; ++j, ++offset) {
281 weights[offset] = curr_weight_data;
282 }
283 } else {
284 weights[offset] = 1.0;
285 ++offset;
286 }
287 }
288 break;
289 }
290
291 // distance weighted
292 case (YAC_INTERP_SPMAP_DIST): {
293
294 yac_const_coordinate_pointer src_field_coords =
296 yac_const_coordinate_pointer tgt_field_coords =
298
299 // for each source point
300 for (size_t i = 0, offset = 0; i < num_src_points; ++i) {
301
302 size_t curr_num_tgt = num_tgt_per_src[i];
303
304 if (curr_num_tgt == 0) continue;
305
306 double * curr_weights = weights + offset;
307
308 if (curr_num_tgt > 1) {
309
310 size_t const * const curr_result_points =
311 tgt_result_points + offset;
312 double const * curr_src_coord = src_field_coords[src_points[offset]];
313 offset += curr_num_tgt;
314
315 int match_flag = 0;
316
317 for (size_t j = 0; j < curr_num_tgt; ++j) {
318
319 double distance =
321 (double*)curr_src_coord,
322 (double*)tgt_field_coords[curr_result_points[j]]);
323
324 if (distance < yac_angle_tol) {
325 for (size_t k = 0; k < curr_num_tgt; ++k) curr_weights[k] = 0.0;
326 curr_weights[j] = 1.0;
327 match_flag = 1;
328 break;
329 }
330 curr_weights[j] = 1.0 / distance;
331 }
332
333 if (!match_flag) {
334
335 // compute scaling factor for the weights
336 double inv_distance_sum = 0.0;
337 for (size_t j = 0; j < curr_num_tgt; ++j)
338 inv_distance_sum += curr_weights[j];
339 double scale = 1.0 / inv_distance_sum;
340
341 for (size_t j = 0; j < curr_num_tgt; ++j) curr_weights[j] *= scale;
342 }
343 } else {
344 *curr_weights = 1.0;
345 ++offset;
346 }
347 }
348 break;
349 }
350 };
351
352 return weights;
353}
354
356 struct yac_const_basic_grid_data * basic_grid_data,
357 int const * required_cell_areas, double area_scale, char const * type,
358 double * cell_areas) {
359
360 struct yac_grid_cell grid_cell;
361 yac_init_grid_cell(&grid_cell);
362
363 size_t num_cells = basic_grid_data->count[YAC_LOC_CELL];
364
365 for (size_t i = 0; i < num_cells; ++i) {
366 if (required_cell_areas[i]) {
367 yac_const_basic_grid_data_get_grid_cell(basic_grid_data, i, &grid_cell);
368 double cell_area = yac_huiliers_area(grid_cell) * area_scale;
370 cell_area > YAC_AREA_TOL,
371 "ERROR(get_cell_areas): "
372 "area of %s cell (global id %"YAC_INT_FMT") is close to zero (%e)",
373 type, basic_grid_data->ids[YAC_LOC_CELL][i], cell_area);
374 cell_areas[i] = cell_area;
375 } else {
376 cell_areas[i] = 0.0;
377 }
378 }
379
380 yac_free_grid_cell(&grid_cell);
381}
382
384 char const * filename, char const * varname, MPI_Comm comm,
385 int * const io_ranks, int io_rank_idx, int num_io_ranks,
386 double ** dist_cell_areas, size_t * dist_cell_areas_global_size) {
387
388#ifndef YAC_NETCDF_ENABLED
389
390 UNUSED(filename);
391 UNUSED(varname);
392 UNUSED(comm);
393 UNUSED(io_ranks);
394 UNUSED(io_rank_idx);
395 UNUSED(num_io_ranks);
396
397 *dist_cell_areas = NULL;
398 *dist_cell_areas_global_size = 0;
399
400 die(
401 "ERROR(interp_method_spmap::dist_read_cell_areas): "
402 "YAC is built without the NetCDF support");
403#else
404
405 if ((io_rank_idx >= 0) && (io_rank_idx < num_io_ranks)) {
406
407 // open file
408 int ncid;
409 yac_nc_open(filename, NC_NOWRITE, &ncid);
410
411 // get variable id
412 int varid;
413 yac_nc_inq_varid(ncid, varname, &varid);
414
415 // get dimension ids
416 int ndims;
417 int dimids[NC_MAX_VAR_DIMS];
419 nc_inq_var(ncid, varid, NULL, NULL, &ndims, dimids, NULL));
420
422 (ndims == 1) || (ndims == 2),
423 "ERROR(dist_read_cell_areas): "
424 "invalid number of dimensions for cell area variable \"%s\" from "
425 "file \"%s\" (is %d, but should be either 1 or 2)",
426 varname, filename, ndims);
427
428 // get size of dimensions
429 size_t dimlen[2];
430 *dist_cell_areas_global_size = 1;
431 for (int i = 0; i < ndims; ++i) {
432 YAC_HANDLE_ERROR(nc_inq_dimlen(ncid, dimids[i], &dimlen[i]));
434 dimlen[i] > 0,
435 "ERROR(dist_read_cell_areas): "
436 "invalid dimension size for cell area variable \"%s\" from "
437 "file \"%s\" (is %zu, should by > 0)",
438 varname, filename, dimlen[i]);
439 *dist_cell_areas_global_size *= dimlen[i];
440 }
441
442 // compute start/count
443 // (in 2D case we have to round a little bit and then adjust the
444 // data afterwards)
445 size_t start[2], count[2], offset, read_size;
446 size_t local_start =
447 (size_t)(
448 ((long long)*dist_cell_areas_global_size * (long long)io_rank_idx) /
449 (long long)num_io_ranks);
450 size_t local_count =
451 (size_t)(
452 ((long long)*dist_cell_areas_global_size *
453 (long long)(io_rank_idx+1)) / (long long)num_io_ranks) - local_start;
454 if (ndims == 1) {
455 start[0] = local_start;
456 count[0] = local_count;
457 offset = 0;
458 read_size = local_count;
459 } else {
460 start[0] = local_start / dimlen[1];
461 count[0] =
462 (local_start + local_count + dimlen[1] - 1) / dimlen[1] - start[0];
463 start[1] = 0;
464 count[1] = dimlen[1];
465 offset = local_start - start[0] * dimlen[1];
466 read_size = count[0] * count[1];
467 }
468
469 // read data
470 *dist_cell_areas = xmalloc(read_size * sizeof(**dist_cell_areas));
472 nc_get_vara_double(ncid, varid, start, count, *dist_cell_areas));
473
474 // adjust data if necessary
475 if (ndims == 2)
476 memmove(
477 *dist_cell_areas, *dist_cell_areas + offset,
478 local_count * sizeof(**dist_cell_areas));
479
480 // close file
481 YAC_HANDLE_ERROR(nc_close(ncid));
482
483 } else {
484 *dist_cell_areas = xmalloc(1*sizeof(**dist_cell_areas));
485 *dist_cell_areas_global_size = 0;
486 }
487
489 MPI_Bcast(
490 dist_cell_areas_global_size, 1, YAC_MPI_SIZE_T, io_ranks[0], comm),
491 comm);
492
493#endif // YAC_NETCDF_ENABLED
494}
495
496static void read_cell_areas(
497 struct yac_const_basic_grid_data * basic_grid_data,
498 struct yac_spmap_cell_area_file_config file_config, MPI_Comm comm,
499 int const * required_cell_areas, char const * type,
500 double * cell_areas) {
501
502 char const * routine = "read_cell_areas";
503
504 size_t num_cells = basic_grid_data->count[YAC_LOC_CELL];
505
506 // get io configuration
507 int local_is_io, * io_ranks, num_io_ranks;
508 yac_get_io_ranks(comm, &local_is_io, &io_ranks, &num_io_ranks);
509
510 int comm_rank, comm_size;
511 yac_mpi_call(MPI_Comm_rank(comm, &comm_rank), comm);
512 yac_mpi_call(MPI_Comm_size(comm, &comm_size), comm);
513
514 int io_rank_idx = 0;
515 while ((io_rank_idx < num_io_ranks) &&
516 (comm_rank != io_ranks[io_rank_idx]))
517 ++io_rank_idx;
519 !local_is_io || (io_rank_idx < num_io_ranks),
520 "ERROR(%s): unable to determine io_rank_idx", routine);
521
522 double * dist_cell_areas;
523 size_t dist_cell_areas_global_size;
524
525 // read the data on the io processes
527 file_config.filename, file_config.varname, comm,
528 io_ranks, io_rank_idx, num_io_ranks,
529 &dist_cell_areas, &dist_cell_areas_global_size);
530
531 // count the number of locally required cell areas
532 size_t num_required_cell_areas = 0;
533 for (size_t i = 0; i < num_cells; ++i)
534 if (required_cell_areas[i]) ++num_required_cell_areas;
535
536 size_t * global_idx = xmalloc(num_required_cell_areas * sizeof(*global_idx));
537 size_t * reorder_idx =
538 xmalloc(num_required_cell_areas * sizeof(*reorder_idx));
539
540 size_t * sendcounts, * recvcounts, * sdispls, * rdispls;
542 1, &sendcounts, &recvcounts, &sdispls, &rdispls, comm);
543
544 // determine global indices of locally required cell areas
545 yac_int const * global_cell_ids = basic_grid_data->ids[YAC_LOC_CELL];
546 yac_int min_global_id = file_config.min_global_id;
547 for (size_t i = 0, j = 0; i < num_cells; ++i) {
548 if (required_cell_areas[i]) {
550 global_cell_ids[i] >= min_global_id,
551 "ERROR(%s): %s global id %" YAC_INT_FMT " is smaller than "
552 "the minimum global id provided by the user (%" YAC_INT_FMT ")",
553 routine, type, global_cell_ids[i], min_global_id);
554 size_t idx = (size_t)(global_cell_ids[i] - min_global_id);
556 idx < dist_cell_areas_global_size,
557 "ERROR(%s): %s global id %" YAC_INT_FMT " exceeds "
558 "available size of array \"%s\" in file \"%s\" "
559 "(min_global_id %" YAC_INT_FMT ")", routine, type, global_cell_ids[i],
560 file_config.varname, file_config.filename, file_config.min_global_id);
561 global_idx[j] = idx;
562 reorder_idx[j] = i;
563 int dist_rank_idx =
564 ((long long)idx * (long long)num_io_ranks +
565 (long long)num_io_ranks - 1) / (long long)dist_cell_areas_global_size;
566 sendcounts[io_ranks[dist_rank_idx]]++;
567 ++j;
568 }
569 }
570 free(io_ranks);
571
573 1, sendcounts, recvcounts, sdispls, rdispls, comm);
574
575 // sort required data by their global index
577 global_idx, num_required_cell_areas, reorder_idx);
578
579 // send required points to io processes
580 size_t request_count = recvcounts[comm_size - 1] + rdispls[comm_size - 1];
581 size_t * request_global_idx =
582 xmalloc(request_count * sizeof(*request_global_idx));
584 global_idx, sendcounts, sdispls+1,
585 request_global_idx, recvcounts, rdispls,
586 sizeof(*global_idx), YAC_MPI_SIZE_T, comm, routine, __LINE__);
587 free(global_idx);
588
589 // pack requested cell areas
590 double * requested_cell_areas =
591 xmalloc(request_count * sizeof(*requested_cell_areas));
592 size_t global_idx_offset =
593 ((long long)io_rank_idx * (long long)dist_cell_areas_global_size) /
594 (long long)num_io_ranks;
595 for (size_t i = 0; i < request_count; ++i)
596 requested_cell_areas[i] =
597 dist_cell_areas[request_global_idx[i] - global_idx_offset];
598 free(request_global_idx);
599 free(dist_cell_areas);
600
601 // return cell areas
602 double * temp_cell_areas =
603 xmalloc(num_required_cell_areas * sizeof(*temp_cell_areas));
605 requested_cell_areas, recvcounts, rdispls,
606 temp_cell_areas, sendcounts, sdispls+1,
607 sizeof(*requested_cell_areas), MPI_DOUBLE, comm, routine, __LINE__);
608 free(requested_cell_areas);
609
610 yac_free_comm_buffers(sendcounts, recvcounts, sdispls, rdispls);
611
612 // unpack cell areas
613 for (size_t i = 0; i < num_required_cell_areas; ++i)
614 cell_areas[reorder_idx[i]] = temp_cell_areas[i];
615
616 free(temp_cell_areas);
617 free(reorder_idx);
618}
619
636static double * get_cell_areas(
637 struct yac_const_basic_grid_data * basic_grid_data,
638 char const * type, struct yac_spmap_cell_area_config const * cell_area_config,
639 MPI_Comm comm, size_t const * required_points, size_t num_required_points) {
640
641 size_t num_cells = basic_grid_data->count[YAC_LOC_CELL];
642
643 // determine which cell areas are actually required
644 int * required_cell_areas = xcalloc(num_cells, sizeof(*required_cell_areas));
645 for (size_t i = 0; i < num_required_points; ++i)
646 required_cell_areas[required_points[i]] = 1;
647
648 // compute and scale cell areas
649 double * cell_areas = xmalloc(num_cells * sizeof(*cell_areas));
650
651 switch (cell_area_config->type) {
652
654 "ERROR(get_cell_areas): unsupported %s cell area origin", type);
655
657
658 double area_scale =
659 cell_area_config->yac.sphere_radius *
660 cell_area_config->yac.sphere_radius;
662 basic_grid_data, required_cell_areas, area_scale, type,
663 cell_areas);
664 break;
665 }
667
669 basic_grid_data, cell_area_config->file_config, comm,
670 required_cell_areas, type, cell_areas);
671 }
672 };
673
674 free(required_cell_areas);
675
676 return cell_areas;
677}
678
685static void scale_weights(
686 struct yac_interp_grid * interp_grid,
687 struct yac_spmap_scale_config const * scale_config,
688 size_t num_src_points, size_t const * src_points,
689 size_t const * num_tgt_per_src, size_t const * tgt_points,
690 size_t total_num_weights, double * weights) {
691
692 // if there is no scaling
693 if (scale_config->type == YAC_INTERP_SPMAP_NONE) return;
694
695 // get cell areas if they are required
696 double const * src_cell_areas =
697 ((scale_config->type == YAC_INTERP_SPMAP_SRCAREA) ||
698 (scale_config->type == YAC_INTERP_SPMAP_FRACAREA))?
701 "source", scale_config->src, yac_interp_grid_get_MPI_Comm(interp_grid),
702 src_points, total_num_weights):NULL;
703 double const * tgt_cell_areas =
704 ((scale_config->type == YAC_INTERP_SPMAP_INVTGTAREA) ||
705 (scale_config->type == YAC_INTERP_SPMAP_FRACAREA))?
708 "target", scale_config->tgt, yac_interp_grid_get_MPI_Comm(interp_grid),
709 tgt_points, total_num_weights):NULL;
710
711#define SCALE_WEIGHTS( \
712 SRC_CELL_AREA, TGT_CELL_AREA) \
713{ \
714 for (size_t i = 0, offset = 0; i < num_src_points; ++i) { \
715 size_t curr_num_tgt = num_tgt_per_src[i]; \
716 for (size_t j = 0; j < curr_num_tgt; ++j, ++offset) { \
717 weights[offset] *= SRC_CELL_AREA / TGT_CELL_AREA; \
718 } \
719 } \
720}
721
722 switch (scale_config->type) {
724 "ERROR(scale_weights): invalid scale_type");
726 SCALE_WEIGHTS(src_cell_areas[src_points[offset]], 1.0)
727 break;
729 SCALE_WEIGHTS(1.0, tgt_cell_areas[tgt_points[offset]])
730 break;
733 src_cell_areas[src_points[offset]], tgt_cell_areas[tgt_points[offset]])
734 break;
735 }
736
737 free((void*)src_cell_areas);
738 free((void*)tgt_cell_areas);
739}
740
759static void spread_src_data(
760 struct yac_interp_grid * interp_grid,
761 struct yac_interp_spmap_config const * spmap_config,
762 size_t num_src_points, size_t ** src_points_,
763 size_t ** tgt_result_points_, double ** weights_,
764 size_t * total_num_weights_) {
765
766 // shortcut in case there is only a single "1.0" weight for all source points
767 if ((spmap_config->spread_distance <= 0) &&
768 (spmap_config->scale_config->type == YAC_INTERP_SPMAP_NONE)) {
769
770 *weights_ = xmalloc(num_src_points * sizeof(**weights_));
771 for (size_t i = 0; i < num_src_points; ++i) (*weights_)[i] = 1.0;
772 *total_num_weights_ = num_src_points;
773 return;
774 }
775
776 size_t * src_points = *src_points_;
777 size_t * tgt_result_points = *tgt_result_points_;
778
779 size_t * num_tgt_per_src =
780 xmalloc(num_src_points * sizeof(*num_tgt_per_src));
781 size_t total_num_weights;
782
783 // search for additional target points if spread distance is bigger than 0.0
784 if (spmap_config->spread_distance > 0.0) {
785
786 double sin_spread_distance, cos_spread_distance;
788 spmap_config->spread_distance, &sin_spread_distance, &cos_spread_distance);
789 struct sin_cos_angle spread_distance =
790 sin_cos_angle_new(sin_spread_distance, cos_spread_distance);
791 yac_const_coordinate_pointer tgt_field_coords =
793
794 struct bounding_circle * search_bnd_circles =
795 xmalloc(num_src_points * sizeof(*search_bnd_circles));
796 for (size_t i = 0; i < num_src_points; ++i) {
797 memcpy(
798 search_bnd_circles[i].base_vector,
799 tgt_field_coords[tgt_result_points[i]], sizeof(*tgt_field_coords));
800 search_bnd_circles[i].inc_angle = spread_distance;
801 search_bnd_circles[i].sq_crd = DBL_MAX;
802 }
803 size_t * spread_tgt_result_points = NULL;
804
805 // do bounding circle search around found tgt points
806 // (ensures that all required target points are locally available)
808 interp_grid, search_bnd_circles, num_src_points,
809 &spread_tgt_result_points, num_tgt_per_src);
810 free(search_bnd_circles);
811
812 // remove target points which exceed the spread distance and only keep
813 // targets that are connected to the original target point or other
814 // target that have already been selected
815 total_num_weights =
817 interp_grid, spread_distance, num_src_points,
818 tgt_result_points, num_tgt_per_src, spread_tgt_result_points);
819 free((void*)tgt_result_points);
820 tgt_result_points =
821 xrealloc(
822 spread_tgt_result_points,
823 total_num_weights * sizeof(*spread_tgt_result_points));
824
825 // adjust src_points (one source per target)
826 size_t * new_src_points =
827 xmalloc(total_num_weights * sizeof(*new_src_points));
828 for (size_t i = 0, offset = 0; i < num_src_points; ++i)
829 for (size_t j = 0, curr_src_point = src_points[i];
830 j < num_tgt_per_src[i]; ++j, ++offset)
831 new_src_points[offset] = curr_src_point;
832 free((void*)src_points);
833 src_points = new_src_points;
834
835 } else {
836
837 for (size_t i = 0; i < num_src_points; ++i) num_tgt_per_src[i] = 1;
838 total_num_weights = num_src_points;
839 }
840
841 // compute weights
842 double * weights =
844 interp_grid, spmap_config->weight_type, num_src_points, src_points,
845 num_tgt_per_src, total_num_weights, tgt_result_points);
846
847 // scale weights
849 interp_grid, spmap_config->scale_config, num_src_points, src_points,
850 num_tgt_per_src, tgt_result_points, total_num_weights, weights);
851
852 free(num_tgt_per_src);
853
854 // set return values
855 *tgt_result_points_ = tgt_result_points;
856 *src_points_ = src_points;
857 *weights_ = weights;
858 *total_num_weights_ = total_num_weights;
859}
860
865 struct yac_interp_grid * interp_grid,
866 struct yac_interp_spmap_config const * config,
867 size_t * src_points, size_t num_src_points, yac_coordinate_pointer src_coords,
868 InterpLink ** combined_result, size_t * combined_result_count) {
869
870 // search for matching tgt points
871 size_t * tgt_result_points =
872 xmalloc(num_src_points * sizeof(*tgt_result_points));
874 interp_grid, src_coords, num_src_points, 1, tgt_result_points,
875 (config->max_search_distance == 0.0)?M_PI:config->max_search_distance);
876
877 // remove source points for which matching target point was found
878 {
879 size_t new_num_src_points = 0;
880 for (size_t i = 0; i < num_src_points; ++i) {
881 if (tgt_result_points[i] != SIZE_MAX) {
882 if (i != new_num_src_points) {
883 src_points[new_num_src_points] = src_points[i];
884 tgt_result_points[new_num_src_points] =
885 tgt_result_points[i];
886 }
887 ++new_num_src_points;
888 }
889 }
890 num_src_points = new_num_src_points;
891 }
892
893 // spread the data from each source point to multiple target points
894 double * weight_data;
895 size_t total_num_weights;
897 interp_grid, config, num_src_points, &src_points, &tgt_result_points,
898 &weight_data, &total_num_weights);
899
900 // relocate source-target-point-pairs to dist owners of the respective
901 // target points (these processes have the required target points in their
902 // local list of target points that have to be interpolated)
903 size_t result_count = total_num_weights;
904 int to_tgt_owner = 1;
906 interp_grid, to_tgt_owner,
907 0, &src_points, &tgt_result_points, &weight_data, &result_count);
908 total_num_weights = result_count;
909
910 // add interpolation links (src_point, tgt_point, weight) to combined list of
911 // results
912 *combined_result =
913 xrealloc(
914 *combined_result,
915 (*combined_result_count + result_count) * sizeof(**combined_result));
916
917 struct yac_const_basic_grid_data * src_basic_grid_data =
919 yac_int const * src_global_ids = src_basic_grid_data->ids[YAC_LOC_CELL];
920 InterpLink * temp_result = *combined_result + *combined_result_count;
921 for (size_t i = 0; i < result_count; ++i) {
922 temp_result[i].src_point.local = src_points[i];
923 temp_result[i].src_point.global = src_global_ids[src_points[i]];
924 temp_result[i].tgt_point = tgt_result_points[i];
925 temp_result[i].weight = weight_data[i];
926 }
927 *combined_result_count += result_count;
928
929 free(tgt_result_points);
930 free(weight_data);
931 free(src_points);
932}
933
935 struct yac_point_selection const * src_point_selection,
936 size_t * src_points, size_t num_src_points,
937 yac_coordinate_pointer src_coords,
938 size_t ** selected_src_points, size_t * num_selected_src_points,
939 yac_coordinate_pointer * selected_src_coords) {
940
941 // get all matching source points
943 src_point_selection, src_coords, src_points, num_src_points,
944 num_selected_src_points);
945
946 // get the coordinates and point indices of the selected source points
947 *selected_src_points =
948 xmalloc(*num_selected_src_points * sizeof(**selected_src_points));
949 memcpy(
950 *selected_src_points, src_points + num_src_points - *num_selected_src_points,
951 *num_selected_src_points * sizeof(**selected_src_points));
952 *selected_src_coords = src_coords + num_src_points - *num_selected_src_points;
953}
954
958static int compare_interp_link_tgt_point(void const * a, void const * b) {
959
960 InterpLink const * link_a = (InterpLink const *)a;
961 InterpLink const * link_b = (InterpLink const *)b;
962
963 int ret =
964 (link_a->tgt_point > link_b->tgt_point) -
965 (link_a->tgt_point < link_b->tgt_point);
966 if (ret) return ret;
967
968 ret =
969 (link_a->src_point.global > link_b->src_point.global) -
970 (link_a->src_point.global < link_b->src_point.global);
971 if (ret) return ret;
972
973 return
974 (link_a->weight > link_b->weight) -
975 (link_a->weight < link_b->weight);
976}
977
991static size_t do_search_spmap (struct interp_method * method,
992 struct yac_interp_grid * interp_grid,
993 size_t * tgt_points, size_t tgt_point_count,
994 struct yac_interp_weights * weights,
995 int * interpolation_complete) {
996
997 if (*interpolation_complete) return 0;
998
1000 yac_interp_grid_get_num_src_fields(interp_grid) == 1,
1001 "ERROR(do_search_spmap): invalid number of source fields")
1002 YAC_ASSERT(
1004 "ERROR(do_search_spmap): "
1005 "invalid source field location (has to be YAC_LOC_CELL)")
1006 YAC_ASSERT(
1008 "ERROR(do_search_spmap): "
1009 "invalid target field location (has to be YAC_LOC_CELL)")
1010
1011 // get coordinates of all source points
1012 size_t * src_points;
1013 size_t num_src_points;
1015 interp_grid, 0, &src_points, &num_src_points);
1016 yac_coordinate_pointer src_coords = xmalloc(num_src_points * sizeof(*src_coords));
1018 interp_grid, src_points, num_src_points, 0, src_coords);
1019
1020 struct yac_spmap_overwrite_config const * const * overwrite_configs =
1021 (struct yac_spmap_overwrite_config const * const *)
1022 ((struct interp_method_spmap*)method)->overwrite_configs;
1023
1024 InterpLink * combined_result = NULL;
1025 size_t combined_result_count = 0;
1026
1027 // for all alternative configurations
1028 for (size_t i = 0;
1029 (overwrite_configs != NULL) && (overwrite_configs[i] != NULL); ++i) {
1030
1031 // extract source points matching the current criteria
1032 size_t * selected_src_points;
1033 size_t num_selected_src_points;
1034 yac_coordinate_pointer selected_src_coords;
1036 overwrite_configs[i]->src_point_selection,
1037 src_points, num_src_points, src_coords,
1038 &selected_src_points, &num_selected_src_points, &selected_src_coords);
1039 num_src_points -= num_selected_src_points;
1040
1041 // apply source to target mapping to selected source points
1043 interp_grid, overwrite_configs[i]->config, selected_src_points,
1044 num_selected_src_points, selected_src_coords,
1045 &combined_result, &combined_result_count);
1046 }
1047
1048 // apply default configuration to remaining source points
1050 interp_grid, ((struct interp_method_spmap*)method)->default_config,
1051 src_points, num_src_points, src_coords, &combined_result,
1052 &combined_result_count);
1053 free(src_coords);
1054
1055 // sort source-target-point-pairs by target points
1056 qsort(
1057 combined_result, combined_result_count,
1058 sizeof(*combined_result), compare_interp_link_tgt_point);
1059
1060 // generate num_src_per_tgt and determine list of unique target points
1061 size_t * num_src_per_tgt =
1062 xmalloc(combined_result_count * sizeof(*num_src_per_tgt));
1063 size_t * unique_result_tgt_points =
1064 xmalloc(combined_result_count * sizeof(*unique_result_tgt_points));
1065 size_t num_unique_result_tgt_points = 0;
1066 for (size_t i = 0; i < combined_result_count;) {
1067 size_t prev_i = i;
1068 size_t curr_tgt = combined_result[i].tgt_point;
1069 while (
1070 (i < combined_result_count) &&
1071 (curr_tgt == combined_result[i].tgt_point)) ++i;
1072 num_src_per_tgt[num_unique_result_tgt_points] = i - prev_i;
1073 unique_result_tgt_points[num_unique_result_tgt_points] = curr_tgt;
1074 ++num_unique_result_tgt_points;
1075 }
1076 num_src_per_tgt =
1077 xrealloc(
1078 num_src_per_tgt, num_unique_result_tgt_points * sizeof(*num_src_per_tgt));
1079 unique_result_tgt_points =
1080 xrealloc(
1081 unique_result_tgt_points,
1082 num_unique_result_tgt_points * sizeof(*unique_result_tgt_points));
1083
1084 // match unique_result_tgt_points with target points that are supposed to
1085 // be interpolated
1086 qsort(tgt_points, tgt_point_count, sizeof(*tgt_points), compare_size_t);
1087 int * unused_tgt_point_flag =
1088 xmalloc(tgt_point_count * sizeof(*unused_tgt_point_flag));
1089 {
1090 size_t j = 0;
1091 for (size_t i = 0; i < num_unique_result_tgt_points; ++i) {
1092 size_t curr_result_tgt = unique_result_tgt_points[i];
1093 while ((j < tgt_point_count) && (tgt_points[j] < curr_result_tgt)) {
1094 unused_tgt_point_flag[j++] = 1;
1095 }
1096 YAC_ASSERT(
1097 (j < tgt_point_count) && (curr_result_tgt == tgt_points[j]),
1098 "ERROR(do_search_spmap): "
1099 "required target points already in use or not available")
1100 unused_tgt_point_flag[j++] = 0;
1101 }
1102 for (; j < tgt_point_count; ++j) unused_tgt_point_flag[j] = 1;
1103 }
1104
1105 // sort used target points to the beginning of the array
1107 tgt_points, unused_tgt_point_flag, num_unique_result_tgt_points);
1108 free(unused_tgt_point_flag);
1109
1110 size_t * combined_result_src_points =
1111 xmalloc(combined_result_count * sizeof(*combined_result_src_points));
1112 double * combined_result_weights =
1113 xmalloc(combined_result_count * sizeof(*combined_result_weights));
1114 for (size_t i = 0; i < combined_result_count; ++i) {
1115 combined_result_src_points[i] = combined_result[i].src_point.local;
1116 combined_result_weights[i] = combined_result[i].weight;
1117 }
1118 free(combined_result);
1119
1120 struct remote_point * srcs =
1122 interp_grid, 0, combined_result_src_points, combined_result_count);
1123 struct remote_points tgts = {
1124 .data =
1126 interp_grid, unique_result_tgt_points, num_unique_result_tgt_points),
1127 .count = num_unique_result_tgt_points};
1128 free(unique_result_tgt_points);
1129
1130 // store results
1132 weights, &tgts, num_src_per_tgt, srcs, combined_result_weights);
1133
1134 // cleanup
1135 free(combined_result_src_points);
1136 free(combined_result_weights);
1137 free(tgts.data);
1138 free(srcs);
1139 free(num_src_per_tgt);
1140
1141 return num_unique_result_tgt_points;
1142}
1143
1145 struct yac_spmap_cell_area_config const * cell_area_config,
1146 char const * desc) {
1147
1148 if (cell_area_config == NULL) cell_area_config = &cell_area_config_default;
1149
1150 struct yac_spmap_cell_area_config * copy;
1151
1152 switch (cell_area_config->type) {
1154 "ERROR(yac_spmap_cell_area_config_copy): "
1155 "invalid %s cell area provider type", desc);
1157 copy =
1159 break;
1160 }
1162 copy =
1164 cell_area_config->file_config.filename,
1165 cell_area_config->file_config.varname,
1166 cell_area_config->file_config.min_global_id);
1167 break;
1168 }
1169 }
1170
1171 return copy;
1172}
1173
1175 struct yac_spmap_scale_config const * scale_config) {
1176
1177 if (scale_config == NULL) scale_config = &spmap_scale_config_default;
1178
1179 return
1181 scale_config->type, scale_config->src, scale_config->tgt);
1182}
1183
1185 struct yac_interp_spmap_config const * spmap_config) {
1186
1187 if (spmap_config == NULL) spmap_config = &spmap_config_default;
1188
1189 return
1191 spmap_config->spread_distance, spmap_config->max_search_distance,
1192 spmap_config->weight_type, spmap_config->scale_config);
1193}
1194
1196 struct yac_spmap_overwrite_config const * overwrite_config) {
1197
1198 if (overwrite_config == NULL) overwrite_config = &overwrite_config_default;
1199
1200 struct yac_spmap_overwrite_config * copy = xmalloc(1 * sizeof(*copy));
1201
1202 copy->src_point_selection =
1204 copy->config = yac_interp_spmap_config_copy(overwrite_config->config);
1205
1206 return copy;
1207}
1208
1210 struct yac_spmap_overwrite_config const * const * overwrite_configs) {
1211
1212 size_t overwrite_config_count = 0;
1213
1214 for (;(overwrite_configs != NULL) &&
1215 (overwrite_configs[overwrite_config_count] != NULL);
1216 ++overwrite_config_count);
1217
1218 struct yac_spmap_overwrite_config ** copy =
1219 (overwrite_config_count > 0)?
1220 xcalloc(overwrite_config_count + 1, sizeof(*copy)):NULL;
1221
1222 for (size_t i = 0; i < overwrite_config_count; ++i)
1223 copy[i] = yac_spmap_overwrite_config_copy(overwrite_configs[i]);
1224
1225 return copy;
1226}
1227
1229 struct yac_interp_spmap_config const * default_config,
1230 struct yac_spmap_overwrite_config const * const * overwrite_configs) {
1231
1232 struct interp_method_spmap * method = xmalloc(1 * sizeof(*method));
1233
1236 method->overwrite_configs =
1238
1239 return (struct interp_method*)method;
1240}
1241
1243 double sphere_radius) {
1244
1246 sphere_radius > 0.0,
1247 "ERROR(yac_spmap_cell_area_config_yac_new): "
1248 "invalid sphere_radius %lf (has to be >= 0.0)", sphere_radius);
1249
1250 struct yac_spmap_cell_area_config * cell_area_config =
1251 xmalloc(1 * sizeof(*cell_area_config));
1252
1253 cell_area_config->type = YAC_INTERP_SPMAP_CELL_AREA_YAC;
1254 cell_area_config->yac.sphere_radius = sphere_radius;
1255
1256 return cell_area_config;
1257}
1258
1260 char const * filename, char const * varname, yac_int min_global_id) {
1261
1262 YAC_ASSERT(
1263 (filename != NULL) && (strlen(filename) > 0),
1264 "ERROR(yac_spmap_cell_area_config_file_new): invalid filename for areas");
1265 YAC_ASSERT(
1266 (varname != NULL) && (strlen(varname) > 0),
1267 "ERROR(yac_spmap_cell_area_config_file_new): invalid varname for areas");
1268
1269 struct yac_spmap_cell_area_config * cell_area_config =
1270 xmalloc(1 * sizeof(*cell_area_config));
1271
1272 cell_area_config->type = YAC_INTERP_SPMAP_CELL_AREA_FILE;
1273 cell_area_config->file_config.filename = strdup(filename);
1274 cell_area_config->file_config.varname = strdup(varname);
1275 cell_area_config->file_config.min_global_id = min_global_id;
1276
1277 return cell_area_config;
1278}
1279
1281 char const * filename, char const * varname, int min_global_id) {
1282
1284 (min_global_id >= YAC_INT_MIN) && (min_global_id <= YAC_INT_MAX),
1285 "ERROR(yac_spmap_cell_area_config_file_new_f2c): "
1286 "min_global_id %d is outside of the valid range "
1287 "(%" YAC_INT_FMT " <= min_global_id <= %" YAC_INT_FMT ")",
1288 min_global_id, YAC_INT_MIN, YAC_INT_MAX);
1289
1290 return
1293}
1294
1296 struct yac_spmap_cell_area_config * cell_area_config) {
1297
1298 if ((cell_area_config != &cell_area_config_default) &&
1299 (cell_area_config != NULL)) {
1300
1301 switch(cell_area_config->type) {
1303 "ERROR(yac_spmap_cell_area_config_delete): "
1304 "invalid cell area configuration type");
1306 // nothing to be done
1307 break;
1309 free((void*)cell_area_config->file_config.filename);
1310 free((void*)cell_area_config->file_config.varname);
1311 break;
1312 }
1313 }
1314 free(cell_area_config);
1315 }
1316}
1317
1319 struct yac_spmap_cell_area_config const * cell_area_config) {
1320
1321 if (cell_area_config == NULL) cell_area_config = &cell_area_config_default;
1322
1323 return cell_area_config->type;
1324}
1325
1327 struct yac_spmap_cell_area_config const * cell_area_config) {
1328
1329 if (cell_area_config == NULL) cell_area_config = &cell_area_config_default;
1330
1332 cell_area_config->type == YAC_INTERP_SPMAP_CELL_AREA_YAC,
1333 "ERROR(yac_spmap_cell_area_config_get_sphere_radius): "
1334 "invalid cell area configuration type %d "
1335 "(has to be YAC_INTERP_SPMAP_CELL_AREA_YAC)", (int)cell_area_config->type);
1336
1337 return cell_area_config->yac.sphere_radius;
1338}
1339
1341 struct yac_spmap_cell_area_config const * cell_area_config) {
1342
1343 if (cell_area_config == NULL) cell_area_config = &cell_area_config_default;
1344
1346 cell_area_config->type == YAC_INTERP_SPMAP_CELL_AREA_FILE,
1347 "ERROR(yac_spmap_cell_area_config_get_filename): "
1348 "invalid cell area configuration type %d "
1349 "(has to be YAC_INTERP_SPMAP_CELL_AREA_FILE)", (int)cell_area_config->type);
1350
1351 return cell_area_config->file_config.filename;
1352}
1353
1355 struct yac_spmap_cell_area_config const * cell_area_config) {
1356
1357 if (cell_area_config == NULL) cell_area_config = &cell_area_config_default;
1358
1360 cell_area_config->type == YAC_INTERP_SPMAP_CELL_AREA_FILE,
1361 "ERROR(yac_spmap_cell_area_config_get_varname): "
1362 "invalid cell area configuration type %d "
1363 "(has to be YAC_INTERP_SPMAP_CELL_AREA_FILE)", (int)cell_area_config->type);
1364
1365 return cell_area_config->file_config.varname;
1366}
1367
1369 struct yac_spmap_cell_area_config const * cell_area_config) {
1370
1371 if (cell_area_config == NULL) cell_area_config = &cell_area_config_default;
1372
1374 cell_area_config->type == YAC_INTERP_SPMAP_CELL_AREA_FILE,
1375 "ERROR(yac_spmap_cell_area_config_get_min_global_id): "
1376 "invalid cell area configuration type %d "
1377 "(has to be YAC_INTERP_SPMAP_CELL_AREA_FILE)", (int)cell_area_config->type);
1378
1379 return cell_area_config->file_config.min_global_id;
1380}
1381
1383 enum yac_interp_spmap_scale_type scale_type,
1384 struct yac_spmap_cell_area_config const * source_cell_area_config,
1385 struct yac_spmap_cell_area_config const * target_cell_area_config) {
1386
1387 struct yac_spmap_scale_config * scale_config =
1388 xmalloc(1 * sizeof(*scale_config));
1389
1391 (scale_type == YAC_INTERP_SPMAP_NONE) ||
1392 (scale_type == YAC_INTERP_SPMAP_SRCAREA) ||
1393 (scale_type == YAC_INTERP_SPMAP_INVTGTAREA) ||
1394 (scale_type == YAC_INTERP_SPMAP_FRACAREA),
1395 "ERROR(yac_spmap_scale_config_new): "
1396 "invalid scale configuration type (%d)", (int)scale_type);
1397
1398 scale_config->type = scale_type;
1399 scale_config->src =
1400 yac_spmap_cell_area_config_copy(source_cell_area_config, "source");
1401 scale_config->tgt =
1402 yac_spmap_cell_area_config_copy(target_cell_area_config, "target");
1403
1404 return scale_config;
1405}
1406
1408 int scale_type,
1409 struct yac_spmap_cell_area_config * source_cell_area_config,
1410 struct yac_spmap_cell_area_config * target_cell_area_config) {
1411
1413 (scale_type == YAC_INTERP_SPMAP_NONE) ||
1414 (scale_type == YAC_INTERP_SPMAP_SRCAREA) ||
1415 (scale_type == YAC_INTERP_SPMAP_INVTGTAREA) ||
1416 (scale_type == YAC_INTERP_SPMAP_FRACAREA),
1417 "ERROR(yac_spmap_scale_config_new_f2c): "
1418 "invalid scale configuration type (%d)", scale_type);
1419
1420 return
1422 (enum yac_interp_spmap_scale_type)scale_type,
1423 source_cell_area_config, target_cell_area_config);
1424}
1425
1427 struct yac_spmap_scale_config * scale_config) {
1428
1429 if ((scale_config != &spmap_scale_config_default) &&
1430 (scale_config != NULL)) {
1433 free(scale_config);
1434 }
1435}
1436
1438 struct yac_spmap_scale_config const * scale_config) {
1439
1440 if (scale_config == NULL) scale_config = &spmap_scale_config_default;
1441
1442 return scale_config->type;
1443}
1444
1445struct yac_spmap_cell_area_config const *
1447 struct yac_spmap_scale_config const * scale_config) {
1448
1449 if (scale_config == NULL) scale_config = &spmap_scale_config_default;
1450
1451 return scale_config->src;
1452}
1453
1454struct yac_spmap_cell_area_config const *
1456 struct yac_spmap_scale_config const * scale_config) {
1457
1458 if (scale_config == NULL) scale_config = &spmap_scale_config_default;
1459
1460 return scale_config->tgt;
1461}
1462
1464 double spread_distance, double max_search_distance,
1466 struct yac_spmap_scale_config const * scale_config) {
1467
1468 struct yac_interp_spmap_config * spmap_config =
1469 xmalloc(1 * sizeof(*spmap_config));
1470
1472 (spread_distance >= 0.0) && (spread_distance <= M_PI_2),
1473 "ERROR(yac_interp_spmap_config_new): invalid spread_distance "
1474 "(has to be >= 0 and <= PI/2 (%lf)", spread_distance);
1475
1477 (max_search_distance >= 0.0) && (max_search_distance <= M_PI),
1478 "ERROR(yac_interp_spmap_config_new): invalid max_search_distance "
1479 "(has to be >= 0 and <= PI (%lf)", max_search_distance);
1480
1484 "ERROR(yac_interp_spmap_config_new): invalid weight type (%d)",
1485 (int)weight_type);
1486
1487 spmap_config->spread_distance = spread_distance;
1489 spmap_config->weight_type = weight_type;
1491
1492 return spmap_config;
1493}
1494
1496 double spread_distance, double max_search_distance,
1498
1502 "ERROR(yac_interp_spmap_config_new_f2c): invalid weight type (%d)",
1503 weight_type);
1504
1505 return
1509}
1510
1512 struct yac_interp_spmap_config * config) {
1513
1514 if ((config != &spmap_config_default) && (config != NULL)) {
1516 free(config);
1517 }
1518}
1519
1521 struct yac_interp_spmap_config const * spmap_config) {
1522
1523 if (spmap_config == NULL) spmap_config = &spmap_config_default;
1524
1525 return spmap_config->spread_distance;
1526}
1527
1529 struct yac_interp_spmap_config const * spmap_config) {
1530
1531 if (spmap_config == NULL) spmap_config = &spmap_config_default;
1532
1533 return spmap_config->max_search_distance;
1534}
1535
1537 struct yac_interp_spmap_config const * spmap_config) {
1538
1539 if (spmap_config == NULL) spmap_config = &spmap_config_default;
1540
1541 return spmap_config->weight_type;
1542}
1543
1545 struct yac_interp_spmap_config const * spmap_config) {
1546
1547 if (spmap_config == NULL) spmap_config = &spmap_config_default;
1548
1549 return spmap_config->scale_config;
1550}
1551
1554 struct yac_interp_spmap_config const * config) {
1555
1556 struct yac_spmap_overwrite_config * overwrite_config =
1557 xmalloc(1 * sizeof(*overwrite_config));
1558
1559 overwrite_config->src_point_selection =
1561 overwrite_config->config = yac_interp_spmap_config_copy(config);
1562
1563 return overwrite_config;
1564}
1565
1567 struct yac_spmap_overwrite_config * overwrite_config) {
1568
1569 if ((overwrite_config != &overwrite_config_default) &&
1570 (overwrite_config != NULL)) {
1572 yac_interp_spmap_config_delete(overwrite_config->config);
1573 free(overwrite_config);
1574 }
1575}
1576
1578 struct yac_spmap_overwrite_config ** overwrite_configs) {
1579
1580 for (size_t i = 0;
1581 (overwrite_configs != NULL) && (overwrite_configs[i] != NULL); ++i)
1582 yac_spmap_overwrite_config_delete(overwrite_configs[i]);
1583 free(overwrite_configs);
1584}
1585
1586struct yac_point_selection const *
1588 struct yac_spmap_overwrite_config const * overwrite_config) {
1589
1590 if (overwrite_config == NULL) overwrite_config = &overwrite_config_default;
1591
1592 return overwrite_config->src_point_selection;
1593}
1594
1595struct yac_interp_spmap_config const *
1597 struct yac_spmap_overwrite_config const * overwrite_config) {
1598
1599 if (overwrite_config == NULL) overwrite_config = &overwrite_config_default;
1600
1601 return overwrite_config->config;
1602}
1603
1604static void delete_spmap(struct interp_method * method) {
1605
1606 struct interp_method_spmap * method_spmap =
1607 (struct interp_method_spmap*)(method);
1608
1611
1612 free(method);
1613}
1614
1616 struct yac_spmap_cell_area_config const * a,
1617 struct yac_spmap_cell_area_config const * b) {
1618
1619 int ret;
1620 if ((ret = ((int)(a->type) > (int)(b->type)) -
1621 ((int)(a->type) < (int)(b->type))))
1622 return ret;
1623
1624 switch (a->type) {
1625 default:
1627 return
1628 ((int)(a->yac.sphere_radius) > (int)(b->yac.sphere_radius)) -
1629 ((int)(a->yac.sphere_radius) < (int)(b->yac.sphere_radius));
1630 }
1632 if ((ret = strcmp(a->file_config.filename, b->file_config.filename)))
1633 return ret;
1634 if ((ret = strcmp(a->file_config.varname, b->file_config.varname)))
1635 return ret;
1636 return
1637 ((int)(a->file_config.min_global_id) >
1638 (int)(b->file_config.min_global_id)) -
1639 ((int)(a->file_config.min_global_id) <
1640 (int)(b->file_config.min_global_id));
1641 }
1642 }
1643}
1644
1646 struct yac_spmap_scale_config const * a,
1647 struct yac_spmap_scale_config const * b) {
1648
1649 int ret;
1650 if ((ret = ((int)(a->type) > (int)(b->type)) -
1651 ((int)(a->type) < (int)(b->type))))
1652 return ret;
1653 if ((ret = yac_spmap_cell_area_config_compare(a->src, b->src))) return ret;
1654 if ((ret = yac_spmap_cell_area_config_compare(a->tgt, b->tgt))) return ret;
1655 return 0;
1656}
1657
1659 struct yac_interp_spmap_config const * a,
1660 struct yac_interp_spmap_config const * b) {
1661 if (fabs(a->spread_distance - b->spread_distance) > yac_angle_tol)
1662 return (a->spread_distance > b->spread_distance) -
1665 return (a->max_search_distance > b->max_search_distance) -
1667 if (a->weight_type != b->weight_type)
1668 return
1669 (a->weight_type > b->weight_type) - (a->weight_type < b->weight_type);
1671}
1672
1674 struct yac_spmap_overwrite_config const * a,
1675 struct yac_spmap_overwrite_config const * b) {
1676
1677 int ret =
1679 if (ret) return ret;
1680
1682}
1683
1685 struct yac_spmap_cell_area_config const * cell_area_config, MPI_Comm comm) {
1686
1687 int int_pack_size, dbl_pack_size;
1688 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &int_pack_size), comm);
1689 yac_mpi_call(MPI_Pack_size(1, MPI_DOUBLE, comm, &dbl_pack_size), comm);
1690
1691 size_t pack_size = (size_t)int_pack_size; // cell_area_provider
1692
1693 if (cell_area_config == NULL) cell_area_config = &cell_area_config_default;
1694
1695 switch (cell_area_config->type) {
1697 "ERROR(yac_spmap_cell_area_config_get_pack_size): "
1698 "invalid cell area provider type");
1700 pack_size += (size_t)dbl_pack_size; // sphere_radius
1701 break;
1702 }
1704 pack_size +=
1706 "yac_spmap_cell_area_config_get_pack_size",
1707 cell_area_config->file_config.filename, comm, 0) + // filename
1709 "yac_spmap_cell_area_config_get_pack_size",
1710 cell_area_config->file_config.varname, comm, 0) + // varname
1711 int_pack_size; // min_global_id
1712 break;
1713 }
1714 }
1715
1716 return pack_size;
1717}
1718
1720 struct yac_spmap_scale_config const * scale_config, MPI_Comm comm) {
1721
1722 int int_pack_size;
1723 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &int_pack_size), comm);
1724
1725 return (size_t)int_pack_size + // type
1726 yac_spmap_cell_area_config_get_pack_size(scale_config->src, comm) +
1727 yac_spmap_cell_area_config_get_pack_size(scale_config->tgt, comm);
1728}
1729
1731 struct yac_interp_spmap_config const * spmap_config, MPI_Comm comm) {
1732
1733 int int_pack_size, dbl_pack_size;
1734 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &int_pack_size), comm);
1735 yac_mpi_call(MPI_Pack_size(1, MPI_DOUBLE, comm, &dbl_pack_size), comm);
1736
1737 return (size_t)dbl_pack_size + // spread_distance
1738 (size_t)dbl_pack_size + // max_search_distance
1739 (size_t)int_pack_size + // weight_type
1741}
1742
1744 struct yac_spmap_overwrite_config const * overwrite_config, MPI_Comm comm) {
1745
1746 return
1748 overwrite_config->src_point_selection, comm) +
1750 overwrite_config->config, comm);
1751}
1752
1754 struct yac_spmap_overwrite_config const * const * overwrite_configs,
1755 MPI_Comm comm) {
1756
1757 size_t over_write_configs_pack_size = 0;
1758 for (size_t i = 0;
1759 (overwrite_configs != NULL) && (overwrite_configs[i] != NULL); ++i)
1760 over_write_configs_pack_size +=
1762
1763 int size_t_pack_size;
1765 MPI_Pack_size(1, YAC_MPI_SIZE_T, comm, &size_t_pack_size), comm);
1766
1767 return over_write_configs_pack_size +
1768 size_t_pack_size; // overwrite_config_count
1769}
1770
1772 struct yac_spmap_cell_area_config const * cell_area_config,
1773 void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1774
1775 if (cell_area_config == NULL) cell_area_config = &cell_area_config_default;
1776
1777 int type = (int)(cell_area_config->type);
1779 MPI_Pack(&type, 1, MPI_INT, buffer, buffer_size, position, comm), comm);
1780
1781 switch (cell_area_config->type) {
1783 "ERROR(yac_spmap_cell_area_config_pack): "
1784 "invalid cell area provider type");
1787 MPI_Pack(
1788 &(cell_area_config->yac.sphere_radius), 1, MPI_DOUBLE,
1789 buffer, buffer_size, position, comm), comm);
1790 break;
1791 }
1794 "yac_spmap_cell_area_config_pack",
1795 cell_area_config->file_config.filename,
1796 buffer, buffer_size, position, comm, 1);
1798 "yac_spmap_cell_area_config_pack",
1799 cell_area_config->file_config.varname,
1800 buffer, buffer_size, position, comm, 1);
1801 YAC_ASSERT(
1802 (cell_area_config->file_config.min_global_id >= -INT_MAX) &&
1803 (cell_area_config->file_config.min_global_id <= INT_MAX),
1804 "ERRROR(yac_spmap_cell_area_config_pack): invalid minimum global id");
1805 int min_global_id = (int)(cell_area_config->file_config.min_global_id);
1807 MPI_Pack(
1808 &min_global_id, 1, MPI_INT, buffer, buffer_size, position, comm),
1809 comm);
1810 break;
1811 }
1812 }
1813}
1814
1816 struct yac_spmap_scale_config const * scale_config,
1817 void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1818
1819 int scale_type = (int)(scale_config->type);
1821 MPI_Pack(
1822 &scale_type, 1, MPI_INT, buffer, buffer_size, position, comm),
1823 comm);
1825 scale_config->src, buffer, buffer_size, position, comm);
1827 scale_config->tgt, buffer, buffer_size, position, comm);
1828}
1829
1831 struct yac_interp_spmap_config const * spmap_config,
1832 void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1833
1835 MPI_Pack(
1836 &(spmap_config->spread_distance), 1, MPI_DOUBLE,
1837 buffer, buffer_size, position, comm), comm);
1839 MPI_Pack(
1840 &(spmap_config->max_search_distance), 1, MPI_DOUBLE,
1841 buffer, buffer_size, position, comm), comm);
1842 int weight_type = (int)(spmap_config->weight_type);
1844 MPI_Pack(
1845 &weight_type, 1, MPI_INT, buffer, buffer_size, position, comm),
1846 comm);
1848 spmap_config->scale_config, buffer, buffer_size, position, comm);
1849}
1850
1852 struct yac_spmap_overwrite_config const * overwrite_config,
1853 void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1854
1856 overwrite_config->src_point_selection,
1857 buffer, buffer_size, position, comm);
1858
1860 overwrite_config->config, buffer, buffer_size, position, comm);
1861}
1862
1864 struct yac_spmap_overwrite_config const * const * overwrite_configs,
1865 void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1866
1867 size_t overwrite_config_count = 0;
1868 for (; (overwrite_configs != NULL) &&
1869 (overwrite_configs[overwrite_config_count] != NULL);
1870 ++overwrite_config_count);
1871
1873 MPI_Pack(
1874 &overwrite_config_count, 1, YAC_MPI_SIZE_T, buffer, buffer_size,
1875 position, comm), comm);
1876
1877 for (size_t i = 0; i < overwrite_config_count; ++i)
1879 overwrite_configs[i], buffer, buffer_size, position, comm);
1880}
1881
1883 void * buffer, int buffer_size, int * position,
1884 struct yac_spmap_cell_area_config ** cell_area_config, MPI_Comm comm) {
1885
1886 *cell_area_config = xmalloc(1 * sizeof(**cell_area_config));
1887
1888 int cell_area_provider;
1890 MPI_Unpack(
1891 buffer, buffer_size, position, &cell_area_provider, 1, MPI_INT, comm),
1892 comm);
1893 (*cell_area_config)->type =
1894 (enum yac_interp_spmap_cell_area_provider)cell_area_provider;
1895
1896 switch ((*cell_area_config)->type) {
1898 "ERROR(yac_spmap_cell_area_config_unpack): "
1899 "invalid cell area provider type");
1902 MPI_Unpack(
1903 buffer, buffer_size, position,
1904 &((*cell_area_config)->yac.sphere_radius), 1, MPI_DOUBLE, comm),
1905 comm);
1906 break;
1907 }
1909 (*cell_area_config)->file_config.filename =
1910 yac_string_unpack(buffer, buffer_size, position, comm);
1911 (*cell_area_config)->file_config.varname =
1912 yac_string_unpack(buffer, buffer_size, position, comm);
1913 int min_global_id;
1915 MPI_Unpack(
1916 buffer, buffer_size, position, &min_global_id, 1, MPI_INT, comm),
1917 comm);
1918 (*cell_area_config)->file_config.min_global_id = (size_t)min_global_id;
1919 }
1920 }
1921}
1922
1924 void * buffer, int buffer_size, int * position,
1925 struct yac_spmap_scale_config ** scale_config, MPI_Comm comm) {
1926
1927 *scale_config = xmalloc(1 * sizeof(**scale_config));
1928 int scale_type;
1930 MPI_Unpack(
1931 buffer, buffer_size, position, &scale_type, 1, MPI_INT, comm),
1932 comm);
1933 (*scale_config)->type =
1934 (enum yac_interp_spmap_scale_type)scale_type;
1936 buffer, buffer_size, position, &((*scale_config)->src), comm);
1938 buffer, buffer_size, position, &((*scale_config)->tgt), comm);
1939}
1940
1942 void * buffer, int buffer_size, int * position,
1943 struct yac_interp_spmap_config ** spmap_config, MPI_Comm comm) {
1944
1945 *spmap_config = xmalloc(1 * sizeof(**spmap_config));
1947 MPI_Unpack(
1948 buffer, buffer_size, position,
1949 &((*spmap_config)->spread_distance), 1, MPI_DOUBLE, comm), comm);
1951 MPI_Unpack(
1952 buffer, buffer_size, position,
1953 &((*spmap_config)->max_search_distance), 1, MPI_DOUBLE, comm), comm);
1954 int weight_type;
1956 MPI_Unpack(
1957 buffer, buffer_size, position, &weight_type, 1, MPI_INT, comm),
1958 comm);
1959 (*spmap_config)->weight_type =
1962 buffer, buffer_size, position, &((*spmap_config)->scale_config), comm);
1963}
1964
1966 void * buffer, int buffer_size, int * position, MPI_Comm comm) {
1967
1968 struct yac_spmap_overwrite_config * overwrite_config =
1969 xmalloc(1 * sizeof(*overwrite_config));
1970
1971 overwrite_config->src_point_selection =
1972 yac_point_selection_unpack(buffer, buffer_size, position, comm);
1974 buffer, buffer_size, position, &(overwrite_config->config), comm);
1975
1976 return overwrite_config;
1977}
1978
1980 void * buffer, int buffer_size, int * position,
1981 struct yac_spmap_overwrite_config *** overwrite_configs, MPI_Comm comm) {
1982
1983 size_t overwrite_config_count;
1985 MPI_Unpack(
1986 buffer, buffer_size, position, &overwrite_config_count, 1,
1987 YAC_MPI_SIZE_T, comm), comm);
1988
1989 *overwrite_configs =
1990 (overwrite_config_count > 0)?
1991 xcalloc(overwrite_config_count + 1, sizeof(**overwrite_configs)):NULL;
1992
1993 for (size_t i = 0; i < overwrite_config_count; ++i)
1994 (*overwrite_configs)[i] =
1995 yac_spmap_overwrite_config_unpack(buffer, buffer_size, position, comm);
1996}
#define YAC_ASSERT(exp, msg)
double yac_huiliers_area(struct yac_grid_cell cell)
Area calculation on a unit sphere taken from ESMF based on L'Huilier's Theorem.
Definition area.c:447
Structs and interfaces for area calculations.
#define YAC_AREA_TOL
Definition area.h:18
#define UNUSED(x)
Definition core.h:72
void yac_const_basic_grid_data_get_grid_cell(struct yac_const_basic_grid_data *grid_data, size_t cell_idx, struct yac_grid_cell *buffer_cell)
Definition dist_grid.c:2356
static struct sin_cos_angle get_vector_angle_2(double const a[3], double const b[3])
Definition geometry.h:361
static void compute_sin_cos(double angle, double *sin_value, double *cos_value)
Definition geometry.h:220
static int compare_angles(struct sin_cos_angle a, struct sin_cos_angle b)
Definition geometry.h:374
#define yac_angle_tol
Definition geometry.h:26
static double get_vector_angle(double const a[3], double const b[3])
Definition geometry.h:340
static struct sin_cos_angle sin_cos_angle_new(double sin, double cos)
Definition geometry.h:351
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)
yac_size_t_2_pointer yac_interp_grid_generate_tgt_edge_to_cell(struct yac_interp_grid *interp_grid)
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)
MPI_Comm yac_interp_grid_get_MPI_Comm(struct yac_interp_grid *interp_grid)
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:86
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)
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, double max_search_distance)
struct yac_const_basic_grid_data * yac_interp_grid_get_basic_grid_data_src(struct yac_interp_grid *interp_grid)
enum callback_type type
char const * yac_spmap_cell_area_config_get_filename(struct yac_spmap_cell_area_config const *cell_area_config)
size_t yac_spmap_overwrite_configs_get_pack_size(struct yac_spmap_overwrite_config const *const *overwrite_configs, MPI_Comm comm)
static int compare_interp_link_tgt_point(void const *a, void const *b)
struct yac_spmap_cell_area_config const * yac_spmap_scale_config_get_tgt_cell_area_config(struct yac_spmap_scale_config const *scale_config)
static void compute_cell_areas(struct yac_const_basic_grid_data *basic_grid_data, int const *required_cell_areas, double area_scale, char const *type, double *cell_areas)
static void delete_spmap(struct interp_method *method)
static struct yac_spmap_overwrite_config * yac_spmap_overwrite_config_unpack(void *buffer, int buffer_size, int *position, MPI_Comm comm)
void yac_interp_spmap_config_unpack(void *buffer, int buffer_size, int *position, struct yac_interp_spmap_config **spmap_config, MPI_Comm comm)
struct yac_interp_spmap_config const * yac_spmap_overwrite_config_get_spmap_config(struct yac_spmap_overwrite_config const *overwrite_config)
static size_t check_tgt_result_points(struct yac_interp_grid *interp_grid, struct sin_cos_angle 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)
double yac_spmap_cell_area_config_get_sphere_radius(struct yac_spmap_cell_area_config const *cell_area_config)
struct yac_interp_spmap_config * yac_interp_spmap_config_new_f2c(double spread_distance, double max_search_distance, int weight_type, struct yac_spmap_scale_config *scale_config)
static int compare_size_t(const void *a, const void *b)
struct yac_spmap_overwrite_config * yac_spmap_overwrite_config_copy(struct yac_spmap_overwrite_config const *overwrite_config)
struct yac_spmap_scale_config * yac_spmap_scale_config_new_f2c(int scale_type, struct yac_spmap_cell_area_config *source_cell_area_config, struct yac_spmap_cell_area_config *target_cell_area_config)
static void src_point_selection_apply(struct yac_point_selection const *src_point_selection, size_t *src_points, size_t num_src_points, yac_coordinate_pointer src_coords, size_t **selected_src_points, size_t *num_selected_src_points, yac_coordinate_pointer *selected_src_coords)
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, int *interpolation_complete)
basic routine for the computation of the interpolation weights
static struct interp_method_vtable interp_method_spmap_vtable
static void yac_spmap_overwrite_config_pack(struct yac_spmap_overwrite_config const *overwrite_config, void *buffer, int buffer_size, int *position, MPI_Comm comm)
struct yac_spmap_cell_area_config * yac_spmap_cell_area_config_file_new(char const *filename, char const *varname, yac_int min_global_id)
size_t yac_spmap_scale_config_get_pack_size(struct yac_spmap_scale_config const *scale_config, MPI_Comm comm)
void yac_spmap_scale_config_unpack(void *buffer, int buffer_size, int *position, struct yac_spmap_scale_config **scale_config, MPI_Comm comm)
struct yac_spmap_overwrite_config * yac_spmap_overwrite_config_new(struct yac_point_selection const *src_point_selection, struct yac_interp_spmap_config const *config)
static void spread_src_data(struct yac_interp_grid *interp_grid, struct yac_interp_spmap_config const *spmap_config, size_t num_src_points, size_t **src_points_, size_t **tgt_result_points_, double **weights_, size_t *total_num_weights_)
static void read_cell_areas(struct yac_const_basic_grid_data *basic_grid_data, struct yac_spmap_cell_area_file_config file_config, MPI_Comm comm, int const *required_cell_areas, char const *type, double *cell_areas)
void yac_spmap_overwrite_configs_delete(struct yac_spmap_overwrite_config **overwrite_configs)
struct yac_point_selection const * yac_spmap_overwrite_config_get_src_point_selection(struct yac_spmap_overwrite_config const *overwrite_config)
int yac_interp_spmap_config_compare(struct yac_interp_spmap_config const *a, struct yac_interp_spmap_config const *b)
static void yac_spmap_cell_area_config_pack(struct yac_spmap_cell_area_config const *cell_area_config, void *buffer, int buffer_size, int *position, MPI_Comm comm)
yac_int yac_spmap_cell_area_config_get_min_global_id(struct yac_spmap_cell_area_config const *cell_area_config)
void yac_spmap_overwrite_configs_unpack(void *buffer, int buffer_size, int *position, struct yac_spmap_overwrite_config ***overwrite_configs, MPI_Comm comm)
enum yac_interp_spmap_cell_area_provider yac_spmap_cell_area_config_get_type(struct yac_spmap_cell_area_config const *cell_area_config)
void yac_spmap_scale_config_pack(struct yac_spmap_scale_config const *scale_config, void *buffer, int buffer_size, int *position, MPI_Comm comm)
int yac_spmap_overwrite_config_compare(struct yac_spmap_overwrite_config const *a, struct yac_spmap_overwrite_config const *b)
void yac_spmap_overwrite_configs_pack(struct yac_spmap_overwrite_config const *const *overwrite_configs, void *buffer, int buffer_size, int *position, MPI_Comm comm)
double yac_interp_spmap_config_get_max_search_distance(struct yac_interp_spmap_config const *spmap_config)
struct yac_spmap_cell_area_config const * yac_spmap_scale_config_get_src_cell_area_config(struct yac_spmap_scale_config const *scale_config)
char const * yac_spmap_cell_area_config_get_varname(struct yac_spmap_cell_area_config const *cell_area_config)
void yac_interp_spmap_config_pack(struct yac_interp_spmap_config const *spmap_config, void *buffer, int buffer_size, int *position, MPI_Comm comm)
static void yac_spmap_cell_area_config_unpack(void *buffer, int buffer_size, int *position, struct yac_spmap_cell_area_config **cell_area_config, MPI_Comm comm)
struct interp_method * yac_interp_method_spmap_new(struct yac_interp_spmap_config const *default_config, struct yac_spmap_overwrite_config const *const *overwrite_configs)
static struct yac_spmap_cell_area_config * yac_spmap_cell_area_config_copy(struct yac_spmap_cell_area_config const *cell_area_config, char const *desc)
size_t yac_spmap_overwrite_config_get_pack_size(struct yac_spmap_overwrite_config const *overwrite_config, MPI_Comm comm)
static double * get_cell_areas(struct yac_const_basic_grid_data *basic_grid_data, char const *type, struct yac_spmap_cell_area_config const *cell_area_config, MPI_Comm comm, size_t const *required_points, size_t num_required_points)
struct yac_interp_spmap_config * yac_interp_spmap_config_new(double spread_distance, double max_search_distance, enum yac_interp_spmap_weight_type weight_type, struct yac_spmap_scale_config const *scale_config)
void yac_spmap_scale_config_delete(struct yac_spmap_scale_config *scale_config)
void yac_interp_spmap_config_delete(struct yac_interp_spmap_config *config)
struct yac_spmap_scale_config const * yac_interp_spmap_config_get_scale_config(struct yac_interp_spmap_config const *spmap_config)
size_t yac_interp_spmap_config_get_pack_size(struct yac_interp_spmap_config const *spmap_config, MPI_Comm comm)
static struct yac_spmap_scale_config * yac_spmap_scale_config_copy(struct yac_spmap_scale_config const *scale_config)
struct yac_interp_spmap_config * yac_interp_spmap_config_copy(struct yac_interp_spmap_config const *spmap_config)
static void scale_weights(struct yac_interp_grid *interp_grid, struct yac_spmap_scale_config const *scale_config, size_t num_src_points, size_t const *src_points, size_t const *num_tgt_per_src, size_t const *tgt_points, size_t total_num_weights, double *weights)
#define SCALE_WEIGHTS(SRC_CELL_AREA, TGT_CELL_AREA)
struct yac_spmap_cell_area_config * yac_spmap_cell_area_config_file_new_f2c(char const *filename, char const *varname, int min_global_id)
static struct yac_spmap_overwrite_config overwrite_config_default
static struct yac_spmap_cell_area_config cell_area_config_default
double yac_interp_spmap_config_get_spread_distance(struct yac_interp_spmap_config const *spmap_config)
static void dist_read_cell_areas(char const *filename, char const *varname, MPI_Comm comm, int *const io_ranks, int io_rank_idx, int num_io_ranks, double **dist_cell_areas, size_t *dist_cell_areas_global_size)
static size_t yac_spmap_cell_area_config_get_pack_size(struct yac_spmap_cell_area_config const *cell_area_config, MPI_Comm comm)
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 tgt_result_points)
void yac_spmap_cell_area_config_delete(struct yac_spmap_cell_area_config *cell_area_config)
enum yac_interp_spmap_scale_type yac_spmap_scale_config_get_type(struct yac_spmap_scale_config const *scale_config)
struct yac_spmap_overwrite_config ** yac_spmap_overwrite_configs_copy(struct yac_spmap_overwrite_config const *const *overwrite_configs)
struct yac_spmap_cell_area_config * yac_spmap_cell_area_config_yac_new(double sphere_radius)
enum yac_interp_spmap_weight_type yac_interp_spmap_config_get_weight_type(struct yac_interp_spmap_config const *spmap_config)
static struct yac_interp_spmap_config spmap_config_default
static struct yac_spmap_scale_config spmap_scale_config_default
void yac_spmap_overwrite_config_delete(struct yac_spmap_overwrite_config *overwrite_config)
static int yac_spmap_cell_area_config_compare(struct yac_spmap_cell_area_config const *a, struct yac_spmap_cell_area_config const *b)
int yac_spmap_scale_config_compare(struct yac_spmap_scale_config const *a, struct yac_spmap_scale_config const *b)
struct yac_spmap_scale_config * yac_spmap_scale_config_new(enum yac_interp_spmap_scale_type scale_type, struct yac_spmap_cell_area_config const *source_cell_area_config, struct yac_spmap_cell_area_config const *target_cell_area_config)
struct interp_link InterpLink
static void do_search_spmap_(struct yac_interp_grid *interp_grid, struct yac_interp_spmap_config const *config, size_t *src_points, size_t num_src_points, yac_coordinate_pointer src_coords, InterpLink **combined_result, size_t *combined_result_count)
#define YAC_INTERP_SPMAP_MAX_SEARCH_DISTANCE_DEFAULT
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
#define YAC_INTERP_SPMAP_SCALE_CONFIG_DEFAULT
#define YAC_INTERP_SPMAP_WEIGHTED_DEFAULT
#define YAC_INTERP_SPMAP_SPREAD_DISTANCE_DEFAULT
yac_interp_spmap_cell_area_provider
@ YAC_INTERP_SPMAP_CELL_AREA_FILE
@ YAC_INTERP_SPMAP_CELL_AREA_YAC
#define YAC_INTERP_SPMAP_SPHERE_RADIUS_DEFAULT
#define YAC_INTERP_SPMAP_SCALE_TYPE_DEFAULT
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_get_io_ranks(MPI_Comm comm, int *local_is_io_, int **io_ranks_, int *num_io_ranks_)
Definition io_utils.c:309
void yac_nc_inq_varid(int ncid, char const *name, int *varidp)
Definition io_utils.c:411
void yac_nc_open(const char *path, int omode, int *ncidp)
Definition io_utils.c:350
@ YAC_LOC_CELL
Definition location.h:14
int yac_point_selection_compare(struct yac_point_selection const *a, struct yac_point_selection const *b)
struct yac_point_selection * yac_point_selection_unpack(void const *buffer, int buffer_size, int *position, MPI_Comm comm)
struct yac_point_selection * yac_point_selection_copy(struct yac_point_selection const *point_select)
void yac_point_selection_apply(struct yac_point_selection const *point_select, yac_coordinate_pointer point_coords, size_t *point_indices, size_t num_points, size_t *num_selected_points)
void yac_point_selection_pack(struct yac_point_selection const *point_select, void *buffer, int buffer_size, int *position, MPI_Comm comm)
size_t yac_point_selection_get_pack_size(struct yac_point_selection const *point_select, MPI_Comm comm)
void yac_point_selection_delete(struct yac_point_selection *point_select)
#define xrealloc(ptr, size)
Definition ppm_xfuncs.h:67
#define xcalloc(nmemb, size)
Definition ppm_xfuncs.h:64
#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:53
double base_vector[3]
Definition geometry.h:51
double sq_crd
Definition geometry.h:56
struct yac_interp_spmap_config * default_config
struct yac_spmap_overwrite_config ** overwrite_configs
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, int *interpolation_complete)
information (global id and location) about a point that
structure containing the information (global id and location)
struct remote_point * data
const const_int_pointer num_vertices_per_cell
const_size_t_pointer cell_to_edge
const const_yac_int_pointer ids[3]
const_size_t_pointer cell_to_edge_offsets
struct yac_spmap_scale_config * scale_config
enum yac_interp_spmap_weight_type weight_type
struct yac_spmap_cell_area_config::@50::@52 yac
struct yac_spmap_cell_area_config::@50::yac_spmap_cell_area_file_config file_config
enum yac_interp_spmap_cell_area_provider type
struct yac_point_selection * src_point_selection
struct yac_interp_spmap_config * config
struct yac_spmap_cell_area_config * src
struct yac_spmap_cell_area_config * tgt
enum yac_interp_spmap_scale_type type
size_t num_cells[2]
double * buffer
#define YAC_HANDLE_ERROR(exp)
Definition toy_output.c:13
static void yac_flag_sort_size_t(size_t *array_size_t, int *flag, size_t false_count)
Definition utils_core.h:229
void yac_quicksort_index_size_t_size_t(size_t *a, size_t n, size_t *idx)
#define YAC_UNREACHABLE_DEFAULT_F(format,...)
Definition yac_assert.h:41
#define YAC_ASSERT_F(exp, format,...)
Definition yac_assert.h:19
#define die(msg)
Definition yac_assert.h:12
#define YAC_UNREACHABLE_DEFAULT(msg)
Definition yac_assert.h:34
void yac_generate_alltoallv_args(int count, size_t const *sendcounts, size_t *recvcounts, size_t *sdispls, size_t *rdispls, MPI_Comm comm)
Definition yac_mpi.c:578
void yac_free_comm_buffers(size_t *sendcounts, size_t *recvcounts, size_t *sdispls, size_t *rdispls)
Definition yac_mpi.c:634
void yac_get_comm_buffers(int count, size_t **sendcounts, size_t **recvcounts, size_t **sdispls, size_t **rdispls, MPI_Comm comm)
Definition yac_mpi.c:603
size_t yac_string_get_pack_size(char const *caller, char const *string, MPI_Comm comm, int allow_null)
Compute number of bytes required to pack a string for MPI transport.
Definition yac_mpi.c:646
char * yac_string_unpack(void const *buffer, int buffer_size, int *position, MPI_Comm comm)
Unpack a C string from a buffer packed with yac_string_pack.
Definition yac_mpi.c:697
void yac_string_pack(char const *caller, char const *string, void *buffer, int buffer_size, int *position, MPI_Comm comm, int allow_null)
Pack a C string into a provided buffer using MPI_Pack semantics.
Definition yac_mpi.c:667
void yac_alltoallv_p2p(void const *send_buffer, size_t const *sendcounts, size_t const *sdispls, void *recv_buffer, size_t const *recvcounts, size_t const *rdispls, size_t dt_size, MPI_Datatype dt, MPI_Comm comm, char const *caller, int line)
Definition yac_mpi.c:132
#define yac_mpi_call(call, comm)
#define YAC_MPI_SIZE_T
double const (* yac_const_coordinate_pointer)[3]
Definition yac_types.h:22
YAC_INT yac_int
Definition yac_types.h:15
size_t(* yac_size_t_2_pointer)[2]
Definition yac_types.h:25
double(* yac_coordinate_pointer)[3]
Definition yac_types.h:21