19 size_t * tgt_points,
size_t count,
21 int * interpolation_complete);
24 size_t * tgt_points,
size_t count,
26 int * interpolation_complete);
29 size_t * tgt_points,
size_t count,
31 int * interpolation_complete);
71 double * weights,
double const dummy) {
77 double weight = 1.0 / (double)n;
78 for (
size_t i = 0; i < n; ++i) weights[i] = weight;
83 double * weights,
double const dummy) {
87 for (
size_t i = 0; i < n; ++i) {
93 for (
size_t j = 0; j < n; ++j) weights[j] = 0.0;
98 weights[i] = 1.0 / distance;
102 double inv_distance_sum = 0.0;
103 for (
size_t i = 0; i < n; ++i) inv_distance_sum += weights[i];
104 double scale = 1.0 / inv_distance_sum;
106 for (
size_t i = 0; i < n; ++i) weights[i] *= scale;
111 double * weights,
double const gauss_scale) {
113 for (
size_t i = 0; i < n; ++i) {
117 weights[i] = distance * distance;
121 double src_distances_sum = 0.0;
122 double src_distances_count = 0.5 * (double)(n * n - n);
123 for (
size_t i = 0; i < n-1; ++i)
124 for (
size_t j = i + 1; j < n; ++j)
129 "ERROR(compute_weights_gauss): "
130 "all %zu source points for target point (%.3lf; %.3lf; %.3lf) "
131 "are nearly identical (%.3lf; %.3lf; %.3lf)",
132 n, tgt_coord[0], tgt_coord[1], tgt_coord[2],
133 src_coords[0][0], src_coords[0][1], src_coords[0][2]);
136 double src_distances_mean = src_distances_sum / src_distances_count;
137 double scale = -1.0 / (gauss_scale * src_distances_mean * src_distances_mean);
142 double weights_sum = 0.0;
143 for (
size_t i = 0; i < n; ++i) {
144 weights[i] = exp(scale * weights[i]);
145 weights_sum += weights[i];
150 if (fabs(weights_sum) < 1e-9) {
157 tgt_coord, src_coords, n, weights, gauss_scale);
162 for (
size_t i = 0; i < n; ++i) weights[i] /= weights_sum;
168#ifdef YAC_LAPACK_NO_DSYTR
169 lapack_int ipiv[n+1];
172 for (
size_t i = 0; i < n+1; ++i) ipiv[i] = 0;
173 for (
size_t i = 0; i < n*n; ++i) work[i] = 0;
177 LAPACK_COL_MAJOR, (lapack_int) n, (lapack_int) n,
178 A, (lapack_int) n, ipiv),
"internal ERROR: dgetrf")
181 !LAPACKE_dgetri_work(
182 LAPACK_COL_MAJOR, (lapack_int) n, A, (lapack_int) n,
183 ipiv, work, (lapack_int) (n * n)),
"internal ERROR: dgetri")
189 !LAPACKE_dsytrf_work(
190 LAPACK_COL_MAJOR,
'L', (lapack_int) n , A,
191 (lapack_int) n, ipiv, work, (lapack_int) n),
"internal ERROR: dsytrf")
194 !LAPACKE_dsytri_work(
195 LAPACK_COL_MAJOR,
'L', (lapack_int) n , A,
196 (lapack_int) n, ipiv, work),
"internal ERROR: dsytri")
198 for (
size_t i = 0; i < n; ++i)
199 for (
size_t j = i + 1; j < n; ++j)
206 double * weights,
double const rbf_scale) {
211 double sum_d = 0.0, scale_d = 1.0;
214 for (
size_t i = 0; i < n; ++i) A[i][i] = 0.0;
215 for (
size_t i = 0; i < n - 1; ++i) {
216 for (
size_t j = i + 1; j < n; ++j) {
226 scale_d = ((double)((n - 1) * n)) / (2.0 * sum_d);
227 scale_d /= rbf_scale;
229 double sq_scale_d = scale_d * scale_d;
234 for (
size_t i = 0; i < n; ++i) {
235 for (
size_t j = 0; j < n; ++j) {
238 A[i][j] = exp(-1.0 * d * d * sq_scale_d);
253 for (
size_t i = 0; i < n; ++i) {
256 a[i] = exp(-1.0 * d * d * sq_scale_d);
261 for (
size_t i = 0; i < n; ++i) {
263 for (
size_t j = 0; j < n; ++j) weights[i] += A[i][j] * a[j];
269 size_t * tgt_points,
size_t count,
271 int * interpolation_complete) {
273 if (*interpolation_complete)
return 0;
279 "ERROR(do_search_nnn): invalid number of source fields")
284 interp_grid, tgt_points, count, tgt_coords);
286 size_t n = method_nnn->
n;
288 size_t * size_t_buffer =
xmalloc((2 *
n + 1) * count *
sizeof(*size_t_buffer));
289 size_t * src_points = size_t_buffer;
290 size_t * src_points_reorder = size_t_buffer +
n * count;
291 size_t * reorder_idx = size_t_buffer + 2 *
n * count;
292 int * fail_flag =
xmalloc(count *
sizeof(*fail_flag));
296 interp_grid, tgt_coords, count,
n, src_points,
299 size_t result_count = 0;
302 for (
size_t i = 0, k = 0; i < count; ++i) {
304 for (
size_t j = 0; j <
n; ++j, ++k)
flag |= src_points[k] == SIZE_MAX;
305 result_count += !(size_t)(fail_flag[i] =
flag);
311 for (
size_t i = 0; i < count; ++i) reorder_idx[i] = i;
319 double * w =
xmalloc(
n * result_count *
sizeof(*w));
320 size_t * num_weights_per_tgt =
321 xmalloc(result_count *
sizeof(*num_weights_per_tgt));
327 for (
size_t i = 0; i < result_count; ++i) {
328 size_t curr_reorder_idx = reorder_idx[i];
329 for (
size_t j = 0; j <
n; ++j) {
330 size_t curr_src_point = src_points[curr_reorder_idx *
n + j];
331 memcpy(src_coord_buffer[j], src_field_coordinates[curr_src_point],
333 src_points_reorder[i *
n + j] = curr_src_point;
337 tgt_coords[curr_reorder_idx], src_coord_buffer,
n, w + i *
n,
scale);
338 num_weights_per_tgt[i] =
n;
342 for (
size_t i = 0; i < count; ++i) src_points[reorder_idx[i]] = i;
345 free(src_coord_buffer);
350 interp_grid, 0, src_points_reorder, result_count * n);
355 interp_grid, tgt_points, result_count),
356 .count = result_count};
360 weights, &tgts, num_weights_per_tgt, srcs, w);
366 free(num_weights_per_tgt);
373 size_t * tgt_points,
size_t count,
375 int * interpolation_complete) {
377 if (*interpolation_complete)
return 0;
381 "ERROR(do_search_1nn): invalid number of source fields")
386 interp_grid, tgt_points,
count, tgt_coords);
388 size_t * src_points =
xmalloc(
count *
sizeof(*src_points));
392 interp_grid, tgt_coords,
count, 1, src_points,
401 size_t result_count = 0;
402 for (; (result_count <
count) && (src_points[result_count] != SIZE_MAX);
407 interp_grid, 0, src_points, result_count);
412 interp_grid, tgt_points, result_count),
413 .count = result_count};
417 weights, &tgts, srcs);
430 size_t * num_src_per_tgt =
xmalloc(tgts->
count *
sizeof(*num_src_per_tgt));
434 for (
size_t i = 0; i < tgts->
count; ++i) {
435 num_src_per_tgt[i] = 1;
444 free(num_src_per_tgt);
449 size_t * tgt_points,
size_t count,
451 int * interpolation_complete) {
453 if (*interpolation_complete)
return 0;
457 "ERROR(do_search_zero): invalid number of source fields")
462 size_t * src_points, src_count;
464 yac_int * src_global_ids =
xmalloc(src_count *
sizeof(*src_global_ids));
467 interp_grid, src_points, src_count, 0, src_global_ids);
472 yac_int min_src_global_id = XT_INT_MAX;
473 for (
size_t i = 0; i < src_count; ++i)
474 if (src_global_ids[i] < min_src_global_id)
475 min_src_global_id = src_global_ids[i];
476 free(src_global_ids);
483 MPI_IN_PLACE, &min_src_global_id, 1,
yac_int_dt, MPI_MIN, comm), comm);
485 min_src_global_id != XT_INT_MAX,
486 "ERROR(do_search_zero): unable to find unmasked source points");
490 size_t min_src_local_id;
492 interp_grid, 0, &min_src_global_id, 1, &min_src_local_id);
496 interp_grid, 0, &min_src_local_id, 1);
501 interp_grid, tgt_points,
count),
518 "ERROR(yac_interp_method_nnn_new): "
519 "unsupported value for max_search_distance (%lf), has to be in [0.0,PI]",
526 "ERROR(yac_interp_method_nnn_new): n != 1 does not make sense for zero")
529 "max_search_distance != 0.0 does not make sense for zero")
536 double max_search_distance =
553 method->
n = config.
n;
560 "ERROR(yac_interp_method_nnn_new): invalid NNN type")
562 switch (config.
type) {
566 "ERROR(yac_interp_method_nnn_new): n needs to be at least 1 for "
567 "distance weighted average")
574 "ERROR(yac_interp_method_nnn_new): n needs to be at least 2 for "
575 "distance weighted average")
582 "ERROR(yac_interp_method_nnn_new): n needs to be at least 2 for gauss")
590 "ERROR(yac_interp_method_nnn_new): n needs to be at least 2 for RBF")
#define YAC_ASSERT(exp, msg)
static double get_vector_angle(double const a[3], double const b[3])
size_t yac_interp_grid_get_num_src_fields(struct yac_interp_grid *interp_grid)
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)
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)
void yac_interp_grid_do_nnn_search_src(struct yac_interp_grid *interp_grid, yac_coordinate_pointer search_coords, size_t count, size_t n, size_t *src_points, double max_search_distance)
yac_const_coordinate_pointer yac_interp_grid_get_src_field_coords(struct yac_interp_grid *interp_grid, size_t src_field_idx)
void yac_interp_grid_get_tgt_coordinates(struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count, yac_coordinate_pointer tgt_coordinates)
void yac_interp_grid_get_src_global_ids(struct yac_interp_grid *interp_grid, size_t *src_points, size_t count, size_t src_field_idx, yac_int *src_global_ids)
void yac_interp_grid_src_global_to_local(struct yac_interp_grid *interp_grid, size_t src_field_idx, yac_int *src_global_ids, size_t count, size_t *src_local_ids)
static void compute_weights(struct tgt_point_search_data *tgt_point_data, size_t num_tgt_points, struct edge_interp_data *edge_data, size_t num_edges, struct triangle_interp_data *triangle_data, size_t num_triangles, struct weight_vector_data **weights, size_t **num_weights_per_tgt, size_t *total_num_weights)
static void compute_weights_gauss(double tgt_coord[3], yac_coordinate_pointer src_coords, size_t const n, double *weights, double const gauss_scale)
static size_t do_search_nnn(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 void compute_weights_rbf(double tgt_coord[3], yac_coordinate_pointer src_coords, size_t const n, double *weights, double const rbf_scale)
static void delete_nnn(struct interp_method *method)
static size_t do_search_1nn(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 struct interp_method_vtable interp_method_1nn_vtable
static void compute_weights_dist(double tgt_coord[3], yac_coordinate_pointer src_coords, size_t const n, double *weights, double const dummy)
static void interp_weights_add_zero(struct yac_interp_weights *weights, struct remote_points *tgts, struct remote_point src)
static struct interp_method_vtable interp_method_zero_vtable
static void inverse(double *A, size_t n)
static size_t do_search_zero(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 struct interp_method_vtable interp_method_nnn_vtable
struct interp_method * yac_interp_method_nnn_new(struct yac_nnn_config config)
static void compute_weights_avg(double tgt_coord[3], yac_coordinate_pointer src_coords, size_t const n, double *weights, double const dummy)
@ YAC_INTERP_NNN_GAUSS
distance with Gauss weights of n source points
@ YAC_INTERP_NNN_RBF
radial basis functions
@ YAC_INTERP_NNN_AVG
average of n source points
@ YAC_INTERP_NNN_DIST
distance weighted average of n source points
@ YAC_INTERP_NNN_ZERO
all weights are set to zero
void yac_interp_weights_add_wsum(struct yac_interp_weights *weights, struct remote_points *tgts, size_t *num_src_per_tgt, struct remote_point *srcs, double *w)
void yac_interp_weights_add_direct(struct yac_interp_weights *weights, struct remote_points *tgts, struct remote_point *srcs)
void(* interp_weights_add)(struct yac_interp_weights *weights, struct remote_points *tgts, struct remote_point *srcs)
double max_search_distance
struct interp_method_vtable * vtable
void(* compute_weights)(double[3], yac_coordinate_pointer, size_t const, double *, double const)
struct interp_method_vtable * vtable
double max_search_distance
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)
struct interp_method_vtable * vtable
information (global id and location) about a point that
structure containing the information (global id and location)
struct remote_point * data
double max_search_distance
union yac_nnn_config::@28 data
enum yac_interp_nnn_weight_type type
void yac_quicksort_index_int_size_t(int *a, size_t n, size_t *idx)
void yac_quicksort_index_size_t_size_t(size_t *a, size_t n, size_t *idx)
#define YAC_ASSERT_F(exp, format,...)
#define yac_mpi_call(call, comm)
double const (* yac_const_coordinate_pointer)[3]
double(* yac_coordinate_pointer)[3]