18#define AREA_TOL_FACTOR (1e-6)
22 size_t * tgt_points,
size_t count,
24 int * interpolation_complete);
27 size_t * tgt_points,
size_t count,
29 int * interpolation_complete);
81 int max_num_vertices_per_cell = 0;
84 max_num_vertices_per_cell)
85 max_num_vertices_per_cell =
87 return max_num_vertices_per_cell;
99 *src_grid_cells =
xmalloc(max_num_src_per_tgt *
sizeof(**src_grid_cells));
101 double (*coordinates_xyz_buffer)[3];
105 int max_num_vertices_per_cell =
110 xmalloc((max_num_src_per_tgt + 1) * (
size_t)max_num_vertices_per_cell *
111 sizeof(*edge_type_buffer));
112 coordinates_xyz_buffer =
113 xmalloc((max_num_src_per_tgt + 1) * (
size_t)max_num_vertices_per_cell *
114 sizeof(*coordinates_xyz_buffer));
117 tgt_grid_cell->
edge_type = edge_type_buffer;
118 tgt_grid_cell->
array_size = max_num_vertices_per_cell;
119 for (
size_t i = 0; i < max_num_src_per_tgt; ++i) {
120 (*src_grid_cells)[i].coordinates_xyz =
121 coordinates_xyz_buffer + (i + 1) * max_num_vertices_per_cell;
122 (*src_grid_cells)[i].edge_type =
123 edge_type_buffer + (i + 1) * max_num_vertices_per_cell;
124 (*src_grid_cells)[i].array_size = max_num_vertices_per_cell;
138 int max_num_vertices_per_cell =
143 xmalloc(2 * (
size_t)max_num_vertices_per_cell *
144 sizeof(*edge_type_buffer));
146 xmalloc(2 * (
size_t)max_num_vertices_per_cell *
147 sizeof(*coordinates_xyz_buffer));
150 tgt_grid_cell->
edge_type = edge_type_buffer;
151 tgt_grid_cell->
array_size = max_num_vertices_per_cell;
154 coordinates_xyz_buffer + max_num_vertices_per_cell;
156 edge_type_buffer + max_num_vertices_per_cell;
157 src_grid_cell->
array_size = max_num_vertices_per_cell;
163 size_t * src_cells,
struct yac_grid_cell tgt_grid_cell_buffer,
165 double * weights,
size_t * num_weights,
int partial_coverage,
167 int enforced_conserv) {
170 tgt_basic_grid_data, tgt_cell, &tgt_grid_cell_buffer);
171 for (
size_t i = 0; i < src_count; ++i)
173 src_basic_grid_data, src_cells[i], src_grid_cell_buffer + i);
175 double * area = weights;
177 src_count, src_grid_cell_buffer, tgt_grid_cell_buffer, area);
179 size_t num_valid_weights = 0;
180 for (
size_t i = 0; i < src_count; ++i) {
183 if (i != num_valid_weights) {
184 area[num_valid_weights] = area[i];
185 src_cells[num_valid_weights] = src_cells[i];
190 *num_weights = num_valid_weights;
191 if (num_valid_weights == 0)
return 0;
199 "ERROR(compute_weights_order_first_conserv_no_partial): "
200 "invalid normalisation option in conservative remapping")
201 switch(normalisation) {
203 norm_factor = 1.0 / tgt_cell_area;
207 double fracarea = 0.0;
208 for (
size_t i = 0; i < num_valid_weights; ++i) fracarea += area[i];
209 norm_factor = 1.0 / fracarea;
214 if (partial_coverage) {
215 for (
size_t i = 0; i < num_valid_weights; ++i) weights[i] *= norm_factor;
218 double tgt_cell_area_diff = tgt_cell_area;
220 for (
size_t i = 0; i < num_valid_weights; ++i) {
221 double curr_area = area[i];
222 tgt_cell_area_diff -= curr_area;
223 weights[i] = curr_area * norm_factor;
225 int successful = fabs(tgt_cell_area_diff) <= area_tol;
226 if (successful && enforced_conserv)
234 size_t * tgt_points,
size_t count,
236 int * interpolation_complete) {
238 if (*interpolation_complete)
return 0;
245 "ERROR(do_search_conserv): invalid number of source fields")
249 "ERROR(do_search_conserv): unsupported source field location type")
253 "ERROR(do_search_conserv): unsupported target field location type")
256 size_t * src_cells = NULL;
257 size_t * num_src_per_tgt =
xmalloc(count *
sizeof(*num_src_per_tgt));
261 interp_grid, tgt_points, count, &src_cells, num_src_per_tgt);
270 size_t total_num_weights = 0;
271 size_t max_num_src_per_tgt = 0;
272 for (
size_t i = 0; i <
count; ++i) {
273 size_t curr_num_src_per_tgt = num_src_per_tgt[i];
274 if (curr_num_src_per_tgt > max_num_src_per_tgt)
275 max_num_src_per_tgt = curr_num_src_per_tgt;
276 total_num_weights += num_src_per_tgt[i];
282 yac_int * temp_src_global_ids =
283 xmalloc(max_num_src_per_tgt *
sizeof(*temp_src_global_ids));
285 for (
size_t i = 0, offset = 0; i <
count; ++i) {
287 size_t curr_num_src_per_tgt = num_src_per_tgt[i];
288 size_t * curr_src_cells = src_cells + offset;
289 offset += curr_num_src_per_tgt;
291 for (
size_t j = 0; j < curr_num_src_per_tgt; ++j)
292 temp_src_global_ids[j] =
296 temp_src_global_ids, curr_num_src_per_tgt, curr_src_cells);
299 free(temp_src_global_ids);
302 double * w =
xmalloc(total_num_weights *
sizeof(*w));
303 size_t result_count = 0;
304 size_t * failed_tgt =
xmalloc(
count *
sizeof(*failed_tgt));
305 total_num_weights = 0;
315 interp_grid, max_num_src_per_tgt, &tgt_grid_cell, &src_grid_cells);
318 for (
size_t i = 0, offset = 0, result_offset = 0; i < count; ++i) {
320 size_t curr_src_count = num_src_per_tgt[i];
321 size_t curr_tgt_point = tgt_points[i];
326 tgt_basic_grid_data, curr_tgt_point,
327 src_basic_grid_data, curr_src_count, src_cells + offset,
328 tgt_grid_cell, src_grid_cells, w + result_offset, &num_weights,
329 partial_coverage, normalisation, enforced_conserv)) {
331 if (offset != result_offset) {
334 src_cells + result_offset, src_cells + offset,
335 num_weights *
sizeof(*src_cells));
337 tgt_points[result_count] = curr_tgt_point;
338 num_src_per_tgt[result_count] = num_weights;
340 result_offset += num_weights;
341 total_num_weights += num_weights;
343 failed_tgt[i - result_count] = curr_tgt_point;
346 offset += curr_src_count;
352 free(src_grid_cells);
354 if (result_count != count)
355 memcpy(tgt_points + result_count, failed_tgt,
356 (count - result_count) *
sizeof(*tgt_points));
362 interp_grid, tgt_points, result_count),
363 .count = result_count};
366 interp_grid, 0, src_cells, total_num_weights);
370 weights, &tgts, num_src_per_tgt, srcs, w);
375 free(num_src_per_tgt);
426 for (
size_t k = 0; k < 3; ++k)
427 for (
size_t l = 0; l < 3; ++l)
428 M[k][l] = - src_cell_centroid[k] * src_cell_centroid[l];
429 for (
size_t k = 0; k < 3; ++k)
435 for (
size_t i = 0; i < N; ++i) {
438 for (
size_t j = 0; j < 3; ++j) buffer[i].
weight[j] = 0.0;
441 for (
size_t n = 0; n < N; ++n)
442 for (
size_t i = 0; i < 3; ++i)
443 for (
size_t j = 0; j < 3; ++j)
446 memcpy(G_i->
data, buffer, N *
sizeof(*buffer));
450 void const * a,
void const * b) {
459 double abs_weight_a = fabs(weight_a->
weight);
460 double abs_weight_b = fabs(weight_b->
weight);
461 ret = (abs_weight_a > abs_weight_b) - (abs_weight_a < abs_weight_b);
468 void const * a,
void const * b) {
491 for (
size_t i = 1; i < n_; ++i, ++curr_weight_data) {
499 *prev_weight_data = *curr_weight_data;
507 for (
size_t i = 0; i < n_; ++i) {
509 if (weights[i].
weight == 0.0)
continue;
510 if (i != new_n) weights[new_n] = weights[i];
526 size_t N = src_cell_gradient->
n;
531 double * overlap_barycenter = super_cell->
barycenter;
533 for (
size_t n = 1; n <= N; ++n) {
535 (gradient_weights[n].
weight[0] * overlap_barycenter[0] +
536 gradient_weights[n].
weight[1] * overlap_barycenter[1] +
537 gradient_weights[n].
weight[2] * overlap_barycenter[2]) *
549 double barycenter[3]) {
552 size_t const * vertices =
559 for (
size_t i = 0; i < num_vertices; ++i) {
560 double const * curr_vertex_coordinate =
562 barycenter[0] += curr_vertex_coordinate[0];
563 barycenter[1] += curr_vertex_coordinate[1];
564 barycenter[2] += curr_vertex_coordinate[2];
570 struct yac_interp_grid * interp_grid,
size_t * tgt_points,
size_t count,
572 int * interp_fail_flag,
size_t ** src_cells,
size_t * num_src_cells,
574 int partial_coverage) {
579 "ERROR(compute_super_cells): "
580 "invalid normalisation option in conservative remapping")
582 size_t * num_src_per_tgt =
xmalloc(count *
sizeof(*num_src_per_tgt));
586 interp_grid, tgt_points, count, src_cells, num_src_per_tgt);
589 size_t total_num_overlaps = 0;
590 for (
size_t i = 0; i < count; ++i) total_num_overlaps += num_src_per_tgt[i];
592 *num_src_cells = total_num_overlaps;
595 size_t * num_tgt_per_src =
596 xrealloc(num_src_per_tgt, *num_src_cells *
sizeof(*num_tgt_per_src));
601 size_t * tgt_cells = NULL;
603 interp_grid, *src_cells, *num_src_cells, &tgt_cells, num_tgt_per_src);
605 total_num_overlaps = 0;
606 for (
size_t i = 0; i < *num_src_cells; ++i)
607 total_num_overlaps += num_tgt_per_src[i];
610 xmalloc(total_num_overlaps *
sizeof(*super_cells));
617 for (
size_t i = 0, j = 0; i < *num_src_cells; ++i) {
619 size_t curr_num_overlaps = num_tgt_per_src[i];
620 size_t curr_src_cell = (*src_cells)[i];
624 for (
size_t k = 0; k < curr_num_overlaps; ++k, ++j) {
626 size_t curr_tgt_cell = tgt_cells[j];
636 free(num_tgt_per_src);
640 qsort(super_cells, total_num_overlaps,
sizeof(*super_cells),
652 size_t new_num_super_cells = 0;
654 for (
size_t i = 0, j = 0; i < total_num_overlaps;) {
657 size_t curr_tgt_cell = super_cells[i].
tgt.
local_id;
659 tgt_basic_grid_data, curr_tgt_cell, &tgt_grid_cell);
660 double curr_tgt_cell_coverage = 0.0;
663 for (;(i < total_num_overlaps) &&
664 (super_cells[i].tgt.
local_id == curr_tgt_cell); ++i) {
668 src_basic_grid_data, super_cells[i].
src.local_id, &src_grid_cell);
671 double super_cell_area;
672 double barycenter[3];
674 1, &src_grid_cell, tgt_grid_cell, &super_cell_area, &barycenter);
677 if (super_cell_area > 0.0) {
679 super_cells[new_num_super_cells].
src = super_cells[i].
src;
680 super_cells[new_num_super_cells].
tgt = super_cells[i].
tgt;
681 super_cells[new_num_super_cells].
area = super_cell_area;
682 memcpy(super_cells[new_num_super_cells].barycenter, barycenter,
685 ++new_num_super_cells;
687 curr_tgt_cell_coverage += super_cell_area;
694 if (new_num_super_cells != j) {
700 "ERROR(compute_super_cells): invalid normalisation")
701 switch (normalisation) {
704 norm_factor = 1.0 / curr_tgt_cell_area;
707 norm_factor = 1.0 / curr_tgt_cell_coverage;
711 for (; j < new_num_super_cells; ++j)
712 super_cells[j].norm_area = super_cells[j].area * norm_factor;
717 while ((tgt_idx < count) && (tgt_points[tgt_idx] < curr_tgt_cell))
718 interp_fail_flag[tgt_idx++] = 1;
720 if ((tgt_idx < count) && (tgt_points[tgt_idx] == curr_tgt_cell)) {
724 if (partial_coverage) {
725 interp_fail_flag[tgt_idx] = curr_tgt_cell_coverage < area_tol;
727 interp_fail_flag[tgt_idx] =
728 fabs(curr_tgt_cell_area - curr_tgt_cell_coverage) > area_tol;
734 for (; tgt_idx < count; ++tgt_idx) interp_fail_flag[tgt_idx] = 1;
735 *num_super_cells = new_num_super_cells;
737 xrealloc(super_cells, new_num_super_cells *
sizeof(*super_cells));
745 size_t * src_cells,
int * skip_src_cell,
size_t num_src_cells,
749 xmalloc(num_src_cells *
sizeof(*src_cell_centroids));
753 qsort(super_cells, num_super_cells,
sizeof(*super_cells),
769 for (
size_t i = 0, offset = 0; i < num_src_cells; ++i) {
771 if (skip_src_cell[i])
continue;
773 size_t curr_src_cell = src_cells[i];
776 size_t curr_num_super_cells = offset;
777 while ((offset < num_super_cells) &&
778 (super_cells[offset].
src.local_id == curr_src_cell)) ++offset;
779 curr_num_super_cells = offset - curr_num_super_cells;
781 double src_cell_centroid[3] = {0.0, 0.0, 0.0};
783 if (curr_num_super_cells > 0) {
784 for (
size_t j = 0; j < curr_num_super_cells; ++j) {
786 double super_cell_area = curr_super_cells[j].
area;
787 double * super_cell_barycenter = curr_super_cells[j].
barycenter;
788 src_cell_centroid[0] += super_cell_area * super_cell_barycenter[0];
789 src_cell_centroid[1] += super_cell_area * super_cell_barycenter[1];
790 src_cell_centroid[2] += super_cell_area * super_cell_barycenter[2];
799 src_basic_grid_data, curr_src_cell, &src_grid_cell);
800 for (
size_t j = 0; j < src_grid_cell.
num_corners; ++j) {
808 src_cell_centroids[i][0] = src_cell_centroid[0];
809 src_cell_centroids[i][1] = src_cell_centroid[1];
810 src_cell_centroids[i][2] = src_cell_centroid[2];
816 return src_cell_centroids;
822 size_t num_src_cells,
size_t * src_cell_neighbours) {
825 xmalloc(num_src_cells *
sizeof(*src_cell_gradients));
830 size_t total_num_gradient_weights = 0;
831 size_t max_num_neigh_per_src = 0;
832 for (
size_t i = 0; i < num_src_cells; ++i) {
833 src_cell_gradients[i].
data = NULL;
834 src_cell_gradients[i].
n = 0;
835 size_t curr_num_neigh =
837 total_num_gradient_weights += curr_num_neigh + 1;
838 if (max_num_neigh_per_src < curr_num_neigh)
839 max_num_neigh_per_src = curr_num_neigh;
842 (total_num_gradient_weights > 0)?
843 (
xmalloc(total_num_gradient_weights *
844 sizeof(*weight_vector_data_buffer))):NULL;
845 for (
size_t i = 0; i < total_num_gradient_weights; ++i)
846 for (
size_t j = 0; j < 3; ++j)
847 weight_vector_data_buffer[i].
weight[j] = 0.0;
850 xmalloc((max_num_neigh_per_src + 1) *
sizeof(*orth_buffer));
874 for (
size_t i = 0, offset = 0, weight_vector_data_buffer_offset = 0;
875 i < num_src_cells; ++i) {
877 size_t curr_num_neigh =
879 size_t * curr_neighs = src_cell_neighbours + offset;
880 offset += curr_num_neigh;
882 G_i->
data = weight_vector_data_buffer + weight_vector_data_buffer_offset;
884 if (skip_src_cell[i])
continue;
886 weight_vector_data_buffer_offset += curr_num_neigh + 1;
887 G_i->
n = curr_num_neigh + 1;
891 for (
size_t j = 0; j < curr_num_neigh; ++j) {
892 size_t curr_neigh = curr_neighs[j];
894 if (curr_neigh != SIZE_MAX) {
913 .num_corners = 3, .array_size = 0};
923 for (
size_t j = 0; j < curr_num_neigh; ++j) {
925 size_t neigh_idx[2] = {j + 1, (j+1)%curr_num_neigh+1};
926 size_t neigh_local_ids[2] =
930 if (neigh_local_ids[0] == neigh_local_ids[1])
continue;
932 double neigh_cell_barycenters[2][3];
934 src_basic_grid_data, neigh_local_ids[0], neigh_cell_barycenters[0]);
936 src_basic_grid_data, neigh_local_ids[1], neigh_cell_barycenters[1]);
938 centroid_triangle.
coordinates_xyz[1][0] = neigh_cell_barycenters[0][0];
939 centroid_triangle.
coordinates_xyz[1][1] = neigh_cell_barycenters[0][1];
940 centroid_triangle.
coordinates_xyz[1][2] = neigh_cell_barycenters[0][2];
941 centroid_triangle.
coordinates_xyz[2][0] = neigh_cell_barycenters[1][0];
942 centroid_triangle.
coordinates_xyz[2][1] = neigh_cell_barycenters[1][1];
943 centroid_triangle.
coordinates_xyz[2][2] = neigh_cell_barycenters[1][2];
950 neigh_cell_barycenters[0], neigh_cell_barycenters[1], C_j_x_C_k);
952 double curr_edge_direction =
965 for (
size_t l = 0; l < 3; ++l) C_j_x_C_k[l] *= 0.5;
968 G_i->
data[neigh_idx[0]].
weight[0] += C_j_x_C_k[0];
969 G_i->
data[neigh_idx[0]].
weight[1] += C_j_x_C_k[1];
970 G_i->
data[neigh_idx[0]].
weight[2] += C_j_x_C_k[2];
973 G_i->
data[neigh_idx[1]].
weight[0] += C_j_x_C_k[0];
974 G_i->
data[neigh_idx[1]].
weight[1] += C_j_x_C_k[1];
975 G_i->
data[neigh_idx[1]].
weight[2] += C_j_x_C_k[2];
980 for (
size_t j = 0; j <= curr_num_neigh; ++j)
981 for (
size_t k = 0; k < 3; ++k)
984 double inv_A_C_K = (A_C_k >
YAC_AREA_TOL)?(1.0/A_C_k):0.0;
986 for (
size_t k = 0; k <= curr_num_neigh; ++k)
987 for (
size_t l = 0; l < 3; ++l)
991 src_cell_centroids[i], G_i, orth_buffer);
995 return src_cell_gradients;
999 size_t * tgt_cells,
int * interp_fail_flag,
size_t num_tgt_cells,
1001 size_t ** src_per_tgt,
double ** weights,
size_t * num_src_per_tgt) {
1003 size_t num_interpolated_tgt = 0;
1007 qsort(super_cells, num_super_cells,
sizeof(*super_cells),
1010 size_t max_num_weights_per_tgt = 0;
1011 size_t max_num_total_weights = 0;
1014 for (
size_t i = 0, j = 0; i < num_tgt_cells; ++i) {
1016 if (interp_fail_flag[i])
continue;
1018 size_t curr_tgt_cell = tgt_cells[i];
1019 size_t curr_num_weights = 0;
1022 while ((j < num_super_cells) &&
1023 (super_cells[j].tgt.
local_id < curr_tgt_cell)) ++j;
1026 while ((j < num_super_cells) &&
1027 (super_cells[j].tgt.
local_id == curr_tgt_cell))
1030 max_num_total_weights += curr_num_weights;
1031 if (max_num_weights_per_tgt < curr_num_weights)
1032 max_num_weights_per_tgt = curr_num_weights;
1033 num_interpolated_tgt++;
1037 xmalloc(max_num_weights_per_tgt *
sizeof(*weight_buffer));
1038 *weights =
xmalloc(max_num_total_weights *
sizeof(**weights));
1039 *src_per_tgt =
xmalloc(max_num_total_weights *
sizeof(**src_per_tgt));
1060 for (
size_t i = 0, j = 0; i < num_interpolated_tgt; ++i) {
1062 size_t curr_tgt_cell = tgt_cells[i];
1065 while ((j < num_super_cells) &&
1066 (super_cells[j].tgt.
local_id != curr_tgt_cell)) ++j;
1068 size_t weight_buffer_offset = 0;
1071 while ((j < num_super_cells) &&
1072 (super_cells[j].tgt.
local_id == curr_tgt_cell)) {
1074 size_t num_weights =
1076 super_cells + j, weight_buffer + weight_buffer_offset);
1077 weight_buffer_offset += num_weights;
1084 num_src_per_tgt[i] = weight_buffer_offset;
1086 for (
size_t k = 0; k < weight_buffer_offset; ++k, ++w_idx) {
1087 (*weights)[w_idx] = weight_buffer[k].
weight;
1088 (*src_per_tgt)[w_idx] = weight_buffer[k].
local_id;
1091 free(weight_buffer);
1093 return num_interpolated_tgt;
1098 size_t * tgt_points,
size_t count,
1100 int * interpolation_complete) {
1102 if (*interpolation_complete)
return 0;
1109 "ERROR(do_search_conserv): invalid number of source fields")
1113 "ERROR(do_search_conserv): unsupported source field location type")
1117 "ERROR(do_search_conserv): unsupported target field location type")
1122 int * interp_fail_flag =
xmalloc(count *
sizeof(*interp_fail_flag));
1124 size_t num_super_cells = 0;
1125 size_t * src_cells = NULL;
1126 size_t num_src_cells = 0;
1130 interp_grid, tgt_points, count, &super_cells, &num_super_cells,
1131 interp_fail_flag, &src_cells, &num_src_cells,
1134 size_t total_num_src_cell_neighbours = 0;
1137 for (
size_t i = 0; i < num_src_cells; ++i)
1138 total_num_src_cell_neighbours +=
1140 size_t * src_cell_neighbours =
1141 xmalloc(total_num_src_cell_neighbours *
sizeof(*src_cell_neighbours));
1145 interp_grid, src_cells, num_src_cells, src_cell_neighbours);
1149 int * skip_src_cell =
xmalloc(num_src_cells *
sizeof(*skip_src_cell));
1153 if (src_cell_mask != NULL) {
1154 for (
size_t i = 0, offset = 0; i < num_src_cells; ++i) {
1155 size_t curr_src_cell = src_cells[i];
1156 if ((skip_src_cell[i] = !src_cell_mask[curr_src_cell]))
continue;
1157 size_t * curr_neighbours = src_cell_neighbours + offset;
1158 size_t curr_num_neigh =
1160 offset += curr_num_neigh;
1161 for (
size_t j = 0; j < curr_num_neigh; ++j)
1162 if ((curr_neighbours[j] != SIZE_MAX) &&
1163 (!src_cell_mask[curr_neighbours[j]]))
1164 curr_neighbours[j] = SIZE_MAX;
1167 memset(skip_src_cell, 0, num_src_cells *
sizeof(*skip_src_cell));
1173 num_src_cells, super_cells, num_super_cells);
1178 interp_grid, src_cells, src_cell_centroids,
1179 skip_src_cell, num_src_cells, src_cell_neighbours);
1180 free(src_cell_neighbours);
1181 free(src_cell_centroids);
1184 qsort(super_cells, num_super_cells,
sizeof(*super_cells),
1186 for (
size_t i = 0, j = 0; i < num_src_cells; ++i) {
1187 size_t curr_src_cell = src_cells[i];
1192 (j >= num_super_cells) ||
1193 (super_cells[j].
src.local_id >= curr_src_cell),
1194 "ERROR(do_search_conserv_2nd_order): internal error");
1195 while ((j < num_super_cells) &&
1196 (super_cells[j].
src.local_id == curr_src_cell)) {
1200 free(skip_src_cell);
1203 size_t * src_per_tgt = NULL;
1205 size_t * num_src_per_tgt =
xmalloc(count *
sizeof(*num_src_per_tgt));
1208 size_t num_interpolated_tgt =
1210 tgt_points, interp_fail_flag, count, super_cells, num_super_cells,
1211 &src_per_tgt, &w, num_src_per_tgt);
1212 if (num_src_cells > 0) free(src_cell_gradients->
data);
1213 free(src_cell_gradients);
1215 free(interp_fail_flag);
1217 size_t total_num_weights = 0;
1218 for (
size_t i = 0; i < num_interpolated_tgt; ++i)
1219 total_num_weights += num_src_per_tgt[i];
1224 interp_grid, tgt_points, num_interpolated_tgt),
1225 .count = num_interpolated_tgt};
1228 interp_grid, 0, src_per_tgt, total_num_weights);
1232 weights, &tgts, num_src_per_tgt, srcs, w);
1237 free(num_src_per_tgt);
1240 return num_interpolated_tgt;
1244 int order,
int enforced_conserv,
int partial_coverage,
1251 "ERROR(yac_interp_method_conserv_new): interp_method_conserv only "
1252 "supports enforced_conserv with first order conservative remapping")
1254 (order == 1) || (order == 2),
1255 "ERROR(yac_interp_method_conserv_new): invalid order")
double yac_huiliers_area(struct yac_grid_cell cell)
Area calculation on a unit sphere taken from ESMF based on L'Huilier's Theorem.
Structs and interfaces for area calculations.
static int edge_direction(double *a, double *b)
void yac_correct_weights(size_t nSourceCells, double *weight)
correct interpolation weights
void yac_compute_overlap_info(size_t N, struct yac_grid_cell *source_cell, struct yac_grid_cell target_cell, double *overlap_areas, double(*overlap_barycenters)[3])
calculates partial areas for all overlapping parts of the source cells with arbitrary target cells,...
void yac_compute_overlap_areas(size_t N, struct yac_grid_cell *source_cell, struct yac_grid_cell target_cell, double *partial_areas)
calculates partial areas for all overlapping parts of the source cells with arbitrary target cells,...
void yac_compute_overlap_buf_free()
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)
int const * const_int_pointer
static void crossproduct_kahan(double const a[], double const b[], double cross[])
static void normalise_vector(double v[])
@ YAC_GREAT_CIRCLE_EDGE
great circle
void yac_interp_grid_do_cell_search_tgt(struct yac_interp_grid *interp_grid, size_t *src_cells, size_t count, size_t **tgt_cells, size_t *num_tgt_per_src)
enum yac_location yac_interp_grid_get_tgt_field_location(struct yac_interp_grid *interp_grid)
size_t yac_interp_grid_get_num_src_fields(struct yac_interp_grid *interp_grid)
const_int_pointer yac_interp_grid_get_src_field_mask(struct yac_interp_grid *interp_grid, size_t src_field_idx)
void yac_interp_grid_get_src_cell_neighbours(struct yac_interp_grid *interp_grid, size_t *src_cells, size_t count, size_t *neighbours)
struct remote_point * yac_interp_grid_get_tgt_remote_points(struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count)
enum yac_location yac_interp_grid_get_src_field_location(struct yac_interp_grid *interp_grid, size_t src_field_idx)
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)
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_cell_search_src(struct yac_interp_grid *interp_grid, size_t *tgt_cells, size_t count, size_t **src_cells, size_t *num_src_per_tgt)
struct yac_const_basic_grid_data * yac_interp_grid_get_basic_grid_data_src(struct yac_interp_grid *interp_grid)
static void delete_conserv(struct interp_method *method)
static void get_cell_buffers_(struct yac_interp_grid *interp_grid, struct yac_grid_cell *tgt_grid_cell, struct yac_grid_cell *src_grid_cell)
static size_t compute_2nd_order_weights(size_t *tgt_cells, int *interp_fail_flag, size_t num_tgt_cells, struct supermesh_cell *super_cells, size_t num_super_cells, size_t **src_per_tgt, double **weights, size_t *num_src_per_tgt)
static size_t do_search_conserv_1st_order(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)
static yac_coordinate_pointer compute_src_cell_centroids(struct yac_interp_grid *interp_grid, size_t *src_cells, int *skip_src_cell, size_t num_src_cells, struct supermesh_cell *super_cells, size_t num_super_cells)
static void get_cell_buffers(struct yac_interp_grid *interp_grid, size_t max_num_src_per_tgt, struct yac_grid_cell *tgt_grid_cell, struct yac_grid_cell **src_grid_cells)
static void compute_cell_barycenter(struct yac_const_basic_grid_data *grid_data, size_t cell_idx, double barycenter[3])
static void compact_weight_vector_data(struct weight_vector_data *weights, size_t *n)
static struct interp_method_vtable interp_method_conserv_2nd_order_vtable
struct interp_method * yac_interp_method_conserv_new(int order, int enforced_conserv, int partial_coverage, enum yac_interp_method_conserv_normalisation normalisation)
static int get_max_num_vertices_per_cell(struct yac_const_basic_grid_data *basic_grid_data)
static void compute_super_cells(struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count, struct supermesh_cell **super_cells_, size_t *num_super_cells, int *interp_fail_flag, size_t **src_cells, size_t *num_src_cells, enum yac_interp_method_conserv_normalisation normalisation, int partial_coverage)
static int compare_supermesh_cell_tgt_local_ids(const void *a, const void *b)
static void orthogonalise_weight_vector(double *src_cell_centroid, struct weight_vector_3d *G_i, struct weight_vector_data_3d *buffer)
static struct interp_method_vtable interp_method_conserv_1st_order_vtable
static int compare_supermesh_cell_src_local_ids(const void *a, const void *b)
static size_t do_search_conserv_2nd_order(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)
static size_t compute_2nd_order_tgt_cell_weights(struct supermesh_cell *super_cell, struct weight_vector_data *weights)
static int compare_weight_vector_data_weight(void const *a, void const *b)
static int compare_weight_vector_data(void const *a, void const *b)
static struct weight_vector_3d * compute_src_cell_gradients(struct yac_interp_grid *interp_grid, size_t *src_cells, yac_coordinate_pointer src_cell_centroids, int *skip_src_cell, size_t num_src_cells, size_t *src_cell_neighbours)
static int compute_1st_order_weights(struct yac_const_basic_grid_data *tgt_basic_grid_data, size_t tgt_cell, struct yac_const_basic_grid_data *src_basic_grid_data, size_t src_count, size_t *src_cells, struct yac_grid_cell tgt_grid_cell_buffer, struct yac_grid_cell *src_grid_cell_buffer, double *weights, size_t *num_weights, int partial_coverage, enum yac_interp_method_conserv_normalisation normalisation, int enforced_conserv)
yac_interp_method_conserv_normalisation
@ YAC_INTERP_CONSERV_DESTAREA
@ YAC_INTERP_CONSERV_FRACAREA
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)
#define xrealloc(ptr, size)
enum yac_interp_method_conserv_normalisation normalisation
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
struct weight_vector_3d * src_cell_gradient
struct supermesh_cell::@9 src
struct supermesh_cell::@9 tgt
struct weight_vector_data_3d * data
const yac_const_coordinate_pointer vertex_coordinates
const_size_t_pointer cell_to_vertex_offsets
const_size_t_pointer cell_to_vertex
const const_int_pointer num_vertices_per_cell
const const_yac_int_pointer ids[3]
enum yac_edge_type * edge_type
double(* coordinates_xyz)[3]
void yac_quicksort_index_yac_int_size_t(yac_int *a, size_t n, size_t *idx)
void yac_quicksort_index_int_size_t(int *a, size_t n, size_t *idx)
static void yac_remove_duplicates_size_t(size_t *array, size_t *n)
void yac_quicksort_index_size_t_int(size_t *a, size_t n, int *idx)
#define YAC_ASSERT(exp, msg)
double(* yac_coordinate_pointer)[3]