21#ifndef HCSBB_GAUSS_NNN
22#define HCSBB_GAUSS_NNN (4)
25#define HCSBB_D_NNN (7)
28#ifndef HCSBB_GAUSS_ORDER
29#define HCSBB_GAUSS_ORDER (6)
33#if HCSBB_GAUSS_ORDER == 0
34#define HCSBB_NUM_GAUSS_POINTS (1)
35#elif HCSBB_GAUSS_ORDER == 1
36#define HCSBB_NUM_GAUSS_POINTS (1)
37#elif HCSBB_GAUSS_ORDER == 2
38#define HCSBB_NUM_GAUSS_POINTS (3)
39#elif HCSBB_GAUSS_ORDER == 3
40#define HCSBB_NUM_GAUSS_POINTS (4)
41#elif HCSBB_GAUSS_ORDER == 4
42#define HCSBB_NUM_GAUSS_POINTS (6)
43#elif HCSBB_GAUSS_ORDER == 5
44#define HCSBB_NUM_GAUSS_POINTS (7)
45#elif HCSBB_GAUSS_ORDER == 6
46#define HCSBB_NUM_GAUSS_POINTS (12)
47#elif HCSBB_GAUSS_ORDER == 7
48#define HCSBB_NUM_GAUSS_POINTS (13)
49#elif HCSBB_GAUSS_ORDER == 8
50#define HCSBB_NUM_GAUSS_POINTS (16)
51#elif HCSBB_GAUSS_ORDER == 9
52#define HCSBB_NUM_GAUSS_POINTS (19)
54#define HCSBB_NUM_GAUSS_POINTS (-1)
55#error "interpolation_method_hcsbb: the specified gauss order is currently not supported."
61#define HCSBB_NUM_SBB_COEFFS (10)
65#define SB_COORD_TOL (1.0e-6)
69 size_t * tgt_points,
size_t count,
152 double coordinate_xyz[3];
201 double * sb_coords,
size_t num_vertices,
double triangle[3][3]) {
204 lapack_int n = 3, nrhs = (lapack_int) num_vertices, lda = n, ldx = n, ipiv[3];
205 memcpy(A, triangle,
sizeof(A));
215 LAPACK_COL_MAJOR, n, nrhs, &A[0][0], lda, ipiv, sb_coords, ldx),
216 "ERROR: internal error (could not solve linear 3x3 system)")
221 size_t const * a_ = a, * b_ = b;
223 return (*a_ > *b_) - (*b_ > *a_);
228 size_t const * a_ = a, * b_ = b;
230 if ((ret = (a_[0] > b_[0]) - (b_[0] > a_[0])))
return ret;
231 else return (a_[1] > b_[1]) - (b_[1] > a_[1]);
236 size_t const * a_ = a, * b_ = b;
238 if ((ret = (a_[0] > b_[0]) - (b_[0] > a_[0])))
return ret;
239 if ((ret = (a_[1] > b_[1]) - (b_[1] > a_[1])))
return ret;
240 else return (a_[2] > b_[2]) - (b_[2] > a_[2]);
245 size_t const * a_ = a, * b_ = b;
248 if ((ret = (a_[i] > b_[i]) - (b_[i] > a_[i])))
259 size_t num_triangles,
260 size_t **unique_vertices,
size_t * num_unique_vertices,
261 size_t (**unique_edge_to_unique_vertex)[2],
size_t * num_unique_edges,
262 size_t (**unique_triangle_to_unique_edge)[3],
size_t * num_unique_triangles) {
264 size_t (*edge_vertices)[2] =
265 xmalloc((num_edges + 3 * num_triangles) *
sizeof(*edge_vertices));
266 size_t (*triangle_vertices)[3] =
267 xmalloc(num_triangles *
sizeof(*triangle_vertices));
270 for (
size_t i = 0; i < num_edges; ++i, ++tgt_point_data)
271 memcpy(edge_vertices[i], tgt_point_data->
src_points, 2 *
sizeof(
size_t));
272 for (
size_t i = 0; i < num_triangles; ++i, ++tgt_point_data) {
273 edge_vertices[3*i+num_edges+0][0] = tgt_point_data->
src_points[0];
274 edge_vertices[3*i+num_edges+0][1] = tgt_point_data->
src_points[1];
275 edge_vertices[3*i+num_edges+1][0] = tgt_point_data->
src_points[0];
276 edge_vertices[3*i+num_edges+1][1] = tgt_point_data->
src_points[2];
277 edge_vertices[3*i+num_edges+2][0] = tgt_point_data->
src_points[1];
278 edge_vertices[3*i+num_edges+2][1] = tgt_point_data->
src_points[2];
280 triangle_vertices[i], tgt_point_data->
src_points, 3 *
sizeof(
size_t));
284 qsort(edge_vertices, num_edges + 3 * num_triangles,
286 qsort(triangle_vertices, num_triangles,
289 *num_unique_edges = num_edges + 3 * num_triangles;
290 *num_unique_triangles = num_triangles;
297 *num_unique_vertices = 2 * (*num_unique_edges);
298 size_t * vertices =
xmalloc((*num_unique_vertices) *
sizeof(*vertices));
300 vertices, &(edge_vertices[0][0]), *num_unique_vertices *
sizeof(*vertices));
301 qsort(vertices, *num_unique_vertices,
sizeof(*vertices),
compare_size_t);
304 xrealloc(vertices, *num_unique_vertices *
sizeof(*vertices));
306 size_t (*triangle_edges)[3] =
307 xmalloc(3 * (*num_unique_triangles) *
sizeof(*triangle_edges));
308 for (
size_t i = 0; i < *num_unique_triangles; ++i) {
310 triangle_edges[3*i+0][0] = triangle_vertices[i][1];
311 triangle_edges[3*i+0][1] = triangle_vertices[i][2];
312 triangle_edges[3*i+0][2] = 3*i+0;
314 triangle_edges[3*i+1][0] = triangle_vertices[i][0];
315 triangle_edges[3*i+1][1] = triangle_vertices[i][2];
316 triangle_edges[3*i+1][2] = 3*i+1;
318 triangle_edges[3*i+2][0] = triangle_vertices[i][0];
319 triangle_edges[3*i+2][1] = triangle_vertices[i][1];
320 triangle_edges[3*i+2][2] = 3*i+2;
324 qsort(triangle_edges, 3 * (*num_unique_triangles),
328 *unique_triangle_to_unique_edge =
329 xmalloc(*num_unique_triangles *
sizeof(**unique_triangle_to_unique_edge));
330 for (
size_t i = 0, j = 0; i < 3 * (*num_unique_triangles); ++i) {
331 size_t * curr_edge = triangle_edges[i];
333 (&(*unique_triangle_to_unique_edge)[0][0])[curr_edge[2]] = j;
335 free(triangle_edges);
337 tgt_point_data -= num_edges + num_triangles;
338 for (
size_t i = 0, j = 0; i < num_edges; ++i, ++tgt_point_data) {
341 j < *num_unique_edges,
"ERROR(get_unique_interp_data): edge ids missmatch")
344 for (
size_t i = 0, j = 0; i < num_triangles; ++i, ++tgt_point_data) {
348 j < *num_unique_triangles,
349 "ERROR(get_unique_interp_data): triangle ids missmatch")
352 free(triangle_vertices);
355 *unique_edge_to_unique_vertex =
356 xmalloc(*num_unique_edges *
sizeof(**unique_edge_to_unique_vertex));
357 size_t * reorder_idx =
358 xmalloc(2 * (*num_unique_edges) *
sizeof(*reorder_idx));
359 for (
size_t i = 0; i < 2 * (*num_unique_edges); ++i) reorder_idx[i] = i;
361 &(edge_vertices[0][0]), 2 * (*num_unique_edges), reorder_idx);
362 for (
size_t i = 0, j = 0; i < 2 * (*num_unique_edges); ++i) {
363 size_t curr_vertex = (&(edge_vertices[0][0]))[i];
364 while (curr_vertex != (*unique_vertices)[j]) ++j;
365 (&(*unique_edge_to_unique_vertex[0][0]))[reorder_idx[i]] = j;
373 double (*gauss_points)[3],
size_t * nnn_search_results,
379 memcpy(src_point_buffer, nnn_search_results,
387 for (
size_t i = 0; i < num_unique_result_points; ++i)
388 global_id_buffer[i] = src_point_global_ids[src_point_buffer[i]];
390 global_id_buffer, num_unique_result_points, src_point_buffer);
393 xmalloc(num_unique_result_points *
sizeof(*src_point_buffer));
395 num_unique_result_points *
sizeof(*src_point_buffer));
400 for (
size_t i = 0; i < num_unique_result_points; ++i)
408 size_t * curr_result_points = nnn_search_results + i *
HCSBB_GAUSS_NNN;
409 double * curr_gauss_points = gauss_points[i];
410 double distance_sum = 0.0;
419 (
double*)(src_point_coords[curr_result_points[j]]));
424 double inv_distance = 1.0 / (distance * distance);
425 inv_distances[j] = inv_distance;
426 distance_sum += inv_distance;
434 curr_global_ids[k] = src_point_global_ids[curr_result_points[k]];
441 distance_sum = 1.0 / distance_sum;
443 yac_int curr_global_id = curr_global_ids[k];
444 while (curr_global_id != global_id_buffer[l]) ++l;
445 w_nnn[l][i] = inv_distances[reorder_idx[k]] * distance_sum;
450 yac_int curr_global_id = src_point_global_ids[curr_result_points[j]];
452 while (curr_global_id != global_id_buffer[l]) ++l;
463 xmalloc(num_unique_result_points *
sizeof(*weights));
465 for (
size_t i = 0; i < num_unique_result_points; ++i) {
469 accu += w_g[j][l] * w_nnn[i][l];
470 weights[i][j] = accu;
482 double bnd_triangle[3][3],
double direction[3],
double coordinate_xyz[3],
485 double sb_coord_p[3] = {
486 coordinate_xyz[0], coordinate_xyz[1], coordinate_xyz[2]};
487 double sb_coord_d[3] = {direction[0], direction[1], direction[2]};
494#define POW_0(x) (1.0)
495#define POW_1(x) ((x))
496#define POW_2(x) ((x)*(x))
497#define POW_3(x) ((x)*(x)*(x))
503 d_sbb_polynomials[0] =
510 d_sbb_polynomials[1] =
517 d_sbb_polynomials[2] =
524 d_sbb_polynomials[3] =
531 d_sbb_polynomials[4] =
538 d_sbb_polynomials[5] =
545 d_sbb_polynomials[6] =
552 d_sbb_polynomials[7] =
559 d_sbb_polynomials[8] =
566 d_sbb_polynomials[9] =
587 double mult_factor) {
593 d_sbb_vertex_polynomials);
599 for (
size_t i = 0, k = 0; i < num_src_points; ++i) {
603 weight += d_sbb_vertex_polynomials[j] * d_data_weights[k];
605 weights[i].
weight = weight * mult_factor;
606 weights[i].
point_id = src_points[i];
613 size_t edge_weight_vector_data_buffer_size = 0;
615 for (
size_t i = 0; i < num_edges; ++i)
616 edge_weight_vector_data_buffer_size +=
624 (edge_weight_vector_data_buffer_size > 0)?
625 xmalloc(edge_weight_vector_data_buffer_size *
626 sizeof(*curr_edge_weight_vector_data)):NULL;
628 for (
size_t i = 0; i < num_edges; ++i) {
634 double direction[3] = {
643 for (
size_t j = 0; j < 2; ++j) {
650 curr_edge_weight_vector_data, 1.0/3.0);
652 curr_edge_weight_vector_data[n-1].
weight = 1.0;
653 curr_edge_weight_vector_data[n-1].
point_id =
655 curr_edge->
c[j].
data = curr_edge_weight_vector_data;
656 curr_edge->
c[j].
n = n;
658 direction[0] *= -1, direction[1] *= -1, direction[2] *= -1;
660 curr_edge_weight_vector_data += n;
666 void const * a,
void const * b) {
676 double abs_weight_a = fabs(weight_a->
weight);
677 double abs_weight_b = fabs(weight_b->
weight);
678 ret = (abs_weight_a > abs_weight_b) - (abs_weight_a < abs_weight_b);
685 void const * a,
void const * b) {
697 void const * a,
void const * b) {
711 for (
size_t i = 0; i < n_; ++i) {
712 buffer[i].
weight = weights + i;
722 for (
size_t i = 1; i < n_; ++i, ++curr_weight_data_pos) {
727 if (prev_weight_data_pos->
pos > curr_weight_data_pos->
pos)
728 prev_weight_data_pos->
pos = curr_weight_data_pos->
pos;
731 ++prev_weight_data_pos;
732 *prev_weight_data_pos = *curr_weight_data_pos;
733 prev_weight_data = prev_weight_data_pos->
weight;
737 if (n_ == new_n)
return;
741 for (
size_t i = 0; i < new_n; ++i) weights[i] = *(buffer[i].
weight);
756 sizeof(*weight_vector_data_buffer));
760 sizeof(*weight_vector_data_pos_buffer));
763 for (
size_t i = 0; i < num_triangles; ++i, ++curr_triangle) {
795 size_t src_points[3] = {
803 {.
weight = 1.0, .point_id = src_points[0]},
804 {.weight = 1.0, .point_id = src_points[1]},
805 {.weight = 1.0, .point_id = src_points[2]}};
807 {.data = &(c_3_data[1]), .
n = 1},
808 {.data = &(c_3_data[2]), .
n = 1}};
819 double corner_coordinate_xyz[3][3] = {
833 &(curr_edges[0]->
g[0]), &(curr_edges[1]->g[0]), &(curr_edges[2]->
g[0])};
836 double b_g[3][3] = {{g[0][0], g[0][1], g[0][2]},
837 {g[1][0], g[1][1], g[1][2]},
838 {g[2][0], g[2][1], g[2][2]}};
862#define COPY_D_DATA(edge_idx) \
864 get_derivative_weights( \
865 curr_edges[edge_idx]->middle_d_data.gauss_nnn_patch, \
866 curr_edges[edge_idx]->middle_d_data.coordinate_xyz, g[edge_idx], \
867 weight_vector_data_buffer + n, 1.0 / 3.0); \
868 n += curr_edges[edge_idx]->middle_d_data.gauss_nnn_patch->num_src_points; \
870#define COPY_COEFF(c_ijk, edge_idx, b_idx, bw_factor) \
872 struct weight_vector_data * curr_buffer = weight_vector_data_buffer + n; \
873 size_t curr_n = c_ijk->n; \
874 memcpy(curr_buffer, c_ijk->data, curr_n * sizeof(*curr_buffer)); \
876 double factor = - bw[edge_idx] * b_g[edge_idx][b_idx] * bw_factor; \
877 for (size_t i_ = 0; i_ < curr_n; ++i_) curr_buffer[i_].weight *= factor; \
879#define MULT_COEFF(edge_idx) \
881 double factor = 1.0 / (2.0 * bw[edge_idx] * b_g[edge_idx][edge_idx]); \
882 for (size_t i_ = 0; i_ < n; ++i_) \
883 weight_vector_data_buffer[i_].weight *= factor; \
885#define COMPACT_WEIGHTS(edge_idx) \
887 compact_weight_vector_data( \
888 weight_vector_data_buffer, &n, weight_vector_data_pos_buffer); \
889 curr_triangle->c_111_a[edge_idx].data = \
890 xmalloc(n * sizeof(*(curr_triangle->c_111_a[edge_idx].data))); \
891 memcpy(curr_triangle->c_111_a[edge_idx].data, weight_vector_data_buffer, \
892 n * sizeof(*weight_vector_data_buffer)); \
893 curr_triangle->c_111_a[edge_idx].n = n; \
950#undef COMPACT_WEIGHTS
955 free(weight_vector_data_buffer);
956 free(weight_vector_data_pos_buffer);
966 "ERROR(get_max_num_weights): invalid type_flag")
979 triangle_data->
edges[0]->
c[0].
n + triangle_data->
edges[0]->
c[1].
n +
980 triangle_data->
edges[1]->
c[0].
n + triangle_data->
edges[1]->
c[1].
n +
981 triangle_data->
edges[2]->
c[0].
n + triangle_data->
edges[2]->
c[1].
n +
1003 double * sb_coords = tgt_point_data->
sb_coords;
1009 double B_300 = sb_coords[0] * sb_coords[0] * sb_coords[0];
1010 double B_030 = sb_coords[1] * sb_coords[1] * sb_coords[1];
1011 double B_210 = 3.0 * sb_coords[0] * sb_coords[0] * sb_coords[1];
1012 double B_120 = 3.0 * sb_coords[0] * sb_coords[1] * sb_coords[1];
1021 size_t * src_points = tgt_point_data->
src_points;
1025 weights[0].
weight = B_300;
1026 weights[0].
point_id = src_points[0];
1029 weights[1].
weight = B_030;
1030 weights[1].
point_id = src_points[1];
1033 memcpy(curr_weights, c[0].data, c[0].n *
sizeof(*curr_weights));
1034 for (
size_t i = 0; i < c[0].
n; ++i) curr_weights[i].
weight *= B_210;
1036 curr_weights += c[0].
n;
1037 memcpy(curr_weights, c[1].data, c[1].n *
sizeof(*curr_weights));
1038 for (
size_t i = 0; i < c[1].
n; ++i) curr_weights[i].
weight *= B_120;
1040 *n = 2 + c[0].
n + c[1].
n;
1044 double * sb_coords,
double * A) {
1046 double b[3] = {sb_coords[1]*sb_coords[1] * sb_coords[2]*sb_coords[2],
1047 sb_coords[0]*sb_coords[0] * sb_coords[2]*sb_coords[2],
1048 sb_coords[0]*sb_coords[0] * sb_coords[1]*sb_coords[1]};
1049 double temp = 1.0 / (b[0] + b[1] + b[2]);
1051 for (
size_t i = 0; i < 3; ++i) {
1053 if (fabs(b[i]) < 1e-9) A[i] = 0.0;
1054 else A[i] = b[i] * temp;
1063 double * sb_coords = tgt_point_data->
sb_coords;
1076 double B_vertex[3] =
1077 {sb_coords[0] * sb_coords[0] * sb_coords[0],
1078 sb_coords[1] * sb_coords[1] * sb_coords[1],
1079 sb_coords[2] * sb_coords[2] * sb_coords[2]};
1080 double B_edge[3][2] =
1081 {{3.0 * sb_coords[1] * sb_coords[1] * sb_coords[2],
1082 3.0 * sb_coords[1] * sb_coords[2] * sb_coords[2]},
1083 {3.0 * sb_coords[0] * sb_coords[0] * sb_coords[2],
1084 3.0 * sb_coords[0] * sb_coords[2] * sb_coords[2]},
1085 {3.0 * sb_coords[0] * sb_coords[0] * sb_coords[1],
1086 3.0 * sb_coords[0] * sb_coords[1] * sb_coords[1]}};
1087 double B_111 = 6.0 * sb_coords[0] * sb_coords[1] * sb_coords[2];
1092 for (
size_t i = 0; i < 3; ++i) {
1093 weights[i].
weight = B_vertex[i];
1101 {&(curr_edges[0]->
c[0]),
1102 &(curr_edges[0]->c[1])},
1103 {&(curr_edges[1]->
c[0]),
1104 &(curr_edges[1]->c[1])},
1105 {&(curr_edges[2]->
c[0]),
1106 &(curr_edges[2]->c[1])}
1108 for (
size_t edge_idx = 0; edge_idx < 3; ++edge_idx) {
1109 for (
size_t i = 0; i < 2; ++i) {
1111 size_t curr_n = c_ijk[edge_idx][i]->
n;
1113 memcpy(curr_weights, c_ijk[edge_idx][i]->data,
1114 c_ijk[edge_idx][i]->n *
sizeof(*curr_weights));
1115 double B = B_edge[edge_idx][i];
1116 for (
size_t j = 0; j < curr_n; ++j)
1117 curr_weights[j].
weight *= B;
1129 for (
size_t i = 0; i < 3; ++i) {
1131 size_t curr_n = c_111_a[i].
n;
1133 memcpy(curr_weights, c_111_a[i].data, curr_n *
sizeof(*curr_weights));
1134 double B_111_x_A_i = B_111 * A[i];
1135 for (
size_t j = 0; j < curr_n; ++j)
1136 curr_weights[j].
weight *= B_111_x_A_i;
1151 "ERROR(compute_hcsbb_weights): invalid type_flag")
1175 size_t * total_num_weights) {
1189 size_t weight_vector_data_array_size = 0;
1190 size_t total_num_weights_ = 0;
1191 size_t * num_weights_per_tgt_ =
1192 xmalloc(num_tgt_points *
sizeof(*num_weights_per_tgt_));
1198 sizeof(*compact_buffer));
1204 for (
size_t i = 0; i < (num_tgt_points + 127) / 128; ++i) {
1206 size_t curr_num_tgt_points =
MIN(128, num_tgt_points - i * 128);
1208 tgt_point_data + i * 128;
1209 size_t * curr_num_weights_per_tgt = num_weights_per_tgt_ + i * 128;
1211 size_t curr_max_num_weights = 0;
1212 for (
size_t j = 0; j < curr_num_tgt_points; ++j)
1216 total_num_weights_ + curr_max_num_weights);
1218 for (
size_t j = 0; j < curr_num_tgt_points; ++j) {
1221 curr_num_weights_per_tgt + j, compact_buffer);
1222 total_num_weights_ += curr_num_weights_per_tgt[j];
1226 free(compact_buffer);
1231 *num_weights_per_tgt = num_weights_per_tgt_;
1232 *total_num_weights = total_num_weights_;
1236 const void * a,
const void * b) {
1245 for (
int i = 0; i <= (int)a_->
type_flag; ++i)
1253 double bnd_triangle[][3]) {
1258 memcpy(point_coords[i], coords[
points[i]], 3 *
sizeof(
double));
1261 &(point_coords[0][0]),
HCSBB_D_NNN, bnd_triangle, 16);
1266 double const * tri_a = a, * tri_b = b;
1269 for (
size_t i = 0; (!ret) && (i < 9); ++i) {
1270 double a_ = tri_a[i], b_ = tri_b[i];
1271 if (fabs(a_ - b_) > 1e-9) ret = (a_ > b_) - (a_ < b_);
1279 double bnd_triangle[3][3]) {
1281#if HCSBB_GAUSS_ORDER == 3
1283 {1.0-0.333333333333333-0.333333333333333,0.333333333333333,0.333333333333333},
1284 {1.0-0.200000000000000-0.200000000000000,0.200000000000000,0.200000000000000},
1285 {1.0-0.600000000000000-0.200000000000000,0.600000000000000,0.200000000000000},
1286 {1.0-0.200000000000000-0.600000000000000,0.200000000000000,0.600000000000000}
1288#elif HCSBB_GAUSS_ORDER == 4
1290 {1.0-0.091576213509771-0.091576213509771,0.091576213509771,0.091576213509771},
1291 {1.0-0.816847572980459-0.091576213509771,0.816847572980459,0.091576213509771},
1292 {1.0-0.091576213509771-0.816847572980459,0.091576213509771,0.816847572980459},
1293 {1.0-0.445948490915965-0.445948490915965,0.445948490915965,0.445948490915965},
1294 {1.0-0.108103018168070-0.445948490915965,0.108103018168070,0.445948490915965},
1295 {1.0-0.445948490915965-0.108103018168070,0.445948490915965,0.108103018168070}
1297#elif HCSBB_GAUSS_ORDER == 5
1299 {1.0-0.333333333333333-0.333333333333333,0.333333333333333,0.333333333333333},
1300 {1.0-0.101286507323456-0.101286507323456,0.101286507323456,0.101286507323456},
1301 {1.0-0.797426985353087-0.101286507323456,0.797426985353087,0.101286507323456},
1302 {1.0-0.101286507323456-0.797426985353087,0.101286507323456,0.797426985353087},
1303 {1.0-0.470142064105115-0.470142064105115,0.470142064105115,0.470142064105115},
1304 {1.0-0.059715871789770-0.470142064105115,0.059715871789770,0.470142064105115},
1305 {1.0-0.470142064105115-0.059715871789770,0.470142064105115,0.059715871789770}
1307#elif HCSBB_GAUSS_ORDER == 6
1309 {1.0-0.063089014491502-0.063089014491502,0.063089014491502,0.063089014491502},
1310 {1.0-0.873821971016996-0.063089014491502,0.873821971016996,0.063089014491502},
1311 {1.0-0.063089014491502-0.873821971016996,0.063089014491502,0.873821971016996},
1312 {1.0-0.249286745170910-0.249286745170910,0.249286745170910,0.249286745170910},
1313 {1.0-0.501426509658179-0.249286745170910,0.501426509658179,0.249286745170910},
1314 {1.0-0.249286745170910-0.501426509658179,0.249286745170910,0.501426509658179},
1315 {1.0-0.310352451033785-0.053145049844816,0.310352451033785,0.053145049844816},
1316 {1.0-0.053145049844816-0.310352451033785,0.053145049844816,0.310352451033785},
1317 {1.0-0.636502499121399-0.053145049844816,0.636502499121399,0.053145049844816},
1318 {1.0-0.053145049844816-0.636502499121399,0.053145049844816,0.636502499121399},
1319 {1.0-0.636502499121399-0.310352451033785,0.636502499121399,0.310352451033785},
1320 {1.0-0.310352451033785-0.636502499121399,0.310352451033785,0.636502499121399}
1322#elif HCSBB_GAUSS_ORDER == 7
1324 {1.0-0.333333333333333-0.333333333333333,0.333333333333333,0.333333333333333},
1325 {1.0-0.260345966079038-0.260345966079038,0.260345966079038,0.260345966079038},
1326 {1.0-0.479308067841923-0.260345966079038,0.479308067841923,0.260345966079038},
1327 {1.0-0.260345966079038-0.479308067841923,0.260345966079038,0.479308067841923},
1328 {1.0-0.065130102902216-0.065130102902216,0.065130102902216,0.065130102902216},
1329 {1.0-0.869739794195568-0.065130102902216,0.869739794195568,0.065130102902216},
1330 {1.0-0.065130102902216-0.869739794195568,0.065130102902216,0.869739794195568},
1331 {1.0-0.312865496004874-0.048690315425316,0.312865496004874,0.048690315425316},
1332 {1.0-0.048690315425316-0.312865496004874,0.048690315425316,0.312865496004874},
1333 {1.0-0.638444188569809-0.048690315425316,0.638444188569809,0.048690315425316},
1334 {1.0-0.048690315425316-0.638444188569809,0.048690315425316,0.638444188569809},
1335 {1.0-0.638444188569809-0.312865496004874,0.638444188569809,0.312865496004874},
1336 {1.0-0.312865496004874-0.638444188569809,0.312865496004874,0.638444188569809}
1338#elif HCSBB_GAUSS_ORDER == 8
1340 {1.0-0.333333333333333-0.333333333333333,0.333333333333333,0.333333333333333},
1341 {1.0-0.081414823414554-0.459292588292723,0.081414823414554,0.459292588292723},
1342 {1.0-0.459292588292723-0.081414823414554,0.459292588292723,0.081414823414554},
1343 {1.0-0.459292588292723-0.459292588292723,0.459292588292723,0.459292588292723},
1344 {1.0-0.658861384496480-0.170569307751760,0.658861384496480,0.170569307751760},
1345 {1.0-0.170569307751760-0.658861384496480,0.170569307751760,0.658861384496480},
1346 {1.0-0.170569307751760-0.170569307751760,0.170569307751760,0.170569307751760},
1347 {1.0-0.898905543365938-0.050547228317031,0.898905543365938,0.050547228317031},
1348 {1.0-0.050547228317031-0.898905543365938,0.050547228317031,0.898905543365938},
1349 {1.0-0.050547228317031-0.050547228317031,0.050547228317031,0.050547228317031},
1350 {1.0-0.008394777409958-0.263112829634638,0.008394777409958,0.263112829634638},
1351 {1.0-0.263112829634638-0.008394777409958,0.263112829634638,0.008394777409958},
1352 {1.0-0.008394777409958-0.728492392955404,0.008394777409958,0.728492392955404},
1353 {1.0-0.728492392955404-0.008394777409958,0.728492392955404,0.008394777409958},
1354 {1.0-0.263112829634638-0.728492392955404,0.263112829634638,0.728492392955404},
1355 {1.0-0.728492392955404-0.263112829634638,0.728492392955404,0.263112829634638}
1358 static double const abscissa[1][3];
1359#error "interpolation_method_hcsbb: the specified gauss order is currently not supported."
1364 gauss_vertices[i][0] = bnd_triangle[0][0] * abscissa[i][0] +
1365 bnd_triangle[1][0] * abscissa[i][1] +
1366 bnd_triangle[2][0] * abscissa[i][2];
1367 gauss_vertices[i][1] = bnd_triangle[0][1] * abscissa[i][0] +
1368 bnd_triangle[1][1] * abscissa[i][1] +
1369 bnd_triangle[2][1] * abscissa[i][2];
1370 gauss_vertices[i][2] = bnd_triangle[0][2] * abscissa[i][0] +
1371 bnd_triangle[1][2] * abscissa[i][1] +
1372 bnd_triangle[2][2] * abscissa[i][2];
1373 double scale = 1.0 / sqrt(gauss_vertices[i][0] * gauss_vertices[i][0] +
1374 gauss_vertices[i][1] * gauss_vertices[i][1] +
1375 gauss_vertices[i][2] * gauss_vertices[i][2]);
1376 gauss_vertices[i][0] *= scale;
1377 gauss_vertices[i][1] *= scale;
1378 gauss_vertices[i][2] *= scale;
1379 gauss_sb_coords[i][0] = abscissa[i][0] * scale;
1380 gauss_sb_coords[i][1] = abscissa[i][1] * scale;
1381 gauss_sb_coords[i][2] = abscissa[i][2] * scale;
1392#define POW_0(x) (1.0)
1393#define POW_1(x) ((x))
1394#define POW_2(x) ((x)*(x))
1395#define POW_3(x) ((x)*(x)*(x))
1402 sbb_polynomials[0][vertex_idx] =
1407 sbb_polynomials[1][vertex_idx] =
1412 sbb_polynomials[2][vertex_idx] =
1417 sbb_polynomials[3][vertex_idx] =
1422 sbb_polynomials[4][vertex_idx] =
1427 sbb_polynomials[5][vertex_idx] =
1432 sbb_polynomials[6][vertex_idx] =
1437 sbb_polynomials[7][vertex_idx] =
1442 sbb_polynomials[8][vertex_idx] =
1447 sbb_polynomials[9][vertex_idx] =
1465#ifdef YAC_LAPACK_NO_DSYTR
1476 !LAPACKE_dgetri_work(
1480 "internal ERROR: dgetri")
1486 !LAPACKE_dsytrf_work(
1492 !LAPACKE_dsytri_work(
1495 "internal ERROR: dsytri")
1505 double (*gauss_vertices)[3],
1511 3 *
sizeof(*bnd_triangle));
1534 accu += gauss_sbb_polynomials[i][k] * gauss_sbb_polynomials[j][k];
1548 accu += C[i][k] * gauss_sbb_polynomials[k][j];
1557 struct gauss_nnn_patch * gauss_nnn_patches,
size_t num_gauss_nnn_patches) {
1559 for (
size_t i = 0; i < num_gauss_nnn_patches; ++i) {
1562 free(gauss_nnn_patches[i].weights);
1565 free(gauss_nnn_patches);
1575 double (**unique_bnd_triangles_)[3][3],
size_t ** coord_to_triangle) {
1579 size_t * nnn_search_results =
1582 interp_grid, coords, count,
HCSBB_D_NNN, nnn_search_results, M_PI);
1589 for (
size_t i = 0, j = count - 1; i < count; ++i, --j) {
1591 size_t * curr_nnn_search_results =
1595 nnn_search_result_global_ids[k] =
1596 src_global_ids[curr_nnn_search_results[k]];
1599 nnn_search_result_global_ids,
HCSBB_D_NNN, curr_nnn_search_results);
1601 memmove(nnn_search_results + j * (
HCSBB_D_NNN + 1),
1602 curr_nnn_search_results,
1609 qsort(nnn_search_results, count,
1613 size_t * coord_to_search_results =
1614 xmalloc(count *
sizeof(*coord_to_search_results));
1615 size_t num_unique_search_results = 0;
1618 dummy_search_results[i] = SIZE_MAX;
1619 for (
size_t i = 0, * prev_search_result = dummy_search_results;
1622 size_t * curr_search_result = nnn_search_results + i * (
HCSBB_D_NNN + 1);
1623 size_t coord_idx = curr_search_result[
HCSBB_D_NNN];
1625 prev_search_result = curr_search_result;
1626 ++num_unique_search_results;
1628 coord_to_search_results[coord_idx] = num_unique_search_results - 1;
1639 xmalloc(num_unique_search_results *
sizeof(*bnd_triangles_reorder));
1640 for (
size_t i = 0, j = 0, * prev_search_result = dummy_search_results;
1643 size_t * curr_search_result = nnn_search_results + i * (
HCSBB_D_NNN + 1);
1646 curr_search_result, src_point_coords, bnd_triangles_reorder[j].
coords);
1648 prev_search_result = curr_search_result;
1652 free(nnn_search_results);
1655 qsort(bnd_triangles_reorder, num_unique_search_results,
1659 size_t * search_result_to_bnd_triangle =
1660 xmalloc(num_unique_search_results *
sizeof(*search_result_to_bnd_triangle));
1661 double (*unique_bnd_triangles)[3][3] = (double(*)[3][3])bnd_triangles_reorder;
1662 size_t num_unique_triangles = 0;
1663 double dummy_bnd_triangle[3][3] = {{-1,-1,-1},{-1,-1,-1},{-1,-1,-1}};
1664 double (*prev_bnd_triangle)[3] = dummy_bnd_triangle;
1665 for (
size_t i = 0; i < num_unique_search_results; ++i) {
1666 double (*curr_bnd_triangle)[3] = bnd_triangles_reorder[i].
coords;
1669 memmove(unique_bnd_triangles[num_unique_triangles], curr_bnd_triangle,
1670 sizeof(*unique_bnd_triangles));
1671 ++num_unique_triangles;
1672 prev_bnd_triangle = curr_bnd_triangle;
1674 search_result_to_bnd_triangle[
reorder_idx] = num_unique_triangles - 1;
1678 for (
size_t i = 0; i < count; ++i)
1679 coord_to_search_results[i] =
1680 search_result_to_bnd_triangle[coord_to_search_results[i]];
1681 free(search_result_to_bnd_triangle);
1683 *num_unique_triangles_ = num_unique_triangles;
1684 *unique_bnd_triangles_ =
1686 num_unique_triangles *
sizeof(*unique_bnd_triangles));
1687 *coord_to_triangle =
1688 xrealloc(coord_to_search_results, count *
sizeof(*coord_to_search_results));
1701 struct yac_interp_grid * interp_grid,
size_t * num_gauss_nnn_patches_,
1709 for (
size_t i = 0; i < num_vertices; ++i)
1710 memcpy(
coords[i], vertex_data[i].coordinate_xyz,
sizeof(*
coords));
1711 for (
size_t i = 0; i < num_edges; ++i)
1716 size_t num_gauss_nnn_patches;
1717 double (*bnd_triangles)[3][3];
1718 size_t * coord_to_gauss_nnn_patch;
1720 num_vertices + num_edges,
coords, interp_grid,
1721 &num_gauss_nnn_patches, &bnd_triangles, &coord_to_gauss_nnn_patch);
1725 xmalloc(num_gauss_nnn_patches *
sizeof(*gauss_nnn_patches));
1727 xmalloc(num_gauss_nnn_patches *
sizeof(*gauss_points));
1733 *num_gauss_nnn_patches_ = num_gauss_nnn_patches;
1734 *gauss_nnn_patches_ = gauss_nnn_patches;
1737 for (
size_t i = 0; i < num_gauss_nnn_patches; ++i)
1739 gauss_nnn_patches + i, bnd_triangles[i],
1740 gauss_points[i], gauss_sbb_polynomials_buffer, work_buffer);
1742 free(gauss_sbb_polynomials_buffer);
1743 free(bnd_triangles);
1745 for (
size_t i = 0; i < num_vertices; ++i)
1747 gauss_nnn_patches + coord_to_gauss_nnn_patch[i];
1748 for (
size_t i = 0; i < num_edges; ++i)
1750 gauss_nnn_patches + coord_to_gauss_nnn_patch[i + num_vertices];
1751 free(coord_to_gauss_nnn_patch);
1754 size_t * nnn_search_results =
1756 sizeof(*nnn_search_results));
1766 size_t * src_point_buffer =
1777 for (
size_t i = 0; i < num_gauss_nnn_patches; ++i)
1779 gauss_nnn_patches + i, gauss_points[i],
1781 w_nnn_buffer, src_point_buffer, global_id_buffer, src_point_coords,
1782 src_point_global_ids);
1784 free(nnn_search_results);
1785 free(global_id_buffer);
1786 free(src_point_buffer);
1792 double * check_coord,
int num_vertices,
size_t const * vertices,
1795 size_t * triangle,
double * sb_coords) {
1798 size_t num_triangles = (size_t)(num_vertices - 2);
1799 size_t triangle_indices[num_triangles][3];
1801 vertices, num_vertices, vertex_start_idx, &(triangle_indices[0]));
1804 for (
size_t i = 0; (!ret) && (i < num_triangles); ++i) {
1806 triangle[0] = triangle_indices[i][0];
1807 triangle[1] = triangle_indices[i][1];
1808 triangle[2] = triangle_indices[i][2];
1810 {global_ids[triangle[0]],
1811 global_ids[triangle[1]],
1812 global_ids[triangle[2]]};
1817 double triangle_coords[3][3];
1818 for (
int j = 0; j < 3; ++j)
1820 triangle_coords[j], point_coords[triangle[j]], 3 *
sizeof(
double));
1822 sb_coords[0] = check_coord[0];
1823 sb_coords[1] = check_coord[1];
1824 sb_coords[2] = check_coord[2];
1837 double * tgt_coord,
size_t src_cell,
1840 size_t * src_triangle_vertices,
double * sb_coords) {
1842 size_t const * src_vertices =
1850 size_t lowest_vertex_id_idx = 0;
1852 yac_int lowest_vertex_id = vertex_ids[src_vertices[0]];
1853 for (
int i = 1; i < num_src_vertices; ++i) {
1854 if (vertex_ids[src_vertices[i]] < lowest_vertex_id) {
1855 lowest_vertex_id = vertex_ids[src_vertices[i]];
1856 lowest_vertex_id_idx = i;
1863 tgt_coord, num_src_vertices, src_vertices, lowest_vertex_id_idx,
1864 vertex_ids, src_point_coords, src_triangle_vertices, sb_coords);
1868 double * tgt_coord,
size_t src_cell,
1871 size_t * vertex_to_cell,
size_t * vertex_to_cell_offsets,
1872 int * num_cells_per_vertex,
size_t * src_triangle,
double * sb_coords) {
1875 size_t const * curr_vertices =
1883 for (
size_t i = 0; (!ret) && (i < num_vertices); ++i) {
1885 size_t curr_vertex = curr_vertices[i];
1887 int curr_num_src_cells = num_cells_per_vertex[curr_vertex];
1888 if (curr_num_src_cells == 0)
continue;
1890 size_t * curr_src_cells =
1891 vertex_to_cell + vertex_to_cell_offsets[curr_vertex];
1897 tgt_coord, curr_num_src_cells, curr_src_cells, 0, cell_ids,
1898 src_point_coords, src_triangle, sb_coords);
1905 size_t num_tgt_points,
size_t * selected_tgt,
size_t * tgt_points,
1913 xmalloc(num_tgt_points *
sizeof(*tgt_point_data));
1917 size_t * vertex_to_cell = NULL;
1918 size_t * vertex_to_cell_offsets = NULL;
1919 int * num_cells_per_vertex = NULL;
1922 interp_grid, src_cells, num_tgt_points,
1923 &vertex_to_cell, &vertex_to_cell_offsets, &num_cells_per_vertex);
1935 for (
size_t i = 0; i < num_tgt_points; ++i, ++tgt_point_data) {
1937 size_t tgt_idx = selected_tgt[i];
1939 double * tgt_coord = tgt_coords[tgt_idx];
1940 tgt_point_data->
tgt_point = tgt_points[tgt_idx];
1942 tgt_point_data->
coordinate_xyz, tgt_coord, 3 *
sizeof(*tgt_coord));
1947 size_t src_triangle_vertices[3];
1948 double sb_coords[3];
1952 "ERROR(init_tgt_point_search_data): invalid source location")
1956 tgt_coord, src_cells[i], src_grid_data, src_point_coords,
1957 src_triangle_vertices, sb_coords);
1961 tgt_coord, src_cells[i], src_grid_data, src_point_coords,
1962 vertex_to_cell, vertex_to_cell_offsets, num_cells_per_vertex,
1963 src_triangle_vertices, sb_coords);
1968 int tmp_type_flag = -1;
1970 for (
size_t k = 0; k < 3; ++k) {
1973 tgt_point_data->
src_points[tmp_type_flag] = src_triangle_vertices[k];
1974 tgt_point_data->
sb_coords[tmp_type_flag] = sb_coords[k];
1976 if (src_mask != NULL) is_masked |= !src_mask[src_triangle_vertices[k]];
1985 free(num_cells_per_vertex);
1986 free(vertex_to_cell_offsets);
1987 free(vertex_to_cell);
1989 return tgt_point_data - num_tgt_points;
1993 size_t num_vertices,
size_t * vertices,
2000 xmalloc(num_vertices *
sizeof(*vertex_data));
2002 for (
size_t i = 0; i < num_vertices; ++i) {
2003 size_t vertex_idx = vertices[i];
2005 src_point_coords[vertex_idx],
sizeof(*src_point_coords));
2013 size_t num_edges,
size_t (*edge_to_vertex_d_data)[2],
2017 xmalloc(num_edges *
sizeof(*edge_data));
2019 for (
size_t i = 0; i < num_edges; ++i) {
2022 edge_data[i].
vertex_d_data[0] = vertex_data + edge_to_vertex_d_data[i][0];
2023 edge_data[i].
vertex_d_data[1] = vertex_data + edge_to_vertex_d_data[i][1];
2025 double * vertex_coordinates_xyz[2] = {
2031 middle_point[0] = vertex_coordinates_xyz[0][0] +
2032 vertex_coordinates_xyz[1][0];
2033 middle_point[1] = vertex_coordinates_xyz[0][1] +
2034 vertex_coordinates_xyz[1][1];
2035 middle_point[2] = vertex_coordinates_xyz[0][2] +
2036 vertex_coordinates_xyz[1][2];
2038 1.0 / sqrt(middle_point[0] * middle_point[0] +
2039 middle_point[1] * middle_point[1] +
2040 middle_point[2] * middle_point[2]);
2041 middle_point[0] *= sb_coord;
2042 middle_point[1] *= sb_coord;
2043 middle_point[2] *= sb_coord;
2048 crossproduct_d(vertex_coordinates_xyz[0], vertex_coordinates_xyz[1],
2049 &(edge_data[i].
g[0]));
2056 size_t num_triangles,
size_t (*triangle_to_edge_data)[3],
2060 xmalloc(num_triangles *
sizeof(*triangle_data));
2062 for (
size_t i = 0; i < num_triangles; ++i) {
2065 triangle_data[i].
edges[0] = edge_data + triangle_to_edge_data[i][0];
2066 triangle_data[i].
edges[1] = edge_data + triangle_to_edge_data[i][1];
2067 triangle_data[i].
edges[2] = edge_data + triangle_to_edge_data[i][2];
2070 return triangle_data;
2075 size_t * tgt_points,
size_t count,
2082 "ERROR(do_search_hcsbb): invalid number of source fields")
2089 "ERROR(do_search_hcsbb): unsupported source field location type")
2094 interp_grid, tgt_points, count, tgt_coords);
2096 size_t * size_t_buffer =
xmalloc(2 * count *
sizeof(*size_t_buffer));
2097 size_t * src_cells = size_t_buffer;
2098 size_t * reorder_idx = size_t_buffer + count;
2103 interp_grid, tgt_coords, count, src_cells);
2107 for (
size_t i = 0; i < count; ++i) reorder_idx[i] = i;
2111 size_t temp_result_count = 0;
2112 for (temp_result_count = 0; temp_result_count < count; ++temp_result_count)
2113 if (src_cells[temp_result_count] == SIZE_MAX)
break;
2119 temp_result_count, reorder_idx, tgt_points, tgt_coords, src_cells,
2125 qsort(tgt_point_data, temp_result_count,
sizeof(*tgt_point_data),
2129 for (
size_t i = temp_result_count; i < count; ++i)
2130 reorder_idx[i] = tgt_points[reorder_idx[i]];
2131 memcpy(tgt_points + temp_result_count, reorder_idx + temp_result_count,
2132 (count - temp_result_count) *
sizeof(*tgt_points));
2135 for (
size_t i = 0; i < temp_result_count; ++i)
2136 tgt_points[i] = tgt_point_data[i].
tgt_point;
2137 free(size_t_buffer);
2140 size_t result_count = 0;
2141 size_t result_counts[3] = {0,0,0};
2142 for (result_count = 0; result_count < temp_result_count; ++result_count) {
2143 if (tgt_point_data[result_count].
is_masked)
break;
2144 else result_counts[(int)(tgt_point_data[result_count].
type_flag)]++;
2150 size_t * unique_vertices;
2151 size_t (*unique_edge_to_unique_vertex)[2];
2152 size_t (*unique_triangle_to_unique_edge)[3];
2153 size_t num_unique_vertices, num_unique_edges, num_unique_triangles;
2155 tgt_point_data + result_counts[0], result_counts[1], result_counts[2],
2156 &unique_vertices, &num_unique_vertices,
2157 &unique_edge_to_unique_vertex, &num_unique_edges,
2158 &unique_triangle_to_unique_edge, &num_unique_triangles);
2163 num_unique_vertices, unique_vertices, interp_grid);
2166 num_unique_edges, unique_edge_to_unique_vertex, vertex_data);
2169 num_unique_triangles, unique_triangle_to_unique_edge, edge_data);
2170 free(unique_vertices);
2171 free(unique_edge_to_unique_vertex);
2172 free(unique_triangle_to_unique_edge);
2175 for (
size_t i = result_counts[0];
2176 i < result_counts[0] + result_counts[1]; ++i)
2177 tgt_point_data[i].interp_data.
edge =
2179 for (
size_t i = result_counts[0] + result_counts[1];
2180 i < result_counts[0] + result_counts[1] + result_counts[2]; ++i)
2181 tgt_point_data[i].interp_data.
triangle =
2186 size_t num_gauss_nnn_patches;
2189 num_unique_vertices, vertex_data, num_unique_edges, edge_data, interp_grid,
2190 &num_gauss_nnn_patches, &gauss_nnn_patches);
2194 size_t * num_weights_per_tgt, total_num_weights;
2196 edge_data, num_unique_edges,
2197 triangle_data, num_unique_triangles,
2200 if (num_unique_edges > 0) free(edge_data->
c[0].
data);
2202 for (
size_t i = 0; i < num_unique_triangles; ++i)
2203 for (
size_t j = 0; j < 3; ++j) free(triangle_data[i].c_111_a[j].data);
2204 free(triangle_data);
2205 free(tgt_point_data);
2210 size_t * src_points =
xmalloc(total_num_weights *
sizeof(*src_points));
2211 double * weight_data =
xmalloc(total_num_weights *
sizeof(*weight_data));
2212 for (
size_t i = 0; i < total_num_weights; ++i) {
2220 interp_grid, 0, src_points, total_num_weights);
2225 interp_grid, tgt_points, result_count),
2226 .count = result_count};
2230 weights, &tgts, num_weights_per_tgt, srcs, weight_data);
2236 free(num_weights_per_tgt);
2238 return result_count;
void yac_compute_bnd_triangle(double *vertices, size_t num_vertices, double triangle[][3], size_t num_tests)
int const * const_int_pointer
yac_int const * const_yac_int_pointer
#define ENSURE_ARRAY_SIZE(arrayp, curr_array_size, req_size)
void yac_triangulate_cell_indices(size_t const *corner_indices, size_t num_corners, size_t start_corner, size_t(*triangle_indices)[3])
static void crossproduct_d(const double a[], const double b[], double cross[])
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)
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_aux_grid_src(struct yac_interp_grid *interp_grid, size_t *cells, size_t count, size_t **vertex_to_cell, size_t **vertex_to_cell_offsets, int **num_cells_per_vertex)
const_yac_int_pointer yac_interp_grid_get_src_field_global_ids(struct yac_interp_grid *interp_grid, size_t src_field_idx)
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)
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_do_points_search_gc(struct yac_interp_grid *interp_grid, yac_coordinate_pointer search_coords, size_t count, size_t *src_cells)
struct yac_const_basic_grid_data * yac_interp_grid_get_basic_grid_data_src(struct yac_interp_grid *interp_grid)
static struct triangle_interp_data * init_triangle_interp_data(size_t num_triangles, size_t(*triangle_to_edge_data)[3], struct edge_interp_data *edge_data)
static struct edge_interp_data * init_edge_interp_data(size_t num_edges, size_t(*edge_to_vertex_d_data)[2], struct vertex_interp_data *vertex_data)
static int compare_tgt_point_search_data(const void *a, const void *b)
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_gauss_nnn_patch(struct gauss_nnn_patch *gauss_nnn_patch, double(*gauss_points)[3], size_t *nnn_search_results, double w_nnn[][HCSBB_NUM_GAUSS_POINTS], size_t *src_point_buffer, yac_int *global_id_buffer, yac_const_coordinate_pointer src_point_coords, const_yac_int_pointer src_point_global_ids)
static struct vertex_interp_data * init_vertex_interp_data(size_t num_vertices, size_t *vertices, struct yac_interp_grid *interp_grid)
static int compare_HCSBB_D_NNN_size_t(const void *a, const void *b)
static int compare_size_t(const void *a, const void *b)
static void generate_d_data_triangle(size_t count, yac_coordinate_pointer coords, struct yac_interp_grid *interp_grid, size_t *num_unique_triangles_, double(**unique_bnd_triangles_)[3][3], size_t **coord_to_triangle)
static struct interp_method_vtable interp_method_hcsbb_vtable
#define HCSBB_NUM_SBB_COEFFS
#define HCSBB_NUM_GAUSS_POINTS
@ ON_EDGE
the target point is on an edge of the source point grid
static void compute_triangle_coefficients(struct triangle_interp_data *triangle_data, size_t num_triangles)
#define COMPACT_WEIGHTS(edge_idx)
#define COPY_D_DATA(edge_idx)
static void generate_derivative_data(size_t num_vertices, struct vertex_interp_data *vertex_data, size_t num_edges, struct edge_interp_data *edge_data, struct yac_interp_grid *interp_grid, size_t *num_gauss_nnn_patches_, struct gauss_nnn_patch **gauss_nnn_patches_)
static void compute_hcsbb_weights_vertex(struct tgt_point_search_data *tgt_point_data, struct weight_vector_data *weights, size_t *n)
#define MULT_COEFF(edge_idx)
static void compute_sb_coords(double *sb_coords, size_t num_vertices, double triangle[3][3])
static void generate_bnd_triangle(size_t *points, yac_const_coordinate_pointer coords, double bnd_triangle[][3])
static void compute_hcsbb_weights_edge(struct tgt_point_search_data *tgt_point_data, struct weight_vector_data *weights, size_t *n)
static void inverse(double A[HCSBB_NUM_SBB_COEFFS][HCSBB_NUM_SBB_COEFFS])
static void compute_hcsbb_weights(struct tgt_point_search_data *tgt_point_data, struct weight_vector_data *weights, size_t *n, struct weight_vector_data_pos *compact_buffer)
static void compact_weight_vector_data(struct weight_vector_data *weights, size_t *n, struct weight_vector_data_pos *buffer)
static void get_unique_interp_data(struct tgt_point_search_data *tgt_point_data, size_t num_edges, size_t num_triangles, size_t **unique_vertices, size_t *num_unique_vertices, size_t(**unique_edge_to_unique_vertex)[2], size_t *num_unique_edges, size_t(**unique_triangle_to_unique_edge)[3], size_t *num_unique_triangles)
static void delete_hcsbb(struct interp_method *method)
static void compute_edge_coefficients(struct edge_interp_data *edge_data, size_t num_edges)
static int compare_bnd_triangles(void const *a, void const *b)
static void compute_sbb_polynomials_gauss_3d(double sb_coords[HCSBB_NUM_GAUSS_POINTS][3], double sbb_polynomials[HCSBB_NUM_SBB_COEFFS][HCSBB_NUM_GAUSS_POINTS])
#define COPY_COEFF(c_ijk, edge_idx, b_idx, bw_factor)
static int compare_2_size_t(const void *a, const void *b)
static void init_gauss_nnn_patch(struct gauss_nnn_patch *gauss_nnn_patch, double(*bnd_triangle)[3], double(*gauss_vertices)[3], double gauss_sbb_polynomials[HCSBB_NUM_SBB_COEFFS][HCSBB_NUM_GAUSS_POINTS], double C[HCSBB_NUM_SBB_COEFFS][HCSBB_NUM_SBB_COEFFS])
static int check_polygon(double *check_coord, int num_vertices, size_t const *vertices, size_t vertex_start_idx, const_yac_int_pointer global_ids, yac_const_coordinate_pointer point_coords, size_t *triangle, double *sb_coords)
static int compare_3_size_t(const void *a, const void *b)
struct interp_method * yac_interp_method_hcsbb_new()
static int compare_weight_vector_data_point(void const *a, void const *b)
static void compute_hcsbb_weights_triangle(struct tgt_point_search_data *tgt_point_data, struct weight_vector_data *weights, size_t *n)
static size_t do_search_hcsbb(struct interp_method *method, struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count, struct yac_interp_weights *weights)
static void generate_gauss_legendre_points(double gauss_vertices[HCSBB_NUM_GAUSS_POINTS][3], double gauss_sb_coords[HCSBB_NUM_GAUSS_POINTS][3], double bnd_triangle[3][3])
static int compare_weight_vector_data_pos_pos(void const *a, void const *b)
static size_t get_max_num_weights(struct tgt_point_search_data *tgt_point_data)
static void evaluate_blending_function(double *sb_coords, double *A)
static int compare_weight_vector_data_pos_weight(void const *a, void const *b)
static int get_matching_aux_cell_triangle(double *tgt_coord, size_t src_cell, struct yac_const_basic_grid_data *src_grid_data, yac_const_coordinate_pointer src_point_coords, size_t *vertex_to_cell, size_t *vertex_to_cell_offsets, int *num_cells_per_vertex, size_t *src_triangle, double *sb_coords)
static void free_gauss_nnn_patches(struct gauss_nnn_patch *gauss_nnn_patches, size_t num_gauss_nnn_patches)
static int get_matching_vertex_triangle(double *tgt_coord, size_t src_cell, struct yac_const_basic_grid_data *src_grid_data, yac_const_coordinate_pointer src_point_coords, size_t *src_triangle_vertices, double *sb_coords)
static struct tgt_point_search_data * init_tgt_point_data(size_t num_tgt_points, size_t *selected_tgt, size_t *tgt_points, yac_coordinate_pointer tgt_coords, size_t *src_cells, struct yac_interp_grid *interp_grid)
static void get_derivative_weights(struct gauss_nnn_patch *gauss_nnn_patch, double coordinate_xyz[3], double direction[3], struct weight_vector_data *weights, double mult_factor)
static void compute_d_sbb_polynomials_3d(double bnd_triangle[3][3], double direction[3], double coordinate_xyz[3], double d_sbb_polynomials[HCSBB_NUM_SBB_COEFFS])
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)
double coordinate_xyz[3]
point at which a derivative is to be estimated
double sb_coord_middle_point
struct weight_vector c[2]
struct vertex_interp_data * vertex_d_data[2]
derivative data of both vertices
struct edge_interp_data::@19 middle_d_data
derivative data of edge middle point
struct gauss_nnn_patch * gauss_nnn_patch
gauss integration point patch used to estimate the derivative
double bnd_triangle[3][3]
bounding triangle
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)
information (global id and location) about a point that
structure containing the information (global id and location)
struct remote_point * data
enum interp_type_flag type_flag
depending on type flag interp_data contains a point to the required data
struct triangle_interp_data * triangle
union tgt_point_search_data::@20 interp_data
struct edge_interp_data * edge
struct weight_vector c_111_a[3]
weights for alpha values used to compute c_111
struct edge_interp_data * edges[3]
edges of the triangle (edge[0] is the on opposing corner src_points[0])
size_t src_point
index of the associacted source point
double coordinate_xyz[3]
coordinate of the source point
struct gauss_nnn_patch * gauss_nnn_patch
struct weight_vector_data * weight
struct weight_vector_data * data
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]
void yac_quicksort_index_yac_int_size_t(yac_int *a, size_t n, size_t *idx)
static void yac_remove_duplicates_size_t_3(size_t(*array)[3], size_t *n)
static void yac_remove_duplicates_size_t(size_t *array, size_t *n)
void yac_quicksort_index_size_t_size_t(size_t *a, size_t n, size_t *idx)
static void yac_remove_duplicates_size_t_2(size_t(*array)[2], size_t *n)
static struct user_input_data_points ** points
#define YAC_ASSERT(exp, msg)
double const (* yac_const_coordinate_pointer)[3]
double(* yac_coordinate_pointer)[3]