19 size_t * tgt_points,
size_t count,
23 size_t * tgt_points,
size_t count,
27 size_t * tgt_points,
size_t count,
68 double * weights,
double const dummy) {
74 double weight = 1.0 / (double)n;
75 for (
size_t i = 0; i < n; ++i) weights[i] = weight;
80 double * weights,
double const dummy) {
84 for (
size_t i = 0; i < n; ++i) {
90 for (
size_t j = 0; j < n; ++j) weights[j] = 0.0;
95 weights[i] = 1.0 / distance;
99 double inv_distance_sum = 0.0;
100 for (
size_t i = 0; i < n; ++i) inv_distance_sum += weights[i];
101 double scale = 1.0 / inv_distance_sum;
103 for (
size_t i = 0; i < n; ++i) weights[i] *= scale;
108 double * weights,
double const gauss_scale) {
110 for (
size_t i = 0; i < n; ++i) {
116 for (
size_t j = 0; j < n; ++j) weights[j] = 0.0;
120 weights[i] = distance * distance;
124 double src_distances_sum = 0.0;
125 double src_distances_count = 0.5 * (double)(n * n - n);
126 for (
size_t i = 0; i < n-1; ++i)
127 for (
size_t j = i + 1; j < n; ++j)
131 double src_distances_mean = src_distances_sum / src_distances_count;
132 double scale = -1.0 / (gauss_scale * src_distances_mean * src_distances_mean);
137 double weights_sum = 0.0;
138 for (
size_t i = 0; i < n; ++i) {
139 weights[i] = exp(scale * weights[i]);
140 weights_sum += weights[i];
145 if (fabs(weights_sum) < 1e-9) {
152 tgt_coord, src_coords, n, weights, gauss_scale);
157 for (
size_t i = 0; i < n; ++i) weights[i] /= weights_sum;
163#ifdef YAC_LAPACK_NO_DSYTR
164 lapack_int ipiv[n+1];
167 for (
size_t i = 0; i < n+1; ++i) ipiv[i] = 0;
168 for (
size_t i = 0; i < n*n; ++i) work[i] = 0;
172 LAPACK_COL_MAJOR, (lapack_int) n, (lapack_int) n,
173 A, (lapack_int) n, ipiv),
"internal ERROR: dgetrf")
176 !LAPACKE_dgetri_work(
177 LAPACK_COL_MAJOR, (lapack_int) n, A, (lapack_int) n,
178 ipiv, work, (lapack_int) (n * n)),
"internal ERROR: dgetri")
184 !LAPACKE_dsytrf_work(
185 LAPACK_COL_MAJOR,
'L', (lapack_int) n , A,
186 (lapack_int) n, ipiv, work, (lapack_int) n),
"internal ERROR: dsytrf")
189 !LAPACKE_dsytri_work(
190 LAPACK_COL_MAJOR,
'L', (lapack_int) n , A,
191 (lapack_int) n, ipiv, work),
"internal ERROR: dsytri")
193 for (
size_t i = 0; i < n; ++i)
194 for (
size_t j = i + 1; j < n; ++j)
201 double * weights,
double const rbf_scale) {
206 double sum_d = 0.0, scale_d = 1.0;
209 for (
size_t i = 0; i < n; ++i) A[i][i] = 0.0;
210 for (
size_t i = 0; i < n - 1; ++i) {
211 for (
size_t j = i + 1; j < n; ++j) {
221 scale_d = ((double)((n - 1) * n)) / (2.0 * sum_d);
222 scale_d /= rbf_scale;
224 double sq_scale_d = scale_d * scale_d;
229 for (
size_t i = 0; i < n; ++i) {
230 for (
size_t j = 0; j < n; ++j) {
233 A[i][j] = exp(-1.0 * d * d * sq_scale_d);
248 for (
size_t i = 0; i < n; ++i) {
251 a[i] = exp(-1.0 * d * d * sq_scale_d);
256 for (
size_t i = 0; i < n; ++i) {
258 for (
size_t j = 0; j < n; ++j) weights[i] += A[i][j] * a[j];
264 size_t * tgt_points,
size_t count,
271 "ERROR(do_search_nnn): invalid number of source fields")
276 interp_grid, tgt_points, count, tgt_coords);
278 size_t n = method_nnn->
n;
280 size_t * size_t_buffer =
xmalloc((2 *
n + 1) * count *
sizeof(*size_t_buffer));
281 size_t * src_points = size_t_buffer;
282 size_t * src_points_reorder = size_t_buffer +
n * count;
283 size_t * reorder_idx = size_t_buffer + 2 *
n * count;
284 int * fail_flag =
xmalloc(count *
sizeof(*fail_flag));
288 interp_grid, tgt_coords, count,
n, src_points,
291 size_t result_count = 0;
294 for (
size_t i = 0, k = 0; i < count; ++i) {
296 for (
size_t j = 0; j <
n; ++j, ++k) flag |= src_points[k] == SIZE_MAX;
297 result_count += !(size_t)(fail_flag[i] = flag);
303 for (
size_t i = 0; i < count; ++i) reorder_idx[i] = i;
311 double * w =
xmalloc(
n * result_count *
sizeof(*w));
312 size_t * num_weights_per_tgt =
313 xmalloc(result_count *
sizeof(*num_weights_per_tgt));
319 for (
size_t i = 0; i < result_count; ++i) {
320 size_t curr_reorder_idx = reorder_idx[i];
321 for (
size_t j = 0; j <
n; ++j) {
322 size_t curr_src_point = src_points[curr_reorder_idx *
n + j];
323 memcpy(src_coord_buffer[j], src_field_coordinates[curr_src_point],
325 src_points_reorder[i *
n + j] = curr_src_point;
329 tgt_coords[curr_reorder_idx], src_coord_buffer,
n, w + i *
n,
scale);
330 num_weights_per_tgt[i] =
n;
334 for (
size_t i = 0; i < count; ++i) src_points[reorder_idx[i]] = i;
337 free(src_coord_buffer);
342 interp_grid, 0, src_points_reorder, result_count * n);
347 interp_grid, tgt_points, result_count),
348 .count = result_count};
352 weights, &tgts, num_weights_per_tgt, srcs, w);
358 free(num_weights_per_tgt);
365 size_t * tgt_points,
size_t count,
370 "ERROR(do_search_1nn): invalid number of source fields")
375 interp_grid, tgt_points,
count, tgt_coords);
377 size_t * src_points =
xmalloc(
count *
sizeof(*src_points));
381 interp_grid, tgt_coords,
count, 1, src_points,
390 size_t result_count = 0;
391 for (; (result_count <
count) && (src_points[result_count] != SIZE_MAX);
396 interp_grid, 0, src_points, result_count);
401 interp_grid, tgt_points, result_count),
402 .count = result_count};
406 weights, &tgts, srcs);
419 size_t * num_src_per_tgt =
xmalloc(tgts->
count *
sizeof(*num_src_per_tgt));
423 for (
size_t i = 0; i < tgts->
count; ++i) {
424 num_src_per_tgt[i] = 1;
433 free(num_src_per_tgt);
438 size_t * tgt_points,
size_t count,
443 "ERROR(do_search_zero): invalid number of source fields")
448 size_t * src_points, src_count;
450 yac_int * src_global_ids =
xmalloc(src_count *
sizeof(*src_global_ids));
453 interp_grid, src_points, src_count, 0, src_global_ids);
458 yac_int min_src_global_id = XT_INT_MAX;
459 for (
size_t i = 0; i < src_count; ++i)
460 if (src_global_ids[i] < min_src_global_id)
461 min_src_global_id = src_global_ids[i];
462 free(src_global_ids);
469 MPI_IN_PLACE, &min_src_global_id, 1,
yac_int_dt, MPI_MIN, comm), comm);
471 min_src_global_id != XT_INT_MAX,
472 "ERROR(do_search_zero): unable to find unmasked source points");
476 size_t min_src_local_id;
478 interp_grid, 0, &min_src_global_id, 1, &min_src_local_id);
482 interp_grid, 0, &min_src_local_id, 1);
487 interp_grid, tgt_points,
count),
504 "ERROR(yac_interp_method_nnn_new): "
505 "unsupported value for max_search_distance (%lf), has to be in [0.0,PI]",
512 "ERROR(yac_interp_method_nnn_new): n != 1 does not make sense for zero")
515 "max_search_distance != 0.0 does not make sense for zero")
522 double max_search_distance =
539 method->
n = config.
n;
546 "ERROR(yac_interp_method_nnn_new): invalid NNN type")
548 switch (config.
type) {
552 "ERROR(yac_interp_method_nnn_new): n needs to be at least 1 for "
553 "distance weighted average")
560 "ERROR(yac_interp_method_nnn_new): n needs to be at least 2 for "
561 "distance weighted average")
568 "ERROR(yac_interp_method_nnn_new): n needs to be at least 2 for gauss")
576 "ERROR(yac_interp_method_nnn_new): n needs to be at least 2 for RBF")
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)
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 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)
static void delete_nnn(struct interp_method *method)
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_1nn(struct interp_method *method, struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count, struct yac_interp_weights *weights)
static struct interp_method_vtable interp_method_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)
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::@21 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_ASSERT(exp, msg)
#define yac_mpi_call(call, comm)
double const (* yac_const_coordinate_pointer)[3]
double(* yac_coordinate_pointer)[3]